Реальний приклад розробки плагіна WordPress

376

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

Реальний приклад – Список філій компанії

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

Даний функціонал можна було б реалізувати у дочірньої темі, але з-за його універсальності краще створити плагін, який потім можна буде використовувати і на інших сайтах.

У прикладі ми розповімо про розробку плагіна, який буде обробляти дані і виводити їх у вигляді списку місць. Місця будуть представляти собою користувальницький тип контенту з додатковими мета даних для зберігання інформації про місцезнаходження. В плагіні буде можливість відображати інформацію кількома способами (окрема сторінка місць, віджет зі списком місць і шорткод зі списком місць).

Реальний приклад розробки плагіна WordPress

Налаштування

Давайте всі налаштуємо, перейдіть в папку плагіна і створіть наступні папки/файлову структуру

Реальний приклад розробки плагіна WordPress

Самий верхній файл wp_simple_location_plugin.php буде головним. Тут ми будемо завантажувати наші стилі з папки CSS, а також додаткові PHP файли з папки inc.

Основний клас розташування

У файлі wp_simple_location_plugin.php буде прописано ядро плагіна. Також в цьому файлі ми підключимо додаткові файли, які потрібні для створення віджета і шорткодов.

Непрямий доступ

Рекомендується закривати прямий доступ до PHP файлів за допомогою перевірки на існування константи ABSPATH (якщо не існує, скрипт припиняє роботу). Розмістіть код нижче прямо після відкриваючого PHP тега:

defined( ‘ABSPATH’ ) or die( ‘Nope, not accessing this’ );

Оголошення плагіна

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

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

Клас Class wp_simple_location

Тепер необхідно створити оболонку для класу wp_simple_location. В цьому класі буде прописана велика частина функціоналу плагіна, в ньому будуть зберігатися наші властивості і методи.

class wp_simple_location{
}

Підключаємо файли шорткодов і віджету

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

//шорткоди
include(plugin_dir_path(__FILE__) . ‘inc/wp_location_shortcode.php’);
//віджети
include(plugin_dir_path(__FILE__) . ‘inc/wp_location_widget.php’);

Код вище підключає наші файли. Про них ми поговоримо трохи пізніше.

Властивості класу

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

//Властивості
private $wp_location_trading_hour_days = array();

Функція _construct

Функція _construct – важлива частина плагіна. Це майстер-функція, з допомогою якої можна обробляти і запускати інші функції.

Функція відноситься до так званих magic (магічним) функцій. Магічні функції являють собою спеціальні функції, додані в PHP5, автоматично запускаються при певних умовах. Ця функція спрацьовує відразу ж після створення екземпляра класу (клас створений і створено його примірник у вигляді змінної).

В плагіні цю функцію ви будете використовувати для додавання всіх екшенів, фільтрів і виклику інших функцій. Хуки можна додавати і з іншого місця, але краще хай вони залишаться там. Скопіюйте код нижче. Ми пройдемося по кожному елементу, щоб ви зрозуміли, що тут відбувається.

//магічна функція (запускається при створенні екземпляра класу)
public function __construct(){
add_action(‘init’, array($this,’set_location_trading_hour_days’)); //задає робочі дні (використовується типом контенту)
add_action(‘init’, array($this,’register_location_content_type’)); //реєструє тип контенту розташування
add_action(‘add_meta_boxes’, array($this,’add_location_meta_boxes’)); //додає мета поля
add_action(‘save_post_wp_locations’, array($this,’save_location’)); //зберігає розташування
add_action(‘admin_enqueue_scripts’, array($this,’enqueue_admin_scripts_and_styles’)); //скрипти і стилі адміністратора
add_action(‘wp_enqueue_scripts’, array($this,’enqueue_public_scripts_and_styles’)); //публічні стилі і скрипти
add_filter(‘the_content’, array($this,’prepend_location_meta_to_content’)); //витягає наші мета дані і показує їх перед контентом
register_activation_hook(__FILE__, array($this,’plugin_activate’)); //активує хук
register_deactivation_hook(__FILE__, array($this,’plugin_deactivate’)); //відключає хук
}

