{"id":229701,"date":"2022-11-22T17:24:00","date_gmt":"2022-11-22T14:24:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229701"},"modified":"2022-11-22T20:39:30","modified_gmt":"2022-11-22T17:39:30","slug":"ladda-upp-filer-i-wordpress-revisited-del-2-serversidan","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/sv\/ladda-upp-filer-i-wordpress-revisited-del-2-serversidan\/","title":{"rendered":"Ladda upp filer i WordPress Revisited, del 2 &#8211; Serversidan"},"content":{"rendered":"\n<p>Innan jag hoppade direkt in i koden f\u00f6r detta ville jag n\u00e4mna tv\u00e5 saker:<\/p>\n<ol>\n<li>Ja, jag har t\u00e4ckt det h\u00e4r i detalj f\u00f6r <strong><a href=\"https:\/\/tommcfarlin.com\/uploading-files-to-a-custom-directory\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ett tag sedan,<\/a><\/strong><\/li>\n<li>Och detta \u00e4r den andra delen av en serie i tv\u00e5 delar.<\/li>\n<\/ol>\n<p>Om du inte har l\u00e4st <a href=\"https:\/\/wordpress.mediadoma.com\/sv\/ladda-upp-filer-i-wordpress-revisited-del-1-kundsidan\/\" title=\"den f\u00f6rsta delen\">den f\u00f6rsta delen<\/a>, g\u00f6r det f\u00f6rst. Tanken \u00e4r att koden ska fungera tillsammans med det jag ska ta upp i det h\u00e4r inl\u00e4gget f\u00f6r att s\u00e4kerst\u00e4lla att b\u00e5de klientsidan och serversidan t\u00e4cks.<\/p>\n<p>I slut\u00e4ndan \u00e4r anledningen till att dela upp det s\u00e5 h\u00e4r inte bara f\u00f6r att se till att saker g\u00f6rs korrekt, utan ocks\u00e5 f\u00f6r att se till att anv\u00e4ndaren f\u00e5r en s\u00e5 positiv upplevelse som m\u00f6jligt.<\/p>\n<p>Med det sagt, s\u00e5 h\u00e4r g\u00e5r du tillv\u00e4ga f\u00f6r att ladda upp filer i WordPress p\u00e5 serversidan.<\/p>\n<h2>Ladda upp filer i WordPress p\u00e5 serversidan<\/h2>\n<p>Observera att \u00e4ven om det finns vissa s\u00e4kerhetskontroller som kan \u2013 och b\u00f6r \u2013 g\u00f6ras, har jag \u00e4nnu inte hittat ett s\u00e4tt som \u00e4r helt idiots\u00e4kert f\u00f6r att uppt\u00e4cka att filen som laddas upp \u00e4r av r\u00e4tt typ.<\/p>\n<p>Det betyder att det fortfarande finns en chans att en felaktig filtyp kan laddas upp. Huruvida detta \u00e4r skadligt eller inte \u00e4r uppenbarligen upp till slutanv\u00e4ndaren. Jag delar just detta f\u00f6r att vara tydlig med att koden jag kommer att visa \u00e4r s\u00e5 bra som jag kan g\u00f6ra, men att det fortfarande finns en niv\u00e5 av diskretion du b\u00f6r anv\u00e4nda.<\/p>\n<p>Kanske \u00e4r det v\u00e4rt att till och med leta efter ett tredjepartsbibliotek f\u00f6r att validera bin\u00e4ra data n\u00e4r de v\u00e4l har tagits emot. Men jag avviker.<\/p>\n<h3>1 Verifiera anv\u00e4ndarbeh\u00f6righeter<\/h3>\n<p>Kom ih\u00e5g att n\u00e4r vi har skapat gr\u00e4nssnittet s\u00e5 l\u00e5ter vi WordPress generera en nonce s\u00e5 att vi kan anv\u00e4nda detta f\u00f6r att se till att anv\u00e4ndaren har beh\u00f6righet att ladda upp filen.<\/p>\n<p>F\u00f6rutom att kontrollera nonce, finns det flera andra saker jag gillar att kontrollera som alla \u00e4r inlindade i en metod som kallas <strong>userCanSave<\/strong>.<\/p>\n<p>Kom f\u00f6rst <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-00-nonce-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ih\u00e5g gr\u00e4nssnittet:<\/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>Ta sedan en titt p\u00e5 hur jag anv\u00e4nder det i koden. F\u00f6rst definierar jag <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-01-usercansave-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">funktionen<\/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>Och d\u00e5 kallar jag helt enkelt detta i b\u00f6rjan av processen. Om det misslyckas, d\u00e5 <a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-01-save-part1-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">\u00e5terkommer<\/a> jag .<\/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>Jag rekommenderar att du visar ett felmeddelande, men jag avviker fr\u00e5n denna punkt eftersom det finns n\u00e5gra s\u00e4tt att g\u00f6ra detta i inl\u00e4gget.<\/p>\n<h3>2 Ladda upp filen<\/h3>\n<p>F\u00f6rutsatt att anv\u00e4ndaren har beh\u00f6righet att kontrollera filen, d\u00e5 \u00e4r det s\u00e4kert att ladda upp filen. Processen f\u00f6r att g\u00f6ra detta \u00e4r enkel men kr\u00e4ver fortfarande lite arbete med WordPress API (n\u00e4mligen med funktionen <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>F\u00f6rst m\u00e5ste filen h\u00e4mtas fr\u00e5n PHP:s <a href=\"https:\/\/php.net\/manual\/en\/reserved.variables.files.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">$_FILES<\/a> globala och sedan laddas upp. N\u00e4r du g\u00f6r det \u00e4r det dock viktigt att se till att du laddar upp en fil med <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-02-save-part2-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">r\u00e4tt filtill\u00e4gg<\/a><\/strong> (\u00e5tminstone).<\/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>Om filtypen inte \u00e4r en PDF kan du skicka ett felmeddelande, helt enkelt returnera (\u00e4ven om jag inte \u00e4r ett fan av detta), eller <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-03-save-part3-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ge anv\u00e4ndarna feedback<\/a><\/strong> (vilket jag \u00e4r ett fan av att g\u00f6ra).<\/p>\n<pre><code>&lt;?php\n\nif ($uploadFile['error']) {\n  \/\/ Your preferred method of feedback here.\n}<\/code><\/pre>\n<p>Det sista steget \u00e4r dock att f\u00e5 in filen i mediauppladdningsprogrammet.<\/p>\n<h3>3 Laddar den i Media Uploader<\/h3>\n<p>Det sista steget i allt detta \u00e4r att f\u00e5 filen till mediauppladdningsprogrammet. F\u00f6r att g\u00f6ra detta beh\u00f6ver du flera saker fr\u00e5n WordPress-k\u00e4rnan:<\/p>\n<ol>\n<li>biblioteket file.php,<\/li>\n<li>en bilaga som beh\u00f6vs f\u00f6r att ber\u00e4tta f\u00f6r WordPress vad som l\u00e4ggs till,<\/li>\n<li>en WordPress API-funktion, <strong>wp_insert_attachment<\/strong><\/li>\n<li>omdirigerar tillbaka till uppringningssidan<\/li>\n<\/ol>\n<p>L\u00e5ter som mycket, eller hur? Det \u00e4r inte s\u00e5 illa.<\/p>\n<p>Jag brukar gruppera inkluderingen av WordPress-filbiblioteket och <strong>wp_insert_attachment<\/strong> i ett enda block.<\/p>\n<p>Du kommer att m\u00e4rka att jag st\u00e4ller in MIME-typen till <strong>pdf<\/strong> och jag ser till att titeln inte inneh\u00e5ller n\u00e5got f\u00f6rutom filnamnet. Efter det anv\u00e4nder jag <a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/wp_insert_attachment\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wp_insert_attachment<\/a> f\u00f6r att ladda filen i mediebiblioteket.<\/p>\n<\/p>\n<p>Den fullst\u00e4ndiga koden f\u00f6r det \u00e4r <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-05-save-part5-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">f\u00f6ljande:<\/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>Efter det omdirigerar jag tillbaka till sidan som startade allt detta (som vanligtvis \u00e4r adminsidan vi s\u00e5g i f\u00f6rra inl\u00e4gget. Till detta tar jag tag i <strong>_wp_http_referer<\/strong> fr\u00e5n <a href=\"https:\/\/php.net\/manual\/en\/reserved.variables.request.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">PHPs $_REQUEST-<\/a> array.<\/p>\n<pre><code>&lt;?php\nwp_safe_redirect(\n    $_REQUEST['_wp_http_referer'],\n    301\n);\nexit;\n<\/code><\/pre>\n<p>Och det kommer att <a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-06-save-part6-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">omdirigera<\/a> anv\u00e4ndaren tillbaka till sidan varifr\u00e5n de kom.<\/p>\n<h2>Och filen laddas upp<\/h2>\n<p>Vid det h\u00e4r laget har vi best\u00e4mt vad vi vill g\u00f6ra:<\/p>\n<ol>\n<li>Ge en anst\u00e4ndig kundupplevelse,<\/li>\n<li>Laddade upp filen till mediebiblioteket (med m\u00f6jligheter att ge feedback)<\/li>\n<li>Och omdirigeras tillbaka till sidan som startade det hela.<\/li>\n<\/ol>\n<p>Visst, det finns mycket utrymme f\u00f6r feedback i detta, och jag uppmanar dig att anpassa detta efter behov f\u00f6r din kod, men grunden f\u00f6r vad du beh\u00f6ver b\u00f6r tillhandah\u00e5llas b\u00e5de <a href=\"https:\/\/wordpress.mediadoma.com\/sv\/ladda-upp-filer-i-wordpress-revisited-del-1-kundsidan\/\" title=\"i det tidigare inl\u00e4gget\">i det tidigare inl\u00e4gget<\/a> och i det h\u00e4r inl\u00e4gget.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Inspelningsk\u00e4lla:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ett exempel p\u00e5 kod p\u00e5 serversidan som kr\u00e4vs f\u00f6r att ladda upp en fil via WordPress (och 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":[848,901,868],"tags":[1173],"class_list":["post-229701","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-handledningar","category-koda","category-wordpress-9","tag-affiai-sv"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/229701","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/comments?post=229701"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/229701\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media\/164785"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media?parent=229701"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/categories?post=229701"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/tags?post=229701"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}