{"id":230958,"date":"2022-12-09T10:44:00","date_gmt":"2022-12-09T07:44:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230958"},"modified":"2022-12-07T11:58:53","modified_gmt":"2022-12-07T08:58:53","slug":"envio-seguro-de-formularios-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/envio-seguro-de-formularios-wordpress\/","title":{"rendered":"Envio seguro de formul\u00e1rios WordPress"},"content":{"rendered":"\n<p>Anos atr\u00e1s, escrevi um post no qual compartilhei uma fun\u00e7\u00e3o p\u00fablica para determinar se o usu\u00e1rio tinha permiss\u00e3o para salvar informa\u00e7\u00f5es no banco de dados do WordPress. Voc\u00ea pode ver a ess\u00eancia original em toda a sua gl\u00f3ria envelhecida (junto com os coment\u00e1rios s\u00f3lidos) <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/4468321\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">aqui<\/a><\/strong> (tem cinco anos, at\u00e9 \u2013 uau).<\/p>\n<p>Como acontece com qualquer coisa relacionada \u00e0 programa\u00e7\u00e3o, o tempo passa, as coisas s\u00e3o refinadas e as coisas [espero] ficam melhores do que eram antes.<\/p>\n<p>Embora eu ainda use e recomende uma variante da fun\u00e7\u00e3o <strong>user_can_save<\/strong> (ou <strong>userCanSave<\/strong> ), tamb\u00e9m acho importante passar pelo processo de separa\u00e7\u00e3o do processo de verifica\u00e7\u00e3o da solicita\u00e7\u00e3o.<\/p>\n<p>Portanto, agora n\u00e3o se trata apenas de determinar se o usu\u00e1rio tem permiss\u00f5es, mas de verificar as informa\u00e7\u00f5es de seguran\u00e7a vindas do cliente \u2013 seja por meio de um post de volta ao servidor ou uma solicita\u00e7\u00e3o feita via Ajax \u2013 e faz\u00ea-lo usando boas t\u00e9cnicas de programa\u00e7\u00e3o que se alinhem tanto com WordPress quanto com PHP.<\/p>\n<p>Para ser claro, isso \u00e9 mais sobre o envio seguro de formul\u00e1rios do WordPress a partir de uma p\u00e1gina de op\u00e7\u00f5es ou uma p\u00e1gina de configura\u00e7\u00f5es do que, digamos, um formul\u00e1rio proveniente de um modelo. Esse \u00e9 outro post para outro momento.<\/p>\n<p>Mas ainda assim, h\u00e1 muitos de n\u00f3s trabalhando na constru\u00e7\u00e3o de aplicativos no WordPress e que exigem o seguinte.<\/p>\n<h2>Envio seguro de formul\u00e1rios WordPress<\/h2>\n<p>Neste post, n\u00e3o vou me preocupar em passar pelos detalhes para determinar se algo \u00e9 um <strong><a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/wp_is_post_autosave\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">salvamento autom\u00e1tico<\/a><\/strong> ou uma <strong><a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/wp_is_post_revision\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">revis\u00e3o de postagem.<\/a><\/strong><\/p>\n<\/p>\n<p>No entanto, vou percorrer o processo de pegar uma fun\u00e7\u00e3o respons\u00e1vel por validar as informa\u00e7\u00f5es recebidas e faz\u00ea-lo usando uma abordagem moderna usando pr\u00e1ticas orientadas a objetos e APIs do WordPress e fun\u00e7\u00f5es PHP.<\/p>\n<h3>1 Come\u00e7ando em um n\u00edvel gen\u00e9rico<\/h3>\n<p>A partir do n\u00edvel fundamental, vamos supor que h\u00e1 uma classe base da qual existem outras subclasses que aproveitam essa fun\u00e7\u00e3o. Isso nos diz que precisamos usar o modificador de visibilidade protegido.<\/p>\n<p>Tamb\u00e9m sabemos que vamos lidar com um valor nonce do WordPress e uma a\u00e7\u00e3o relacionada. Isso significa que a <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-00-function-signature-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">assinatura da fun\u00e7\u00e3o ser\u00e1 algo assim<\/a><\/strong> :<\/p>\n<pre><code>&lt;?php\nprotected function verifyRequest($nonce, $action);<\/code><\/pre>\n<h3>2 Higienize os dados, verifique o Nonce<\/h3>\n<p>De acordo com qualquer coisa que seja postada no servidor, sabemos que precisaremos verificar se os dados est\u00e3o definidos e, em caso afirmativo, precisaremos limpar as informa\u00e7\u00f5es.<\/p>\n<p>Isso significa que vamos precisar das seguintes fun\u00e7\u00f5es:<\/p>\n<ul>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.isset.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">isset<\/a><\/li>\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><strong><a href=\"https:\/\/php.net\/manual\/en\/function.stripslashes.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tiras<\/a><\/strong><\/li>\n<\/ul>\n<p>E tamb\u00e9m sabemos que precisaremos verificar o nonce, ent\u00e3o tamb\u00e9m precisaremos de <strong><a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/wp_verify_nonce\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wp_verify_nonce<\/a><\/strong>.<\/p>\n<h3>3 Um Primeiro Passe de Trabalho<\/h3>\n<p>Uma primeira passagem funcional desta fun\u00e7\u00e3o pode ser algo <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-00-verify-request-1-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">assim:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\nprotected function verifyRequest($nonce, $action)\n{\n    return isset($_GET[$nonce]) &amp;&amp;\n           wp_verify_nonce(strip_tags(stripslashes($_GET[$nonce])), $action);\n}\n<\/code><\/pre>\n<p>Mas e se algu\u00e9m estiver compartilhando dados que enviaram uma solicita\u00e7\u00e3o <strong>POST<\/strong> (versus uma solicita\u00e7\u00e3o <strong>GET<\/strong> )? Ent\u00e3o poder\u00edamos modificar a fun\u00e7\u00e3o para ficar <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-02-verify-request-2-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">assim:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\nprotected function verifyRequest($nonce, $action)\n{\n    return (isset($_GET[$nonce]) &amp;&amp;\n            wp_verify_nonce(strip_tags(stripslashes($_GET[$nonce])), $action)) || (isset($_POST[$nonce]) &amp;&amp;\n            wp_verify_nonce(strip_tags(stripslashes($_POST[$nonce])), $action)\n        );\n}\n<\/code><\/pre>\n<p>E isso seria suficiente. Mas se realmente queremos que uma determinada fun\u00e7\u00e3o seja a mais pura poss\u00edvel, podemos decomp\u00f4-la ainda mais.<\/p>\n<h3>4 Uma Fun\u00e7\u00e3o Para Cada Prop\u00f3sito<\/h3>\n<p>Dado o c\u00f3digo acima, sabemos que precisamos lidar com solicita\u00e7\u00f5es GET e solicita\u00e7\u00f5es POST. O PHP oferece uma fun\u00e7\u00e3o <strong>filter_input<\/strong> que \u00e9 \u00fatil, mais f\u00e1cil de ler (bem, isso \u00e9 subjetivo), mas tamb\u00e9m passa por v\u00e1rias inspe\u00e7\u00f5es de qualidade de c\u00f3digo.<\/p>\n<p>Al\u00e9m disso, podemos usar uma fun\u00e7\u00e3o <strong><a href=\"https:\/\/en.wikipedia.org\/wiki\/Factory_method_pattern\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">simples de f\u00e1brica<\/a><\/strong> para separar a l\u00f3gica em fun\u00e7\u00f5es separadas como esta:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-162230-61e73927a6ca8.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-162230-61e73927a6ca8.png\" alt=\"Envio seguro de formul\u00e1rios WordPress\" ><\/a><\/p>\n<p>Primeiro, precisamos escrever duas fun\u00e7\u00f5es separadas \u2013 uma <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-03-verify-post-request-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">para uma solicita\u00e7\u00e3o POST:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\nprivate function verifyPostRequest($nonce, $action)\n{\n    return\n        isset($_POST[$nonce]) &amp;&amp;\n        wp_verify_nonce(strip_tags(stripslashes(filter_input(INPUT_POST, $nonce))), $action);\n}<\/code><\/pre>\n<p>E um <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-04-verify-get-request-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">para uma solicita\u00e7\u00e3o GET:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\nprivate function verifyGetRequest($nonce, $action)\n{\n    return\n        isset($_GET[$nonce]) &amp;&amp;\n        wp_verify_nonce(strip_tags(stripslashes(filter_input(INPUT_GET, $nonce))), $action);\n}<\/code><\/pre>\n<p>Ent\u00e3o podemos junt\u00e1-lo na <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/b1eac5df600177b7beb423477ccceee6#file-05-verify-request-factory-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">fun\u00e7\u00e3o original assim:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\nprotected function verifyRequest($nonce, $action)\n{\n    switch (strtolower($_SERVER['REQUEST_METHOD'])) {\n        case 'post':\n            return $this-&gt;verifyPostRequest($nonce, $action);\n            break;\n        case 'get':\n            return $this-&gt;verifyGetRequest($nonce, $action);\n            break;\n        default:\n            return false;\n            break;\n    }\n}<\/code><\/pre>\n<h2>Gerenciando de forma limpa as solicita\u00e7\u00f5es recebidas<\/h2>\n<p>Talvez isso pare\u00e7a uma maneira complicada de lidar com uma solu\u00e7\u00e3o simples, dado o conjunto inicial de c\u00f3digo que foi compartilhado.<\/p>\n<p>Isso \u00e9 certamente poss\u00edvel, especialmente se voc\u00ea estiver sob as restri\u00e7\u00f5es de tempo ou n\u00e3o se importar tanto em dividir as coisas nos menores componentes at\u00f4micos poss\u00edveis (ou mesmo test\u00e1veis).<\/p>\n<p>Mas se voc\u00ea deseja escrever c\u00f3digo orientado a objetos com o mais alto grau de precis\u00e3o, talvez esse processo ajude exatamente nisso.<\/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>Isso \u00e9 mais sobre o envio seguro de formul\u00e1rios do WordPress a partir de uma p\u00e1gina de op\u00e7\u00f5es ou uma p\u00e1gina de configura\u00e7\u00f5es do que um formul\u00e1rio proveniente de um modelo.<\/p>\n","protected":false},"author":1,"featured_media":236238,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[898,806,846,867],"tags":[1170],"class_list":["post-230958","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo-2","category-php-8","category-tutoriais","category-wordpress-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/230958","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=230958"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/230958\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/236238"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=230958"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=230958"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=230958"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}