Przekazywanie argumentów do wywołania zwrotnego strony menu administratora?

14

Sytuacja: Pracuję nad wtyczką i rozwijam ją jako klasę, wszystko działało dobrze, dopóki nie wpadłem w taką sytuację. Chciałem uczynić rzeczy nieco czystszymi i spróbowałem tego ...

class MyPlugin {
    function __construct() {
        add_action('admin_menu', array(&$this, 'myplugin_create_menus');
    }        

    //I don't want to write a function for every options page I create
    //so I prefer to just load the content from an external file.        
    function load_view($filename) {
        $view = require(dirname(__FILE__).'/views/'.$filename.'.php');
        return $view;
    }

    //Here is where the problem comes
    function myplugin_create_menus() {
        add_menu_page( 'Plugin name',
                       'Plugin name',
                       'manage_options',
                       'my-plugin-settings',
                       array(&$this, 'load_view') // Where do I specify the value of $filename??
                     );
    }

}#end of class

Próbowałem wielu różnych opcji, ale nic nie działa, może jestem przed tym, ale nie widzę.

Oczywiście, że jest to ponowne tworzenie, mam przedrostek wszystkich moich funkcji i nie są one dokładnie takie, jak tutaj napisałem, ale mam nadzieję, że masz pomysł, o który proszę.

Z góry dziękuję.

PD: Jeśli chcesz zobaczyć oryginalny kod źródłowy, chętnie go wkleję i podam link.

Luis
źródło

Odpowiedzi:

8

Nie można przekazać argumentu do funkcji zwrotnej. add_menu_page()dodaje go jako moduł obsługi akcji i admin.phpuruchamia akcję bez żadnych argumentów.

Widzę dwa proste rozwiązania tego problemu. Jednym z nich jest przechowywanie całej nazwy pliku w tablicy w klasie, indeksowanej według nazwy haka. Następnie możesz użyć tego, aby wyszukać plik, który chcesz załadować (możesz również przechowywać dodatkowe dane w tej tablicy).

class WPSE16415_Plugin
{
    protected $views = array();

    function load_view() {
        // current_filter() also returns the current action
        $current_views = $this->views[current_filter()];
        include(dirname(__FILE__).'/views/'.$current_views.'.php');
    }

