Статьи

Понимание пространств имен в системе WordPress Hook

Хуки — фундаментальная концепция для разработчиков WordPress. В предыдущих статьях о SitePoint мы узнали, что такое хуки и их важность, два типа хуков: actions и filters с примерами кода, как они работают, и альтернативный способ запуска действий и фильтров событий, а также как перехватывать статические и нестатические методы класса для действий и фильтров .

В этой статье я расскажу, как подключить методы экземпляра класса (объекта) к действиям и фильтрам, как интегрировать метод класса с пространством имен в ловушку, предостережения об использовании пространств имен в системе подключений WordPress и их решение.

WordPress Крючки и Пространства имен

Методы перехвата объектов

Предположим, ваш работодатель поручил вам создать плагин управления рекламой для большого новостного сайта, чтобы сделать вставку рекламы в новостной контент без проблем. Вот как вы могли бы построить его.

Вы должны создать класс AdManager с несколькими методами, которые содержат различные рекламные коды рекламных сетей.

 class AdManager { /** * AdSense unit code. */ public function adsense() { ?> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <ins class="adsbygoogle" style="display:inline-block;width:336px;height:280px" data-ad-client="ca-pub-xxxxxxxxxxxxxxxx" data-ad-slot="6762452247"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> <?php } /** * Buysellads ad code. */ public function buysellads() { // ... } } 

Допустим, у темы веб-сайта есть action 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' ) ); 

И скажем, класс включает метод, который возвращает одноэлементный экземпляр класса.

 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' ) ); 

Пространства имен

Система ловушек WordPress была разработана в то время, когда в WordPress не было функции пространства имен . В результате может оказаться затруднительным привязать функцию пространства имен и метод класса к action и filter .

Скажем, ваш класс AdManager имеет пространство имен SitePoint\Plugin следующим образом.

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

Чтобы подключить метод adsense класса before_post_content действию before_post_content , вы должны добавить имя класса к пространству имен следующим образом:

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

Если class и вызов функции add_action находятся в одном и том же пространстве имен файлов PHP с помощью SitePoint\Plugin\ , добавление пространства имен к имени класса не требуется, поскольку они охватываются одним и тем же глобальным пространством имен.

Достаточно примеров классов, теперь давайте посмотрим на простую функцию.

Допустим, у вас есть следующая функция пространства имен, которая должна быть подключена к действию wp_head .

 namespace SitePoint\Plugin; function google_site_verification() { echo '<meta name="google-site-verification" content="ytl89rlFsAzH7dWLs_U2mdlivbrr_jgV4Gq7wClHDUJ8" />'; } 

Вот как это можно сделать с помощью пространства имен, добавленного к функции:

 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 { // ... /** Callback to run when the uninstalled hook is called. */ public static function on_uninstall() { if ( ! current_user_can( 'activate_plugins' ) ) { return; } delete_option( 'abdc_options' ); } // ... } 

Можете ли вы определить причину, по которой on_uninstall класса on_uninstall не был запущен при удалении плагина?

Можно подумать, поскольку функция register_uninstall_hook определена в пространстве имен, класс должен охватываться им, но это не так. Вам все еще нужно добавить пространство имен к классу следующим образом, чтобы он работал.

 register_uninstall_hook( __FILE__, array( 'ProfilePress\PP_Admin_Bar_Control\PP_Admin_Bar_Control', 'on_uninstall' ) ); 

Мне действительно было трудно разобраться в проблеме. Я решил, что не хочу, чтобы вы переживали тот же стресс и удары головой, что и я.

Вывод

Такие причуды заставляют некоторых разработчиков съеживаться и держаться подальше от WordPress. Мы не должны забывать, что WordPress был разработан в то время, когда PHP не хватало всех языковых улучшений и возможностей, которые он имеет сейчас. Я всегда пытаюсь понять, как обойти эти причуды, а затем учить людей.

Я надеюсь, что мне удалось демистифицировать систему хуков в WordPress. Если у вас есть какие-либо вопросы или предложения, пожалуйста, сообщите нам об этом в комментариях.