{"id":231346,"date":"2022-12-18T19:41:00","date_gmt":"2022-12-18T16:41:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231346"},"modified":"2022-12-18T19:42:00","modified_gmt":"2022-12-18T16:42:00","slug":"widgets-do-wordpress-refatoracao-parte-7","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/widgets-do-wordpress-refatoracao-parte-7\/","title":{"rendered":"Widgets do WordPress: Refatora\u00e7\u00e3o, Parte 7"},"content":{"rendered":"\n<p>Nas \u00faltimas postagens, trabalhamos muito para levar o c\u00f3digo ao ponto de refatora\u00e7\u00e3o que ser\u00e1 abordado neste artigo.<\/p>\n<p>Especificamente, cobrimos:<\/p>\n<ul>\n<li>ganchos,<\/li>\n<li>um <a href=\"https:\/\/tommcfarlin.com\/wordpress-widgets-part-4\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Registro<\/a> ,<\/li>\n<li>e <a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/widgets-do-wordpress-refatoracao-parte-3\/\" title=\"Assinantes\">Assinantes<\/a>.<\/li>\n<\/ul>\n<p>Tudo isso vai desempenhar um papel no que vamos fazer hoje.<\/p>\n<h2>The WordPress Widget Boilerplate: Refatora\u00e7\u00e3o, Parte 7<\/h2>\n<p>Para aqueles que est\u00e3o familiarizados com o <a href=\"https:\/\/codex.wordpress.org\/Widgets_API\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WordPress Widgets API<\/a>, ent\u00e3o voc\u00ea provavelmente sabe que n\u00e3o mudou muito nos \u00faltimos anos.<\/p>\n<p>Al\u00e9m disso, ele realmente consiste apenas em quatro fun\u00e7\u00f5es (uma das quais \u00e9 o construtor):<\/p>\n<ol>\n<li>O construtor \u00e9 respons\u00e1vel por definir v\u00e1rias propriedades no widget, mais comumente seu nome e a descri\u00e7\u00e3o do mesmo.<\/li>\n<li>A fun\u00e7\u00e3o widget \u00e9 respons\u00e1vel por renderizar o conte\u00fado do widget.<\/li>\n<li>A fun\u00e7\u00e3o de formul\u00e1rio \u00e9 respons\u00e1vel por exibir o formul\u00e1rio na \u00e1rea de administra\u00e7\u00e3o do WordPress ao trabalhar com o widget.<\/li>\n<li>A fun\u00e7\u00e3o de atualiza\u00e7\u00e3o \u00e9 respons\u00e1vel por atualizar as op\u00e7\u00f5es que est\u00e3o salvas no banco de dados (ou inicializadas e depois salvar as op\u00e7\u00f5es que ainda n\u00e3o existem no banco de dados).<\/li>\n<\/ol>\n<p>O bom \u00e9 que essa abordagem espec\u00edfica \u00e9 alcan\u00e7ada herdando uma funcionalidade para a classe <a href=\"https:\/\/developer.wordpress.org\/reference\/classes\/wp_widget\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WP_Widget<\/a>.<\/p>\n<p>O problema, por\u00e9m, \u00e9 que \u00e9 muito trabalho para uma \u00fanica classe fazer.<\/p>\n<p>Em vez disso, devemos separar cada uma das fun\u00e7\u00f5es em sua pr\u00f3pria \u00e1rea de funcionalidade.<\/p>\n<p>Como acontece com qualquer coisa na programa\u00e7\u00e3o, haver\u00e1 maneiras pelas quais algumas coisas ser\u00e3o claras sobre como podem ser feitas e, em seguida, algumas coisas poder\u00e3o ser feitas de v\u00e1rias maneiras.<\/p>\n<p>O que vou apresentar \u00e9 como estou abordando isso por enquanto. Isso pode mudar no futuro, ou talvez n\u00e3o, e outros podem ter uma opini\u00e3o diferente sobre isso.<\/p>\n<p>Independentemente disso, a implementa\u00e7\u00e3o ser\u00e1 muito mais orientada a objetos e dar\u00e1 a cada classe seu pr\u00f3prio conjunto de responsabilidades.<\/p>\n<p>A primeira pergunta, por\u00e9m, \u00e9 como dividir uma classe com quatro fun\u00e7\u00f5es e que herda de uma classe pai?<\/p>\n<h3>Atualizando o Bootstrap<\/h3>\n<p>Primeiro, h\u00e1 algumas coisas que precisamos ajustar no bootstrap do plugin. Ou seja, precisamos fazer o seguinte:<\/p>\n<ol>\n<li>instanciar o Registro e disponibiliz\u00e1-lo atrav\u00e9s do projeto,<\/li>\n<li>atualize a classe Plugin para que ela aceite um registro e carregue os assinantes,<\/li>\n<li>revise o bootstrap<\/li>\n<\/ol>\n<p>Aqui est\u00e1 uma olhada em todos os tr\u00eas acima.<\/p>\n<h3>1 Instanciar o Registro<\/h3>\n<p>Como j\u00e1 abordamos isso no in\u00edcio da s\u00e9rie, deve ficar claro como fazer isso.<\/p>\n<p>Primeiramente, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-00-instantiate-the-registry-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">veja o seguinte c\u00f3digo<\/a> :<\/p>\n<pre><code>&lt;?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});<\/code><\/pre>\n<p>Em seguida, observe que estamos instanciando o Registro (falaremos sobre seu namespace momentaneamente) e, em seguida, estamos conectando-o a um filtro personalizado que nos permite acess\u00e1-lo em todo o plug-in sempre que quisermos.<\/p>\n<h3>2 Atualize a Classe do Plugin<\/h3>\n<p>Em seguida, precisamos atualizar a classe do plugin principal (que reside no\u00a0 diret\u00f3rio <strong>src<\/strong>) para que fa\u00e7a refer\u00eancia ao registro e carregue <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-01-update-the-plugin-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">todos os assinantes registrados<\/a> :<\/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 WordPressWidgetBoilerplate;\n\nuse WordPressWidgetBoilerplateUtilitiesRegistry;\n\n\/**\n * The base class for this plugin. Maintains a copy of the registry and starts\n * all of the objects that should hook into WordPress.\n *\/\nclass Plugin\n{\n    \/**\n     * @var Registry a reference to the simple container used to maintain plugin objects\n     *\/\n    private $registry;\n\n    \/**\n     * @param Registry $registry a reference to the simple container used to maintain plugin objects\n     *\/\n    public function __construct(Registry $registry)\n    {\n        $this-&gt;registry = $registry;\n    }\n\n    \/**\n     * Iterates through each of the subscribers maintained in the registry and registers them\n     * to the proper WordPress hook.\n     *\/\n    public function start()\n    {\n        array_map(function ($subscriber) {\n            add_action($subscriber-&gt;getHook(), [$subscriber, 'load']);\n        }, $this-&gt;registry-&gt;getRegisteredSubscribers());\n    }\n}<\/code><\/pre>\n<p>Observe, no entanto, que ainda n\u00e3o configuramos nenhum assinante. Come\u00e7amos isso no in\u00edcio da s\u00e9rie e agora \u00e9 hora de voltar, mas faremos isso mais tarde.<\/p>\n<p>No entanto, precisamos <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-03-new-registry-function-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">adicionar uma fun\u00e7\u00e3o<\/a> \u2013 mesmo que tempor\u00e1ria \u2013 para que possamos adicionar classes que n\u00e3o sejam assinantes de eventos expl\u00edcitos:<\/p>\n<pre><code>&lt;?php\n\/**\n * @return array all of the the objects that aren't subscribers registered with WordPress\n *\/\npublic function getRegisteredObjects()\n{\n    $objects = [];\n    foreach ($this-&gt;registry as $object) {\n        if (!$object instanceof AbstractSubscriber) {\n            $objects[] = $object;\n        }\n    }\n\n    return array_filter($objects);\n}<\/code><\/pre>\n<p>Isso ser\u00e1 reformulado posteriormente, pois transformaremos as classes principais em assinantes posteriormente.<\/p>\n<h3>3 Revise o Bootstrap<\/h3>\n<p>Antes de prosseguir, acho importante revisar o bootstrap. Embora o cabe\u00e7alho e a documenta\u00e7\u00e3o possam variar, \u00e9 importante observar que estamos fazendo o seguinte:<\/p>\n<ul>\n<li>namespace do bootstrap,<\/li>\n<li>impedindo que o arquivo seja acessado,<\/li>\n<li>chamando o autoloader,<\/li>\n<li>configurando o registro,<\/li>\n<li>e iniciando o plug-in.<\/li>\n<\/ul>\n<p>Parece muito, mas <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-02-the-current-bootstrap-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">o c\u00f3digo \u00e9 bem curto<\/a> :<\/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;\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\/\/ Start the machine.\n(new Plugin($registry))-&gt;start();\n<\/code><\/pre>\n<p>Neste ponto, por\u00e9m, \u00e9 hora de ver como \u00e9 dividir a classe filha da <a href=\"https:\/\/codex.wordpress.org\/Widgets_API\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">API Widgets<\/a> padr\u00e3o em algo que se encaixe no modelo de c\u00f3digo com o qual estamos trabalhando.<\/p>\n<h2>Dividindo uma classe filha<\/h2>\n<p>Esta parte provavelmente abranger\u00e1 alguns posts, pois h\u00e1 um pouco de trabalho a ser feito, mas come\u00e7aremos criando nossa pr\u00f3pria classe de widget que herdar\u00e1 da classe Widget base.<\/p>\n<p>Primeiro, v\u00e1 em frente e crie um\u00a0 diret\u00f3rio de <strong>API<\/strong> no diret\u00f3rio <strong>src<\/strong> e adicione um arquivo chamado <strong>Widget.php<\/strong>. \u00c9 aqui que o b\u00e1sico do widget residir\u00e1. Entraremos em folhas de estilo administrativas e p\u00fablicas e arquivos JavaScript na pr\u00f3xima postagem.<\/p>\n<p>Neste ponto, o b\u00e1sico do arquivo deve <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-04-widget-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ficar assim<\/a> :<\/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 WordPressWidgetBoilerplateAPI;\n\nuse WP_Widget;\n\nclass Widget extends WP_Widget\n{\n    \/**\n     * @var string unique identifier for your widget\n     *\/\n    protected $widgetSlug;\n\n    \/**\n     * Initializes the plugin by setting its properties and calling the parent class with the description.\n     *\n     * @param mixed $widgetSlug\n     *\/\n    public function __construct($widgetSlug)\n    {\n        $this-&gt;widgetSlug = $widgetSlug;\n\n        \/\/ TODO: update description\n        parent::__construct(\n            $this-&gt;getWidgetSlug(),\n            __('Widget Name', $this-&gt;getWidgetSlug()),\n            [\n                'classname' =&gt; $this-&gt;getWidgetSlug().'-class',\n                'description' =&gt; __('Short description of the widget goes here.', $this-&gt;getWidgetSlug()),\n            ]\n        );\n    }\n\n    \/**\n     * Return the widget slug.\n     *\n     * @return string slug variable\n     *\/\n    public function getWidgetSlug()\n    {\n        return $this-&gt;widgetSlug;\n    }\n\n    \/**\n     * TODO: This is a temporary message to show that the Boilerplate has loaded.\n     *\/\n    public function load()\n    {\n        $html = '&lt;p style=\"text-align:center; background: #fff; padding: 1em; border: 1px dotted gray; margin: 2em 2em 2em 14em;\"&gt;';\n        $html .= 'The Widget Boilerplate is loaded.';\n        $html .= '&lt;\/p&gt;';\n        echo $html;\n    }\n}\n<\/code><\/pre>\n<p>Observe que ele recebe um \u00fanico argumento. Eu usei o nome do widget, mas voc\u00ea pode usar o que quiser, desde que represente seu widget.<\/p>\n<p>Isso \u00e9 para mostrar que a classe est\u00e1 sendo instanciada e carregada corretamente quando o plugin \u00e9 ativado. Se voc\u00ea n\u00e3o vir isso, algo n\u00e3o est\u00e1 certo (o que revisaremos momentaneamente).<\/p>\n<p>Em seguida, \u00e9 importante garantir que essa classe seja adicionada ao Registro. Ent\u00e3o adicione as seguintes linhas do c\u00f3digo <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-05-add-registry-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">no bootstrap:<\/a><\/p>\n<pre><code>&lt;?php\n\n\/\/ Add the Widget base class to the Registry.\n$registry-&gt;add('widget', new Widget('widget-name'));<\/code><\/pre>\n<p>E agora, ao ativar o plugin, voc\u00ea dever\u00e1 ver o seguinte:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-160983-61e7189c9c671.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-160983-61e7189c9c671.png\" alt=\"Widgets do WordPress: Refatora\u00e7\u00e3o, Parte 7\"><\/a><\/p>\n<p>Caso contr\u00e1rio, certifique-se de revisar o c\u00f3digo na <a href=\"https:\/\/github.com\/tommcfarlin\/WordPress-Widget-Boilerplate\/tree\/develop\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ramifica\u00e7\u00e3o de desenvolvimento<\/a> para garantir que voc\u00ea tenha tudo o que est\u00e1 descrito neste post.<\/p>\n<h2>Implementando assinantes<\/h2>\n<p>Nas pr\u00f3ximas postagens, veremos como podemos implementar assinantes para o lado p\u00fablico do site (ou seja, onde o conte\u00fado do widget \u00e9 exibido). E faremos o mesmo para a \u00e1rea de administra\u00e7\u00e3o do site.<\/p>\n<p>Por fim, voltaremos nossa aten\u00e7\u00e3o para o c\u00f3digo respons\u00e1vel por proteger e serializar os dados (leia-se: atualizar nosso widget) e, em seguida, ver como \u00e9 a vers\u00e3o final de um clich\u00ea atualizado.<\/p>\n<p>Neste post, por\u00e9m, a principal estrat\u00e9gia que estamos empregando \u00e9 dividir uma classe filha para que ela ainda possa ser usada com outras classes usando interfaces e classes base que j\u00e1 est\u00e3o definidas no c\u00f3digo base.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte de grava\u00e7\u00e3o:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>O problema com WP_Widget \u00e9 que d\u00e1 muito trabalho para uma \u00fanica classe fazer. Ent\u00e3o, vamos come\u00e7ar a refator\u00e1-lo agora.<\/p>\n","protected":false},"author":1,"featured_media":236064,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[722],"tags":[1170],"class_list":["post-231346","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desenvolvedor","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/231346","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/comments?post=231346"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/231346\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/236064"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=231346"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=231346"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=231346"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}