Функції register_activation_hook і register_deactivation_hook використовуються для вбудовування в інші функції при активації і відключенні плагіна. Ми будемо використовувати ці функції для перевірки правильності доданого типу контенту (наші місця) і обробки посилань (ми будемо використовувати людинозрозумілі посилання).

Налаштування робочих годин для певного філії

Наш плагін дозволяє адміністратору встановлювати годинник відкриття і закриття філії для кожного дня тижня окремо.

Робочі дні зберігаються на стороні back-end’а у властивості $wp_location_trading_hour_days. Для налаштування робочих днів і годин необхідно викликати функцію set_location_trading_hour_days.

//Встановлює стандартні робочі дні та години (використовується на стороні back-end)
public function set_location_trading_hour_days(){
//задаємо дні, які будуть використовуватися для робочих годин
$this->wp_location_trading_hour_days = apply_filters(‘wp_location_trading_hours_days’,
array(‘monday’ => ‘Monday’,
‘tuesday’ => ‘Tuesday’,
‘wednesday’ => ‘Wednesday’,
‘thursday’ => ‘Thursday’,
‘friday’ => ‘Friday’,
‘saturday’ => ‘Субота’,
‘sunday’ => ‘Sunday’,
)
);
}

Після заповнення значень масиву необхідно викликати фільтр wp_location_trading_hours_days. Тобто тема або інший плагін зможуть переписати робочі дні магазину (вони можуть фільтрувати масив і додати поле канікул «holidays», щоб потім поставити для цього періоду свій робочий час).

Налаштування робочих годин заданого філії

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

//реєстрація типу контенту розташування
public function register_location_content_type(){
//Лейбли типу постів
$labels = array(
‘name’ => ‘Location’,
‘singular_name’ => ‘Location’,
‘menu_name’ => ‘Locations’,
‘name_admin_bar’ => ‘Location’,
‘add_new’ => ‘Add New’,
‘add_new_item’ => ‘Add New Location’,
‘new_item’ => ‘New Location’,
‘edit_item’ => ‘Edit Location’,
‘view_item’ => ‘View Location’,
‘all_items’ => ‘All Locations’,
‘search_items’ => ‘Search Locations’,
‘parent_item_colon’ => ‘Parent Location:’,
‘not_found’ => ‘No Locations found.’,
‘not_found_in_trash’ => ‘No Locations found in Trash.’,
);
//аргументи типу постів
$args = array(
‘labels’ => $labels,
‘public’ => true,
‘publicly_queryable’=> true,
‘show_ui’ => true,
‘show_in_nav’ => true,
‘query_var’ => true,
‘hierarchical’ => false,
‘supports’ => array(‘title’,’thumbnail’,’editor’),
‘has_archive’ => true,
‘menu_position’ => 20,
‘show_in_admin_bar’ => true,
‘menu_icon’ => ‘dashicons-location-alt’,
‘rewrite’ => array(‘slug’ => ‘locations’, ‘with_front’ => ‘true’)
);
//реєстрація типу постів
register_post_type(‘wp_locations’, $args);
}

Після додавання цього коду в меню повинна з’явитися нова рядок.

Реальний приклад розробки плагіна WordPress

Додаємо мета бокс до нового типу розташування

Необхідно створити користувальницький мета бокс, який буде відображатися на сторінці місцезнаходжень. В цьому боксі будуть розташовуватися всі додаткові поля, які нам знадобляться у вигляді мета даних (номер телефону, електронна пошта, адреса). Всередині функції викликаємо функцію add_meta_box() і передаємо їй наші аргументи.

//додавання мета боксу до местоположениям*/
public function add_location_meta_boxes(){
add_meta_box(
‘wp_location_meta_box’, //id
‘Location Information’, //назва
array($this,’location_meta_box_display’), //функція відображення
‘wp_locations’, //тип поста
‘normal’, //Розташування
‘default’ //Пріоритет
);
}

Третє значення add_meta_box – функція, яка буде показувати наш бокс. Тут ми викликаємо функцію location_meta_box_display, її ми створимо наступної.

