Podczas ładowania rdzenia waniliowego WP konfigurowany jest bieżący użytkownik, $wp-init()
który jest po załadowaniu motywu i przed init
zaczepieniem. Jest to zgodne z dobrą praktyką polegającą na podłączaniu funkcjonalności init
lub później.
Jednak powszechną praktyką jest również wywoływanie funkcji powiązanych, na przykład current_user_can()
wcześniej . Jest to z definicji wymagane dla wtyczek, które działają na wcześniejszych etapach procesu ładowania (moja wtyczka Toolbar Theme Switcher byłaby przykładem).
Dokumentacja nie wysuwa żadnych roszczeń za lub przeciw tej praktyce (którą mogłem znaleźć).
Jednak niektóre wtyczki wydają się łączyć z funkcjami związanymi z użytkownikiem i przez init
cały czas oczekują stanu po.
Na przykład bbPress rzuca następujące powiadomienie:
// If the current user is being setup before the "init" action has fired,
// strange (and difficult to debug) role/capability issues will occur.
if ( ! did_action( 'after_setup_theme' ) ) {
_doing_it_wrong( __FUNCTION__, __( 'The current user is being initialized without using $wp->init().', 'bbpress' ), '2.3' );
}
Aby szybko zademonstrować, wrzuć to do podstawowej definicji current_user_can()
:
function current_user_can( $capability ) {
if ( ! did_action('after_setup_theme') ) {
echo wp_debug_backtrace_summary();
}
Kto ma rację w tej sytuacji? Czy istnieje kanoniczne określenie wcześniejszego dozwolonego / zabronionego użycia funkcji związanych z użytkownikiem init
?
źródło
Odpowiedzi:
Jedynym warunkiem
current_user_can()
jest istnieniewp_get_current_user()
. Ten ostatni jest zdefiniowany wpluggable.php
, więc możesz go użyć późniejplugins_loaded
._doing_it_wrong()
Wezwanie jesteś powołując się na swoje pytanie jest niewłaściwe dla siebie. Domyślam się, że wziąłeś to z BuddyPress lub bbPress. Obaj wpadają w rekurencję, jeśli nie czekają tak długo. Istnieją inne, lepsze sposoby zapobiegania rekursji.W niektórych przypadkach, takich jak zmiana ustawień regionalnych , musisz wcześniej uzyskać dostęp do bieżącego obiektu użytkownika, więc oczekiwanie na
after_setup_theme
nie jest nawet opcją.źródło
Jeśli wcześniej sprawdzisz możliwości użytkownika,
init
oznacza to, że istnieje prawdopodobieństwo, że jesteś odpowiedzialny za ustawienie bieżącego obiektu użytkownika.Jeśli uzyskasz dostęp do użytkownika później
init
, masz pewność, że coś innego już go skonfigurowało, w większości przypadków sam rdzeń.Dlatego dostęp do użytkownika po
init
jest uważany za bezpieczny .W rzeczywistości wczesny dostęp może zepsuć działający filtr
determine_current_user
.Warto powiedzieć, że jeden jest „kruchym” hakiem, ponieważ są szanse, że nigdy się nie uruchomi, ponieważ jest wystrzeliwany tylko w funkcjach wtykowych.
Są jednak przypadki (jak powiedział @toscho ), w których nie możesz czekać do init, w tych przypadkach nie masz wyboru.
Jedynym sposobem rozwiązania każdej niezgodności jest przypadek, jeśli masz taką wolę.
Rozwiązaniem, które może działać w większości przypadków (w tym bbPress / BuddyPress) jest użycie następującej funkcji zamiast
current_user_can
:Pozwala to wcześnie sprawdzić bieżące możliwości użytkownika bez ustawiania globalnego użytkownika, więc teoretycznie można go uruchomić wcześniej
init
.Problem polega na tym, że, jak wspomniano powyżej, każdy kod, który przesłania funkcje wtykowe i nie uruchamia się,
determine_current_user
psuje go.źródło
Skłaniam się do myślenia, że BuddyPress i bbPress powinni sprawdzić coś jeszcze przed
_doing_it_wrong
wysłaniem wiadomościZmieniłem obie procedury, aby sprawdzić również rzeczywiste ustawienie $ current_user.
Powiadomienia nie były już wyświetlane.
Testowanie
did_action( "after_setup_theme" )
staje się szelkami pasującymi do pasa.źródło