Статьи

Использование пространств имен и автозагрузка в плагинах WordPress, часть 1

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

Отчасти это связано с сообществом, которое его окружает, отчасти это связано с версиями PHP, которые поддерживает WordPress, а отчасти это связано с тем, что об этом говорят не многие люди.

И это нормально, в некоторой степени.

Ни пространства имен, ни автозагрузка не являются темами, которые вам абсолютно необходимо использовать для создания плагинов. Однако они могут обеспечить лучший способ организации и структурирования вашего кода, а также сократить количество операторов require , require_once , include или include_once , используемых вашими плагинами.

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

Для начала вам понадобятся следующие инструменты:

  • Локальная среда разработки, которая включает PHP 5.6.20, веб-сервер Apache и сервер базы данных MySQL.
  • Каталог, из которого размещается WordPress 4.6.
  • Текстовый редактор или IDE на ваш выбор, которые вы можете использовать для написания плагина.
  • Знание API плагинов WordPress.

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

Кроме того, вы можете следить за мной в моем блоге и / или Twitter по адресу @tommcfarlin, где я говорю о разработке программного обеспечения в контексте WordPress.

С этим сказал, давайте начнем.

В этой серии мы собираемся создать простой плагин, чтобы продемонстрировать, как пространства имен и автозагрузка работают в PHP. Но для этого всегда полезно применять концепции на практике.

Для этого мы создадим плагин, который облегчит загрузку таблиц стилей и стилей JavaScript в наш плагин, и который отображает мета-поле, в котором пользователю задается вопрос, чтобы помочь ему в мозговом штурме.

Нет, это не то, что вы, вероятно, отправили бы в репозиторий плагинов WordPress, и это не то, что вы, вероятно, будете использовать вне этой конкретной демонстрации. Но помните, цель этой серии — показать, как работают пространства имен и автозагрузка.

И именно через этот пример мы собираемся сделать именно это.

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

  1. Определите файл начальной загрузки для запуска плагина.
  2. Установите каталог для всех файлов, которые будут отображать мета-поле.
  3. Создайте каталог для размещения класса, который будет загружать наши зависимости.
  4. Подготовьте таблицы стилей и JavaScript для нашего плагина.

Это кажется простым, верно? Если нет, не беспокойтесь. Я собираюсь провести вас через весь процесс с кодом, комментариями, скриншотами и пояснениями.

Давайте начнем.

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

Давайте продолжим и создадим это сейчас:

Исходная структура каталогов плагинов

Очевидно, у нас есть один пустой файл и каталог администратора. Давайте настроим этот плагин так, чтобы он отображался в контексте экрана активации плагинов WordPress.

Для этого нам нужно добавить следующий блок кода в начало файла плагина:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
/**
 * The plugin bootstrap file
 *
 * This file is read by WordPress to generate the plugin information in the
 * plugin admin area.
 * the plugin, registers the activation and deactivation functions, and defines
 * a function that starts the plugin.
 *
 * @link http://.tutsplus.com/tutorials/using-namespaces-and-autoloading-in-wordpress-plugins-part-1
 * @since 0.1.0
 * @package tutsplus_namespace_demo
 *
 * @wordpress-plugin
 * Plugin Name: Tuts+ Namespace Demo
 * Plugin URI: http://.tutsplus.com/tutorials/using-namespaces-and-autoloading-in-wordpress-plugins-part-1
 * Description: Learn how to use Namespaces and Autoloading in WordPress.
 * Version: 0.1.0
 * Author: Tom McFarlin
 * Author URI: https://tommcfarlin.com/
 * License: GPL-2.0+
 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
 */

Затем, когда вы перейдете на страницу плагинов WordPress в области администрирования, вы увидите ее в списке плагинов. Если вы решите активировать его, ничего не произойдет, так как мы не написали никакого кода.

Демонстрационный плагин Tuts Namespace в области администрирования WordPress

На этом этапе мы можем продолжить и начать определение класса, который будет отображать наш мета-блок на Добавить новую страницу сообщений .

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

Во-первых, давайте создадим файл с именем class-meta-box-display.php в директории администратора нашего плагина. Код должен включать следующее. Обязательно просмотрите комментарии, чтобы убедиться, что вы понимаете все, за что отвечает этот класс.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
/**
 * Defines the functionality required to render the content within the Meta Box
 * to which this display belongs.
 */
 
/**
 * Defines the functionality required to render the content within the Meta Box
 * to which this display belongs.
 *
 * When the render method is called, the contents of the string it includes
 * or the file it includes to render within the meta box.
 */
class Meta_Box_Display {
 
    /**
     * Renders a single string in the context of the meta box to which this
     * Display belongs.
     */
    public function render() {
        echo ‘This is the meta box.’;
    }
}

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

Мы изменим это позже в уроке.

Далее нам нужно ввести класс, который представляет сам метабокс. Поэтому создайте файл class-meta-box.php в директории администратора нашего плагина. Вот код для этого. Снова просмотрите код, а затем я объясню, что происходит ниже класса:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php
/**
 * Represents a meta box to be displayed within the ‘Add New Post’ page.
 */
 