Функція location_meta_box_display

Ця функція буде викликатися з мета боксу і буде показувати додаткові поля, які адміністратор зможе використовувати для запису інформації про місці.

//функція відображення мета боксу box*/
public function location_meta_box_display($post){
//поле ” nonce
wp_nonce_field(‘wp_location_nonce’, ‘wp_location_nonce_field’);
//збираємо змінні
$wp_location_phone = get_post_meta($post->ID,’wp_location_phone’,true);
$wp_location_email = get_post_meta($post->ID,’wp_location_email’,true);
$wp_location_address = get_post_meta($post->ID,’wp_location_address’,true);
?>

Enter additional information about your location

Contact Phone
main contact number
Contact Email
Contact Email
Address
Physical address of your location

wp_location_trading_hour_days)){
echo ‘

‘;
echo ‘Hours Trading ‘;
echo ‘ hours Trading for the location (e.g 9am – 5pm) ‘;
//проходимся в циклі через всі робочі дні
foreach($this->wp_location_trading_hour_days as $day_key => $day_value){
//збираємо мета дані про робочих годинах
$wp_location_trading_hour_value = get_post_meta($post->ID,’wp_location_trading_hours_’ . $day_key, true);
//показуємо лейбли і инпут
echo ” . $day_key . “;
echo “;
}
echo ‘

‘;
}
?>

Що робить функція:

Спершу створюється безпечне nonce поле для мета боксу (nonce використовується для перевірки того, що екшен відправки форми прийшов з потрібного місця).

Поле збираємо наші телефони, пошту і адреси (якщо вони є).

Перед самою формою ми додаємо хук wp_location_admin_form_start. Це дозволить іншим плагінів і тем вбудуватися в це місце, щоб додати додаткові поля або дані.

Показуємо поля телефону, пошти і адреси (якщо є якісь дані, то заповнюємо їх).

Показуємо список робочих днів для окремого мета. Тут адміністратор може встановлювати робочі години для кожного дня окремо. Дні можуть змінюватися, якщо вони прикріплені до фільтру wp_location_trading_hours_days.

Перед закриттям форми додаємо хук wp_location_admin_form_end. Це дозволить іншим плагінів і тем вбудуватися в це місце і додати додаткові поля або дані.

Мета бокс повинен здатися на сторінці місця. Виглядати це буде приблизно так:

Реальний приклад розробки плагіна WordPress

Реєстрація типу контенту і обробка правил перезапису під час активації

Під час першої активації плагіна можна викликати функцію, яка буде виконана лише раз. Для цього ми будеи використовувати функцію plugin_activate.

Ми зареєстрували тип контенту через хук init, але нам все одно потрібно викликати функцію register_location_content_type (щоб перевірити, додався наш тип).

Також ми змінимо правила перезапису, щоб можна було використовувати людинозрозумілі посилання (у нас будуть посилання типу example.com/location/mylocation замість example.com/?p=144)

//Спрацьовує при активації плагіна (викликається один раз)
public function plugin_activate(){
//викликаємо функцію перевірки користувальницького типу вмісту
$this->register_location_content_type();
//обробляємо посилання
flush_rewrite_rules();
}

Скидання правил перезапису при відключенні плагіна

Функція plugin_deactivate спрацьовує при відключенні плагіна. Так як ми видаляємо плагін, а в плагіні використовувався користувальницький тип контенту, то для вірності необхідно скинути правила перезапису.

// Спрацьовує при відключенні плагіна (викликається один раз)
public function plugin_deactivate(){
//Скидання посилань
flush_rewrite_rules();
}

Показуємо мета дані для конкретного місця

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

Функція prepend_location_meta_to_content чіпляється до фільтру the_content, тобто ми можемо додати свої дані перед головним контентом сторінок.

