Поняття простору імен в системі хуків у WordPress

41

Від автора: хуки – фундаментальна концепція в WordPress розробці. У цій статті я розповім вам, як чіпляти методи екземпляра класу до екшенам і фільтрів, як інтегрувати методи класів зі своїм простором імен у хук, які є складності з використанням простору імен в системі хуків WP, а також ми розглянемо способи вирішення даних проблем.

Як причепити методи об’єкта

Скажімо, ваш бос дав вам завдання написати плагін управління рекламою для великого новинного сайту, щоб реклама гладко вставлялася в новинний контент. Тоді ви могли б зробити наступне.

Ви могли б створити клас AdManager з парою методів, в яких буде зберігатися код декількох рекламних мереж.

class AdManager {
/**
* AdSense код.
*/
public function adsense() { ?>
(adsbygoogle = window.adsbygoogle || []).push({});
Наприклад, у темі сайту є екшен before_post_content, який запускається до появи контенту поста на екрані, і ви хочете причепити метод adsense до нього, щоб відображати рекламу до завантаження контенту. Як би ви зробили це?

На відміну від прикладів з другої частини, де ми прикріплювали метод через конструктор класу, вам доведеться спробувати причепити метод до екшену не з класу.

public function __construct() {
add_action( ‘before_post_content’, array( $this, ‘adsense’ ) );
}

Щоб причепити метод adsense до екшену before_post_content зовні класу (можливо, в файлі functions.php активної теми) для відображення реклами Google AdSense ще до завантаження контенту посту, вам доведеться замінити $this на екземпляр класу.

add_action( ‘before_post_content’, array( new AdManager(), ‘adsense’ ) );

Скажімо, в класі є метод, який повертає екземпляр класу за шаблоном singleton.

class AdManager {
// …
/**
* Singleton class instance.
*
* @return AdManager
*/
public static function get_instance() {
static $instance = null;
if ( $instance == null ) {
$instance = new self();
}
return $instance;
}
}

Тоді метод adsense можна причепити до екшену before_post_content наступним чином.

add_action( ‘before_post_content’, array( AdManager::get_instance(), ‘adsense’ ) );

Простору імен

Система хуків в WP розроблялася в той час, коли в WP ще не було простору імен. Ви можете помітити, що причепити функції з простором імен та методи класів до екшенам і фільтрів досить складно. Скажімо, у класу AdManager простір імен SitePoint\Plugin.

namespace SitePoint\Plugin;
class AdManager {
// …
}

Щоб причепити метод adsense класу AdManager до екшену before_post_content, необхідно додати перед ім’ям класу простір імен:

add_action( ‘before_post_content’, array( SitePoint\Plugin\AdManager::get_instance(), ‘adsense’ ) );

Якщо клас і виклик функції add_action прописані в просторі імен SitePoint\Plugin\ одного файлу, дописувати простір імен до імені класу немає необхідності, так як все знаходиться в межах одного простору імен. З прикладами класів закінчили, давайте поглянемо на функцію. Приміром, у вас є наступна функція з простором імен, яку необхідно причепити до екшену wp_head.

namespace SitePoint\Plugin;
function google_site_verification() {
echo «;
}

Причепити функцію можна, додавши до назви функції простір імен:

add_action( ‘wp_head’, ‘SitePoint\Plugin\google_site_verification’ );

Мій кошмар з простором імен і системою хуків

У своєму плагіні Admin Bar & Dashboard Access Control я зареєстрував хук видалення, який видаляє настройки після видалення плагіна.

Що-небудь просте зразок рядки нижче легко зробити. PP_Admin_Bar_Control – ім’я класу, а on_uninstall – метод, що викликається під час видалення.

register_uninstall_hook( __FILE__, array( ‘PP_Admin_Bar_Control’, ‘on_uninstall’ ) );

Щоб перевірити роботу хука, я спробував видалити плагін і подивитися, пішли налаштування. На мій подив я отримав наступну помилку: The plugin generated 2137 characters of unexpected output during activation.

Подивіться, як заданий клас і функція register_uninstall_hook в просторі імен ProfilePress\PP_Admin_Bar_Control.

namespace ProfilePress\PP_Admin_Bar_Control;
register_uninstall_hook( __FILE__, array( ‘PP_Admin_Bar_Control’, ‘on_uninstall’ ) );
class PP_Admin_Bar_Control {
// …
/** Колбек функція запускається при виклику хука видалення. */
public static function on_uninstall() {
if ( ! current_user_can( ‘activate_plugins’ ) ) {
return;
}
delete_option( ‘abdc_options’ );
}
// …
}

Бачите причину, чому не спрацював метод on_uninstall під час видалення плагіна? Вам може здатися, що якщо функція register_uninstall_hook знаходиться в просторі імен, то й клас буде в ньому. Не в цьому випадку. Необхідно так само додавати перед назвою методу простір імен.

register_uninstall_hook( __FILE__, array( ‘ProfilePress\PP_Admin_Bar_Control\PP_Admin_Bar_Control’, ‘on_uninstall’ ) );

Я дуже довго з’ясовував, у чому проблема, і вирішив вберегти вас від тієї ж помилки.

Висновок

Такі глюки лякають деяких розробників і змушують відмовитися від роботи з WP. Не варто забувати, що WP був розроблений в той час, коли сам PHP ще був далекий від ідеалу і не мав всіх сьогоднішніх поліпшень і функцій. Я завжди намагаюся зрозуміти причину глюка і намагаюся розповісти про це людям.

Сподіваюся, мені вдалося зняти покрив таємничості з системи хуків в WP. Якщо у вас є питання або вам є, що сказати, пишіть про це в коментарях.