{"id":229550,"date":"2022-11-22T17:03:00","date_gmt":"2022-11-22T14:03:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229550"},"modified":"2022-11-22T20:19:04","modified_gmt":"2022-11-22T17:19:04","slug":"przesylanie-plikow-w-wordpress-ponownie-czesc-2-strona-serwera","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/przesylanie-plikow-w-wordpress-ponownie-czesc-2-strona-serwera\/","title":{"rendered":"Przesy\u0142anie plik\u00f3w w WordPress ponownie, cz\u0119\u015b\u0107 2 \u2014 strona serwera"},"content":{"rendered":"\n<p>Zanim wskocz\u0119 od razu do kodu, chcia\u0142em wspomnie\u0107 o dw\u00f3ch rzeczach:<\/p>\n<ol>\n<li>Tak, om\u00f3wi\u0142em to szczeg\u00f3\u0142owo <strong><a href=\"https:\/\/tommcfarlin.com\/uploading-files-to-a-custom-directory\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">jaki\u015b czas temu,<\/a><\/strong><\/li>\n<li>A to ju\u017c druga cz\u0119\u015b\u0107 dwucz\u0119\u015bciowej serii.<\/li>\n<\/ol>\n<p>Je\u015bli nie przeczyta\u0142e\u015b <a href=\"https:\/\/wordpress.mediadoma.com\/pl\/przesylanie-plikow-w-wordpressie-zrewidowane-czesc-1-po-stronie-klienta\/\" title=\"pierwszej cz\u0119\u015bci\">pierwszej cz\u0119\u015bci<\/a>, zr\u00f3b to najpierw. Pomys\u0142 polega na tym, \u017ce kod b\u0119dzie dzia\u0142a\u0142 w po\u0142\u0105czeniu z tym, co zamierzam om\u00f3wi\u0107 w tym po\u015bcie, aby upewni\u0107 si\u0119, \u017ce uwzgl\u0119dniona jest zar\u00f3wno strona klienta, jak i strona serwera.<\/p>\n<p>Ostatecznie powodem takiego podzia\u0142u jest nie tylko upewnienie si\u0119, \u017ce wszystko jest zrobione poprawnie, ale tak\u017ce upewnienie si\u0119, \u017ce u\u017cytkownik ma jak najbardziej pozytywne wra\u017cenia.<\/p>\n<p>Maj\u0105c to na uwadze, oto jak przes\u0142a\u0107 pliki do WordPressa po stronie serwera.<\/p>\n<h2>Przesy\u0142anie plik\u00f3w w WordPress po stronie serwera<\/h2>\n<p>Zwr\u00f3\u0107 uwag\u0119, \u017ce chocia\u017c istniej\u0105 pewne kontrole bezpiecze\u0144stwa, kt\u00f3re mo\u017cna \u2013 i nale\u017cy \u2013 wykona\u0107, nie znalaz\u0142em jeszcze sposobu, kt\u00f3ry by\u0142by ca\u0142kowicie niezawodny w wykrywaniu, \u017ce przesy\u0142any plik jest odpowiedniego typu.<\/p>\n<p>Oznacza to, \u017ce nadal istnieje szansa, \u017ce \u200b\u200bmo\u017cna przes\u0142a\u0107 nieprawid\u0142owy typ pliku. To, czy jest to z\u0142o\u015bliwe, zale\u017cy oczywi\u015bcie od u\u017cytkownika ko\u0144cowego. Dziel\u0119 si\u0119 tym, aby by\u0142o jasne, \u017ce kod, kt\u00f3ry zamierzam pokaza\u0107, jest tak dobry, jak mog\u0119 zapewni\u0107, ale nadal istnieje pewien poziom dyskrecji, kt\u00f3rego powiniene\u015b u\u017cywa\u0107.<\/p>\n<p>By\u0107 mo\u017ce warto nawet poszuka\u0107 biblioteki innej firmy do walidacji danych binarnych po ich otrzymaniu. Ale robi\u0119 dygresj\u0119.<\/p>\n<h3>1 Sprawd\u017a uprawnienia u\u017cytkownika<\/h3>\n<p>Pami\u0119taj, \u017ce za ka\u017cdym razem, gdy tworzymy front-end, WordPress generuje jednorazowy, aby\u015bmy mogli to wykorzysta\u0107, aby upewni\u0107 si\u0119, \u017ce u\u017cytkownik ma uprawnienia do przes\u0142ania pliku.<\/p>\n<p>Opr\u00f3cz sprawdzania warto\u015bci jednorazowych jest kilka innych rzeczy, kt\u00f3re chcia\u0142bym sprawdzi\u0107, z kt\u00f3rych wszystkie s\u0105 zawarte w metodzie o nazwie <strong>userCanSave<\/strong>.<\/p>\n<p>Najpierw <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-00-nonce-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">przypomnij sobie 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>Nast\u0119pnie sp\u00f3jrz, jak go u\u017cywam w kodzie. Najpierw definiuj\u0119 <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-01-usercansave-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">funkcj\u0119<\/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>A potem po prostu nazywam to na pocz\u0105tku procesu. Je\u015bli si\u0119 nie powiedzie, to <a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-01-save-part1-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wracam<\/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>Zalecam pokazywanie komunikatu o b\u0142\u0119dzie, ale dygresj\u0119 w tej kwestii, poniewa\u017c istnieje kilka sposob\u00f3w na zrobienie tego w po\u015bcie.<\/p>\n<h3>2 Prze\u015blij plik<\/h3>\n<p>Zak\u0142adaj\u0105c, \u017ce u\u017cytkownik ma uprawnienia do sprawdzenia pliku, mo\u017cna bezpiecznie przes\u0142a\u0107 plik. Proces jest prosty, ale nadal wymaga troch\u0119 pracy z API WordPress (a mianowicie z funkcj\u0105 <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>Najpierw plik musi zosta\u0107 pobrany z globalnego <a href=\"https:\/\/php.net\/manual\/en\/reserved.variables.files.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">$_FILES<\/a> PHP, a nast\u0119pnie przes\u0142any. Jednak robi\u0105c to, wa\u017cne jest, aby upewni\u0107 si\u0119, \u017ce przesy\u0142asz plik z <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-02-save-part2-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">poprawnym rozszerzeniem pliku<\/a><\/strong> (przynajmniej).<\/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>Je\u015bli typ pliku nie jest plikiem PDF, mo\u017cesz zg\u0142osi\u0107 b\u0142\u0105d, po prostu wr\u00f3ci\u0107 (chocia\u017c nie jestem tego fanem) lub <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-03-save-part3-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">przekaza\u0107 opini\u0119 u\u017cytkownika<\/a><\/strong> (co jestem fanem).<\/p>\n<pre><code>&lt;?php\n\nif ($uploadFile['error']) {\n  \/\/ Your preferred method of feedback here.\n}<\/code><\/pre>\n<p>Ostatnim krokiem jest jednak umieszczenie pliku w programie do przesy\u0142ania multimedi\u00f3w.<\/p>\n<h3>3 \u0141adowanie do programu do przesy\u0142ania multimedi\u00f3w<\/h3>\n<p>Ostatnim krokiem w tym wszystkim jest umieszczenie pliku w programie do przesy\u0142ania multimedi\u00f3w. Aby to zrobi\u0107, potrzebujesz kilku rzeczy z rdzenia WordPress:<\/p>\n<ol>\n<li>biblioteka plik.php,<\/li>\n<li>tablica za\u0142\u0105cznik\u00f3w niezb\u0119dna do poinformowania WordPressa, co jest dodawane,<\/li>\n<li>funkcja API WordPress, <strong>wp_insert_attachment<\/strong><\/li>\n<li>przekierowanie z powrotem do strony dzwoni\u0105cej<\/li>\n<\/ol>\n<p>Brzmi jak du\u017co, prawda? Nie jest a\u017c tak \u017ale.<\/p>\n<p>Zwykle grupuj\u0119 w\u0142\u0105czenie biblioteki plik\u00f3w WordPress i <strong>wp_insert_attachment<\/strong> w jeden blok.<\/p>\n<p>Zauwa\u017cysz, \u017ce ustawiam typ MIME na <strong>pdf<\/strong> i upewniam si\u0119, \u017ce tytu\u0142 nie zawiera niczego poza nazw\u0105 pliku. Nast\u0119pnie u\u017cywam <a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/wp_insert_attachment\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wp_insert_attachment<\/a>, aby za\u0142adowa\u0107 plik do Biblioteki multimedi\u00f3w.<\/p>\n<\/p>\n<p>Pe\u0142ny kod tego jest <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-05-save-part5-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">nast\u0119puj\u0105cy:<\/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>Nast\u0119pnie przekierowuj\u0119 z powrotem do strony, kt\u00f3ra to wszystko zacz\u0119\u0142a (jest to zwykle strona administratora, kt\u00f3r\u0105 widzieli\u015bmy w poprzednim po\u015bcie. W tym celu <strong>pobieram _wp_http_referer z tablicy<\/strong> <a href=\"https:\/\/php.net\/manual\/en\/reserved.variables.request.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">$_REQUEST<\/a> PHP .<\/p>\n<pre><code>&lt;?php\nwp_safe_redirect(\n    $_REQUEST['_wp_http_referer'],\n    301\n);\nexit;\n<\/code><\/pre>\n<p>A to <a href=\"https:\/\/gist.github.com\/tommcfarlin\/51b158a2cbc4052bef12cc059837a6ee#file-06-save-part6-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">przekieruje<\/a> u\u017cytkownika z powrotem na stron\u0119, z kt\u00f3rej przyby\u0142.<\/p>\n<h2>A plik jest przes\u0142any<\/h2>\n<p>W tym momencie okre\u015blili\u015bmy, co chcemy zrobi\u0107:<\/p>\n<ol>\n<li>Zapewnij przyzwoite wra\u017cenia po stronie klienta,<\/li>\n<li>Przes\u0142ano plik do biblioteki multimedi\u00f3w (z mo\u017cliwo\u015bci\u0105 wyra\u017cenia opinii)<\/li>\n<li>I przekierowany z powrotem na stron\u0119, od kt\u00f3rej wszystko si\u0119 zacz\u0119\u0142o.<\/li>\n<\/ol>\n<p>To prawda, jest w tym du\u017co miejsca na opinie i zach\u0119cam do dostosowania tego do swojego kodu, ale podstawa tego, czego potrzebujesz, powinna by\u0107 podana zar\u00f3wno <a href=\"https:\/\/wordpress.mediadoma.com\/pl\/przesylanie-plikow-w-wordpressie-zrewidowane-czesc-1-po-stronie-klienta\/\" title=\"w poprzednim po\u015bcie\">w poprzednim po\u015bcie<\/a>, jak i w tym po\u015bcie.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">\u0179r\u00f3d\u0142o nagrywania:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Przyk\u0142ad kodu po stronie serwera niezb\u0119dnego do przes\u0142ania pliku przez WordPress (i 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":[897,845,866],"tags":[1169],"class_list":["post-229550","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-kod","category-samouczki","category-wordpress-7","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/229550","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/comments?post=229550"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/229550\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/164785"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=229550"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=229550"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=229550"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}