it-swarm.com.de

Verwendung von register_activation_hook in Klassen

Ich versuche, ein Plugin für grundlegende SEO-Zwecke zu entwickeln, da viele Leute, die ich kenne, Yoast nicht mögen. Ich habe das Plugin buchstäblich gerade gestartet und erstelle die Aktivierungsnachricht, die dem Benutzer angezeigt wird, wenn er das Plugin aktiviert. Ich habe Probleme mit einer Mischung aus OOP und integrierten Wordpress-Funktionen und bin mir nicht sicher, wo ich falsch liege.

Die einzige Möglichkeit, dies zum Laufen zu bringen, besteht darin, eine neue Instanz der Klasse SEO_Plugin_Activation in meinem Hauptdateikonstruktor zu erstellen und dann die activatePlugin-Methode in dieser Klasse aufzurufen. Ich halte das für unnötig. Ich denke auch, wie ich meine Funktionen in der Aktivierungsklassendatei ausführe, ist auch nicht wirklich sinnvoll. Aber nur so kann ich es jetzt zum Laufen bringen.

Ich bin mir nicht sicher, ob das, was ich tue, darauf zurückzuführen ist, dass ich OOP Techniken nicht zu 100% verstehe, oder ob ich die Wordpress-API nicht richtig verwende. Ich habe drei Codebeispiele in der folgenden Reihenfolge eingefügt:

  1. Haupt-Plugin-Datei
  2. Klassendatei, die meine Aktivierungsanforderungen behandelt
  3. Was ich wirklich gehofft hatte, konnte getan werden.

seo.php (Haupt-Plugin-Datei)

<?php
/*
... generic plugin info
*/

require_once(dirname(__FILE__) . '/admin/class-plugin-activation.php');

class SEO {
  function __construct() {
    $activate = new SEO_Plugin_Activation();
    $activate->activatePlugin();
  }

}

new SEO();
?>

class-plugin-activation.php

<?php
class SEO_Plugin_Activation {

  function __construct() {
    register_activation_hook(__FILE__ . '../seo.php', array($this, 'activatePlugin'));
    add_action('admin_notices', array($this, 'showSitemapInfo'));
  }

  function activatePlugin() {
    set_transient('show_sitemap_info', true, 5);
  }

  function showSitemapInfo() {
    if(get_transient('show_sitemap_info')) {
      echo '<div class="updated notice is-dismissible">' .
              'Your sitemap files can be found at these following links: ' .
            '</div>';
      delete_transient('show_sitemap_info');
    }
  }

}
?>

seo.php (auf was ich gehofft habe)

<?php
/*
 ... blah blah blah
*/

require_once(dirname(__FILE__) . '/admin/class-plugin-activation.php');

class SEO {
  function __construct() {
    register_activation_hook(__FILE__, array($this, 'wp_install'));
  }

  function wp_install() {
    $activate = new SEO_Plugin_Activation();
    // Execute some method(s) here that would take care 
    // of all of my plugin activation bootstrapping
  }

}

new SEO();
?>

Ich habe versucht, es so zu machen, wie ich es im dritten Skript skizziere, habe aber keinen Erfolg. Ab sofort wird die Meldung ohne Fehlermeldungen korrekt angezeigt.

3
Dan Zuzevich

Nachdem ich Ihre Frage noch einmal gelesen habe, sehe ich das Problem. Dies ist auf ein Missverständnis der Funktionsweise von register_activation_hook zurückzuführen, verbunden mit einer gewissen Verwirrung darüber, wie Sie Ihren Code booten und was es bedeutet, ihn zu booten

Teil 1: register_activation_hook

Diese Funktion benötigt 2 Parameter:

register_activation_hook (String $ file, aufrufbare $ -Funktion)

Der erste Parameter, $file, ist die Haupt-Plugin-Datei und nicht die Datei, die das enthält, was Sie ausführen möchten. Es wird genauso verwendet wie plugins_url, daher benötigen Sie den Wert von __FILE__, insbesondere den Wert in der Root-Plugin-Datei mit Ihrem Plugin-Header.