/**
 * Represents a meta box to be displayed within the ‘Add New Post’ page.
 *
 * The class maintains a reference to a display object responsible for
 * displaying whatever content is rendered within the display.
 */
class Meta_Box {
 
    /**
     * A reference to the Meta Box Display.
     *
     * @access private
     * @var Meta_Box_Display
     */
    private $display;
 
    /**
     * Initializes this class by setting its display property equal to that of
     * the incoming object.
     *
     * @param Meta_Box_Display $display Displays the contents of this meta box.
     */
    public function __construct( $display ) {
        $this->display = $display;
    }
 
    /**
     * Registers this meta box with WordPress.
     *
     * Defines a meta box that will render inspirational questions at the top
     * of the sidebar of the ‘Add New Post’ page in order to help prompt
     * bloggers with something to write about when they begin drafting a post.
     */
    public function init() {
 
        add_meta_box(
            ‘tutsplus-post-questions’,
            ‘Inspiration Questions’,
            array( $this->display, ‘render’ ),
            ‘post’,
            ‘side’,
            ‘high’
        );
    }
}

Этот класс поддерживает один атрибут, который является ссылкой на его отображение. Это означает, что этот класс отвечает за определение мета-блока (который, в свою очередь, вызывает экранный объект для визуализации сообщения).

Отображение поддерживается как частное свойство, установленное в конструкторе. Мета-блок на самом деле не определен, пока не будет вызван метод init (который мы увидим в начальной загрузке плагина позже в руководстве).

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

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

Это особенно актуально, потому что наш автозагрузчик в конечном итоге сведет на нет необходимость в том, что вы собираетесь увидеть.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<?php
 
// If this file is accessed directory, then abort.
if ( ! defined( ‘WPINC’ ) ) {
    die;
}
 
// Include the files for rendering the display.
include_once( ‘admin/class-meta-box.php’ );
include_once( ‘admin/class-meta-box-display.php’ );
 
add_action( ‘plugins_loaded’, ‘tutsplus_namespace_demo’ );
/**
 * Starts the plugin by initializing the meta box, its display, and then
 * sets the plugin in motion.
 */
function tutsplus_namespace_demo() {
 
    $meta_box = new Meta_Box( new Meta_Box_Display() );
    $meta_box->init();
}

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

Далее, мы include_once классы, которые мы создали до сих пор. Затем мы создаем экземпляр Meta_Box и передаем ему экземпляр Meta_Box_Display в его конструкторе.

Наконец, мы вызываем метод init который находится в классе Meta_Box .

Предполагая, что все идет хорошо, мы сможем активировать плагин и увидеть мета-поле на странице « Добавить новое сообщение» (или, на самом деле, также на странице « Обновить сообщение» ).

Наш Meta Box появляется на странице нового сообщения Редактировать пост

На данный момент у нас есть работающий плагин, но он на самом деле не делает ничего, кроме создания мета-блока и отображения строки текста.

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

Для начала нам нужно найти текстовый файл вдохновляющих цитат. К счастью, Интернет предоставляет множество из них, которые мы можем использовать в нашем проекте (и они свободно доступны ). Для этого я создал подкаталог data в admin который я использую для размещения своего файла questions.txt .

Файл questionstxt в подкаталоге data

Далее нам нужно создать класс, который будет:

  1. Откройте файл.
  2. Прочитайте случайную строку в строку.
  3. Закройте файл.
  4. Верните строку вызывающей стороне.

Давайте продолжим и создадим этот класс сейчас. Поскольку это утилита, и она будет использоваться в административной части плагина, давайте создадим подкаталог util в admin . Далее, давайте создадим файл с именем class-question-reader.php .

Мы определим код для этого класса через минуту, но вернемся к файлу начальной загрузки плагина и не забудьте включить этот файл. Полученный код должен выглядеть так:

1
2
3
4
5
6
<?php
 
// Include the files for rendering the display.
include_once( ‘admin/class-meta-box.php’ );
include_once( ‘admin/class-meta-box-display.php’ );
include_once( ‘admin/util/class-question-reader.php’ );

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

А сейчас давайте вернемся к читателю вопросов. Код для класса должен выглядеть так:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php
/**
* Reads the contents of a specified file and returns a random line from the
* file.
*/
 
/**
* Reads the contents of a specified file and returns a random line from the
* file.
*
* This class is used to populate the contents of the meta box with questions
* that prompt the user for ideas about which to write.
*
* Note this class is only for demo purposes.
* assumes the specified file always exists.
*/
class Question_Reader {
 
  /**
   * Retrieves a question from the specified file.
   *
   * @param string $filename The path to the file that contains the question.
   * @return string $question A single question from the specified file.
   */
  public function get_question_from_file( $filename ) {
 
      $question = »;
 
      $file_handle = $this->open( $filename );
      $question = $this->get_random_question( $file_handle, $filename );
 
      $this->close( $file_handle );
 
      return $question;
  }
 
  /**
   * Opens the file for reading and returns the resource to the file.
   *
   * @access private
   * @param string $filename The path to the file that contains the question.
   * @return resource A resource to the file.
   */
   private function open( $filename ) {
      return fopen( $filename, ‘r’ );
   }
 
