Віджети WordPress: рефакторинг, частина 11
У попередній публікації ми пройшли через багато рефакторингу, який розділив концерни на власні класи.
Зрештою, це допомагає показати, як ми можемо підтримувати високий рівень згуртованості, не лише працюючи з класами в WordPress, але й роблячи це разом із уже існуючими API.
Оскільки кілька останніх дописів про рефакторинг бази коду були дуже довгими, поточний набір дописів зосереджено на невеликих, поступових змінах і, отже, коротших, більш зосереджених.
Як згадувалося в попередній статті:
Але якщо ви оновите сторінку, ви можете помітити, що очищення та серіалізація не працюють під час отримання даних. І саме це ми розглянемо в наступній публікації.
Ось чому ми збираємося зупинитися в цій статті.
Шаблон віджета WordPress: рефакторинг, частина 11
Перш ніж писати будь-який код, перше, на що слід звернути увагу, це те, що якщо ви заповнюєте одну з областей вмісту віджета (наприклад, заголовок) чимось подібним до цього :
<script type="text/javascript">This is the Title</script>
А потім натисніть «Зберегти», фактичний вміст буде очищено та записано в базу даних. Ви можете переконатися, що це правда, подивившись на значення віджета в базі даних.
Крім того, на перший погляд дані виглядають добре, але якщо ви оновите сторінку, з’явиться неочищений вміст. Якщо ви перейдете на іншу сторінку, як-от меню, а потім повернетесь, вміст віджета з’явиться, але буде належним чином очищено.
Чому тоді під час виконання певних кроків він показує одне в базі даних і одне в інтерфейсі області адміністрування?
Це пов’язано з кеш-пам’яттю віджетів, і, на щастя, ми можемо очищати цей кеш за власним бажанням, використовуючи будь-які перехоплювачі, які забажаємо (тобто ми можемо підписатися на будь-яку подію, а потім надати їй очищення кешу).
З посилання на код :
Видаляє вміст кешу, який відповідає ключу та групі.
Однак зауважте, що для цього потрібно надати ключ і необов’язкову групу. У Boilerplate ми використовували слаг віджета як ключ, а група — віджет.
Очищення кешу
Оскільки функцію можна підключити до будь-якої події, ми можемо створити підписника, якого можна підключити до будь-якої події. Це означає , що ми можемо створити передплатника DeleteWidgetCache у нашому просторі імен Subscriber:
<?php
<?php
/*
* This file is part of WordPress Widget Boilerplate
* (c) Tom McFarlin <tom@tommcfarlin.com>
*
* This source file is subject to the GPL license that is bundled
* with this source code in the file LICENSE.
*/
namespace WordPressWidgetBoilerplateSubscriber;
/**
* Deletes the cached contents of the widget.
*/
class DeleteWidgetCacheSubscriber extends AbstractSubscriber
{
/**
* {@inheritdoc}
*/
public function __construct(string $hook)
{
parent::__construct($hook);
}
/**
* Flushes the widget's cache based on the key that's specified in the function arguments.
*/
public function load()
{
/* Because we're implementing an abstract class, we'll parse arguments from the
* func_get_args().
*/
$args = func_get_args();
if (!$this->hasValidArguments($args)) {
return;
}
// TODO: More to come...
}
/**
* Verifies that we have valid arguments with which to work.
*
* @param array $args the array of arguments we are validating
*
* @return bool true if the arguments are valid; otherwise, false
*/
private function hasValidArguments(array $args): bool
{
// First, check the initial index of the arguments.
if (!isset($args[0])) {
return false;
}
// Next, check the values of the arguments for the widget key and group.
$args = $args[0];
if (!isset($args[0]) && !isset($args[1])) {
return false;
}
return true;
}
}
Потім ми оновимо програму початкового завантаження, щоб додати підписника до реєстру, і ми використаємо спеціальний хук, flush_widget_cache, який ми використаємо миттєво.
<?php
/**
* WordPress Widget Boilerplate
*
* The WordPress Widget Boilerplate is an organized, maintainable boilerplate for building
* widgets using WordPress best practices.
*
* @package WordPressWidgetBoilerplate
* @author Your Name <email@example.com>
* @license GPL-3.0+
* @link http://example.com
* @copyright 2018 - 2019 Your Name or Company Name
*
* @wordpress-plugin
* Plugin Name: WordPress Widget Boilerplate
* Plugin URI: https://github.com/tommcfarlin/wordpress-widget-boilerplate
* Description: An object-oriented foundation for building WordPress Widgets.
* Version: 1.0.0
* Author: Tom McFarlin
* Author URI: https://tommcfarlin.com
* Text Domain: widget-name
* License: GPL-3.0+
* License URI: http://www.gnu.org/licenses/gpl-3.0.txt
* Domain Path: /lang
*/
namespace WordPressWidgetBoilerplate;
use WordPressWidgetBoilerplateUtilitiesRegistry;
use WordPressWidgetBoilerplatePlugin;
use WordPressWidgetBoilerplateSubscriberWidgetSubscriber;
use WordPressWidgetBoilerplateSubscriberDeleteWidgetCacheSubscriber;
// Prevent this file from being called directly.
defined('WPINC') || die;
// Include the autoloader.
require_once __DIR__. '/vendor/autoload.php';
// Setup a filter so we can retrieve the registry throughout the plugin.
$registry = new Registry();
add_filter('wpwBoilerplateRegistry', function() use ($registry) {
return $registry;
});
// Add subscribers.
$registry->add('deleteWidgetCacheSubscriber', new DeleteWidgetCacheSubscriber('flush_widget_cache'));
// Add the Widget base class to the Registry.
$registry->add('widgetSubscriber', new WidgetSubscriber('widgets_init'));
// Start the machine.
(new Plugin($registry))->start();
Для цілей Boilerplate ми будемо використовувати спеціальну подію кожного разу, коли буде викликано код серіалізації віджета.
Спочатку ми визначимо виклик do_action, визначимо його як flush_widget_cache, а потім передамо необхідні аргументи події, щоб передплатник міг їх прочитати:
<?php
/*
* This file is part of WordPress Widget Boilerplate
* (c) Tom McFarlin <tom@tommcfarlin.com>
*
* This source file is subject to the GPL license that is bundled
* with this source code in the file LICENSE.
*/
namespace WordPressWidgetBoilerplateWordPress;
/**
* Santiizes and saves the data for the widget.
*/
class WidgetSerializer
{
/**
* @var string a reference to the slug of the widget to which the serialier is associated
*/
private $widgetSlug;
/**
* Initializes the class.
*
* @param string a reference to the slug of the widget to which the serialier is associated
*/
public function __construct(string $widgetSlug)
{
$this->widgetSlug = $widgetSlug;
}
/**
* Updates the values of the widget. Sanitizes the information before saving it.
*
* @param array $newInstance the array of new options to save
*/
public function update($newInstance)
{
$instance = [];
foreach ($newInstance as $key => $value) {
$instance[$key] = strip_tags(
stripslashes($value)
);
}
do_action('flush_widget_cache', [$this->widgetSlug, 'widget']);
return $instance;
}
}
А потім у підписнику ми очистимо кеш на основі вхідних аргументів:
<?php
<?php
/*
* This file is part of WordPress Widget Boilerplate
* (c) Tom McFarlin <tom@tommcfarlin.com>
*
* This source file is subject to the GPL license that is bundled
* with this source code in the file LICENSE.
*/
namespace WordPressWidgetBoilerplateSubscriber;
/**
* Deletes the cached contents of the widget.
*/
class DeleteWidgetCacheSubscriber extends AbstractSubscriber
{
/**
* {@inheritdoc}
*/
public function __construct(string $hook)
{
parent::__construct($hook);
}
/**
* Flushes the widget's cache based on the key that's specified in the function arguments.
*/
public function load()
{
/* Because we're implementing an abstract class, we'll parse arguments from the
* func_get_args().
*/
$args = func_get_args();
if (!$this->hasValidArguments($args)) {
return;
}
$args = $args[0];
wp_cache_delete($args[0], $args[1]);
}
/**
* Verifies that we have valid arguments with which to work.
*
* @param array $args the array of arguments we are validating
*
* @return bool true if the arguments are valid; otherwise, false
*/
private function hasValidArguments(array $args): bool
{
// First, check the initial index of the arguments.
if (!isset($args[0])) {
return false;
}
// Next, check the values of the arguments for the widget key and group.
$args = $args[0];
if (!isset($args[0]) && !isset($args[1])) {
return false;
}
return true;
}
}
І це робиться.
Готовий до Front-End
На даний момент у нас є механізм, який може очищати кеш віджетів у будь-який момент — не лише за допомогою спеціальної події — але й за допомогою будь-якої події, запропонованої WordPress.
Це може стати в нагоді, якщо ви використовуєте Boilerplate для чогось, що використовуватиме кешований запит або будь-який інший механізм кешування, якщо на те пішло, і хочете переконатися, що вміст зрозумілий.
Далі ми розглянемо відтворення вмісту на інтерфейсі. Ми наближаємось до завершення рефакторингу Boilerplate, але залишилося ще трохи зробити, перш ніж ми будемо готові об’єднати його з основною гілкою кодової бази.