{"id":230451,"date":"2022-11-22T17:03:00","date_gmt":"2022-11-22T14:03:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230451"},"modified":"2022-11-22T20:24:10","modified_gmt":"2022-11-22T17:24:10","slug":"caricamento-di-file-in-wordpress-rivisitato-parte-2-il-lato-server","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/it\/caricamento-di-file-in-wordpress-rivisitato-parte-2-il-lato-server\/","title":{"rendered":"Caricamento di file in WordPress rivisitato, parte 2 &#8211; Il lato server"},"content":{"rendered":"\n<p>Prima di saltare direttamente al codice per questo, volevo menzionare due cose:<\/p>\n<ol>\n<li>S\u00ec, l&#8217;ho trattato in dettaglio qualche <strong><a href=\"https:\/\/tommcfarlin.com\/uploading-files-to-a-custom-directory\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tempo fa,<\/a><\/strong><\/li>\n<li>E questa \u00e8 la seconda parte di una serie in due parti.<\/li>\n<\/ol>\n<p>Se non hai letto <a href=\"https:\/\/wordpress.mediadoma.com\/it\/caricamento-di-file-in-wordpress-rivisitato-parte-1-il-lato-client\/\" title=\"la prima parte\">la prima parte<\/a>, fallo prima. L&#8217;idea \u00e8 che il codice funzioner\u00e0 insieme a ci\u00f2 che tratter\u00f2 in questo post per assicurarmi che sia il lato client che il lato server siano coperti.<\/p>\n<p>In definitiva, il motivo per scomporlo in questo modo non \u00e8 solo per assicurarsi che le cose siano fatte correttamente, ma anche per assicurarsi che l&#8217;utente abbia l&#8217;esperienza pi\u00f9 positiva possibile.<\/p>\n<p>Detto questo, ecco come caricare i file in WordPress sul lato server.<\/p>\n<h2>Caricamento di file in WordPress sul lato server<\/h2>\n<p>Nota che anche se ci sono alcuni controlli di sicurezza che possono &#8211; e dovrebbero &#8211; essere eseguiti, devo ancora trovare un modo che sia completamente infallibile per rilevare che il file caricato \u00e8 del tipo corretto.<\/p>\n<p>Ci\u00f2 significa che esiste ancora la possibilit\u00e0 che venga caricato un tipo di file errato. Se questo \u00e8 dannoso o meno dipende ovviamente dall&#8217;utente finale. Condivido solo questo per essere chiaro che il codice che mostrer\u00f2 \u00e8 il massimo che posso fornire, ma che c&#8217;\u00e8 ancora un livello di discrezione che dovresti usare.<\/p>\n<p>Forse vale anche la pena cercare una libreria di terze parti per convalidare i dati binari una volta ricevuti. Ma sto divagando.<\/p>\n<h3>1 Verificare le autorizzazioni utente<\/h3>\n<p>Ricorda che ogni volta che abbiamo creato il front-end, WordPress genera un nonce in modo da poterlo utilizzare per assicurarci che l&#8217;utente abbia l&#8217;autorizzazione per caricare il file.<\/p>\n<p>Oltre a controllare il nonce, ci sono molte altre cose che mi piace controllare, tutte racchiuse in un metodo chiamato <strong>userCanSave<\/strong>.<\/p>\n<p>Innanzitutto, <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-00-nonce-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ricorda il front-end:<\/a><\/strong><\/p>\n<pre><code>&lt;form method=\"post\"\n      enctype=\"multipart\/form-data\"\n      action=\"&lt;?php echo esc_html(admin_url('admin-post.php')); ?&gt;\"\"&gt;\n    &lt;!-- Snip For Brevity ---&gt;\n    &lt;?php\n    wp_nonce_field(\n        'acme-item-upload',\n        'acme-item-importer'\n    );\n    ?&gt;\n&lt;\/form&gt;<\/code><\/pre>\n<p>Quindi dai un&#8217;occhiata a come lo uso nel codice. Innanzitutto, definisco la <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-01-usercansave-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">funzione<\/a><\/strong> <strong>userCanSave<a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-01-usercansave-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external\"><\/a><\/strong> :<\/p>\n<pre><code>&lt;?php\n\n\/**\n * Determines if the current user has permission to upload a file based on their current role and the values\n * of the security nonce.\n *\n * @param  string $nonce     The WordPress-generated nonce.\n * @param  string $action    The developer-generated action name.\n * @return bool              True if the user has permission to save; otherwise, false.\n *\/\nprivate function userCanSave($nonce, $action)\n{\n    $isNonceSet   = isset($_POST[$nonce]);\n    $isValidNonce = false;\n\n    if ($isNonceSet) {\n        $isValidNonce = wp_verify_nonce($_POST[$nonce], $action);\n    }\n\n    return ($isNonceSet &amp;&amp; $isValidNonce);\n}\n<\/code><\/pre>\n<p>E poi lo chiamo semplicemente all&#8217;inizio del processo. Se fallisce, allora <a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-01-save-part1-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ritorno<\/a>.<\/p>\n<pre><code>&lt;?php\n\n\/**\n * Assuming the user has permission, verifies the security nonce and uploads the PDF file to the `uploads`\n * directory and the Media Library.\n *\/\npublic function save()\n{\n  if (!$this-&gt;userCanSave('acme-item-importer', 'acme-item-upload')) {\n    return;\n  }\n\n  \/\/ More to come...\n\n}\n<\/code><\/pre>\n<p>Raccomando di mostrare un messaggio di errore, ma divago su questo punto poich\u00e9 ci sono alcuni modi per farlo all&#8217;interno del post.<\/p>\n<h3>2 Caricare il file<\/h3>\n<p>Supponendo che l&#8217;utente abbia l&#8217;autorizzazione per controllare il file, \u00e8 sicuro caricare il file. Il processo per farlo \u00e8 semplice ma richiede comunque un po&#8217; di lavoro con l&#8217;API di WordPress (vale a dire con la funzione <a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/wp_upload_bits\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wp_upload_bits<\/a> ).<\/p>\n<p>Innanzitutto, il file deve essere prelevato da <a href=\"https:\/\/php.net\/manual\/en\/reserved.variables.files.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">$ _FILES<\/a> globale di PHP e quindi caricato. Quando lo fai, tuttavia, \u00e8 importante assicurarsi di caricare un file con <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-02-save-part2-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">l&#8217;estensione di file corretta<\/a><\/strong> (almeno).<\/p>\n<pre><code>&lt;?php\n\n$file_type = explode('.', $filename);\n$file_type = strtolower($file_type[count($file_type) - 1]);\nif ('pdf' !== $file_type) {\n  \/\/ Give your feedback of choice here.\n}\n<\/code><\/pre>\n<p>Se il tipo di file non \u00e8 un PDF, puoi generare un errore, semplicemente restituire (anche se non ne sono un fan) o <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-03-save-part3-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">fornire un feedback all&#8217;utente<\/a><\/strong> (cosa che sono un fan di fare).<\/p>\n<pre><code>&lt;?php\n\nif ($uploadFile['error']) {\n  \/\/ Your preferred method of feedback here.\n}<\/code><\/pre>\n<p>L&#8217;ultimo passaggio, tuttavia, \u00e8 inserire il file nell&#8217;uploader multimediale.<\/p>\n<h3>3 Caricamento nel Media Uploader<\/h3>\n<p>L&#8217;ultimo passaggio in tutto questo \u00e8 inserire il file nell&#8217;uploader multimediale. Per fare ci\u00f2, hai bisogno di diverse cose dal core di WordPress:<\/p>\n<ol>\n<li>la libreria file.php,<\/li>\n<li>un array di allegati necessario per dire a WordPress cosa viene aggiunto,<\/li>\n<li>una funzione dell&#8217;API di WordPress, <strong>wp_insert_attachment<\/strong><\/li>\n<li>reindirizzamento alla pagina chiamante<\/li>\n<\/ol>\n<p>Sembra molto, vero? Non \u00e8 male.<\/p>\n<p>Di solito raggruppo l&#8217;inclusione della libreria di file di WordPress e di <strong>wp_insert_attachment<\/strong> in un unico blocco.<\/p>\n<p>Noterai che ho impostato il tipo MIME su <strong>pdf<\/strong> e mi assicuro che il titolo non includa nulla tranne il nome del file. Successivamente, utilizzo <a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/wp_insert_attachment\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wp_insert_attachment<\/a> per caricare il file nella libreria multimediale.<\/p>\n<\/p>\n<p>Il codice completo per questo \u00e8 <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-05-save-part5-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">il seguente:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nrequire_once(ABSPATH. \"wp-admin\". '\/includes\/file.php');\n$attachment  = array(\n    'post_mime_type' =&gt; 'pdf',\n    'post_title'     =&gt; preg_replace('\/.[^.]+$\/', '', $filename),\n    'post_status'    =&gt; 'inherit'\n);\n$attachment_id = wp_insert_attachment($attachment, $uploadFile['file']);\n<\/code><\/pre>\n<p>Dopodich\u00e9, ritorno alla pagina che ha avviato tutto questo (che di solito \u00e8 la pagina di amministrazione che abbiamo visto nel post precedente. Per questo, prendo il <strong>_wp_http_referer<\/strong> <a href=\"https:\/\/php.net\/manual\/en\/reserved.variables.request.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">dall&#8217;array $ _REQUEST<\/a> di PHP .<\/p>\n<pre><code>&lt;?php\nwp_safe_redirect(\n    $_REQUEST['_wp_http_referer'],\n    301\n);\nexit;\n<\/code><\/pre>\n<p>E ci\u00f2 <a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-06-save-part6-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">reindirizzer\u00e0<\/a> l&#8217;utente alla pagina da cui \u00e8 venuto.<\/p>\n<h2>E il file viene caricato<\/h2>\n<p>A questo punto, abbiamo definito cosa vogliamo fare:<\/p>\n<ol>\n<li>Offri un&#8217;esperienza decente lato client,<\/li>\n<li>Caricato il file nella libreria multimediale (con possibilit\u00e0 di offrire feedback)<\/li>\n<li>E reindirizzato alla pagina che ha avviato tutto.<\/li>\n<\/ol>\n<p>Certo, c&#8217;\u00e8 molto spazio per il feedback in questo e ti esorto ad adattarlo secondo necessit\u00e0 per il tuo codice, ma le basi di ci\u00f2 di cui hai bisogno dovrebbero essere fornite sia <a href=\"https:\/\/wordpress.mediadoma.com\/it\/caricamento-di-file-in-wordpress-rivisitato-parte-1-il-lato-client\/\" title=\"nel post precedente\">nel post precedente<\/a> che in questo post.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fonte di registrazione:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Un esempio di codice lato server necessario per caricare un file tramite WordPress (e Media Uploader).<\/p>\n","protected":false},"author":1,"featured_media":164785,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[896,844,865],"tags":[1168],"class_list":["post-230451","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codice","category-tutorial","category-wordpress-6","tag-affiai-it"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/230451","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/comments?post=230451"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/posts\/230451\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media\/164785"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/media?parent=230451"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/categories?post=230451"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/it\/wp-json\/wp\/v2\/tags?post=230451"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}