public function prepend_location_meta_to_content($content){
global $post, $post_type;
//Показуємо мета дані тільки для місць (і якщо конкретне місце)
if($post_type == ‘wp_locations’ && is_singular(‘wp_locations’)){
//збираємо змінні
$wp_location_id = $post->ID;
$wp_location_phone = get_post_meta($post->ID,’wp_location_phone’,true);
$wp_location_email = get_post_meta($post->ID,’wp_location_email’,true);
$wp_location_address = get_post_meta($post->ID,’wp_location_address’,true);
//показуємо
$html = “;
$html .= “;
//хук для вставки додаткових даних (на початку форми)
do_action(‘wp_location_meta_data_output_start’,$wp_location_id);
$html .= ‘

‘;
//телефон
if(!empty($wp_location_phone)){
$html .= ‘Location Phone ‘ . $wp_location_phone . ‘
‘;
}
//пошта
if(!empty($wp_location_email)){
$html .= ‘Location Email ‘ . $wp_location_email . ‘
‘;
}
//адреса
if(!empty($wp_location_address)){
$html .= ‘Location Address ‘ . $wp_location_address . ‘
‘;
}
$html .= ‘

‘;
//Місце
if(!empty($this->wp_location_trading_hour_days)){
$html .= ‘

‘;
$html .= ‘Location Hours Trading
‘;
foreach($this->wp_location_trading_hour_days as $day_key => $day_value){
$trading_hours = get_post_meta($post->ID, ‘wp_location_trading_hours_’ . $day_key , true);
$html .= ‘‘ . $day_key . ‘‘ . $trading_hours . ‘
‘;
}
$html .= ‘

‘;
}
//Хук для вставки додаткових мета даних (у кінці форми)
do_action(‘wp_location_meta_data_output_end’,$wp_location_id);
$html .= “;
$html .= $content;
return $html;
}else{
return $content;
}
}

Що робить функція:

Функція додана до хуку the_content, тобто вона буде запускатися при кожному оновленні сторінки. Ми використовуємо глобальні змінні $post і $post_type для перевірки, що ми знаходимося на сторінці конкретного місця

Збираємо базову інформацію: пошта, телефон і адресу.

Перед відображенням мета даних викликаємо хук wp_location_meta_data_output_start. З його допомогою інші плагіни або теми зможуть вбудуватися в це місце і додавати додаткові мета дані (якщо хтось додасть нове поле до місця, цей хук можна буде використовувати для відображення збережених даних).

Показуємо пошту, телефон і адресу.

Пробегаемся по змінної wp_location_trading_hour_days і перевіряємо її на робочі дні. Якщо вони є, пробегаемся за ним в циклі, зберігаємо робочі години і показуємо їх.

Майже в самому кінці викликаємо екшен wp_location_meta_data_output_end. З його допомогою можна буде додати додаткові дані перед закриттям мета боксу.

Виводимо список місць

Необхідно створити функцію для створення HTML коду списку місць. Функція get_locations_output використовується як віджетом, так і шорткодом для створення розмітки. Так як функція багатозадачна, у ній є кілька важливих дій. Розберемо все по порядку.