Der zweite Parameter ist ein aufrufbarer Parameter und funktioniert wie erwartet, es wird jedoch nur intern add_action verwendet

Wenn ein Plugin aktiviert ist, wird die Aktion "activate_PLUGINNAME" aufgerufen. Im Namen dieses Hooks wird PLUGINNAME durch den Namen des Plugins einschließlich des optionalen Unterverzeichnisses ersetzt. Wenn sich das Plugin beispielsweise in wp-content/plugins/sampleplugin/sample.php befindet, lautet der Name dieses Hooks "activate_sampleplugin/sample.php".

Teil 2: Bootstrapping und __FILE__

Ein grundlegendes Problem hierbei ist, dass __FILE__ an verschiedenen Orten unterschiedliche Werte hat und Sie einen bestimmten Wert benötigen.

Sie haben auch das Problem, dass Bootstrapping das Objektdiagramm zusammenstellen sollte, aber das tun Sie nicht. Alle Ihre Objekte werden erstellt, sobald sie definiert oder ineinander erstellt wurden, sodass es schwierig oder unmöglich ist, Werte an sie zu übergeben.

Als Beispiel könnte ich folgendes Plugin schreiben:

plugin.php:

<?php
/**
 * Plugin Name: My Plugin
 * Version: 0.1
 */

// loading step
require_once( 'php/app.php' );

// bootstrapping step
$app = new App( __FILE__ );

// execution step
$app->run();

Ich habe alle meine Klassen im Unterordner php definiert und sie alle an derselben Stelle geladen. PHP weiß jetzt, was meine Klassen sind, ihre Namen usw., aber es ist noch nichts passiert.

Ich erstelle dann alle meine Objekte und übergebe ihnen das, was sie brauchen. In diesem Fall benötigt die App den Wert __FILE__, also gebe ich ihn weiter. Beachten Sie, dass dadurch die Objekte im Speicher erstellt werden, jedoch keine Arbeit ausgeführt wird. Die Plugins-Anwendung ist einsatzbereit und in Aktion, befindet sich jedoch in der Vorbereitungsphase.

Der nächste Schritt könnte sein, diese Objekte in eine Reihe von Unit-Tests zu leiten, aber jetzt werde ich sie ausführen. Ich habe meinen Bootstrapping-Prozess beendet und die Anwendung ist bereit zur Ausführung. Daher starte ich die Methode run. Ich sollte nichts an run übergeben müssen, da alles Notwendige an die Konstruktoren übergeben wurde. Während der run-Methode füge ich alle meine Filter und Hooks hinzu. Während dieser Hooks werden alle anderen Teile des Plugins ausgeführt.

Der wichtige Teil ist jedoch, dass ich eine definierte Struktur habe und das Notwendige während der Konstruktions-/Bootstrapping-Phase mit einem definierten Lebenszyklus weitergebe

7
Tom J Nowell

Tom McFarlin hat ein sehr umfangreiches Plugin Boilerplate (jetzt von Devin Vinson gepflegt) erstellt, das alle in OOP geschrieben ist und mit dem Sie entweder Ihr neues Plugin erstellen oder einfach den Anwendungsfluss studieren können, um Ihre Frage zu beantworten. Ich habe es für einige benutzerdefinierte Plugins verwendet und ich muss sagen, dass es mir die Augen für einige der Geheimnisse von OOP geöffnet hat.

1
Gary D

Sie müssen wirklich Ihre Aktivierungs-/Deaktivierungs-/Deinstallations-Hooks außerhalb Ihrer Plugin-Klasse gemäß Kaisers Antwort hier registrieren, was einen viel besseren Überblick über das Thema bietet, als ich schreiben könnte.

Dies sollte Sie abdecken, wenn Sie dieses Plugin als Lernübung schreiben möchten. Wenn Sie nur nach einem SEO-Plugin suchen, das gut funktioniert und nicht mit Werbung wie Yoast übersät ist, kann ich das SEO-Framework wärmstens empfehlen.

1
Chris Cox