Widżety WordPress: Refaktoryzacja, część 11
W poprzednim poście przeszliśmy przez wiele refaktoryzacji, które rozdzieliły obawy na ich własne klasy.
Ostatecznie pomaga to pokazać, w jaki sposób możemy utrzymać wysoki poziom spójności, nie tylko pracując z klasami w WordPressie, ale robiąc to wraz z istniejącymi interfejsami API.
Ponieważ kilka ostatnich postów na temat refaktoryzacji bazy kodu było tak długich, obecny zestaw postów skupia się na małych, przyrostowych zmianach, a tym samym krótszych, bardziej skoncentrowanych postach.
Jak wspomniano w poprzednim artykule:
Ale jeśli odświeżysz stronę, możesz zauważyć, że oczyszczanie i serializacja nie działają podczas pobierania danych. I tym zajmiemy się w następnym poście.
Więc to właśnie tam zajmiemy się w tym artykule.
WordPress Widget Boilerplate: Refaktoryzacja Część 11
Przed napisaniem jakiegokolwiek kodu, pierwszą rzeczą, na którą należy zwrócić uwagę, jest to, że jeśli wypełnisz jeden z obszarów zawartości widżetu (takiego jak tytuł) czymś takim, jak to :
<script type="text/javascript">This is the Title</script>
A następnie kliknij Zapisz, rzeczywista zawartość zostanie oczyszczona i zapisana w bazie danych. Możesz zobaczyć, że to prawda, patrząc na wartość widżetu w bazie danych.
Co więcej, dane na pierwszy rzut oka wyglądają dobrze, ale jeśli odświeżysz stronę, pojawi się nieoczyszczona zawartość. Jeśli przejdziesz do innej strony, takiej jak Menu, a następnie wrócisz, zawartość widżetu zostanie wyświetlona, ale prawidłowo oczyszczona.
Dlaczego więc pokazuje jedną rzecz w bazie danych i jedną rzecz na froncie obszaru administracyjnego podczas wykonywania określonych kroków?
Ma to związek z pamięcią podręczną widżetów i na szczęście jesteśmy w stanie opróżnić tę pamięć podręczną do woli, używając dowolnych zaczepów (to znaczy, możemy subskrybować dowolne zdarzenie, a następnie opróżnić pamięć podręczną).
Usuwa zawartość pamięci podręcznej pasującą do klucza i grupy.
Pamiętaj jednak, że wymaga to podania klucza i opcjonalnej grupy. W Boilerplate używamy slug widgetu jako klucza i grupy jest widgetem.
Czyszczenie pamięci podręcznej
Ponieważ funkcję można podpiąć do dowolnego zdarzenia, możemy utworzyć subskrybenta, którego możemy podpiąć do dowolnego zdarzenia. Oznacza to , że możemy utworzyć subskrybenta DeleteWidgetCache w naszej przestrzeni nazw subskrybenta:
<?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;
}
}
Następnie zaktualizujemy bootstrap, aby dodać subskrybenta do rejestru i użyjemy niestandardowego haka, flush_widget_cache, którego użyjemy chwilowo.
<?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();
Na potrzeby Boilerplate użyjemy zdarzenia niestandardowego za każdym razem, gdy zostanie wywołany kod serializacji widżetu.
Najpierw zdefiniujemy wywołanie do_action, zidentyfikujemy je jako flush_widget_cache, a następnie przekażemy niezbędne argumenty do zdarzenia, aby subskrybent mógł je odczytać:
<?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;
}
}
A następnie w subskrybencie opróżnimy pamięć podręczną na podstawie przychodzących argumentów:
<?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;
}
}
I to wystarczy.
Gotowy na front-end
W tym momencie mamy mechanizm, który może opróżnić pamięć podręczną widżetów, kiedy tylko zechcemy – nie tylko za pomocą niestandardowego zdarzenia – ale także z dowolnymi zdarzeniami oferowanymi przez WordPress.
Może się to przydać, jeśli używasz Boilerplate do czegoś, co będzie używać buforowanego zapytania lub dowolnego innego mechanizmu buforowania i chcesz się upewnić, że zawartość jest przejrzysta.
Następnie przyjrzymy się renderowaniu treści na interfejsie użytkownika. Zbliżamy się do końca refaktoryzacji Boilerplate, ale jest jeszcze trochę do zrobienia, zanim będziemy gotowi do scalenia go z główną gałęzią bazy kodu.