//головна функція відображення списку місць (використовується шорткодами і віджетами)
public function get_locations_output($arguments = “”){
//стандартні аргументи
$default_args = array(
‘location_id’ => “,
‘number_of_locations’ => -1
);
//якщо передані нові аргументи, оновлюємо
if(!empty($arguments) && is_array($arguments)){
//проходимся в циклі по всім аргументам
foreach($arguments as $arg_key => $arg_val){
//якщо аргумент є в наших дефолтних, оновлюємо його значення
if(array_key_exists($arg_key, $default_args)){
$default_args[$arg_key] = $arg_val;
}
}
}
//знаходимо місця
$location_args = array(
‘post_type’ => ‘wp_locations’,
‘posts_per_page’=> $default_args[‘number_of_locations’],
‘post_status’ => ‘publish’
);
//if we passed in a single location to display
if(!empty($default_args[‘location_id’])){
$location_args[‘include’] = $default_args[‘location_id’];
}
//висновок
$html = “;
$locations = get_posts($location_args);
//Якщо місця є
if($locations){
$html .= “;
//пробегаемся циклом по місцях
foreach($locations as $location){
$html .= “;
//збираємо дані про місця
$wp_location_id = $location->ID;
$wp_location_title = get_the_title($wp_location_id);
$wp_location_thumbnail = get_the_post_thumbnail($wp_location_id,’thumbnail’);
$wp_location_content = apply_filters(‘the_content’, $location->post_content);
if(!empty($wp_location_content)){
$wp_location_content = strip_shortcodes(wp_trim_words($wp_location_content, 40, ‘…’));
}
$wp_location_permalink = get_permalink($wp_location_id);
$wp_location_phone = get_post_meta($wp_location_id,’wp_location_phone’,true);
$wp_location_email = get_post_meta($wp_location_id,’wp_location_email’,true);
//застосовуємо фільтр перед виведенням основного вмісту
//(дозволяємо сторонніх плагінів і тем вбудовуватися в HTML для відображення даних)
$html = apply_filters(‘wp_location_before_main_content’, $html);
//заголовок
$html .= ‘

‘;
$html .= “;
$html .= $wp_location_title;
$html .= “;
$html .= ‘

‘;
//зображення та контент
if(!empty($wp_location_thumbnail) || !empty($wp_location_content)){
$html .= ‘

‘;
if(!empty($wp_location_thumbnail)){
$html .= $wp_location_thumbnail;
}
if(!empty($wp_location_content)){
$html .= $wp_location_content;
}
$html .= ‘

‘;
}
//телефон і пошта
if(!empty($wp_location_phone) || !empty($wp_location_email)){
$html .= ‘

‘;
if(!empty($wp_location_phone)){
$html .= ‘Phone: ‘ . $wp_location_phone . ‘
‘;
}
if(!empty($wp_location_email)){
$html .= ‘Email: ‘ . $wp_location_email;
}
$html .= ‘

‘;
}
// застосовуємо фільтр після виведення основного вмісту
//( дозволяємо сторонніх плагінів і тем вбудовуватися в HTML для відображення даних)
$html = apply_filters(‘wp_location_after_main_content’, $html);
//докладніше
$html .= ‘View Location’;
$html .= “;
}
$html .= “;
$html .= ‘

‘;
}
return $html;
}

У функції є необов’язковий аргумент arguments. Він використовується з-за того, що у нас і віджети і шорткоди передають свої варіанти відображення (для точної настройки того, що буде повернуто).

В масив заносяться стандартні аргументи. Кількість місць буде встановлено -1 (всі місця), ID буде без значення (тобто ми хочемо показати список місць, а не конкретне місце).

Перевіряємо передану змінну $arguments на порожнечу, і вона є масивом. Пробегаемся по всім аргументам $arguments і звіряємо їх ключі на збіг з нашим масивом $default_args. Якщо що-то співпало, оновлюємо масив $default_args.

Масив $default_args використовується для створення запиту для get_posts(), який і буде шукати всі місця (якщо створено всього одне місце, його ми і отримаємо).

Тепер переходимо до створення HTML. Створюємо змінну $html, куди будемо заносити розмітку.

Збираємо всі дані про місце (заголовок, вміст, зображення і т. д.) і готуємо їх до висновку.

Викликаємо фільтр wp_location_before_main_content на змінну $html. Так сторонні плагіни і теми зможуть додавати додатковий контент перед заголовком місця. Вкрай корисно, якщо ми заздалегідь створили додаткові поля в панелі адміністратора, які потім можна виводити.

До висновку додаються заголовок, зображення, контент, телефон і пошта (з умовами на перевірку їх існування).

Перед виведенням кнопки Докладніше ми викликаємо наш другий фільтр wp_location_after_main_content. З його допомогою сторонні плагіни і теми зможуть додавати додатковий контент прямо перед кнопкою.

Додаємо кнопку Детальніше і повертаємо нашу змінну $html.

Збереження додаткових мета даних

При збереженні нового місця необхідно запускати функцію, яка буде збирати і оновлювати наші додаткові мета поля (пошта, телефон, адресу тощо). Для цього ми створимо функцію save_location.