   /**
    * Closes the file that was read.
    *
    * @access private
    * @param string $file_handle The resource to the file that was read.
    */
   private function close( $file_handle ) {
      fclose( $file_handle );
   }
 
   /**
    * Opens the file for reading and returns the resource to the file.
    *
    * @access private
    * @param string $file_handle The resource to the file that was read.
    * @param string $filename The path to the file containing the question.
    * @return string $question The question to display in the meta box.
    */
   private function get_random_question( $file_handle, $filename ) {
 
      $questions = fread( $file_handle, filesize( $filename ) );
      $questions = explode( «\n», $questions );
 
      // Look for a question until an empty string is no longer returned.
      $question = $questions[ rand( 0, 75 ) ];
      while ( empty( $question ) ) {
         $question = $questions[ rand( 0, 75 ) ];
      }
 
      return $question;
    }
}

Обратите внимание, что код для этого относительно прост, но если вы не знакомы с некоторыми основными файловыми операциями в PHP, вот что мы делаем:

  1. Мы открываем файл с помощью fopen , который предоставит нам ресурс для чтения файла.
  2. Затем мы читаем содержимое файла и затем берем каждую строку файла и записываем его в индекс массива.
  3. После этого мы выбираем случайное число из массива вопросов и возвращаем его вызывающему методу. Если он возвращает пустую строку, мы снова смотрим, пока не будет найден вопрос.
  4. Затем мы закрываем ресурс для файла.

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

Примечание. Этот класс не обрабатывает ошибки. Это стандартная практика при работе с файлами. Например, что нам делать, если файл не существует? Что нам делать, если он не отформатирован правильно, или что если нам не удастся закрыть ресурс?

Все это хорошие вопросы, но они выходят за рамки этого урока. Всю эту информацию можно найти в руководстве по PHP (и, возможно, в некоторых других руководствах по сети Envato Tuts +).

На данный момент, однако, мы заинтересованы в чтении файла, который, как мы знаем, существует, и мы заинтересованы в отображении результатов в метабоксе.

На этом этапе мы можем начать собирать все вместе. Предполагая, что мы все сделали правильно, мы должны быть в состоянии передать экземпляр Question_Reader в Meta_Box_Display , задать вопрос, а затем отобразить его в мета-окне.

Сначала давайте обновим файл начальной загрузки:

01
02
03
04
05
06
07
08
09
10
11
12
<?php
 
function tutsplus_namespace_demo() {
 
    $meta_box = new Meta_Box(
        new Meta_Box_Display(
            new Question_Reader()
        )
    );
 
    $meta_box->init();
}

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
/**
 * Defines the functionality required to render the content within the Meta Box
 * to which this display belongs.
 */
 
/**
 * Defines the functionality required to render the content within the Meta Box
 * to which this display belongs.
 *
 * When the render method is called, the contents of the string it includes
 * or the file it includes to render within the meta box.
 */
class Meta_Box_Display {
 
        /**
     * A reference to the object responsible for retrieving a question to display.
     *
     * @access private
     * @var Question_Reader $question_reader
     */
    private $question_reader;
 
    /**
     * Initializes the class by setting the question reader property.
     *
     * @param Question_Reader $question_reader The object for retrieving a question.
     */
    public function __construct( $question_reader ) {
        $this->question_reader = $question_reader;
    }
 
    /**
     * Renders a single string in the context of the meta box to which this
     * Display belongs.
     */
    public function render() {
 
        $file = dirname( __FILE__ ) .
        $question = $this->question_reader->get_question_from_file( $file );
 
        echo wp_kses( $question );
    }
}

Обратите внимание, что этот файл использует путь к вопросам, которые файл добавляет в подкаталог data. Помимо жестко закодированного пути, этот класс также зависит от экземпляра Question_Reader .

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

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

Кроме того, обратите внимание на использование wp_kses для wp_kses данных перед их представлением пользователю.

Обновление страницы « Добавить новое сообщение» должно представить вам изображение, подобное этому:

Случайные вопросы, появляющиеся в метабоксе

И если вы обновите страницу, то увидите новые загружаемые вопросы.

Очевидно, что нам еще предстоит заняться вопросами пространств имен и автозагрузки, но это нормально! Важно, чтобы мы заложили основу для плагина, который их не использует. Таким образом, когда мы их реализуем, мы видим преимущества, которые они несут.

Кроме того, нам еще предстоит проделать дополнительную работу: нам нужно представить JavaScript и CSS и загрузчик ресурсов. Это позволит нам получить еще более широкую картину того, как выгодна упаковка наших файлов в пространства имен.

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

Как всегда, если вы ищете другие утилиты, которые помогут вам создать свой растущий набор инструментов для WordPress или, например, код для изучения и стать более опытным в WordPress, не забудьте посмотреть, что у нас есть в Envato. Рынок

С учетом вышесказанного у нас будет рабочая версия плагина, готовая к загрузке, начиная со следующего урока в этой серии. Если вы хотите использовать код из приведенного выше учебника, не стесняйтесь попробовать это сделать. Кроме того, не стесняйтесь задавать любые вопросы в комментариях.