{"id":230822,"date":"2022-12-06T12:56:00","date_gmt":"2022-12-06T09:56:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230822"},"modified":"2022-11-10T00:09:54","modified_gmt":"2022-11-09T21:09:54","slug":"um-guia-simples-para-organizar-classes-centradas-no-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/um-guia-simples-para-organizar-classes-centradas-no-wordpress\/","title":{"rendered":"Um guia simples para organizar classes centradas no WordPress"},"content":{"rendered":"\n<p>Uma das coisas que tenho feito um esfor\u00e7o muito mais concentrado, provavelmente mais do que j\u00e1 fiz antes, \u00e9 gerenciar a separa\u00e7\u00e3o de preocupa\u00e7\u00f5es entre as classes respons\u00e1veis \u200b\u200bpela interface com o WordPress e as respons\u00e1veis \u200b\u200bpor trabalhar com o dom\u00ednio do problema.<\/p>\n<p>Por exemplo, digamos que voc\u00ea esteja trabalhando em um plug-in e ele se comunicar\u00e1 com uma API de terceiros. Al\u00e9m disso, este plugin tamb\u00e9m oferecer\u00e1 menus, tipos de postagem, taxonomias e assim por diante na \u00e1rea de administra\u00e7\u00e3o do WordPress.<\/p>\n<p>H\u00e1 duas \u00e1reas de responsabilidade aqui:<\/p>\n<ol>\n<li>a \u00e1rea respons\u00e1vel pela solu\u00e7\u00e3o geral do problema,<\/li>\n<li>a \u00e1rea respons\u00e1vel pela interface com o WordPress.<\/li>\n<\/ol>\n<p>Voc\u00ea pode argumentar que \u00e9 importante testar as \u00e1reas de unidade que se comunicam com o WordPress, mas tamb\u00e9m sei que essas s\u00e3o APIs testadas e verdadeiras que t\u00eam seu pr\u00f3prio conjunto de testes.<\/p>\n<p>Em vez disso, devemos nos concentrar no teste de unidade e separar nossa l\u00f3gica de neg\u00f3cios do WordPress.<\/p>\n<p>Mas n\u00e3o \u00e9 esse o objetivo deste post. Em vez disso, trata-se mais de uma maneira de potencialmente apresentar um projeto quando uma parte dele far\u00e1 interface com o WordPress.<\/p>\n<p>J\u00e1 falei sobre a import\u00e2ncia e as vantagens dos namespaces em posts anteriores para n\u00e3o me aprofundar muito nessa discuss\u00e3o aqui.<\/p>\n<p>Em vez disso, estou interessado em falar sobre a organiza\u00e7\u00e3o de arquivos no n\u00edvel do sistema de arquivos e no n\u00edvel do namespace, para que sejam claramente separados em suas \u00e1reas de especializa\u00e7\u00e3o e para que possamos ter certeza de que estamos, digamos, focando nossos testes de unidade (e outros testes) em \u00e1reas que s\u00e3o mais cr\u00edticas.<\/p>\n<h3>Abstraindo Meta Boxes<\/h3>\n<p>Eu gosto de ter certeza de que meu diret\u00f3rio e estrutura de arquivos espelham os meus namespaces. Claro, ajuda na organiza\u00e7\u00e3o dos arquivos, mas tamb\u00e9m na organiza\u00e7\u00e3o conceitual.<\/p>\n<p>Ou seja, se eu for trabalhar com meta boxes, ent\u00e3o eu sei que provavelmente posso encontrar os arquivos de meta box em um diret\u00f3rio aninhado com o diret\u00f3rio pai do <strong>WordPress<\/strong> e dentro de um subdiret\u00f3rio <strong>Admin<\/strong> seguido por um diret\u00f3rio <strong>MetaBox<\/strong>.<\/p>\n<p>Para esse fim, como seria um conjunto de classes projetadas para trabalhar com meta caixas, dever\u00edamos escrever c\u00f3digo para elas de maneira reutiliz\u00e1vel? Dado o que sabemos sobre meta boxes, sabemos que provavelmente precisaremos do seguinte:<\/p>\n<ul>\n<li>uma classe abstrata que define o tipo de postagem ao qual cada meta box ser\u00e1 vinculada,<\/li>\n<li>duas fun\u00e7\u00f5es para a meta box \u2013 uma para registr\u00e1-la, outra para exibir o conte\u00fado,<\/li>\n<li>um diret\u00f3rio para conter a visualiza\u00e7\u00e3o ou a apresenta\u00e7\u00e3o da meta box,<\/li>\n<li>um arquivo que servir\u00e1 como a referida visualiza\u00e7\u00e3o.<\/li>\n<\/ul>\n<p>Dados os pontos acima, talvez a estrutura de diret\u00f3rios ficaria assim:<\/p>\n<\/p>\n<p>Em seguida, temos o c\u00f3digo que espelha essa estrutura. Ou seja, dentro do nosso diret\u00f3rio <strong>WordPress<\/strong>, ter\u00edamos o subdiret\u00f3rio <strong>Admin<\/strong> j\u00e1 que a meta box \u00e9 exibida dentro da \u00e1rea de administra\u00e7\u00e3o do WordPress, e ter\u00edamos o subdiret\u00f3rio <strong>View<\/strong> que conteria o arquivo respons\u00e1vel por exibir as informa\u00e7\u00f5es.<\/p>\n<p>Isso nos deixa com a necessidade de criar algumas classes, conforme listado acima. Talvez a classe base abstrata ficaria <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2fd7f50706c3f1767dc8b5c2b7deefff#file-00-abstract-metabox-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">assim:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nnamespace AcmeWordPressAdminMetaBox;\n\nabstract class AbstractMetaBox\n{\n    protected $postType;\n\n    public function __construct()\n    {\n        $this-&gt;postType = 'acme_post_type';\n    }\n\n    abstract public function render();\n    abstract public function display();\n}\n<\/code><\/pre>\n<p>Em seguida, uma implementa\u00e7\u00e3o concreta estenderia a classe e ficaria <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2fd7f50706c3f1767dc8b5c2b7deefff#file-01-acme-meta-box-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">assim:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nnamespace AcmeWordPressAdminMetaBox;\n\nclass AcmeMetaBox extends AbstractMetaBox\n{\n    \/**\n     * {@inheritdoc}\n     *\/\n    public function render()\n    {\n        add_meta_box(\n            'acme-product-image',\n            'Product Image',\n            [$this, 'display'],\n            $this-&gt;postType,\n            'side',\n            'default'\n        );\n    }\n\n    \/**\n     * {@inheritdoc}\n     *\/\n    public function display()\n    {\n        include_once plugin_dir_path(__FILE__).'Views\/acme-product-image.php';\n    }\n}\n<\/code><\/pre>\n<p>E, finalmente, a visualiza\u00e7\u00e3o da classe conteria qualquer c\u00f3digo de marca\u00e7\u00e3o e modelo <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2fd7f50706c3f1767dc8b5c2b7deefff#file-02-acme-product-image-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">para renderiza\u00e7\u00e3o de informa\u00e7\u00f5es<\/a><\/strong> :<\/p>\n<pre><code>&lt;div class=\"product-image-metabox\"&gt;\n    &lt;p&gt;\n        &lt;img src=\"&lt;?= esc_html(get_post_meta(get_the_ID(), 'product_image', true)); ?&gt;\" alt=\"&lt;?= esc_attr(get_the_title()); ?&gt;\" \/&gt;\n        &lt;input type=\"text\" value=\"&lt;?= esc_html(get_post_meta(get_the_ID(), 'product_image', true)); ?&gt;\" \/&gt;\n    &lt;\/p&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<p>Isso nos d\u00e1 exatamente o que precisamos de uma maneira bem organizada e reutiliz\u00e1vel para trabalhar com meta caixas. Tamb\u00e9m pode ser repetido para itens como menus, tipos de postagem, taxonomias e assim por diante.<\/p>\n<p>Mas eu discordo.<\/p>\n<h3>Uma palavra sobre teste de unidade (com PHPUnit)<\/h3>\n<p>Como mencionei anteriormente no post, acredito que as classes de teste de unidade que resolvem problemas exclusivos do nosso espa\u00e7o de problemas s\u00e3o importantes. Isso significa que voc\u00ea precisa dizer ao seu arquivo de configura\u00e7\u00e3o PHPUnit para excluir seus arquivos centrados no WordPress.<\/p>\n<p>A vantagem do que expus acima \u00e9 que isso se torna trivialmente f\u00e1cil. Simplificando, voc\u00ea pode <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2fd7f50706c3f1767dc8b5c2b7deefff#file-03-phpunit-xml\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">adicionar isso<\/a><\/strong> ao seu arquivo <strong>phpunit.xml<\/strong> :<\/p>\n<pre><code>&lt;testsuites&gt;\n  &lt;testsuite name=\"Plugin\"&gt;\n    &lt;directory&gt;.\/tests&lt;\/directory&gt;\n    &lt;exclude&gt;.\/tests\/phpunit&lt;\/exclude&gt;\n    &lt;exclude&gt;.\/src\/WordPress&lt;\/exclude&gt;\n  &lt;\/testsuite&gt;\n&lt;\/testsuites&gt;<\/code><\/pre>\n<p>Isso lhe d\u00e1 a capacidade de se concentrar em escrever testes especificamente para o seu espa\u00e7o de problema, ao mesmo tempo em que garante que voc\u00ea est\u00e1 escrevendo c\u00f3digo baseado em WordPress escal\u00e1vel, sustent\u00e1vel e reutiliz\u00e1vel.<\/p>\n<p>Atualmente estou escrevendo um eBook (junto com uma variedade de outros conte\u00fados premium). Se voc\u00ea estiver interessado, <a href=\"https:\/\/tommcfarlin.com\/registration-info\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">confira o que voc\u00ea recebe<\/a>.<\/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>Organizar o c\u00f3digo para classes centradas no WordPress nos ajuda a focar mais em nosso dom\u00ednio tanto em termos de resolu\u00e7\u00e3o do problema quanto em termos de escrita de testes de unidade.<\/p>\n","protected":false},"author":1,"featured_media":236089,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[722],"tags":[1170],"class_list":["post-230822","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\/230822","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=230822"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/230822\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/236089"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=230822"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=230822"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=230822"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}