Actualités WEB et WordPress, thèmes, plugins. Ici, nous partageons des conseils et les meilleures solutions de sites Web.

Widgets WordPress : refactorisation, partie 11

13

Dans le post précédent, nous avons parcouru de nombreuses refactorisations qui séparaient les préoccupations dans leurs propres classes.

En fin de compte, cela aide à montrer comment nous pouvons maintenir un haut niveau de cohésion tout en travaillant non seulement avec des classes dans WordPress, mais aussi avec des API préexistantes.

Parce que les derniers messages sur la refactorisation de la base de code ont été si longs, l’ensemble actuel de messages se concentre sur de petits changements incrémentiels et donc des messages plus courts et plus ciblés.

Comme mentionné dans l’article précédent :

Mais si vous actualisez la page, vous remarquerez peut-être que le nettoyage et la sérialisation ne semblent pas fonctionner lors de la récupération des données. Et c’est ce que nous allons examiner dans le prochain article.

C’est donc là que nous allons revenir dans cet article.

Le passe-partout du widget WordPress : refactorisation de la partie 11

Avant d’écrire le moindre code, la première chose à remarquer est que si vous remplissez une des zones de contenu du widget (comme le titre) avec quelque chose comme ceci :

<script type="text/javascript">This is the Title</script>

Et puis cliquez sur Enregistrer, le contenu réel sera nettoyé et écrit dans la base de données. Vous pouvez voir que c’est vrai en regardant la valeur du widget dans la base de données.

De plus, les données semblent correctes à première vue, mais si vous actualisez la page, le contenu non nettoyé apparaît. Si vous naviguez vers une autre page, comme Menus, puis revenez, le contenu du widget apparaît mais correctement filtré.

Pourquoi, alors, affiche-t-il une chose dans la base de données et une chose sur le front-end de la zone d’administration lors de l’exécution de certaines étapes ?

Cela a à voir avec le cache du widget et heureusement, nous pouvons vider ce cache à volonté en utilisant les crochets que nous voulons (c’est-à-dire que nous pouvons nous abonner à n’importe quel événement et ensuite le faire vider le cache).

À partir de la référence du code :

Supprime le contenu du cache correspondant à la clé et au groupe.

Notez cependant que cela nécessite que nous fournissions la clé et un groupe facultatif. Dans le Boilerplate, nous avons utilisé le slug du widget comme clé et le groupe est le widget.

Vider le cache

Étant donné que la fonction peut être accrochée à n’importe quel événement, nous pouvons créer un abonné que nous pouvons accrocher à n’importe quel événement. Cela signifie que nous pouvons créer un abonné DeleteWidgetCache dans notre espace de noms d’abonné :

<?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;
    }
}

Nous mettrons ensuite à jour le bootstrap pour ajouter l’abonné au registre et nous utiliserons un crochet personnalisé, flush_widget_cache, que nous utiliserons momentanément.

<?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();

Pour les besoins du Boilerplate, nous utiliserons l’événement personnalisé chaque fois que le code de sérialisation du widget est appelé.

Tout d’abord, nous allons définir un  appel do_action, l’identifier comme flush_widget_cache, puis nous passerons les arguments nécessaires à l’événement afin que l’abonné puisse les lire :

<?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;
    }
}

Et puis dans l’abonné, nous viderons le cache en fonction des arguments entrants :

<?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;
    }
}

Et ça le fait.

Prêt pour le front-end

À ce stade, nous avons mis en place un mécanisme qui peut vider le cache du widget quand nous le voulons – pas seulement avec un événement personnalisé – mais aussi avec n’importe lequel des événements proposés par WordPress.

Cela peut être utile si vous utilisez le Boilerplate pour quelque chose qui utilisera une requête mise en cache ou tout autre mécanisme de mise en cache, d’ailleurs, et que vous voulez vous assurer que le contenu est clair.

Ensuite, nous allons examiner le rendu du contenu sur le front-end. Nous approchons de la fin de la refactorisation du Boilerplate mais il reste juste un peu plus à faire avant que nous soyons prêts à le fusionner dans la branche master de la base de code.

Source d’enregistrement: tommcfarlin.com

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More