    function myplugin_create_menus() {
        $view_hook_name = add_menu_page( 'Plugin name',
            'Plugin name',
            'manage_options',
            'my-plugin-settings',
            array(&$this, 'load_view'),
        );
        $this->views[$view_hook_name] = 'options';
    }
}

Drugim jest pominięcie argumentu wywołania zwrotnego, więc WordPress uwzględni plik wskazany przez samą nazwę ślimaka, jak sugeruje Brady w swojej odpowiedzi.

Jan Fabry
źródło
ach, dlaczego nie pomyślałem o zrobieniu tego w ten sposób :(
Brady
TAK!! dzisiaj uratowałeś dziesiątki kociąt .. nigdy nie słyszałem o tej funkcji przez 'current_filter'. Bardzo sprytne rozwiązanie. Bardzo dziękuję za pomoc @Brady @Jan Fabry
Luis
4

Zawsze możesz po prostu użyć anonimowej funkcji (lub zamknięcia). Coś na wpływ:

add_menu_page( $page, $menu, $capability, $slug, function() { print_my_admin_page($with_args); }, $icon, $position);
użytkownik35752
źródło
1
To mi nie działa. Korzystam z WordPress 4.1 (i od dzisiaj 4.1.1)
Jeff Vdovjak
Sprytny! I to działa. Oto bardziej kompletny przykład: hastebin.com/segibugice, który wygenerowałby URL taki jak example.com/wp-admin/admin.php?page=my-slug
Quinn Comendant
Powinienem wspomnieć, że przekazując zmienne do zakresu funkcji anonimowej, musisz użyć słowa kluczowego „use”. function() use ($my_var) { // now you can use $my_var }
user35752
0

funkcja load_view powinna wyglądać tak:

function load_view($filename) {
    include(dirname(__FILE__).'/views/'.$filename.'.php');
}

a w twoim pliku dołączanym powinna odzwierciedlać każdą treść wyświetlanej strony.

EDYTOWAĆ:

Oto, co mówi kodeks w tej sprawie:

$menu_slug (string) (required)Nazwa ślimaka, według której ma się odnosić do tego menu (powinna być unikalna dla tego menu). Przed wersją 3.0 było to nazywane parametrem file (lub handle). Jeśli parametr funkcji zostanie pominięty, menu_slug powinien być plikiem PHP, który obsługuje wyświetlanie zawartości strony menu. Domyślnie: brak

$function Funkcja wyświetlająca zawartość strony dla menu. Technicznie parametr funkcji jest opcjonalny, ale jeśli nie zostanie podany, WordPress zasadniczo założy, że dołączenie pliku PHP wygeneruje ekran administracyjny, bez wywoływania funkcji. Większość autorów wtyczek decyduje się na umieszczenie kodu generującego stronę w funkcji w głównym pliku wtyczki. W przypadku, gdy parametr funkcji jest określony, możliwe jest użycie dowolnego łańcucha dla parametru pliku. Pozwala to na użycie stron takich jak? Page = moja_super_plugin_page zamiast? Page = my-super-plugin / admin-options.php.

Mogę więc wyciągnąć z tego, że jeśli pozostawisz funkcję pustą, spróbuje dołączyć plik php na podstawie tego, co ustawiłeś menu_slug.

EDYCJA 2

function load_view() {
    include(dirname(__FILE__).'/views/'.$this->filename.'.php');
}

function myplugin_create_menus() {
    $this->filename = "something";
    add_menu_page( 'Plugin name',
                   'Plugin name',
                   'manage_options',
                   'my-plugin-settings',
                   array(&$this, 'load_view')
                 );
    $this->filename = "somethingelse";
    add_menu_page( 'Plugin name',
                   'Plugin name',
                   'manage_options',
                   'my-plugin-settings',
                   array(&$this, 'load_view')
                 );
}
Brady
źródło
@Brady Wiem o tym, a funkcja „load_view” działa dobrze i poprawnie wyświetla zawartość przy użyciu wartości statycznej. Na przykład: incl .... / views / my-panel.php ');
Luis
@Luis - W czym tkwi problem?
Brady
@Brady array (& $ this, 'load_view') // Gdzie mam podać wartość $ filename ??. Nie mogę zrobić czegoś takiego jak tablica (& $ this, „load_view („ my-value ”)”) Chcę znaleźć sposób na przekazanie parametrów do funkcji, którą wywołuję
Luis
Och, rozumiem teraz. Chcesz przekazać funkcję klasy, ale z parametrem. Cóż, patrzyłem i patrzyłem i nie mogę znaleźć, jak to robisz. Ale skoro zdałeś klasę, to czy nie możesz zrobić tego, co wprowadziłem do EDIT 2?
Brady
@Brady: Twoja druga edycja niewiele pomoże, po prostu przesłonisz filenamezmienną, więc zawsze będzie "somethingelse". Twoja pierwsza edycja może być tutaj sztuczką: jeśli load_viewnic nie robi oprócz włączenia pliku, rzeczywiście nie powinieneś przekazywać funkcji wywołania zwrotnego, a WordPress spróbuje załadować stronę, którą przekazałeś jako ślimak.
Jan Fabry
0

Rozwiązałem ten problem, po prostu dodając identyfikator (lub dowolne dane, których potrzebujesz) do paska menu.

Na przykład:

 add_menu_page( 'Plugin name',
                       'Plugin name',
                       'manage_options',
                       'my-plugin-settings-' . $identifier,
                       'setting-function-callback'
                     );

Spowoduje to utworzenie adresu URL z „my-plugin-settings-filename” (jako przykład) i mogę po prostu przeanalizować tę część adresu URL (za pomocą $ _GET lub filter_input).

Jeff Vdovjak
źródło
Możesz również użyć parametru adresu URL, ale musisz utworzyć element menu (a następnie możesz go ukryć, jeśli chcesz).
Jeff Vdovjak,
Dzięki za umieszczenie mojego kodu w toscho bloku kodu. Kiedy zadaję pytanie, jest na to przycisk, ale nie znam znaczników, by zrobić to w odpowiedzi.
Jeff Vdovjak,
0

Na podstawie odpowiedzi user35752 możesz nawet użyć metody obiektowej z parametrami jako wywołaniem zwrotnym.

$args = [ [new Foo(), 'bar'], [$param1, $param2, ...] ];

$callback = function () use ($args){
                call_user_func_array($args[0], $args[1]);
            };
add_menu_page( $page, $menu, $capability, $slug, $callback , $icon, $position)
Lordgretix
źródło