//запускається при додаванні або редагуванні місця
public function save_location($post_id){
//шукаємо nonce
if(!isset($_POST[‘wp_location_nonce_field’])){
return $post_id;
}
//перевіряємо nonce
if(!wp_verify_nonce($_POST[‘wp_location_nonce_field’], ‘wp_location_nonce’)){
return $post_id;
}
//шукаємо автозбереження
if(defined(‘DOING_AUTOSAVE’) && DOING_AUTOSAVE){
return $post_id;
}
//отримуємо поля телефон, пошта, адреса
$wp_location_phone = isset($_POST[‘wp_location_phone’]) ? sanitize_text_field($_POST[‘wp_location_phone’]) : “;
$wp_location_email = isset($_POST[‘wp_location_email’]) ? sanitize_text_field($_POST[‘wp_location_email’]) : “;
$wp_location_address = isset($_POST[‘wp_location_address’]) ? sanitize_text_field($_POST[‘wp_location_address’]) : “;
//оновлюємо поля телефон, пошта, адреса
update_post_meta($post_id, ‘wp_location_phone’, $wp_location_phone);
update_post_meta($post_id, ‘wp_location_email’, $wp_location_email);
update_post_meta($post_id, ‘wp_location_address’, $wp_location_address);
//шукаємо робочі чати і оновлюємо їх
foreach($_POST as $key => $value){
//якщо знайшли, оновлюємо
if(preg_match(‘/^wp_location_trading_hours_/’, $key)){
update_post_meta($post_id, $key, $value);
}
}
//хук збереження місця використовується для збереження додаткових полів
//через ‘wp_location_meta_data_output_end’ або ‘wp_location_meta_data_output_end’
do_action(‘wp_location_admin_save’,$post_id, $_POST);
}

Що ми робимо:

Спочатку шукаємо поле ” nonce та перевіряємо його на існування (передається через мета бокс). Також перевіряємо автозбереження. Після всіх перевірок їдемо далі.

Збираємо телефон, пошту та адресу та очищаємо дані за допомогою функції sanitize_text_field(). Дані заносяться в змінні і пізніше використовуються в нашій функції update_post_meta() для збереження даних про місці.

Так як наші робочі години динамічні, витягувати і зберігати їх ми змушені трохи по-іншому. Ми не знаємо, скільки буде значень, тому ми не можемо витягувати їх з масиву $_POST по імені. Нам доведеться пройтися по всьому масиву і перевіряти ключі на збіг з «wp_location_trading_hours_». Якщо збіг є, ми оновлюємо значення і зберігаємо їх у якості мета даних.

Майже в кінці викликаємо екшен wp_location_admin_save. Екшен зберігає ID поточного місця в $post_id, щоб сторонні функції могли витягувати додаткові дані з масиву $_POST і зберігати їх на місці.

Завантажуємо адмін і публічні скрипти і стилі

Нам необхідно завантажити додаткові CSS файли як для front-end, так і для back-end боку нашого сайту. Для цього ми створимо дві функції, які будуть завантажувати будь-які скрипти або файли стилів.

Всередині CSS файлів будуть стилі полів мета боксу в панелі адміністратора, а також трохи стилів front-end’а. Плагін чудово працює без CSS стилів. Якщо вам ця частина не цікава, її можна пропустити. (Якщо ви пропускаєте цю частину, не забудьте видалити виклик екшенів в конструкторі)

//підключаємо скрипти і стилі на стороні back-end’а
public function enqueue_admin_scripts_and_styles(){
wp_enqueue_style(‘wp_location_admin_styles’, plugin_dir_url(__FILE__) . ‘/css/wp_location_admin_styles.css’);
}
// підключаємо скрипти і стилі на стороні front-end’а
public function enqueue_public_scripts_and_styles(){
wp_enqueue_style(‘wp_location_public_styles’, plugin_dir_url(__FILE__). ‘/css/wp_location_public_styles.css’);
}

Шорткод

Тепер можна перейти до класу шорткода, який буде працювати в парі з нашим основним класом. Шорткоди надають адміністратору простий інтерфейс відображення різних місць. Шорткоди будуть настроюються, адміністратор зможе задавати конкретний філія (місце) на ID або ж показувати всі філії відразу. Шорткод на сторінці буде виглядати приблизно наступним чином:

