Статьи

Создание плагинов WordPress с помощью методов ООП

Объектно-ориентированный код, помимо прочего, может помочь организовать и добавить возможность многократного использования в ваш код. В этом уроке я научу вас основам написания плагина WordPress с использованием объектно-ориентированных методов. Мы будем использовать API Dribbble в качестве примера для этого урока. Готов?


  • Преимущества использования ООП для плагинов WordPress.
  • Как настроить шорткод.
  • Как настроить тег шаблона.
  • Как включить шорткод в виджетах WordPress.
  • Реальный пример с использованием API Dribbble.

Прежде чем двигаться дальше с этим учебником, вы должны иметь хотя бы элементарное понимание написания плагина WordPress. Джонатан написал замечательное руководство «Как написать плагин для WordPress» . Дайте ему прочитать.

Создание плагинов WordPress с объектно-ориентированным кодом довольно эффективно и аккуратно по сравнению с использованием процедурного кода. Управлять базой кода и расширять ее проще, используя методы наследования, которые могут быть особенно полезны при написании большого плагина.


Чтобы написать плагин для WordPress, нам сначала нужно почувствовать направление. Мы собираемся написать плагин, который будет отображать последние снимки из Dribbble , используя их REST API. Затем мы добавим поддержку шорткода для постов и виджетов, а также тег шаблона для тем.


Объектно-ориентированный код основан на классах и методах (функциях). Давайте создадим наш основной класс, который будет взаимодействовать с хуками и фильтрами WordPress.

1
2
3
4
5
6
7
class WPDribbble {
    public function __construct()
    {
    }
}
 
$wpDribbble = new WPDribbble();

Классы PHP имеют функцию конструктора __construct , которая выполняется, как только создается новый экземпляр класса. Все хуки и фильтры WordPress будут зарегистрированы в конструкторе нашего класса плагинов. Давайте продвинемся вперед и зарегистрируем шорткод для нашего плагина. Функция / ловушка add_shortcode() будет идти под функцией конструктора.

Новый экземпляр класса / объекта регистрируется с использованием new ключевого слова. Обратитесь к последней строке в коде ниже.

01
02
03
04
05
06
07
08
09
10
11
12
class WPDribbble {
    public function __construct()
    {
        add_shortcode(‘Dribbble’, array($this, ‘shortcode’));
    }
     
    public function shortcode()
    {
    }
}
 
$wpDribbble = new WPDribbble();
  • add_shortcode — первый параметр — это тег шорткода, а второй — функция обратного вызова.

Обратите внимание, как мы используем array в параметре функции обратного вызова? Чтобы зарегистрировать функции обратного вызова внутри объекта, мы должны использовать array .

Первый элемент массива ссылается на объект через $this . Вторым элементом в array является имя метода в классе. На все хуки и фильтры нужно ссылаться вот так внутри класса.

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
# 1. Standard usage
add_shortcode(‘shortcode_name’, ‘shortcode_func’);
 
function shortcode_func()
{
 // Contents of this function will execute when the blogger
// uses the [shortcode_name] shortcode.
}
 
# 2. With PHP 5.3, we can pass an anonymous function.
add_shortcode(‘shortcode_name’, function() {
   // Contents of this function will execute when the blogger
  // uses the [shortcode_name] shortcode.
});
 
#3.
class WPDribbble {
    public function __construct()
    {
        add_shortcode(‘Dribbble’, array($this, ‘shortcode’));
    }
     
    public function shortcode()
    {
           // Contents of this function will execute when the blogger
          // uses the [shortcode_name] shortcode.
    }
}

Поскольку в настоящее время нам не требуются какие-либо необычные функции API, мы собираемся создать довольно простую оболочку API для Dribbble. Уже есть библиотека для Dribbble, но для этого урока мы напишем свою. Это поможет вам понять концепции этого урока.

Мы собираемся написать object DribbbleAPI и зарегистрировать method getPlayerShots() для взаимодействия с API Dribbble и возврата array последних снимков.

Давайте создадим новый файл для этого класса с именем DribbbleAPI.php

1
2
3
4
5
6
7
class DribbbleAPI {
    // url to Dribbble api
    protected $apiUrl = ‘http://api.dribbble.com/’;
     
    // Dribbble username or user id
    protected $user;
}

