Cum să pasezi argumente la un callback pentru pagina de meniu în admin WordPress?
Situație: Lucrez la un plugin și îl dezvolt ca o clasă, totul a funcționat bine până am dat peste această situație. Am vrut să fac lucrurile mai clare și am încercat asta..
class MyPlugin {
function __construct() {
add_action('admin_menu', array(&$this, 'myplugin_create_menus');
}
//Nu vreau să scriu o funcție pentru fiecare pagină de opțiuni pe care o creez
//așa că prefer să încărc conținutul dintr-un fișier extern.
function load_view($filename) {
$view = require(dirname(__FILE__).'/views/'.$filename.'.php');
return $view;
}
//Aici apare problema
function myplugin_create_menus() {
add_menu_page( 'Nume plugin',
'Nume plugin',
'manage_options',
'my-plugin-settings',
array(&$this, 'load_view') // Unde specific valoarea pentru $filename??
);
}
}#sfârșitul clasei
Am încercat mai multe variante dar nimic nu funcționează, poate sunt chiar în fața soluției dar nu o văd.
Desigur, acesta este un exemplu recreat, am folosit prefixe pentru toate funcțiile și nu sunt exact cum le-am scris aici dar sper că înțelegeți ideea.
Mulțumesc anticipat.
P.S.: Dacă doriți să vedeți codul sursă original, pot să-l postez și să vă dau link-ul.

Nu poți pasa un argument funcției de callback. add_menu_page()
o adaugă ca un handler de acțiune, iar admin.php
declanșează acțiunea, fără niciun argument.
Văd două soluții simple la această problemă. Una este să stochezi toate numele de fișiere într-un array în clasa ta, indexate după numele hook-ului. Apoi poți folosi acest array pentru a căuta fișierul pe care trebuie să-l încarci (poți stoca și alte date suplimentare în acest array).
class WPSE16415_Plugin
{
protected $views = array();
function load_view() {
// current_filter() returnează și acțiunea curentă
$current_views = $this->views[current_filter()];
include(dirname(__FILE__).'/views/'.$current_views.'.php');
}
function myplugin_create_menus() {
$view_hook_name = add_menu_page( 'Numele plugin-ului',
'Numele plugin-ului',
'manage_options',
'my-plugin-settings',
array(&$this, 'load_view'),
);
$this->views[$view_hook_name] = 'options';
}
}
Cea de-a doua soluție este să omiți argumentul callback, astfel încât WordPress va include fișierul indicat de numele slug-ului în sine, așa cum sugerează Brady în răspunsul său.

Nu funcționează pentru mine. Folosesc WordPress 4.1 (și de astăzi 4.1.1)

Inteligent! Și chiar funcționează. Iată un exemplu mai complet: http://hastebin.com/segibugice care ar genera un URL precum http://example.com/wp-admin/admin.php?page=my-slug

Trebuia să menționez că atunci când transmiți variabile în scopul unei funcții anonime, trebuie să folosești cuvântul cheie "use".
function() use ($my_var) { // acum poți folosi $my_var }

Am rezolvat această problemă prin simpla adăugare a ID-ului (sau orice altă dată de care ai nevoie) la slug-ul meniului.
De exemplu:
add_menu_page( 'Nume plugin',
'Nume plugin',
'manage_options',
'setări-plugin-meu-' . $identifier,
'funcție-callback-setări'
);
Aceasta va crea un URL cu 'setări-plugin-meu-nume-fisier' (ca exemplu), iar eu pot analiza acea parte a URL-ului (cu $_GET sau filter_input).

Ai putea folosi și un parametru URL, dar trebuie să creezi un element de meniu (pe care îl poți ascunde ulterior dacă dorești).

Mulțumesc că ai pus codul meu într-un bloc de cod, toscho. Când pun o întrebare, există un buton pentru asta, dar nu sunt familiarizat cu markup-ul necesar pentru a face același lucru într-un răspuns.

Funcția load_view ar trebui să arate astfel?:
function load_view($filename) {
include(dirname(__FILE__).'/views/'.$filename.'.php');
}
iar în fișierul inclus ar trebui să afișezi orice conținut pentru pagina care este afișată.
EDIT:
Iată ce spune codex-ul pe această temă:
$menu_slug
(string) (obligatoriu)
Numele slug pentru a face referire la acest meniu (ar trebui să fie unic pentru acest meniu). Înainte de Versiunea 3.0 acesta se numea parametrul fișier (sau handle). Dacă parametrul funcției este omis, menu_slug ar trebui să fie fișierul PHP care gestionează afișarea conținutului paginii de meniu.
Implicit: Niciunul
$function
Funcția care afișează conținutul paginii pentru pagina de meniu. Tehnic, parametrul funcției este opțional, dar dacă nu este furnizat, atunci WordPress va presupune că includerea fișierului PHP va genera ecranul de administrare, fără a apela o funcție. Majoritatea autorilor de plugin-uri aleg să pună codul generatoare de pagină într-o funcție în fișierul principal al plugin-ului.: În cazul în care parametrul funcției este specificat, este posibil să folosești orice șir de caractere pentru parametrul fișier. Acest lucru permite utilizarea de pagini precum ?page=my_super_plugin_page în loc de ?page=my-super-plugin/admin-options.php.
Deci, din câte înțeleg, dacă lași funcția goală, acesta va încerca să includă un fișier php bazat pe ceea ce ai setat la menu_slug
.
EDIT 2
function load_view() {
include(dirname(__FILE__).'/views/'.$this->filename.'.php');
}
function myplugin_create_menus() {
$this->filename = "something";
add_menu_page( 'Nume Plugin',
'Nume Plugin',
'manage_options',
'my-plugin-settings',
array(&$this, 'load_view')
);
$this->filename = "somethingelse";
add_menu_page( 'Nume Plugin',
'Nume Plugin',
'manage_options',
'my-plugin-settings',
array(&$this, 'load_view')
);
}

@Brady Știu asta, iar funcția "load_view" funcționează corect și afișează conținutul așa cum trebuie când folosești o valoare statică. De exemplu: incl..../views/my-panel.php');

@Brady array(&$this, 'load_view') // Unde specific valoarea pentru $filename??. Nu pot face ceva de genul array(&$this, 'load_view("my-value")') Vreau să găsesc o metodă de a pasa parametri către funcția pe care o apelez

Ah, acum am înțeles. Vrei să transmiți o funcție de clasă dar cu un parametru. Ei bine, am căutat și căutat și nu pot găsi cum se face. Dar dacă transmiți clasa, atunci nu poți face ce am scris în EDIT 2?

@Brady: A doua ta editare nu va ajuta prea mult, doar suprascrii variabila filename
așa că va fi întotdeauna "altceva"
. Prima ta editare ar putea fi soluția aici: dacă load_view
nu face altceva decât să includă fișierul, atunci într-adevăr nu ar trebui să transmiți o funcție callback și WordPress va încerca să încarce pagina pe care ai transmis-o ca slug.

Bazat pe răspunsul user35752, poți folosi chiar și o metodă a unui obiect cu parametri drept callback.
$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)