Реальний приклад розробки плагіна WordPress

Працювати ми будемо у файлі wp_location_shortcode.php.

Заборона на прямий доступ

Як у випадку з основним файлом PHP, тут ми теж хочемо закрити прямий доступ. Скопіюйте код нижче у верхівку файлу:

defined( ‘ABSPATH’ ) or die( ‘Nope, not accessing this’ );

Клас wp_location_shortcode

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

//задаємо функціонал шорткода для відображення місць
class wp_location_shortcode{
}

Функція __construct

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

//запускається при створенні екземпляра класу
public function __construct(){
add_action(‘init’, array($this,’register_location_shortcodes’)); //шорткоди
}

Функція register_location_shortcodes

З допомогою цієї функції ми будемо додавати шорткод. Ми викликаємо функцію add_shortcode для додавання нового шорткода wp_locations. Для виведення шорткода будемо використовувати функцію location_shortcode_output.

//шорткод місць
public function register_location_shortcodes(){
add_shortcode(‘wp_locations’, array($this,’location_shortcode_output’));
}

Висновок шорткода

Функція виведення викликається з функції add_shortcode і потрібна для формування коду для виведення шорткода на екран.

//відображення шорткода
public function location_shortcode_output($atts, $content = “, $tag){
//робимо клас wp_simple_locations глобальним
global $wp_simple_locations;
//створюємо дефолтні аргументи
$arguments = shortcode_atts(array(
‘location_id’ => “,
‘number_of_locations’ => -1)
,$atts,$tag);
//для виведення використовуємо головну функцію виведення з location клас
$html = $wp_simple_locations->get_locations_output($arguments);
return $html;
}

Що робить функція:

Функція приймає аргументи шорткода у вигляді змінної $atts, контент шорткода $content і назавние шорткода $tag. Ці змінні використовуються для формування коду на висновок.

Створюємо глобальну змінну $wp_simple_locations, щоб отримати доступ до головного класу (і всіх його функцій).

Створюємо дефолтний масив аргументів шорткода з допомогою функції shortcode_atts().

Формуємо код на виведення з допомогою функції get_locations_output з об’єкта $wp_simple_locations. У функцію передаємо наші аргументи, щоб контент в шорткоде міг бути динамічним. Приміром, можна передати ID одного місця, тоді повернеться всього одне місце.

Повертаємо шорткод, який можна відобразити на будь-якій сторінці або пості, куди ви його додаватимете.

Створюємо об’єкт wp_location_shortcode

В самому кінці класу необхідно створити об’єкт wp_location_shortcode. Таким чином буде активований весь функціонал класу.

$wp_location_shortcode = new wp_location_shortcode;

Віджет

Закінчимо статтю класом, які працюють з віджетом. Ми додамо віджет, бо майже всі теми зараз підтримує віджети. Віджети дають адміністраторам простий і швидкий спосіб демонстрації чого-небудь (в нашому випадку це філії компанії). Відкриємо файл wp_location_widget.php і почнемо.

Заборона прямого доступу

І знову ми забороняємо прямий доступ до PHP файлу за допомогою наступної рядка:

defined( ‘ABSPATH’ ) or die( ‘Nope, not accessing this’ );

Клас wp_location_widget

Створимо базову структуру класу wp_location_widget. Клас схожий на попередні, але в цей раз ми розширимо вже існуючий клас WP_widget.

//головний віджет для відображення філій компанії
class wp_location_widget extends WP_widget{
}

Функція __construct

У функції _construct ми визначимо наші базові стилі віджета. А зробимо ми це, перевантаживши батьківський конструктор і передавши в нього наші значення. Нам необхідно задати ID, назву та опис віджета. Також ми причепимо нашу функцію register_wp_location_widgets до хуку widgets_init, щоб зареєструвати наш віджет.

//ініціалізація значень віджету
public function __construct(){
//задаємо базові значення віджета (переписуючи батьківські)
parent::__construct(
‘wp_location_widget’,
‘WP Location Widget’,
array(‘description’ => ‘A widget that displays your locations’)
);
add_action(‘widgets_init’,array($this,’register_wp_location_widgets’));
}

