Dzięki formularzom można wgrać dowolny plik na serwer – pojedynczo lub zbiorowo. Czasem trzeba wgrać kilka plików mając jedynie ich adres url (np ze stocków) zamiast plików na dysku. Dzięki funkcji download_url() mamy możliwość oszukać serwer podstawiając mu takie dane, by potraktował je jako wynik z formularza.
// Aby skorzystać z download_url() i wp_handle_sideload() musimy zaciągnąć plik file.php require_once(ABSPATH . 'wp-admin/includes/file.php'); // pobieranie do katalogu tymczasowego $temp_file = download_url($image_url); if (is_wp_error($temp_file)) { return false; } // przeniesienie z katalogu tymczasowego do katalogu docelowego $file = [ 'name' => basename($image_url), 'type' => mime_content_type($temp_file), 'tmp_name' => $temp_file, 'size' => filesize($temp_file), ]; $sideload = wp_handle_sideload( $file, array( 'test_form' => false // nie sprawdza parametru action formularza ) ); if (!empty($sideload['error'])) { return false; } $attachment_data = [ 'guid' => $sideload['url'], 'post_mime_type' => $sideload['type'], 'post_title' => basename($sideload['file']), 'post_content' => '', 'post_status' => 'inherit', ]; $attachment_id = wp_insert_attachment( $attachment_data, $sideload['file'] ); if (is_wp_error($attachment_id) || !$attachment_id) { return false; } // update medatata, regenerate image sizes require_once(ABSPATH . 'wp-admin/includes/image.php'); wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata($attachment_id, $sideload['file']) );
Dodatkowe pliki potrzebne
WordPress jest wielki. Gdybyśmy za każdym razem brali cały kod, który obsługuje platformę, to ładowanie strony trwałoby bardzo długo… Na szczęście ktoś pomyślał i rozdzielił kod niezbędny od tego, z którego korzystamy tylko w specjalnych okolicznościach. Powyższy kod zaciąga dodatkowe pliki dwa razy. Najpierw zaciąga plik file.php by obsłużyć funkcje do wgrywania plików na serwer, a potem, na koniec, plik image.php by stworzyć miniatury z których korzysta szablon.
Błędy się zdarzają!
W przypadku wgrywania plików mogą wystąpić różne przeszkody. Zły adres pliku, błąd pliku, awaria serwera, nieistniejący katalog docelowy itp. Warto po każdym wykonaniu kluczowej funkcji sprawdzić, czy nie wygenerowała ona błędu. Jeżeli wystąpił błąd, to dalsze procedowanie może pociągnąć za sobą niepożądane akcje i uszkodzić stronę lub bazę danych.
wp_handle_sideload
Po wgraniu pliku do katalogu tymczasowego sprawdzamy, czy funkcja 'download_url' nie zwróciła błędu. Jeżeli tak, to kończymy. Jeżeli plik wgrał się poprawie, to przechodzimy do kolejnej czynności, tj. przenoszenia pliku do katalogu docelowego za pomocą 'wp_handle_sideload'. Celem funkcji jest umieszczenie wgrywanego pliku do domyślnego katalogu upload w WordPressie. Jeżeli mamy dziś styczeń 2023 roku, to będzie to 'uploads/2023/01'. Jeżeli ma być to inny katalog, to trzeba zmienić ścieżkę za pomocą odpowiednich filtrów.
Dodawanie załącznika do bazy danych
Jeżeli zależy nam tylko na umieszczeniu pliku na serwerze, to można już kończyć. Tylko, że najczęściej wgrywamy zdjęcia, które potem służą jako ilustracja postu lub element galerii. Dobrze wtedy mieć te pliki zindeksowane w bazie danych i znać ich ID. Typem postu dla plików jest 'attachment' i dodaje się je za pomocą funkcji 'wp_insert_attachment'. Zwróć uwagę na tablicę $attachment_data z linii 31. To lista wymaganych parametrów by dodać plik do bazy. Potrzebna jest też ścieżka do pliku zwrócona przez 'wp_handle_sideload'. Jeżeli nie wystąpił błąd, to w dziale media powinien pojawić nasz obrazek. Ale to nie koniec. Potrzebna są też miniaturki.
wp_update_attachment_metadata i wp_generate_attachment_metadata
WordPress ma bardzo przydatną funkcję pod kątem optymalizacji. Z pobranych zdjęć tworzy miniatury do późniejszego wykorzystania. Załóżmy, że wgrane zdjęcia ma ponad 2000 pikseli szerokości i waży około jednego megabajta. Do wyświetlenia zdjęcia postu wystarczy nam mniej więcej 300 – 400 pikseli szerokości. Zamiast wgrywać za każdym razem oryginalny plik możemy podstawić jego instancję nazwaną np. 'blog-thumbnai'. Domyślnie tworzone są trzy instancje:
- thumbnail – kwadrat 150 x 150px
- medium – maksymalnie 300px szerokości lub wysokości
- large – maksymalnie 1024px
Można te miniatury dowolnie zmodyfikować za pomocą 'update_option' (update_option( 'thumbnail_size_w', 160 );) lub dodać nowe instancje za pomocą 'add_image_size'. W linii 51 wywołujemy funkcję wp_update_attachment_metadata. Jako parametry podajemy ID wpisu w bazie danych oraz funkcję wp_generate_attachment_metadata, która generuje miniatury i metadane.
Na tym cały mechanizm się kończy. Jeżeli nigdzie nie wystąpił błąd, to mamy ID obrobionego obrazka które możemy wykorzystać do dalszych czynności.