WordPress-widgets: Refactoring, del 11
I förra inlägget gick vi igenom en hel del refaktorering som separerade bekymmer i sina egna klasser.
I slutändan hjälper detta att visa hur vi kan bibehålla en hög nivå av sammanhållning samtidigt som vi inte bara arbetar med klasser i WordPress utan gör det tillsammans med redan existerande API:er.
Eftersom de senaste inläggen om omstrukturering av kodbasen har varit så långa, är den nuvarande uppsättningen av inlägg fokuserad på små, inkrementella förändringar och därmed kortare, mer fokuserade inlägg.
Som nämndes i föregående artikel:
Men om du uppdaterar sidan kanske du märker att saneringen och serialiseringen inte verkar fungera när du hämtar data. Och det är vad vi ska titta på i nästa inlägg.
Så det är där vi ska ta upp i den här artikeln.
WordPress Widget Boilerplate: Refactoring del 11
Innan du skriver någon kod är det första att lägga märke till att om du fyller i ett av innehållsområdena i widgeten (som titeln) med något så här :
<script type="text/javascript">This is the Title</script>
Och klicka sedan på Spara, det faktiska innehållet saneras och skrivs till databasen. Du kan se att detta är sant genom att titta på widgetens värde i databasen.
Vidare ser data bra ut vid första anblicken, men om du uppdaterar sidan visas det osaniserade innehållet. Om du navigerar till en annan sida, som Menyer, och sedan kommer tillbaka, visas widgetinnehållet men ordentligt sanerat.
Varför visar det då en sak i databasen och en sak på administrationsområdets front-end när man utför vissa steg?
Detta har att göra med widget-cachen och lyckligtvis kan vi spola denna cache efter behag med hjälp av vilka krokar vi vill (det vill säga vi kan prenumerera på vilken händelse som helst och sedan få den att spola cachen).
Från kodreferensen :
Tar bort cacheminnehållet som matchar nyckel och grupp.
Observera dock att det kräver att vi tillhandahåller nyckeln och en valfri grupp. I Boilerplate har vi använt widgetens slug som nyckeln och gruppen är widget.
Rensa cachen
Eftersom funktionen kan kopplas till vilket event som helst kan vi skapa en prenumerant som vi kan koppla till vilket event som helst. Det betyder att vi kan skapa DeleteWidgetCache-prenumeranter i vårt namnområde för prenumeranter:
<?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;
}
}
Vi kommer sedan att uppdatera bootstrap för att lägga till prenumeranten i registret och vi kommer att använda en anpassad hook, flush_widget_cache, som vi kommer att använda tillfälligt.
<?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();
För syftet med Boilerplate kommer vi att använda den anpassade händelsen närhelst widgetens serialiseringskod anropas.
Först definierar vi ett do_action -anrop, identifierar det som flush_widget_cache, och sedan skickar vi de nödvändiga argumenten till händelsen så att abonnenten kan läsa dem:
<?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;
}
}
Och sedan i abonnenten spolar vi cachen baserat på de inkommande argumenten:
<?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;
}
}
Och det gör det.
Redo för front-end
Vid det här laget har vi en mekanism på plats som kan spola widgetcachen när vi vill – inte bara med en anpassad händelse – utan med alla händelser som erbjuds av WordPress också.
Detta kan vara praktiskt om du använder Boilerplate för något som kommer att använda en cachad fråga eller någon annan cachningsmekanism, för den delen, och vill se till att innehållet är klart.
Därefter ska vi titta på rendering av innehåll på front-end. Vi närmar oss slutet, av omstruktureringen av Boilerplate, men det finns bara lite mer att göra innan vi är redo att slå samman den i kodbasens huvudgren.