{"id":231380,"date":"2022-12-21T12:30:00","date_gmt":"2022-12-21T09:30:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231380"},"modified":"2022-12-07T10:29:44","modified_gmt":"2022-12-07T07:29:44","slug":"widgets-wordpress-refactorisation-partie-11","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/fr\/widgets-wordpress-refactorisation-partie-11\/","title":{"rendered":"Widgets WordPress : refactorisation, partie 11"},"content":{"rendered":"\n<p>Dans le post pr\u00e9c\u00e9dent, nous avons parcouru de nombreuses refactorisations qui s\u00e9paraient les pr\u00e9occupations dans leurs propres classes.<\/p>\n<p>En fin de compte, cela aide \u00e0 montrer comment nous pouvons maintenir un haut niveau de coh\u00e9sion tout en travaillant non seulement avec des classes dans WordPress, mais aussi avec des API pr\u00e9existantes.<\/p>\n<p>Parce que les derniers messages sur la refactorisation de la base de code ont \u00e9t\u00e9 si longs, l&rsquo;ensemble actuel de messages se concentre sur de petits changements incr\u00e9mentiels et donc des messages plus courts et plus cibl\u00e9s.<\/p>\n<p>Comme mentionn\u00e9 dans l&rsquo;article pr\u00e9c\u00e9dent :<\/p>\n<blockquote>\n<p>Mais si vous actualisez la page, vous remarquerez peut-\u00eatre que le nettoyage et la s\u00e9rialisation ne semblent pas fonctionner lors de la r\u00e9cup\u00e9ration des donn\u00e9es. Et c&rsquo;est ce que nous allons examiner dans le prochain article.<\/p>\n<\/blockquote>\n<p>C&rsquo;est donc l\u00e0 que nous allons revenir dans cet article.<\/p>\n<h2>Le passe-partout du widget WordPress\u00a0: refactorisation de la partie 11<\/h2>\n<p>Avant d&rsquo;\u00e9crire le moindre code, la premi\u00e8re chose \u00e0 remarquer est que si vous remplissez une des zones de contenu du widget (comme le titre) avec quelque chose <a href=\"https:\/\/gist.github.com\/tommcfarlin\/39038338730b7141a19c3d2f48801dac#file-00-example-title-js\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">comme ceci<\/a> :<\/p>\n<pre><code>&lt;script type=\"text\/javascript\"&gt;This is the Title&lt;\/script&gt;<\/code><\/pre>\n<p>Et puis cliquez sur Enregistrer, le contenu r\u00e9el sera nettoy\u00e9 et \u00e9crit dans la base de donn\u00e9es. Vous pouvez voir que c&rsquo;est vrai en regardant la valeur du widget dans la base de donn\u00e9es.<\/p>\n<p>De plus, les donn\u00e9es semblent correctes \u00e0 premi\u00e8re vue, mais si vous actualisez la page, le contenu non nettoy\u00e9 appara\u00eet. Si vous naviguez vers une autre page, comme Menus, puis revenez, le contenu du widget appara\u00eet mais correctement filtr\u00e9.<\/p>\n<p>Pourquoi, alors, affiche-t-il une chose dans la base de donn\u00e9es et une chose sur le front-end de la zone d&rsquo;administration lors de l&rsquo;ex\u00e9cution de certaines \u00e9tapes\u00a0?<\/p>\n<p>Cela a \u00e0 voir avec le cache du widget et heureusement, nous pouvons vider ce cache \u00e0 volont\u00e9 en utilisant les crochets que nous voulons (c&rsquo;est-\u00e0-dire que nous pouvons nous abonner \u00e0 n&rsquo;importe quel \u00e9v\u00e9nement et ensuite le faire vider le cache).<\/p>\n<\/p>\n<p>\u00c0 partir de la <a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/wp_cache_delete\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">r\u00e9f\u00e9rence du code<\/a>\u00a0:<\/p>\n<blockquote>\n<p>Supprime le contenu du cache correspondant \u00e0 la cl\u00e9 et au groupe.<\/p>\n<\/blockquote>\n<p>Notez cependant que cela n\u00e9cessite que nous fournissions la cl\u00e9 et un groupe facultatif. Dans le Boilerplate, nous avons utilis\u00e9 le slug du widget comme cl\u00e9 et le groupe est le widget.<\/p>\n<h3>Vider le cache<\/h3>\n<p>\u00c9tant donn\u00e9 que la fonction peut \u00eatre accroch\u00e9e \u00e0 n&rsquo;importe quel \u00e9v\u00e9nement, nous pouvons cr\u00e9er un abonn\u00e9 que nous pouvons accrocher \u00e0 n&rsquo;importe quel \u00e9v\u00e9nement. Cela signifie <a href=\"https:\/\/gist.github.com\/tommcfarlin\/39038338730b7141a19c3d2f48801dac#file-01-delete-widget-cache-subscriber-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">que nous pouvons cr\u00e9er un abonn\u00e9 DeleteWidgetCache dans notre espace de noms d&rsquo;abonn\u00e9\u00a0:<\/a><\/p>\n<pre><code>&lt;?php\n\n&lt;?php\n\n\/*\n * This file is part of WordPress Widget Boilerplate\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com&gt;\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace WordPressWidgetBoilerplateSubscriber;\n\n\/**\n * Deletes the cached contents of the widget.\n *\/\nclass DeleteWidgetCacheSubscriber extends AbstractSubscriber\n{\n    \/**\n     * {@inheritdoc}\n     *\/\n    public function __construct(string $hook)\n    {\n        parent::__construct($hook);\n    }\n\n    \/**\n     * Flushes the widget's cache based on the key that's specified in the function arguments.\n     *\/\n    public function load()\n    {\n        \/* Because we're implementing an abstract class, we'll parse arguments from the\n         * func_get_args().\n         *\/\n        $args = func_get_args();\n        if (!$this-&gt;hasValidArguments($args)) {\n            return;\n        }\n\n        \/\/ TODO: More to come...\n    }\n\n    \/**\n     * Verifies that we have valid arguments with which to work.\n     *\n     * @param array $args the array of arguments we are validating\n     *\n     * @return bool true if the arguments are valid; otherwise, false\n     *\/\n    private function hasValidArguments(array $args): bool\n    {\n        \/\/ First, check the initial index of the arguments.\n        if (!isset($args[0])) {\n            return false;\n        }\n\n        \/\/ Next, check the values of the arguments for the widget key and group.\n        $args = $args[0];\n        if (!isset($args[0]) &amp;&amp; !isset($args[1])) {\n            return false;\n        }\n\n        return true;\n    }\n}\n<\/code><\/pre>\n<p>Nous mettrons ensuite \u00e0 <a href=\"https:\/\/gist.github.com\/tommcfarlin\/39038338730b7141a19c3d2f48801dac#file-02-wordpress-widget-plugin-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">jour le bootstrap<\/a> pour ajouter l&rsquo;abonn\u00e9 au registre et nous utiliserons un crochet personnalis\u00e9, flush_widget_cache, que nous utiliserons momentan\u00e9ment.<\/p>\n<pre><code>&lt;?php\n\/**\n * WordPress Widget Boilerplate\n *\n * The WordPress Widget Boilerplate is an organized, maintainable boilerplate for building\n * widgets using WordPress best practices.\n *\n * @package   WordPressWidgetBoilerplate\n * @author    Your Name &lt;email@example.com&gt;\n * @license   GPL-3.0+\n * @link      http:\/\/example.com\n * @copyright 2018 - 2019 Your Name or Company Name\n *\n * @wordpress-plugin\n * Plugin Name:       WordPress Widget Boilerplate\n * Plugin URI:        https:\/\/github.com\/tommcfarlin\/wordpress-widget-boilerplate\n * Description:       An object-oriented foundation for building WordPress Widgets.\n * Version:           1.0.0\n * Author:            Tom McFarlin\n * Author URI:        https:\/\/tommcfarlin.com\n * Text Domain:       widget-name\n * License:           GPL-3.0+\n * License URI:       http:\/\/www.gnu.org\/licenses\/gpl-3.0.txt\n * Domain Path:       \/lang\n *\/\n\nnamespace WordPressWidgetBoilerplate;\n\nuse WordPressWidgetBoilerplateUtilitiesRegistry;\nuse WordPressWidgetBoilerplatePlugin;\nuse WordPressWidgetBoilerplateSubscriberWidgetSubscriber;\nuse WordPressWidgetBoilerplateSubscriberDeleteWidgetCacheSubscriber;\n\n\/\/ Prevent this file from being called directly.\ndefined('WPINC') || die;\n\n\/\/ Include the autoloader.\nrequire_once __DIR__. '\/vendor\/autoload.php';\n\n\/\/ Setup a filter so we can retrieve the registry throughout the plugin.\n$registry = new Registry();\nadd_filter('wpwBoilerplateRegistry', function() use ($registry) {\n    return $registry;\n});\n\n\/\/ Add subscribers.\n$registry-&gt;add('deleteWidgetCacheSubscriber', new DeleteWidgetCacheSubscriber('flush_widget_cache'));\n\n\/\/ Add the Widget base class to the Registry.\n$registry-&gt;add('widgetSubscriber', new WidgetSubscriber('widgets_init'));\n\n\/\/ Start the machine.\n(new Plugin($registry))-&gt;start();\n<\/code><\/pre>\n<p>Pour les besoins du Boilerplate, nous utiliserons l&rsquo;\u00e9v\u00e9nement personnalis\u00e9 chaque fois que le code de s\u00e9rialisation du widget est appel\u00e9.<\/p>\n<p>Tout d&rsquo;abord, nous allons d\u00e9finir un\u00a0 appel <a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/do_action\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">do_action<\/a>, l&rsquo;identifier comme flush_widget_cache, puis <a href=\"https:\/\/gist.github.com\/tommcfarlin\/39038338730b7141a19c3d2f48801dac#file-03-widget-serialization-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">nous passerons les arguments n\u00e9cessaires<\/a> \u00e0 l&rsquo;\u00e9v\u00e9nement afin que l&rsquo;abonn\u00e9 puisse les lire\u00a0:<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of WordPress Widget Boilerplate\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com&gt;\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace WordPressWidgetBoilerplateWordPress;\n\n\/**\n * Santiizes and saves the data for the widget.\n *\/\nclass WidgetSerializer\n{\n    \/**\n     * @var string a reference to the slug of the widget to which the serialier is associated\n     *\/\n    private $widgetSlug;\n\n    \/**\n     * Initializes the class.\n     *\n     * @param string a reference to the slug of the widget to which the serialier is associated\n     *\/\n    public function __construct(string $widgetSlug)\n    {\n        $this-&gt;widgetSlug = $widgetSlug;\n    }\n\n    \/**\n     * Updates the values of the widget. Sanitizes the information before saving it.\n     *\n     * @param array $newInstance the array of new options to save\n     *\/\n    public function update($newInstance)\n    {\n        $instance = [];\n        foreach ($newInstance as $key =&gt; $value) {\n            $instance[$key] = strip_tags(\n                stripslashes($value)\n            );\n        }\n\n        do_action('flush_widget_cache', [$this-&gt;widgetSlug, 'widget']);\n\n        return $instance;\n    }\n}\n<\/code><\/pre>\n<p>Et puis dans l&rsquo;abonn\u00e9, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/39038338730b7141a19c3d2f48801dac#file-04-delete-widget-cache-subscriber-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">nous viderons le cache<\/a> en fonction des arguments entrants\u00a0:<\/p>\n<pre><code>&lt;?php\n\n&lt;?php\n\n\/*\n * This file is part of WordPress Widget Boilerplate\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com&gt;\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace WordPressWidgetBoilerplateSubscriber;\n\n\/**\n * Deletes the cached contents of the widget.\n *\/\nclass DeleteWidgetCacheSubscriber extends AbstractSubscriber\n{\n    \/**\n     * {@inheritdoc}\n     *\/\n    public function __construct(string $hook)\n    {\n        parent::__construct($hook);\n    }\n\n    \/**\n     * Flushes the widget's cache based on the key that's specified in the function arguments.\n     *\/\n    public function load()\n    {\n        \/* Because we're implementing an abstract class, we'll parse arguments from the\n         * func_get_args().\n         *\/\n        $args = func_get_args();\n        if (!$this-&gt;hasValidArguments($args)) {\n            return;\n        }\n\n        $args = $args[0];\n        wp_cache_delete($args[0], $args[1]);\n    }\n\n    \/**\n     * Verifies that we have valid arguments with which to work.\n     *\n     * @param array $args the array of arguments we are validating\n     *\n     * @return bool true if the arguments are valid; otherwise, false\n     *\/\n    private function hasValidArguments(array $args): bool\n    {\n        \/\/ First, check the initial index of the arguments.\n        if (!isset($args[0])) {\n            return false;\n        }\n\n        \/\/ Next, check the values of the arguments for the widget key and group.\n        $args = $args[0];\n        if (!isset($args[0]) &amp;&amp; !isset($args[1])) {\n            return false;\n        }\n\n        return true;\n    }\n}\n<\/code><\/pre>\n<p>Et \u00e7a le fait.<\/p>\n<h2>Pr\u00eat pour le front-end<\/h2>\n<p>\u00c0 ce stade, nous avons mis en place un m\u00e9canisme qui peut vider le cache du widget quand nous le voulons &#8211; pas seulement avec un \u00e9v\u00e9nement personnalis\u00e9 &#8211; mais aussi avec n&rsquo;importe lequel des \u00e9v\u00e9nements propos\u00e9s par WordPress.<\/p>\n<p>Cela peut \u00eatre utile si vous utilisez le Boilerplate pour quelque chose qui utilisera une requ\u00eate mise en cache ou tout autre m\u00e9canisme de mise en cache, d&rsquo;ailleurs, et que vous voulez vous assurer que le contenu est clair.<\/p>\n<p>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 \u00e0 faire avant que nous soyons pr\u00eats \u00e0 le fusionner dans la branche master de la base de code.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Source d&rsquo;enregistrement:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Pourquoi, alors, WordPress affiche-t-il une chose dans la base de donn\u00e9es et une chose dans la zone d&rsquo;administration ? Cela a \u00e0 voir avec le cache du widget.<\/p>\n","protected":false},"author":1,"featured_media":235955,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[893,717,832],"tags":[1167],"class_list":["post-231380","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-code-2","category-developpeur","category-guide-pour-les-debutants","tag-affiai-fr"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts\/231380","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/comments?post=231380"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/posts\/231380\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/media\/235955"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/media?parent=231380"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/categories?post=231380"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fr\/wp-json\/wp\/v2\/tags?post=231380"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}