✅ Новости WEB и WordPress, темы, плагины. Здесь мы делимся советами и лучшими решениями для веб-сайтов.

Виджеты WordPress: рефакторинг, часть 11

26

В предыдущем посте мы прошли через множество рефакторингов, которые разделили задачи на их собственные классы.

В конечном счете, это помогает показать, как мы можем поддерживать высокий уровень согласованности, не только работая с классами в 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;
    }
}

И это делает это.

Готов к интерфейсу

На данный момент у нас есть механизм, который может очищать кеш виджета в любое время — не только с помощью специального события, но и с любым из событий, предлагаемых WordPress.

Это может пригодиться, если вы используете Boilerplate для чего-то, что будет использовать кэшированный запрос или любой другой механизм кэширования, если на то пошло, и хотите убедиться, что содержимое понятно.

Далее мы рассмотрим рендеринг контента во внешнем интерфейсе. Мы приближаемся к концу рефакторинга Boilerplate, но осталось сделать еще немного, прежде чем мы будем готовы объединить его с основной веткой кодовой базы.

Источник записи: tommcfarlin.com

Этот веб-сайт использует файлы cookie для улучшения вашего опыта. Мы предполагаем, что вы согласны с этим, но вы можете отказаться, если хотите. Принимаю Подробнее