Выше мы устанавливаем две переменные класса.

  • $ apiUrl — ссылка на API Dribbble, куда будут отправляться звонки.
  • $ user — имя пользователя или идентификатор пользователя Dribbble. Это значение будет установлено из метода конструктора ( __construct ).
01
02
03
04
05
06
07
08
09
10
11
12
class DribbbleAPI {
    // url to Dribbble api
    protected $apiUrl = ‘http://api.dribbble.com/’;
     
    // Dribbble username or user id
    protected $user;
     
    public function __construct($user)
    {
        $this->user = $user;
    }
}

В конструктор передается переменная $user , которая затем передается конструктором в свойство класса, называемое user .

Мы добавляем свойство или имя переменной к public чтобы указать, что значение этого свойства может быть получено извне class . Если вместо этого мы хотим ограничить доступ к свойству только этим class и, возможно, любыми class , наследующими его, мы будем использовать protected префикс. Эта практика называется инкапсуляцией.

У нас есть готовая база для нашей оболочки API Dribbble. Теперь мы собираемся написать новый method , называемый getPlayerShots() . Целью этого method будет запрос API и преобразование результата в array для использования в нашем плагине.

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
class DribbbleAPI {
    // url to Dribbble api
    protected $apiUrl = ‘http://api.dribbble.com/’;
     
    // Dribbble username or user id
    protected $user;
     
    public function __construct($user)
    {
        $this->user = $user;
    }
     
    public function getPlayerShots($perPage = 15)
    {
        $user = $this->user;
         
        $json = wp_remote_get($this->apiUrl . ‘players/’ . $user . ‘/shots?per_page=’ . $perPage);
         
        $array = json_decode($json[‘body’]);
         
        $shots = $array->shots;
         
        return $shots;
    }
}

Узнайте больше о wp_remote_get .

Функция getPlayerShots извлекает пользователя из переменной класса. Он использует функцию wp_remote_get WordPress для запроса API Dribbble. Затем API отвечает на наш запрос строкой JSON, которая затем анализируется в array и отправляется обратно в функцию с помощью ключевого слова return .

Это все, что нам требуется от API на данный момент — просто array кадров для игрока. Если в будущем нам потребуется больше функциональности, мы можем либо добавить больше method к текущему class , либо создать новый class , расширяющий этот class . Опять же, это называется наследством.


Это забавная часть; DribbbleAPI в силу свежеиспеченный class DribbbleAPI . Мы собираемся перебрать снимки, полученные из API, и сгенерировать html список снимков, который будет передан в шорткод и тег шаблона. Во время цикла полноразмерные изображения Dribbble будут кэшироваться и сохраняться в папке плагинов, а миниатюры будут создаваться с использованием TimThumb.

Чтобы определить, хранятся ли полные изображения локально, требуется plugin path к plugin path . Кроме того, для создания миниатюр с помощью timthumb требуется plugin url . Для этого мы создадим две переменные класса с pluginPath и pluginURL в нашем классе WPDribbble , а затем установим их значения из method конструктора.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
class WPDribbble {
    protected $pluginPath;
    protected $pluginUrl;
     
