{"id":231401,"date":"2022-12-20T12:29:00","date_gmt":"2022-12-20T09:29:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231401"},"modified":"2022-12-20T12:30:11","modified_gmt":"2022-12-20T09:30:11","slug":"widgets-do-wordpress-refatoracao-parte-10","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/widgets-do-wordpress-refatoracao-parte-10\/","title":{"rendered":"Widgets do WordPress: Refatora\u00e7\u00e3o, Parte 10"},"content":{"rendered":"\n<p>No que diz respeito \u00e0 refatora\u00e7\u00e3o do WordPress Widget Boilerplate, estamos em um bom lugar. Muito trabalho foi feito de modo que a introdu\u00e7\u00e3o de novas classes, recursos e funcionalidades deve ser muito mais f\u00e1cil.<\/p>\n<p>E n\u00e3o s\u00f3 isso: deveria ser mais f\u00e1cil de seguir.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/widgets-do-wordpress-refatoracao-parte-9\/\" title=\"Obrigado pelo trabalho no \u00faltimo post\">Obrigado pelo trabalho no \u00faltimo post<\/a>, temos muito trabalho para construir \u2013 ou seja, uma interface administrativa b\u00e1sica.<\/p>\n<p>Por fim, o \u00faltimo post dizia:<\/p>\n<blockquote>\n<p>Nos pr\u00f3ximos artigos, isso continuar\u00e1 a evoluir, mas, como voc\u00ea pode ver, estamos nos certificando de que temos uma \u00fanica classe base de funcionalidade para conversar com o WordPress e uma classe espec\u00edfica para renderizar o formul\u00e1rio administrativo.<\/p>\n<\/blockquote>\n<p>E \u00e9 a\u00ed que vamos pegar neste artigo. Especificamente, veremos como limpar e serializar os dados, bem como recuperar os dados salvos no widget.<\/p>\n<h2>The WordPress Widget Boilerplate: Refatorando Parte 10<\/h2>\n<h3>Refatorando a IU<\/h3>\n<p>Antes de entrarmos na serializa\u00e7\u00e3o, h\u00e1 um pequeno trabalho que precisaremos fazer em nossa vis\u00e3o administrativa. Lembre-se de postagens anteriores da s\u00e9rie que criamos um formul\u00e1rio que aceita:<\/p>\n<ul>\n<li>um t\u00edtulo,<\/li>\n<li>algum conte\u00fado,<\/li>\n<li>e uma caixa de sele\u00e7\u00e3o.<\/li>\n<\/ul>\n<p>Isso \u00e9 exibido bem, mas exclui alguns recursos importantes da <a href=\"https:\/\/codex.wordpress.org\/Widgets_API#Widgets_API\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">API de Widgets<\/a>. Ou seja, precisamos ter certeza de que estamos nomeando corretamente nossos elementos usando as seguintes fun\u00e7\u00f5es:<\/p>\n<ul>\n<li><a href=\"https:\/\/developer.wordpress.org\/reference\/classes\/wp_widget\/get_field_id\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">get_field_id<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/reference\/classes\/wp_widget\/get_field_name\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">get_field_name<\/a><\/li>\n<\/ul>\n<p>E ent\u00e3o escreveremos nossa fun\u00e7\u00e3o simplesmente chamada <a href=\"https:\/\/codex.wordpress.org\/Widgets_API#Widgets_API\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">get<\/a>, que explicarei momentaneamente.<\/p>\n<p>As fun\u00e7\u00f5es acima s\u00e3o necess\u00e1rias porque ajudam o WordPress a acompanhar quantas inst\u00e2ncias do widget est\u00e3o sendo usadas e qual o usu\u00e1rio est\u00e1 editando. Em outras palavras, temos muitas funcionalidades de gra\u00e7a.<\/p>\n<p>Antes de mostrar o c\u00f3digo, quero discutir brevemente o prop\u00f3sito da\u00a0 fun\u00e7\u00e3o <strong>get<\/strong> que vamos apresentar. Resumindo, \u00e9 uma maneira de passarmos uma chave (como na chave em um par chave\/valor) para uma fun\u00e7\u00e3o e, em seguida, fazer com que ela recupere facilmente um valor para n\u00f3s, de modo que mantenha nossa interface o mais limpa poss\u00edvel.<\/p>\n<p>Ent\u00e3o, primeiro, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/392a2eda9ebc0b0a59cd4b364e427445#file-00-get-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">o m\u00e9todo get<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/**\n * If the value for the key exists in the current instance of the widget, then it will\n * retrieve it. Otherwise, it will return an empty value.\n *\n * @param string $key the used to identify the value of the widget.\n * @param array $instance the options for the instance of this widget\n *\/\nprotected function get($key, $instance)\n{\n    return empty($instance[$key])? '': $instance[$key];\n}<\/code><\/pre>\n<p>O importante a notar \u00e9 que este m\u00e9todo aceita n\u00e3o apenas a chave para o valor que estamos lendo, mas um array referente \u00e0 inst\u00e2ncia do array.<\/p>\n<p><a href=\"https:\/\/gist.github.com\/tommcfarlin\/392a2eda9ebc0b0a59cd4b364e427445#file-01-admin-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">E agora, a interface do usu\u00e1rio refatorada<\/a> :<\/p>\n<pre><code>&lt;?php\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?&gt;\n\n&lt;div class=\"widget-content\"&gt;\n    &lt;p&gt;\n        &lt;input\n            type=\"text\"\n            id=\"&lt;?php echo esc_attr($this-&gt;get_field_id('title')); ?&gt;\"\n            name=\"&lt;?php echo esc_attr($this-&gt;get_field_name('title')); ?&gt;\"\n            value=\"&lt;?php echo $this-&gt;get('title', $instance) ?&gt;\"\n            placeholder=\"Widget Title\"\n            class=\"widefat\"\n        \/&gt;\n    &lt;\/p&gt;\n\n    &lt;p&gt;\n        &lt;textarea\n            id=\"&lt;?php echo esc_attr($this-&gt;get_field_id('content')); ?&gt;\"\n            name=\"&lt;?php echo esc_attr($this-&gt;get_field_name('content')); ?&gt;\"\n            placeholder=\"Widget Content\"\n            style=\"width:100%;\"&gt;&lt;?php echo $this-&gt;get('content', $instance) ?&gt;&lt;\/textarea&gt;\n    &lt;\/p&gt;\n\n    &lt;p&gt;\n        &lt;input\n            type=\"checkbox\"\n            value=\"on\"\n            name=\"&lt;?php echo esc_attr($this-&gt;get_field_name('display-title')); ?&gt;\"\n            id=\"&lt;?php echo esc_attr($this-&gt;get_field_id('display-title')); ?&gt;\"\n            &lt;?php checked('on', $this-&gt;get('display-title', $instance), true); ?&gt;\n            class=\"checkbox\"\n        \/&gt;\n        &lt;label for=\"&lt;?php echo esc_attr($this-&gt;get_field_id('display-title')); ?&gt;\"&gt;Display Title?&lt;\/label&gt;\n    &lt;\/p&gt;\n&lt;\/div&gt;&lt;!-- .widget-content --&gt;\n<\/code><\/pre>\n<p>Mas isso ainda deixa falta de funcionalidade e deixa trabalho para n\u00f3s fazermos. Ou seja, precisamos higienizar os dados e pass\u00e1-los de volta para o WordPress, para que ele salve os dados.<\/p>\n<h3>Sanitiza\u00e7\u00e3o e Serializa\u00e7\u00e3o<\/h3>\n<p>Para os prop\u00f3sitos do nosso exemplo, seremos muito rigorosos no que permitimos. Ou seja, vamos suportar apenas o texto b\u00e1sico e vamos remover tudo de forma agressiva.<\/p>\n<p>Isso significa que n\u00e3o vamos permitir marca\u00e7\u00e3o ou algo assim. Em vez disso, vamos remover tudo o que n\u00e3o \u00e9 texto b\u00e1sico. Podemos decor\u00e1-lo um pouco quando chegar a hora de exibi-lo no front-end, mas deixaremos isso para o post apropriado.<\/p>\n<p>Para isso, vamos usar as seguintes fun\u00e7\u00f5es:<\/p>\n<ul>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.strip-tags.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">strip_tags<\/a><\/li>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.stripslashes.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tiras<\/a><\/li>\n<\/ul>\n<p>Lembre-se de que temos dois campos em nosso widget \u2013 o campo de t\u00edtulo e o campo de conte\u00fado. Dependendo do tipo de widget que voc\u00ea est\u00e1 construindo, voc\u00ea pode precisar apenas de uma \u00fanica classe ou fun\u00e7\u00e3o para limpar os dados. Em outras situa\u00e7\u00f5es, voc\u00ea pode precisar de algo mais complexo.<\/p>\n<p>Tenha isso em mente enquanto analisamos este c\u00f3digo, pois essa n\u00e3o ser\u00e1 uma solu\u00e7\u00e3o de tamanho \u00fanico. Em vez disso, ser\u00e1 especificamente para isso.<\/p>\n<p>De qualquer forma, para sanitizar os dados, vamos escrever uma classe espec\u00edfica para esse fim, e depois vamos disponibiliz\u00e1-la para nossa classe WidgetAdmin.<\/p>\n<p><a href=\"https:\/\/gist.github.com\/tommcfarlin\/392a2eda9ebc0b0a59cd4b364e427445#file-02-widget-serializer-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Aqui est\u00e1 a classe na \u00edntegra<\/a> com uma descri\u00e7\u00e3o a seguir:<\/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     * 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        return $instance;\n    }\n}\n<\/code><\/pre>\n<p>A aula deve ser direta. Ele recebe os valores recebidos do widget, limpa-os e retorna um novo array para ser devolvido ao WordPress.<\/p>\n<p>H\u00e1 um por\u00e9m. Esta classe deve ser uma propriedade da\u00a0 classe <strong>Widget<\/strong> principal \u00a0que foi mostrada no \u00faltimo post.<\/p>\n<p>Em segundo lugar, o\u00a0 m\u00e9todo de <strong>atualiza\u00e7\u00e3o<\/strong> que faz parte da API Widgets \u00e9 o que chamar\u00e1 essa classe. N\u00e3o \u00e9 necess\u00e1rio passar a vari\u00e1vel <strong>$oldInstance<\/strong> para o serializador, mas \u00e9 necess\u00e1rio para o m\u00e9todo de atualiza\u00e7\u00e3o.<\/p>\n<p>Aqui est\u00e1 a classe <strong>Widget<\/strong> <a href=\"https:\/\/gist.github.com\/tommcfarlin\/392a2eda9ebc0b0a59cd4b364e427445#file-03-widget-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">como est\u00e1 atualmente constru\u00edda<\/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 WordPressWidgetBoilerplateWordPress;\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 string           $widgetSlug       unique identifier for your widget\n     * @param WidgetSerializer $widgetSerializer the class responsible for saving widget options\n     *\/\n    public function __construct($widgetSlug)\n    {\n        $this-&gt;widgetSlug = $widgetSlug;\n\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     * Displays the administrative view of the form and includes the options\n     * for the instance of the widget as arguments passed into the function.\n     *\n     * @param array $instance the options for the instance of this widget\n     *\/\n    public function form($instance)\n    {\n        include plugin_dir_path(__FILE__).'Views\/Admin.php';\n    }\n\n    \/**\n     * Updates the values of the widget. Uses the serialization class to sanitize the\n     * information before saving it.\n     *\n     * @param array $newInstance the values to be sanitized and saved\n     * @param array $oldInstance the values that were originally saved\n     *\/\n    public function update($newInstance, $oldInstance)\n    {\n        return $this-&gt;widgetSerializer-&gt;update($newInstance, $oldInstance);\n    }\n\n    \/**\n     * If the value for the key exists in the current instance of the widget, then it will\n     * retrieve it. Otherwise, it will return an empty value.\n     *\n     * @param string $key      the used to identify the value of the widget\n     * @param array  $instance the options for the instance of this widget\n     *\/\n    protected function get($key, $instance)\n    {\n        return empty($instance[$key])? '': $instance[$key];\n    }\n}\n<\/code><\/pre>\n<p>Mas se voc\u00ea atualizar a p\u00e1gina, poder\u00e1 notar que a sanitiza\u00e7\u00e3o e a serializa\u00e7\u00e3o parecem n\u00e3o funcionar ao recuperar os dados. E \u00e9 isso que veremos no pr\u00f3ximo post.<\/p>\n<h2>Recuperando dados<\/h2>\n<p>Observe que, embora a funcionalidade pare\u00e7a incompleta para isso (j\u00e1 que os dados n\u00e3o higienizados ainda s\u00e3o exibidos), estamos focados em garantir que estamos escrevendo classes com coes\u00e3o, responsabilidade e que n\u00e3o sejam fortemente acopladas.<\/p>\n<p>Vamos iterar um pouco mais sobre isso no pr\u00f3ximo post. Ent\u00e3o estude o c\u00f3digo acima, implemente-o se \u00e9 isso que voc\u00ea est\u00e1 fazendo, e vamos a partir da\u00ed no pr\u00f3ximo post.<\/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>E agora, come\u00e7amos a adicionar a funcionalidade de sanitiza\u00e7\u00e3o e serializa\u00e7\u00e3o no WordPress Widget Boilerplate.<\/p>\n","protected":false},"author":1,"featured_media":234963,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[722,846],"tags":[1170],"class_list":["post-231401","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desenvolvedor","category-tutoriais","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/231401","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=231401"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/231401\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/234963"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=231401"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=231401"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=231401"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}