Zanim wskoczę od razu do kodu, chciałem wspomnieć o dwóch rzeczach:
- Tak, omówiłem to szczegółowo jakiś czas temu,
- A to już druga część dwuczęściowej serii.
Jeśli nie przeczytałeś pierwszej części, zrób to najpierw. Pomysł polega na tym, że kod będzie działał w połączeniu z tym, co zamierzam omówić w tym poście, aby upewnić się, że uwzględniona jest zarówno strona klienta, jak i strona serwera.
Ostatecznie powodem takiego podziału jest nie tylko upewnienie się, że wszystko jest zrobione poprawnie, ale także upewnienie się, że użytkownik ma jak najbardziej pozytywne wrażenia.
Mając to na uwadze, oto jak przesłać pliki do WordPressa po stronie serwera.
Przesyłanie plików w WordPress po stronie serwera
Zwróć uwagę, że chociaż istnieją pewne kontrole bezpieczeństwa, które można – i należy – wykonać, nie znalazłem jeszcze sposobu, który byłby całkowicie niezawodny w wykrywaniu, że przesyłany plik jest odpowiedniego typu.
Oznacza to, że nadal istnieje szansa, że można przesłać nieprawidłowy typ pliku. To, czy jest to złośliwe, zależy oczywiście od użytkownika końcowego. Dzielę się tym, aby było jasne, że kod, który zamierzam pokazać, jest tak dobry, jak mogę zapewnić, ale nadal istnieje pewien poziom dyskrecji, którego powinieneś używać.
Być może warto nawet poszukać biblioteki innej firmy do walidacji danych binarnych po ich otrzymaniu. Ale robię dygresję.
1 Sprawdź uprawnienia użytkownika
Pamiętaj, że za każdym razem, gdy tworzymy front-end, WordPress generuje jednorazowy, abyśmy mogli to wykorzystać, aby upewnić się, że użytkownik ma uprawnienia do przesłania pliku.
Oprócz sprawdzania wartości jednorazowych jest kilka innych rzeczy, które chciałbym sprawdzić, z których wszystkie są zawarte w metodzie o nazwie userCanSave.
Najpierw przypomnij sobie front-end:
<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>
Następnie spójrz, jak go używam w kodzie. Najpierw definiuję funkcję 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);
}
A potem po prostu nazywam to na początku procesu. Jeśli się nie powiedzie, to wracam.
<?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...
}
Zalecam pokazywanie komunikatu o błędzie, ale dygresję w tej kwestii, ponieważ istnieje kilka sposobów na zrobienie tego w poście.
2 Prześlij plik
Zakładając, że użytkownik ma uprawnienia do sprawdzenia pliku, można bezpiecznie przesłać plik. Proces jest prosty, ale nadal wymaga trochę pracy z API WordPress (a mianowicie z funkcją wp_upload_bits ).
Najpierw plik musi zostać pobrany z globalnego $_FILES PHP, a następnie przesłany. Jednak robiąc to, ważne jest, aby upewnić się, że przesyłasz plik z poprawnym rozszerzeniem pliku (przynajmniej).
<?php
$file_type = explode('.', $filename);
$file_type = strtolower($file_type[count($file_type) - 1]);
if ('pdf' !== $file_type) {
// Give your feedback of choice here.
}
Jeśli typ pliku nie jest plikiem PDF, możesz zgłosić błąd, po prostu wrócić (chociaż nie jestem tego fanem) lub przekazać opinię użytkownika (co jestem fanem).
<?php
if ($uploadFile['error']) {
// Your preferred method of feedback here.
}
Ostatnim krokiem jest jednak umieszczenie pliku w programie do przesyłania multimediów.
3 Ładowanie do programu do przesyłania multimediów
Ostatnim krokiem w tym wszystkim jest umieszczenie pliku w programie do przesyłania multimediów. Aby to zrobić, potrzebujesz kilku rzeczy z rdzenia WordPress:
- biblioteka plik.php,
- tablica załączników niezbędna do poinformowania WordPressa, co jest dodawane,
- funkcja API WordPress, wp_insert_attachment
- przekierowanie z powrotem do strony dzwoniącej
Brzmi jak dużo, prawda? Nie jest aż tak źle.
Zwykle grupuję włączenie biblioteki plików WordPress i wp_insert_attachment w jeden blok.
Zauważysz, że ustawiam typ MIME na pdf i upewniam się, że tytuł nie zawiera niczego poza nazwą pliku. Następnie używam wp_insert_attachment, aby załadować plik do Biblioteki multimediów.
Pełny kod tego jest następujący:
<?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']);
Następnie przekierowuję z powrotem do strony, która to wszystko zaczęła (jest to zwykle strona administratora, którą widzieliśmy w poprzednim poście. W tym celu pobieram _wp_http_referer z tablicy $_REQUEST PHP .
<?php
wp_safe_redirect(
$_REQUEST['_wp_http_referer'],
301
);
exit;
A to przekieruje użytkownika z powrotem na stronę, z której przybył.
A plik jest przesłany
W tym momencie określiliśmy, co chcemy zrobić:
- Zapewnij przyzwoite wrażenia po stronie klienta,
- Przesłano plik do biblioteki multimediów (z możliwością wyrażenia opinii)
- I przekierowany z powrotem na stronę, od której wszystko się zaczęło.
To prawda, jest w tym dużo miejsca na opinie i zachęcam do dostosowania tego do swojego kodu, ale podstawa tego, czego potrzebujesz, powinna być podana zarówno w poprzednim poście, jak i w tym poście.