web-dev-qa-db-de.com

Ladereihenfolge des Plugins ändern

Ich schreibe ein Plugin, bar, das davon abhängig ist, dass ein anderes Plugin, foo, aktiviert ist, und ich benötige die Funktionen von foo, um verfügbar zu sein, wenn bar geladen wird . Normalerweise werden Plugins in alphabetischer Reihenfolge basierend auf dem Verzeichnisnamen geladen, daher wird bar vor foo geladen. Wenn ich das Verzeichnis bar in zbar umbenenne, wird es zuletzt geladen und funktioniert einwandfrei. Ich suche jedoch nach einer eleganteren und korrekteren Lösung.

Ich habe jsdaltons Methode zum Ändern der Option active_plugins befolgt und ordne das Array neu an, sodass bar am Ende steht, aber bar kann immer noch nicht auf foo zugreifen. ' s funktioniert, wenn es instanziiert. Ich habe den relevanten Kerncode durchgelesen - im Grunde genommen wp-settings.php und wp_get_active_and_valid_plugins() in wp-includes\load.php - und es scheint, als sollten Plugins in der Reihenfolge geladen werden, in der sie in active_plugins indiziert sind, damit ich nicht herausfinden kann, was falsch läuft.

Dies ist bei einer MultiSite-Installation der Fall. bar ist eine Klasse und foo ist prozedural.

Hier ist eine abgespeckte Version von foo/foo.php

function foo()
{
    // stuff
}

Und hier ist eine abgespeckte Version von bar/bar.php

class bar
{
    public function __construct()
    {
        // ...

        $active_plugins = get_option('active_plugins');
        print_r($active_plugins);

        if( function_exists('foo') )
            wp_die("foo exists");
        else
            wp_die("foo doesn't exist yet");
        }
    }
}

function this_plugin_last() 
{
    $wp_path_to_this_file = preg_replace('/(.*)plugins\/(.*)$/', WP_PLUGIN_DIR."/$2", __FILE__);
    $this_plugin = plugin_basename(trim($wp_path_to_this_file));
    $active_plugins = get_option('active_plugins');
    $this_plugin_key = array_search($this_plugin, $active_plugins);

    if ($this_plugin_key) 
    {
        array_splice($active_plugins, $this_plugin_key, 1);
        array_Push($active_plugins, $this_plugin);
        update_option('active_plugins', $active_plugins);
    }
}
add_action("plugins_loaded", "this_plugin_last");

$bar = new bar();

Dies ist die Ausgabe des Konstruktors von bar:

Array
(
    [0] => foo/foo.php
    [1] => bar/bar.php
)

foo doesn't exist yet
6
Ian Dunn

Berühren Sie nicht die Ladereihenfolge, sondern ändern Sie stattdessen die Aktivierungsreihenfolge. Ein funktionierendes Beispiel finden Sie in diese Antwort .

2
fuxia

Egal was passiert, Ihr Konstruktor von bar wird immer ausgeführt, bevor die Aktion in Ihrem Code aufgerufen wird.

Ich bin vor einiger Zeit auf dieses Szenario gestoßen, und Sie sind hauptsächlich dafür da, wie ich es gemacht habe.

Einfach ausgedrückt - kommentieren Sie alles in dieser Funktion aus und setzen Sie $ bar = new bar (); dort drinnen. und mache einfach die ganze Logik und was auch immer du in dieser Funktion brauchst. dies stellt sicher, dass foo geladen wird, bevor Sie Ihren Code ausführen (das Plugin selbst muss nicht unbedingt vorher geladen werden, genau das, was Sie verwenden, das auf foo beruht).

5
Mike

Fügen Sie am oberen Rand des abhängigen Plugin-Codes unter dem Namen, der Beschreibung usw. des Plugins Folgendes hinzu:

require_once( WP_PLUGIN_DIR . '/foo/foo.php' );

Das "foo" -Plugin muss nicht einmal für "bar" aktiviert werden, um den Code zu finden.

1
danblaker