Перегляд завантаження файлів у WordPress, частина 2 – сторона сервера
Перш ніж перейти безпосередньо до коду для цього, я хотів би згадати дві речі:
- Так, деякий час тому я розповідав про це досить детально ,
- І це друга частина серії з двох частин.
Якщо ви не читали першу частину, зробіть це спочатку. Ідея полягає в тому, що код працюватиме в поєднанні з тим, що я збираюся висвітлити в цій публікації, щоб переконатися, що охоплено як клієнтську, так і серверну сторону.
Зрештою, причиною такої розбивки є не тільки переконатися, що все зроблено правильно, але й переконатися, що користувач має максимально позитивний досвід.
З огляду на це, ось як завантажувати файли в WordPress на стороні сервера.
Завантаження файлів у WordPress на стороні сервера
Зауважте, що навіть незважаючи на певні перевірки безпеки, які можна – і потрібно – виконувати, я ще не знайшов повністю надійного способу виявити, що файл, який завантажується, належного типу.
Це означає, що все ще існує ймовірність завантаження файлу неправильного типу. Чи є це зловмисним чи ні, очевидно, залежить від кінцевого користувача. Я ділюся лише цим, щоб було зрозуміло, що код, який я збираюся показати, настільки хороший, наскільки я можу це зробити, але ви все ще маєте певний рівень обережності.
Можливо, варто навіть пошукати сторонню бібліотеку для перевірки двійкових даних після їх отримання. Але я відволікся.
1 Перевірте права користувача
Пам’ятайте, що щоразу, коли ми створюємо інтерфейс, WordPress генерує nonce, щоб ми могли використовувати його, щоб переконатися, що користувач має дозвіл на завантаження файлу.
На додаток до перевірки nonce, є кілька інших речей, які я люблю перевіряти, і всі вони містяться в методі під назвою userCanSave.
Спочатку пригадайте інтерфейс:
<form method="post"
enctype="multipart/form-data"
action="<?php echo esc_html(admin_url('admin-post.php')); ?>"">
<!-- Snip For Brevity --->
<?php
wp_nonce_field(
'acme-item-upload',
'acme-item-importer'
);
?>
</form>
Тоді подивіться, як я використовую це в коді. Спочатку я визначу функцію userCanSave :
<?php
/**
* Determines if the current user has permission to upload a file based on their current role and the values
* of the security nonce.
*
* @param string $nonce The WordPress-generated nonce.
* @param string $action The developer-generated action name.
* @return bool True if the user has permission to save; otherwise, false.
*/
private function userCanSave($nonce, $action)
{
$isNonceSet = isset($_POST[$nonce]);
$isValidNonce = false;
if ($isNonceSet) {
$isValidNonce = wp_verify_nonce($_POST[$nonce], $action);
}
return ($isNonceSet && $isValidNonce);
}
А потім я просто викликаю це на початку процесу. Якщо не вдається, я повертаюся.
<?php
/**
* Assuming the user has permission, verifies the security nonce and uploads the PDF file to the `uploads`
* directory and the Media Library.
*/
public function save()
{
if (!$this->userCanSave('acme-item-importer', 'acme-item-upload')) {
return;
}
// More to come...
}
Я рекомендую показувати повідомлення про помилку, але я відволікаюся від цього питання, оскільки в дописі є кілька способів зробити це.
2 Завантажте файл
Якщо припустити, що користувач має дозвіл на перевірку файлу, то завантажити файл можна безпечно. Процес виконання цього простий, але все одно вимагає трохи роботи з API WordPress (а саме з функцією wp_upload_bits ).
Спочатку файл потрібно отримати з глобального $_FILES PHP, а потім завантажити. Проте, роблячи це, важливо переконатися, що ви завантажуєте файл із правильним розширенням (принаймні).
<?php
$file_type = explode('.', $filename);
$file_type = strtolower($file_type[count($file_type) - 1]);
if ('pdf' !== $file_type) {
// Give your feedback of choice here.
}
Якщо тип файлу не є PDF, ви можете викинути повідомлення про помилку, просто повернути (хоча я не прихильник цього) або надати користувачеві відгук (я прихильник цього робити).
<?php
if ($uploadFile['error']) {
// Your preferred method of feedback here.
}
Але останнім кроком є завантаження файлу в медіа-завантажувач.
3 Завантаження в медіа-завантажувач
Останнім кроком у всьому цьому є завантаження файлу в медіа-завантажувач. Для цього вам знадобиться кілька речей з ядра WordPress:
- бібліотека file.php,
- масив вкладень, необхідний, щоб повідомляти WordPress, що додається,
- функція WordPress API, wp_insert_attachment
- переспрямування назад на сторінку виклику
Звучить багато, правда? Це не так вже й погано.
Зазвичай я групую включення бібліотеки файлів WordPress і wp_insert_attachment в один блок.
Ви помітите, що я встановлюю тип MIME на pdf і переконаюся, що заголовок не містить нічого, крім назви файлу. Після цього я використовую wp_insert_attachment, щоб завантажити файл у медіатеку.
Повний код для цього виглядає наступним чином:
<?php
require_once(ABSPATH. "wp-admin". '/includes/file.php');
$attachment = array(
'post_mime_type' => 'pdf',
'post_title' => preg_replace('/.[^.]+$/', '', $filename),
'post_status' => 'inherit'
);
$attachment_id = wp_insert_attachment($attachment, $uploadFile['file']);
Після цього я повертаюся на сторінку, з якої все це почалося (зазвичай це сторінка адміністратора, яку ми бачили в попередній публікації. Для цього я забираю _wp_http_referer з масиву $_REQUEST PHP .
<?php
wp_safe_redirect(
$_REQUEST['_wp_http_referer'],
301
);
exit;
І це перенаправить користувача назад на сторінку, з якої він прийшов.
І файл завантажено
На цьому етапі ми визначили, що ми хочемо зробити:
- Надайте гідний клієнтський досвід,
- Завантажив файл до медіатеки (з можливістю запропонувати відгук)
- І переспрямував назад на сторінку, з якої все почалося.
Звичайно, у цьому є багато місця для відгуків, і я закликаю вас адаптувати це за потреби для свого коду, але основу того, що вам потрібно, слід надати як у попередній, так і в цій публікації.