{"id":231412,"date":"2022-12-15T11:30:00","date_gmt":"2022-12-15T08:30:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231412"},"modified":"2022-12-17T14:49:21","modified_gmt":"2022-12-17T11:49:21","slug":"widget-wordpress-refactoring-parte-4","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/it\/widget-wordpress-refactoring-parte-4\/","title":{"rendered":"Widget WordPress: refactoring, parte 4"},"content":{"rendered":"\n<p>Abbiamo implementato una quantit\u00e0 significativa di modifiche al WordPress Widget Boilerplate. Se non hai seguito, ti consiglio di iniziare dall&#8217;inizio della serie e di recuperare il ritardo.<\/p>\n<p>Se, tuttavia, hai seguito e stai anche eseguendo alcuni degli strumenti di qualit\u00e0 del codice che esaminano lo stato del progetto, noterai una manciata di errori nella console.<\/p>\n<p>Normalmente, questo \u00e8 il punto in cui consiglio di prestare attenzione a ci\u00f2 che condivide e quindi di correggere ci\u00f2 che segnala, ma non ci siamo ancora.<\/p>\n<p>Ad esempio, alcuni degli errori che i nostri strumenti stanno mostrando in questo momento si basano sul fatto che abbiamo variabili inutilizzate. Naturalmente, questo \u00e8 il caso, per\u00f2, perch\u00e9 non abbiamo iniziato a creare un widget.<\/p>\n<p>Ma ci sono ancora alcune classi concrete che dobbiamo implementare.<\/p>\n<h2>The WordPress Widget Boilerplate: Refactoring, Parte 4<\/h2>\n<p>Uno dei problemi che esistono ancora nel codice cos\u00ec com&#8217;\u00e8 in questo momento \u00e8 che il costruttore del widget sta registrando le funzioni e questa non \u00e8 una buona cosa.<\/p>\n<p>Lo scopo di un costruttore \u00e8 impostare i valori delle propriet\u00e0 della classe, non implementare alcun tipo di logica. Questo per alcuni motivi:<\/p>\n<ul>\n<li>crea un forte accoppiamento o dipendenze tra le classi nel progetto ogni volta che viene istanziata una determinata classe,<\/li>\n<li>introduce la logica aziendale in una funzione che non \u00e8 destinata a contenere detta funzionalit\u00e0,<\/li>\n<li>rende difficile testare una classe in isolamento.<\/li>\n<\/ul>\n<p>Il modo per gestirlo \u00e8 duplice:<\/p>\n<ol>\n<li>aggiungi un registro che possiamo usare per registrare le classi nell&#8217;applicazione (e passarle in giro con il minor numero possibile di dipendenze che spiegher\u00f2 pi\u00f9 avanti),<\/li>\n<li>creare abbonati in grado di gestire la logica aziendale su base hook-specific.<\/li>\n<\/ol>\n<p>Nei prossimi tre post:<\/p>\n<ol>\n<li>esamineremo la creazione di un registro,<\/li>\n<li>come possiamo introdurlo nel file bootstrap,<\/li>\n<li>e poi guarda alla creazione di iscritti per ciascuna delle nostre funzioni (che non dovrebbe essere troppo difficile visto quello che abbiamo fatto nel post precedente e quello che stiamo facendo in questo post).<\/li>\n<\/ol>\n<h3>Crea il registro<\/h3>\n<p>Prima di scrivere il codice per il Registro, \u00e8 importante notare qual \u00e8 il suo scopo principale. In poche parole, la classe ha lo scopo di contenere un riferimento a qualsiasi classe che \u00e8, ehm, registrata con essa.<\/p>\n<p>Questo viene fatto passando un riferimento a un determinato oggetto a una funzione e anche legandolo a una chiave in modo da poterlo recuperare facilmente in seguito.<\/p>\n<h4>Considerazioni iniziali<\/h4>\n<p>Ma ci sono alcune cose da considerare. Per esempio:<\/p>\n<p>se esiste gi\u00e0 un oggetto nel registro per una determinata chiave, allora \u00e8 necessario generare un&#8217;eccezione: se un utente tenta di acquisire un oggetto dal registro con una determinata chiave, dovrebbe generare un&#8217;eccezione<\/p>\n<p>Naturalmente, non deve necessariamente generare eccezioni. Al contrario, pu\u00f2 anche visualizzare messaggi di errore, restituire valori null o vuoti o qualsiasi altra cosa tu scelga.<\/p>\n<p>In secondo luogo, il registro deve essere in grado di restituire un elenco di tutti gli abbonati che sono contenuti al suo interno in modo che possano essere registrati con WordPress (che \u00e8 quello che vedremo nel prossimo post).<\/p>\n<p>Per fare questo, per\u00f2, dobbiamo assicurarci che supporti tutti gli iscritti ed \u00e8 qui che entra in gioco la nozione di AbstractSubscriber <a href=\"https:\/\/wordpress.mediadoma.com\/it\/widget-wordpress-refactoring-parte-3\/\" title=\"del post precedente .\">del post precedente .<\/a> Cio\u00e8, finch\u00e9 una classe \u00e8 una classe figlia di quella classe, allora siamo a posto.<\/p>\n<h4>Creazione del Registro<\/h4>\n<p>Detto questo, pianifichiamo quanto segue:<\/p>\n<ul>\n<li>Creeremo una classe Registry e la collocheremo in uno spazio dei nomi Utilities (e quindi in una directory) se non esiste gi\u00e0 nel tuo lavoro.<\/li>\n<li>Faremo in modo che il registro mantenga un riferimento a tutti i suoi oggetti in un array associativo.<\/li>\n<li>Abbiamo bisogno di metodi per <strong>aggiungere<\/strong> e <strong>ottenere<\/strong> un singolo abbonato e poi uno per recuperare l&#8217;elenco di interi abbonati.<\/li>\n<\/ul>\n<p>Lo stub per la classe sar\u00e0 <a href=\"https:\/\/gist.github.com\/tommcfarlin\/b45606bde5d777e88fd5e3988f610dea#file-00-registry-stub-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">simile a questo:<\/a><\/p>\n<pre><code>&lt;?php\n\nclass Registry extends AbstractSubscriber\n{\n    public function __construct()\n    {\n    }\n\n    public function add($id, $obj)\n    {\n    }\n\n    public function get($id)\n    {\n    }\n\n    public function getRegisteredSubscribers()\n    {\n    }\n}\n<\/code><\/pre>\n<p>Successivamente, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/b45606bde5d777e88fd5e3988f610dea#file-01-registry-constructor-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">possiamo definire la propriet\u00e0 di base<\/a>, un array e inizializzarlo nel costruttore:<\/p>\n<pre><code>&lt;?php\n\nclass Registry\n{\n    private $registry;\n\n    public function __construct()\n    {\n        $this-&gt;registry = [];\n    }\n\n    \/\/ ...\n\n}<\/code><\/pre>\n<p>Successivamente, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/b45606bde5d777e88fd5e3988f610dea#file-02-registry-add-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">possiamo creare il metodo add<\/a>. Ricorda che nella mia implementazione, sto optando per generare un&#8217;eccezione se una chiave \u00e8 gi\u00e0 definita, ma non devi farlo.<\/p>\n<pre><code>&lt;?php\n\npublic function add($id, $obj)\n{\n    if (isset($this-&gt;registry[$id])) {\n        throw new Exception('An object already exists for this given key.');\n    }\n    $this-&gt;registry[$id] = $obj;\n}<\/code><\/pre>\n<p>Allo stesso modo, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/b45606bde5d777e88fd5e3988f610dea#file-03-registry-get-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">il metodo get<\/a> restituir\u00e0 un riferimento all&#8217;istanza di un oggetto identificato con quella chiave. Se la chiave non \u00e8 impostata, generer\u00e0 un&#8217;eccezione. Se \u00e8 impostato, ma non esiste alcun oggetto, restituiremo null.<\/p>\n<pre><code>&lt;?php\n\npublic function get($id)\n{\n    if (!isset($this-&gt;registry[$id])) {\n        throw new Exception('No object exists for the specified key.');\n    }\n\n    return $this-&gt;registry[$id] ?? null;\n}<\/code><\/pre>\n<p>Infine, abbiamo bisogno di un metodo per restituire tutti gli abbonati registrati. In un post futuro, l&#8217;uso di questo diventer\u00e0 molto pi\u00f9 evidente, ma per ora, tieni presente che creeremo un array di qualsiasi classe che sia un&#8217;istanza della classe <strong>AbstractSubscriber<\/strong> e <a href=\"https:\/\/gist.github.com\/tommcfarlin\/b45606bde5d777e88fd5e3988f610dea#file-04-registry-get-subscribers-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">quindi restituiremo l&#8217;array filtrato.<\/a><\/p>\n<pre><code>&lt;?php\n\npublic function getRegisteredSubscribers()\n{\n    $subscribers = [];\n    foreach ($this-&gt;registry as $object) {\n        if ($object instanceof AbstractSubscriber) {\n            $subscribers[] = $object;\n        }\n    }\n\n    return array_filter($subscribers);\n}<\/code><\/pre>\n<p>A questo punto <a href=\"https:\/\/gist.github.com\/tommcfarlin\/b45606bde5d777e88fd5e3988f610dea#file-05-registry-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">abbiamo la classe<\/a> completa (completa di documentazione):<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of the WordPress Widget Boilerplate\n *\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 WordPressWidgetBoilerplateUtilities;\n\nuse Exception;\nuse WordPressWidgetBoilerplateSubscriberAbstractSubscriber;\n\n\/**\n * This class services as a simple container that can be used to pass objects\n * around the plugin.\n *\n * To use this class you'd make a call to the registry by saying Registry-&gt;get(),\n * then making a class to `register()` and `retrieve()` on an instance of the object.\n *\/\nclass Registry\n{\n    \/**\n     * @var array an array used to maintain the objects registered with the plugin\n     *\/\n    private $registry;\n\n    \/**\n     * Initializes the class by setting up the registry.\n     *\/\n    public function __construct()\n    {\n        $this-&gt;registry = [];\n    }\n\n    \/**\n     * Registers an object with the registry with the specified ID; however, will throw an\n     * exception if the ID is already referencing an object.\n     *\n     * @param string $id  an ID by which the specified object will be referenced\n     * @param mixed  $obj an instance of an object to store in the registry\n     *\n     * @throws Exception if an object already exists for the specified key\n     *\/\n    public function add($id, $obj)\n    {\n        if (isset($this-&gt;registry[$id])) {\n            throw new Exception('An object already exists for this given key.');\n        }\n        $this-&gt;registry[$id] = $obj;\n    }\n\n    \/**\n     * @param string $id the ID for the object that we wish to retrieve\n     *\n     * @throws Exception if no object exists for the specified key\n     *\n     * @return mixed a reference to the object or null\n     *\/\n    public function get($id)\n    {\n        if (!isset($this-&gt;registry[$id])) {\n            throw new Exception('No object exists for the specified key.');\n        }\n\n        return $this-&gt;registry[$id] ?? null;\n    }\n\n    \/**\n     * @return array all of the the Subscribers that should be registered with WordPress\n     *\/\n    public function getRegisteredSubscribers()\n    {\n        $subscribers = [];\n        foreach ($this-&gt;registry as $object) {\n            if ($object instanceof AbstractSubscriber) {\n                $subscribers[] = $object;\n            }\n        }\n\n        return array_filter($subscribers);\n    }\n}\n<\/code><\/pre>\n<p>Ora dobbiamo aggiungerlo al bootstrap del nostro plugin.<\/p>\n<h2>Prima di Bootstrap, per\u00f2<\/h2>\n<p>Come accennato in precedenza nel post, dobbiamo aggiungerlo al bootstrap del plugin. Per fare ci\u00f2, per\u00f2, dobbiamo definire il nostro filtro in modo da poter passare facilmente il registro intorno al resto del plugin (quando arriva il momento di farlo).<\/p>\n<p>Prima di farlo, tuttavia, \u00e8 importante assicurarsi di avere una buona gestione del registro che abbiamo appena creato, che si adatti al plug-in e che stai monitorando con il ramo di <a href=\"https:\/\/github.com\/tommcfarlin\/WordPress-Widget-Boilerplate\/tree\/develop\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">sviluppo<\/a> che abbiamo finora.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte di registrazione:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Un problema che esiste ancora nel codice cos\u00ec com&#8217;\u00e8 in questo momento \u00e8 che il costruttore del widget di WordPress sta registrando le funzioni e questa non \u00e8 una buona cosa.<\/p>\n","protected":false},"author":1,"featured_media":223984,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[896,720,865],"tags":[1168],"class_list":["post-231412","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codice","category-sviluppatore","category-wordpress-6","tag-affiai-it"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/231412","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/comments?post=231412"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/231412\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media\/223984"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media?parent=231412"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/categories?post=231412"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/tags?post=231412"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}