Створюємо інтерфейс віджета панелі адміністратора

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

Функція form() успадкована від батьківського класу WP_widget, вона буде автоматично викликатися, коли ми будемо заходити на екран міні-програми в панелі адміністратора.

//код back-end’а віджету
//$instance – зберігає значення форми
public function form($instance){
//збираємо змінні
$location_id = (isset($instance[‘location_id’]) ? $instance[‘location_id’] : ‘default’);
$number_of_locations = (isset($instance[‘number_of_locations’]) ? $instance[‘number_of_locations’] : 5);
?>

Select your options below

Що тут відбувається:

Спершу ми задаємо ID і кількість місць. Перевіряємо змінну $instance на наявність цих значень (існують). Якщо значення є, витягаємо їх. Якщо їх немає, просто передаємо стандартні значення (встановлюємо кількість місць на 5 і передаємо ID за замовчуванням).

Створюємо лейбл і форму для показу місць в панелі адміністратора. За допомогою функції get_posts() витягуємо всі місця і показуємо їх. Кожне місце ми перевіряємо на збіг з збереженим ID (якщо він вказаний).

Створюємо список select для відображення всіх наших місць. І знову перевіряємо всі варіанти на збіг з переданим значенням.

Оновлення віджета і збереження варіантів

Для збереження значень форми необхідно викликати функцію оновлення віджету. Функція update() успадкована від класу WP_widget. Нам залишилося лише вказати, як зберігати значення.

//оновлення віджету
//$new_instance – нові значення, $old_instance – старі збережені значення
public function update($new_instance, $old_instance){
$instance = array();
$instance[‘location_id’] = $new_instance[‘location_id’];
$instance[‘number_of_locations’] = $new_instance[‘number_of_locations’];
return $instance;
}

У нас є дві змінні $new_instance і $old_instance. $New_instance зберігаються поточні значення форми, а у $old_instance зберігаються старі значення. Нам необхідно створити новий масив для зберігання вилучених значень для подальшого їх повернення.

Відображення віджету на стороні front-end’а

Функція widget() успадкована з класу WP_widget, з її допомогою віджет показується на стороні front-end’а. Для формування коду на висновок використовується функція відображення з класу wp_simple_locations.

//публічне відображення віджету
//$args – аргументи віджета, $instance – збережені значення
public function widget( $args, $instance ) {
//отримуємо доступ до класу wp_simple_location class (з його допомогою будемо виводити віджет на екран)
global $wp_simple_locations;
//передаємо всі наявні аргументи з віджету
$arguments = array();
//якщо місце вибрано
//якщо задано конкретне місце
if($instance[‘location_id’] != ‘default’){
$arguments[‘location_id’] = $instance[‘location_id’];
}
//якщо задано декілька місць
if($instance[‘number_of_locations’] != ‘default’){
$arguments[‘number_of_locations’] = $instance[‘number_of_locations’];
}
//висновок
$html = “;
$html .= $args[‘before_widget’];
$html .= $args[‘before_title’];
$html .= ‘Locations’;
$html .= $args[‘after_title’];
//використовуємо головну функцію виведення з класу location
$html .= $wp_simple_locations->get_locations_output($arguments);
$html .= $args[‘after_widget’];
echo $html;
}

Що ми тут робимо:

Створюємо глобальний об’єкт $wp_simple_locations, нам потрібна його функція виводу на екран.

Створюємо порожній масив аргументів і перевіряємо, задані аргументи для віджета (кількість місць, наприклад).

Починаємо формувати код на висновок і створюємо змінну $html. Викликаємо функцію get_locations_output(), прописану в об’єкті $wp_simple_locations, і передаємо в неї аргументи нам повернеться весь HTML код).

Виводимо весь код із змінною $html на екран.

Реєстрація віджету

Функція нижче потрібна для реєстрації віджета WordPress. Необхідно викликати функцію register_widget() і передати їй назву класу в якості значення.

//реєстрація віджету
public function register_wp_location_widgets(){
register_widget(‘wp_location_widget’);
}

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