{"id":231331,"date":"2022-12-18T14:10:00","date_gmt":"2022-12-18T11:10:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231331"},"modified":"2022-12-18T14:10:41","modified_gmt":"2022-12-18T11:10:41","slug":"widgets-do-wordpress-refatoracao-parte-6","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/widgets-do-wordpress-refatoracao-parte-6\/","title":{"rendered":"Widgets do WordPress: Refatora\u00e7\u00e3o, Parte 6"},"content":{"rendered":"\n<p>Voc\u00ea deve ser bem versado na refatora\u00e7\u00e3o que estamos fazendo em rela\u00e7\u00e3o ao WordPress Widget Boilerplate. Se n\u00e3o, eu recomendo acompanhar a s\u00e9rie at\u00e9 agora por:<\/p>\n<ul>\n<li>lendo <a href=\"https:\/\/tommcfarlin.com\/wordpress-widgets-part-5\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">o post anterior<\/a> ,<\/li>\n<li>ou lendo <a href=\"https:\/\/tommcfarlin.com\/tag\/wordpress-widgets-api\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">a s\u00e9rie inteira<\/a> at\u00e9 este ponto,<\/li>\n<li>e olhando para <a href=\"https:\/\/github.com\/tommcfarlin\/WordPress-Widget-Boilerplate\/tree\/develop\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">o ramo de desenvolvimento do projeto<\/a> no GitHub.<\/li>\n<\/ul>\n<p>No que diz respeito \u00e0 base de c\u00f3digo, estamos em um bom lugar agora. Come\u00e7amos a refatorar grande parte do c\u00f3digo em classes menores e mais focadas. E acabamos de configurar um Registro para que possamos come\u00e7ar a trabalhar com inst\u00e2ncias de objetos em todo o plugin sem a necessidade de muito acoplamento.<\/p>\n<p>Mas ainda h\u00e1 um problema que estamos enfrentando e trata de namespaces e carregamento autom\u00e1tico. Eu falei um pouco sobre isso <a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/namespaces-e-carregamento-automatico-no-wordpress\/\" title=\"alguns anos atr\u00e1s,\">alguns anos atr\u00e1s,<\/a> mas n\u00e3o no que se refere ao Composer.<\/p>\n<p>E \u00e9 isso que vamos ver neste post.<\/p>\n<h2>The WordPress Widget Boilerplate: Refatora\u00e7\u00e3o, Parte 6<\/h2>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/pt-pt\/widgets-do-wordpress-refatoracao-parte-2\/\" title=\"No segundo post desta s\u00e9rie\">No segundo post desta s\u00e9rie<\/a>, come\u00e7amos a falar sobre o Composer. Se voc\u00ea perguntar \u00e0 maioria dos desenvolvedores PHP (incluindo aqueles que trabalham no WordPress), provavelmente ouvir\u00e1 que o Composer \u00e9 um gerenciador de pacotes ou um gerenciador de depend\u00eancias.<\/p>\n<p>Resumindo, \u00e9 uma forma de trazermos bibliotecas de terceiros para nosso projeto e ent\u00e3o utilizarmos seus recursos (para que n\u00e3o tenhamos que escrever nosso pr\u00f3prio c\u00f3digo para isso).<\/p>\n<p>Mas h\u00e1 outro recurso que o Composer oferece que \u00e9 de imensa utilidade, especialmente quando voc\u00ea est\u00e1 usando muitas classes e <strong>n\u00e3o<\/strong> deseja usar instru\u00e7\u00f5es require_once em toda a sua base de c\u00f3digo.<\/p>\n<p>E esse \u00e9 o carregador autom\u00e1tico.<\/p>\n<h3>O Autoloader Definido<\/h3>\n<p>Direto do <a href=\"https:\/\/getcomposer.org\/doc\/01-basic-usage.md#autoloading\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">manual:<\/a><\/p>\n<blockquote>\n<p>Para bibliotecas que especificam informa\u00e7\u00f5es de carregamento autom\u00e1tico, o Composer gera um <code>vendor\/autoload.php<\/code>arquivo. Voc\u00ea pode simplesmente incluir este arquivo e come\u00e7ar a usar as classes que essas bibliotecas fornecem sem nenhum trabalho extra:<\/p>\n<\/blockquote>\n<p>Se voc\u00ea acompanhou o c\u00f3digo at\u00e9 agora, ver\u00e1 que j\u00e1 estamos usando o autoloader gerado pelo Composer.<\/p>\n<p>Primeiro, definimos <a href=\"https:\/\/gist.github.com\/tommcfarlin\/94d1c4d9f22431f12102051cff4300ab#file-00-composer-json\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">a configura\u00e7\u00e3o necess\u00e1ria<\/a> :<\/p>\n<pre><code>{\n    \"name\": \"wordpress-widget-boilerplate\/wordpress-widget-boilerplate\",\n    \"description\": \"An organized, maintainable boilerplate for building widgets using WordPress best practices.\",\n    \"type\": \"wordpress-plugin\",\n    \"license\": \"GPL-3.0-or-later\",\n    \"homepage\": \"https:\/\/github.com\/tommcfarlin\/WordPress-Widget-Boilerplate\",\n    \"authors\": [\n      {\n        \"name\": \"Tom McFarlin\",\n        \"email\": \"tom@pressware.co\",\n        \"homepage\": \"https:\/\/pressware.co\"\n      }\n    ],\n    \"support\": {\n      \"issues\": \"https:\/\/github.com\/tommcfarlin\/WordPress-Widget-Boilerplate\/issues\"\n    },\n    \"config\": {\n      \"preferred-install\": \"dist\",\n      \"platform\": {\n          \"php\": \"7.1\"\n      }\n    },\n    \"repositories\": [\n      {\n        \"type\": \"composer\",\n        \"url\": \"https:\/\/wpackagist.org\"\n      }\n    ],\n    \"require\": {\n      \"php\": \"7.1\",\n      \"composer\/installers\": \"^1.4\"\n    },\n    \"require-dev\": {\n        \"friendsofphp\/php-cs-fixer\": \"^2.13.1\",\n        \"jakub-onderka\/php-parallel-lint\": \"^1.0.0\",\n        \"phpmd\/phpmd\": \"^v2.6.0\",\n        \"nikic\/php-parser\": \"^4.0\",\n        \"ocramius\/proxy-manager\": \"^2.0.0\",\n        \"phpro\/grumphp\": \"^0.13.1\"\n    },\n    \"scripts\": {\n      \"test\": [\n        \".\/vendor\/bin\/grumphp run\"\n      ]\n    },\n    \"minimum-stability\": \"stable\"\n  }<\/code><\/pre>\n<p>Ent\u00e3o <a href=\"https:\/\/gist.github.com\/tommcfarlin\/94d1c4d9f22431f12102051cff4300ab#file-01-plugin-boostrap-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">come\u00e7amos a inclu\u00ed-lo no bootstrap do plugin<\/a> (que finalizaremos hoje):<\/p>\n<pre><code>&lt;?php\n\n\/\/ Include the autoloader.\n\/\/ TODO: Note this has not yet been defined.\nrequire_once __DIR__. '\/inc\/autoload.php';\n<\/code><\/pre>\n<p>Mas h\u00e1 um problema aqui: como carregamos apenas as classes que precisamos para distribui\u00e7\u00e3o?<\/p>\n<p>Colocando de outra forma: h\u00e1 muitas bibliotecas que estamos usando no desenvolvimento para garantir que estamos escrevendo c\u00f3digo de alta qualidade e compat\u00edvel com os padr\u00f5es. Mas n\u00e3o queremos distribuir 10 MB de dados para quem usa nosso projeto.<\/p>\n<p>Em vez disso, precisamos incluir apenas os arquivos necess\u00e1rios, certo? E para fazer isso, precisamos ter certeza de que geramos um autoloader que possamos incluir e que fa\u00e7a exatamente isso.<\/p>\n<p>Primeiro, mostrarei <a href=\"https:\/\/gist.github.com\/tommcfarlin\/94d1c4d9f22431f12102051cff4300ab#file-02-composer-distribution-command-txt\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">o comando<\/a> e explicarei o que ele faz:<\/p>\n<pre><code>$ composer install --no-dev --no-ansi --no-interaction --optimize-autoloader --no-progress --prefer-dist<\/code><\/pre>\n<p>Isso gerar\u00e1 exatamente o que precisamos para que nosso projeto funcione em um ambiente de produ\u00e7\u00e3o. Veja o que cada sinalizador faz:<\/p>\n<ul>\n<li><strong>instala\u00e7\u00e3o do compositor<\/strong>. Isso simplesmente instala todas as depend\u00eancias. Se voc\u00ea j\u00e1 tiver v\u00e1rios deles em seu diret\u00f3rio de fornecedores, isso remover\u00e1 todos, exceto aqueles que s\u00e3o necess\u00e1rios.<\/li>\n<li><strong>n\u00e3o-dev<\/strong>. Isso evitar\u00e1 que o Composer instale os pacotes na se\u00e7\u00e3o <strong>require-dev<\/strong> de seus arquivos de configura\u00e7\u00e3o (ou seja, depend\u00eancias que estamos usando com o GrumPHP).<\/li>\n<li><strong>n\u00e3o-ansi.<\/strong> Isso evita que qualquer sa\u00edda ANSI ocorra. Voc\u00ea pode n\u00e3o se importar em executar isso ou n\u00e3o. Se voc\u00ea optar por fazer algum tipo de implanta\u00e7\u00e3o autom\u00e1tica, use-o; caso contr\u00e1rio, ele pode ser omitido do comando.<\/li>\n<li><strong>sem intera\u00e7\u00e3o<\/strong>. Esse \u00e9 outro sinalizador usado especificamente para ambientes nos quais voc\u00ea deseja construir o projeto automaticamente e n\u00e3o precisa se envolver com perguntas, sa\u00eddas e coisas assim.<\/li>\n<li><strong>otimizar-autoloader<\/strong>. Em suma, isso gera um autoloader mais r\u00e1pido. Pode demorar um pouco para ser executado, dependendo do tamanho do seu projeto, mas compensa na hora de iniciar seu trabalho.<\/li>\n<li><strong>sem progresso<\/strong>. Isso oculta a exibi\u00e7\u00e3o da barra de progresso no terminal. Voc\u00ea pode realmente querer ver isso e, em caso afirmativo, isso \u00e9 \u00f3timo; no entanto, alguns ambientes podem n\u00e3o lidar bem com determinados caracteres (como backspace).<\/li>\n<li><strong>prefer-dist<\/strong>. Isso garantir\u00e1 que os pacotes instalados sejam feitos usando a vers\u00e3o de distribui\u00e7\u00e3o (em vez de algo menos est\u00e1vel).<\/li>\n<\/ul>\n<h4>Ainda interessado?<\/h4>\n<p>Se voc\u00ea est\u00e1 realmente curioso sobre como otimizar o autoloader para projetos fora deste post, recomendo ler <a href=\"https:\/\/getcomposer.org\/doc\/articles\/autoloader-optimization.md\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">esta p\u00e1gina<\/a> na documenta\u00e7\u00e3o do Composer. Est\u00e1 fora do escopo do que estamos fazendo aqui, mas pode ser \u00fatil com outros trabalhos que voc\u00ea tem agora ou que far\u00e1 no futuro.<\/p>\n<h2>Como \u00e9 essa apar\u00eancia no Boilerplate?<\/h2>\n<p>Se voc\u00ea estiver trabalhando no Boilerplate em sua m\u00e1quina local, poder\u00e1 ver algo assim:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-161015-61e719e23bf2d.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-161015-61e719e23bf2d.png\" alt=\"Widgets do WordPress: Refatora\u00e7\u00e3o, Parte 6\"><\/a><\/p>\n<p>Mas se voc\u00ea executar o comando inclu\u00eddo acima, ver\u00e1 algo assim:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-161015-61e719e5afd5a.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-161015-61e719e5afd5a.png\" alt=\"Widgets do WordPress: Refatora\u00e7\u00e3o, Parte 6\"><\/a><\/p>\n<p>Essa \u00e9 uma grande diferen\u00e7a e este \u00e9 um projeto pequeno. Imagine fazer algo muito maior que ser\u00e1 executado em produ\u00e7\u00e3o.<\/p>\n<p>Falando por experi\u00eancia pr\u00f3pria, posso dizer que os projetos podem atingir rapidamente 20 MB ou mais de depend\u00eancias se voc\u00ea estiver usando uma variedade de bibliotecas de terceiros para coisas como log, solicita\u00e7\u00f5es HTTP e ferramentas de qualidade de c\u00f3digo.<\/p>\n<h2>Incluiremos em nosso diret\u00f3rio de fornecedores?<\/h2>\n<p>As pessoas costumam dizer que voc\u00ea n\u00e3o deve incluir o diret\u00f3rio do fornecedor no controle de origem e por um bom motivo: pode ser enorme.<\/p>\n<p>At\u00e9 a documenta\u00e7\u00e3o do Composer <a href=\"https:\/\/getcomposer.org\/doc\/faqs\/should-i-commit-the-dependencies-in-my-vendor-directory.md\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">fala sobre isso:<\/a><\/p>\n<blockquote>\n<p>A melhor pr\u00e1tica \u00e9 fazer com que todos os desenvolvedores usem o Composer para instalar as depend\u00eancias. Da mesma forma, o servidor de compila\u00e7\u00e3o, CI, ferramentas de implanta\u00e7\u00e3o, etc., devem ser adaptados para executar o Composer como parte da inicializa\u00e7\u00e3o do projeto.<\/p>\n<\/blockquote>\n<p>ent\u00e3o o que devemos fazer? Precisamos do autoloader e precisamos de certas depend\u00eancias porque nossos usu\u00e1rios n\u00e3o saber\u00e3o rodar (nem deveriam rodar!) Composer sempre que baixarem nosso trabalho.<\/p>\n<p>Por causa da natureza do WordPress e do trabalho que estamos fazendo, precisaremos confirmar o diret\u00f3rio do fornecedor, mas apenas com certos requisitos.<\/p>\n<ol>\n<li>Criaremos uma ramifica\u00e7\u00e3o que ser\u00e1 usada para lan\u00e7amento (chamaremos criativamente de <strong>lan\u00e7amento<\/strong> e podemos mesclar o <strong>desenvolvimento<\/strong> sempre que necess\u00e1rio).<\/li>\n<li>Garantiremos que o diret\u00f3rio do fornecedor n\u00e3o fa\u00e7a parte do arquivo gitignore; no entanto, nos certificaremos de que os diret\u00f3rios .git dentro do diret\u00f3rio do fornecedor sejam ignorados (isso ainda pode ocupar muito espa\u00e7o).<\/li>\n<\/ol>\n<p>Ent\u00e3o vamos fazer cada passo e ver como fica quando terminarmos.<\/p>\n<h3>Criando a ramifica\u00e7\u00e3o de lan\u00e7amento<\/h3>\n<p>Para criar uma nova ramifica\u00e7\u00e3o de dentro do terminal, digite <a href=\"https:\/\/gist.github.com\/tommcfarlin\/94d1c4d9f22431f12102051cff4300ab#file-03-create-a-branch-txt\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">o seguinte comando<\/a> :<\/p>\n<pre><code>$ git checkout -b release<\/code><\/pre>\n<p>Isso pegar\u00e1 todo o c\u00f3digo no qual estamos trabalhando e criar\u00e1 uma nova ramifica\u00e7\u00e3o com ele. J\u00e1 que este ser\u00e1 o branch que usaremos para atuar como o que nossos usu\u00e1rios ir\u00e3o usar (falaremos sobre <strong>master<\/strong> em um post futuro).<\/p>\n<p>Primeiro, revise seu arquivo composer.json e verifique se ele inclui o seguinte:<\/p>\n<pre><code>\"autoload\": {\n    \"psr-4\": {\n        \"WordPressWidgetBoilerplate\": \"src\/\",\n        \"WordPressWidgetBoilerplateSubscriber\": \"src\/Subscriber\/\",\n        \"WordPressWidgetBoilerplateUtilities\": \"src\/Utilities\/\",\n        \"WordPressWidgetBoilerplateViews\": \"src\/Views\/\"\n    }\n},<\/code><\/pre>\n<p>Agora precisamos ter certeza de que executamos o comando Composer acima para garantir que nada al\u00e9m do que precisamos esteja no diret\u00f3rio do <strong>fornecedor<\/strong>.<\/p>\n<pre><code>$ composer install --no-dev --no-ansi --no-interaction --optimize-autoloader --no-progress --prefer-dist<\/code><\/pre>\n<p>Agora precisamos atualizar o gitignore.<\/p>\n<h3>Atualizando o que ignoramos<\/h3>\n<p>E se voc\u00ea acompanhou a s\u00e9rie e o post at\u00e9 aqui, sabe que ser\u00e1 algo assim (pode incluir mais ou menos, mas deve incluir pelo menos isso).<\/p>\n<p>Para mim, isso se parece <a href=\"https:\/\/gist.github.com\/tommcfarlin\/94d1c4d9f22431f12102051cff4300ab#file-05-gitignore-txt\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">com o seguinte<\/a> :<\/p>\n<pre><code>*.DS_Store\n*.log\nwp-config.php\nwp-content\/advanced-cache.php\nwp-content\/backup-db\/\nwp-content\/backups\/\nwp-content\/blogs.dir\/\nwp-content\/cache\/\nwp-content\/upgrade\/\nwp-content\/uploads\/\nwp-content\/mu-plugins\/\nwp-content\/wp-cache-config.php\nwp-content\/plugins\/hello.php\n\n\/.htaccess\n\/license.txt\n\/readme.html\n\/sitemap.xml\n\/sitemap.xml.gz\n\n\/vendor\/**\/.git\n\/vendor\/bin\ncomposer.lock\n<\/code><\/pre>\n<p>Dependendo se voc\u00ea estiver usando um terminal ou um cliente, ver\u00e1 que h\u00e1 novos arquivos para confirmar (do diret\u00f3rio do fornecedor, especificamente). Portanto, adicione-os ao seu branch.<\/p>\n<p><a href=\"https:\/\/gist.github.com\/tommcfarlin\/94d1c4d9f22431f12102051cff4300ab#file-06-pushing-a-new-branch-txt\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Em seguida, confirme suas altera\u00e7\u00f5es<\/a>. Voc\u00ea pode ter que especificar o seguinte se estiver trabalhando no terminal:<\/p>\n<pre><code>$ git push --set-upstream origin release<\/code><\/pre>\n<p>E com isso, seu c\u00f3digo deve funcionar e estar dispon\u00edvel no GitHub (ou em qualquer servi\u00e7o de controle de origem que voc\u00ea esteja usando). Voc\u00ea pode ver o que tenho dispon\u00edvel <a href=\"https:\/\/github.com\/tommcfarlin\/WordPress-Widget-Boilerplate\/tree\/release\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">aqui<\/a>.<\/p>\n<h2>Adicionando Funcionalidade<\/h2>\n<p>Agora que temos todas as pe\u00e7as necess\u00e1rias no lugar, \u00e9 hora de come\u00e7ar a usar o Composer, o autoloader, nossas classes abstratas e nosso Registry para come\u00e7ar a adicionar algumas funcionalidades b\u00e1sicas ao WordPress Widget Boilerplate para que tenhamos algo para mostrar em nosso trabalho .<\/p>\n<p>Para quem est\u00e1 curioso, neste momento estou planejando manter as filiais organizadas assim:<\/p>\n<ul>\n<li><strong>master<\/strong> ser\u00e1 o que est\u00e1 dispon\u00edvel para qualquer pessoa que queira construir um WordPress Widget,<\/li>\n<li><strong>desenvolver<\/strong> \u00e9 estritamente para desenvolvedores incluem aqueles que sabem usar o Composer e os t\u00f3picos discutidos neste post,<\/li>\n<li><strong>release<\/strong> \u00e9 o que ser\u00e1 usado para fornecer uma demonstra\u00e7\u00e3o de trabalho.<\/li>\n<\/ul>\n<p>Por enquanto, por\u00e9m, revise o que \u00e9 abordado nesta postagem e retomaremos isso na pr\u00f3xima postagem.<\/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>H\u00e1 um problema que estamos enfrentando com namespaces e carregamento autom\u00e1tico e \u00e9 isso que veremos neste post.<\/p>\n","protected":false},"author":1,"featured_media":223641,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[722],"tags":[1170],"class_list":["post-231331","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\/231331","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=231331"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/231331\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/223641"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=231331"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=231331"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=231331"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}