Хуки — фундаментальная концепция для разработчиков WordPress. В предыдущих статьях о SitePoint мы узнали, что такое хуки и их важность, два типа хуков: actions
и filters
с примерами кода, как они работают, и альтернативный способ запуска действий и фильтров событий, а также как перехватывать статические и нестатические методы класса для действий и фильтров .
В этой статье я расскажу, как подключить методы экземпляра класса (объекта) к действиям и фильтрам, как интегрировать метод класса с пространством имен в ловушку, предостережения об использовании пространств имен в системе подключений 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. Если у вас есть какие-либо вопросы или предложения, пожалуйста, сообщите нам об этом в комментариях.