    public function __construct()
    {
        // Set Plugin Path
        $this->pluginPath = dirname(__FILE__);
     
        // Set Plugin URL
        $this->pluginUrl = WP_PLUGIN_URL .
         
        add_shortcode(‘Dribbble’, array($this, ‘shortcode’));
    }

Создайте новый method в class WPDribbble , который называется getImages .

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

1
2
3
public function getImages($user, $images = 3, $width = 50, $height = 50, $caption = true)
{
}
  • $ user — имя пользователя или идентификатор пользователя Dribbble. $user будет использоваться при регистрации нового экземпляра класса DribbbleAPI .
  • $ images — Количество изображений для рендеринга. $images будет использоваться при запросе API через метод getPlayerShots .
  • $ width и $ height — Timthumb будет использоваться для создания миниатюр.
  • $ caption — опция для отображения заголовка изображения.

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

01
02
03
04
05
06
07
08
09
10
public function getImages($user, $images = 3, $width = 50, $height = 50, $caption = true)
{
    include ‘DribbbleAPI.php’;
     
    $DribbbleAPI = new DribbbleAPI($user);
    $shots = $DribbbleAPI->getPlayerShots($images);
     
    if($shots) {
    }
}

Переменная $shots в коде заполнена array из трех последних Dribbbles от $user .

Как упоминалось ранее, мы собираемся $shots array $shots и сохранить локальные изображения в полном размере для целей кэширования. Кэшированные изображения будут использоваться с TimThumb для предоставления миниатюр. Для хранения полных изображений и миниатюр, созданных TimThumb, создайте две папки. Мы будем использовать full-images/ для хранения полноразмерных изображений и cache/ для миниатюр, так как это имя папки по умолчанию для TimThumb.

HTML-код для списка будет создан в цикле $shots .

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
public function getImages($user, $images = 3, $width = 50, $height = 50, $caption = true)
{
    include ‘DribbbleAPI.php’;
     
    $DribbbleAPI = new DribbbleAPI($user);
    $shots = $DribbbleAPI->getPlayerShots($images);
     
    if($shots) {
        $html[] = ‘<ul class=»wp-Dribbble»>’;
         
        foreach($shots as $shot) {
            $image = $shot->image_url;
            $fileName = $shot->id .
             
            if (!file_exists($this->pluginPath . ‘/full-images/’ . $fileName)) { // check if the full image exists
                $rawImage = wp_remote_get($image);
                $newImagePath = $this->pluginPath .
                $fp = fopen($newImagePath, ‘x’);
                fwrite($fp, $rawImage[‘body’]);
                fclose($fp);
            }
             
            // generate thumbnail url
            $localImage = $this->pluginUrl .
             
            if($caption) { // if caption is true
                $captionHTML = ‘<p class=»wp-Dribbble-caption»>’ .
            }
             
            // combine shot url, title and thumbnail to add to the ul list
            $html[] = ‘<li class=»wp-Dribbble-list»><a href=»‘ . $shot->url . ‘» title=»‘ . $shot->title . ‘»><img src=»‘ . $localImage . ‘» alt=»‘ . $shot->title . ‘» /></a>’.$captionHTML.'</li>’;
        }
         
        $html[] = ‘</ul>’;
         
        return implode(«\n», $html);
    }
}

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


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

У нас уже есть add_shortcode ловушка add_shortcode в нашем конструкторе класса плагина. Теперь мы собираемся написать method шорткода внутри нашего class , который будет извлекать атрибуты шорткода и возвращать изображения Dribbble с помощью метода getImages() .

Мы будем называть наш [Dribbble] . Как упоминалось ранее, имя шорткода определяется первым параметром в функции add_shortcode . Он будет использоваться с атрибутами, необходимыми для метода getImages() . Например: [Dribbble user=haris images=5 width=100 height=100 caption=true] .

01
02
03
04
05
06
07
08
09
10
11
12
13
public function shortcode($atts)
{
    // extract the attributes into variables
    extract(shortcode_atts(array(
        ‘images’ => 3,
        ‘width’ => 50,
        ‘height’ => 50,
        ‘caption’ => true,
    ), $atts));
     
    // pass the attributes to getImages function and render the images
    return $this->getImages($atts[‘user’], $images, $width, $height, $caption);
}

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

Мы можем добавить фильтр в наш WPDribbble объектов WPDribbble .

01
02
03
04
05
06
07
08
09
10
11
12
13
public function __construct()
{
    // Set Plugin Path
    $this->pluginPath = dirname(__FILE__);
 
    // Set Plugin URL
    $this->pluginUrl = WP_PLUGIN_URL .
     
    add_shortcode(‘Dribbble’, array($this, ‘shortcode’));
     
    // Add shortcode support for widgets
    add_filter(‘widget_text’, ‘do_shortcode’);
}

Тег шаблона можно использовать непосредственно в темах WordPress. Основной целью тега шаблона будет создание нового экземпляра нашего класса WPDribbble и вызов метода getImages() . Тег шаблона будет простой функцией PHP и должен быть зарегистрирован вне class плагина. Это должно иметь уникальное имя; в противном случае он будет конфликтовать с функциями / плагинами с похожим именем. Поскольку наш плагин называется WP-Dribbble , мы будем называть тег шаблона wp_Dribbble() .

1
2
3
4
5
function wp_Dribbble($user, $images = 3, $width = 50, $height = 50, $caption = true)
{
    $wpDribbble = new WPDribbble;
    echo $wpDribbble->getImages($user, $images, $width, $height, $caption);
}

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