Я сохраняю изображение для загрузки папки, но я использую file_put_contents вместо wp_handle_upload – потому что я получаю изображение в base64, а не как файл в $ _FILES.
Изображение и определенные данные сообщения сохраняются / обновляются, поскольку они должны использовать следующие функции:
Проблема в том, когда я хочу удалить старое изображение (при сохранении нового).
wp_delete_attachment не удаляет изображение (он, кажется, удаляет материал в db, хотя ..). Я думаю, проблема заключается не в использовании wp_handle_upload. (когда я загружаю изображение через upload btn и получаю его с помощью $ _FILES, а затем загружаю его с помощью wp_handle_upload – удаляет работы)
Кто-нибудь имеет представление о том, что может быть правильным способом удалить изображение в моем случае? Возможно, я могу сохранить его правильно, используя wp_handle_upload, даже если у меня есть изображение в base64?
Спасибо за любую информацию.
EDIT: Я также попытался сохранить изображение с помощью wp_upload_bits, а wp_delete_attachment все еще не работает.
Еще одна вещь, которую я проверил: код функции wp_handle_upload, расположенный в wp-admin/includes/file.php
: я не вижу простого способа изменить или скопировать существующую функцию и добавить пользовательский, который будет принимать изображение base64 вместо файл как в $ _FILES. Возможно, у кого-то есть «base64 to $ _FILES»?
как сказал @KamilP, WP вставляет записи в wp_posts
и wp_postmeta
.
Поэтому сначала вам нужно сохранить изображения base64 во временном каталоге, а затем, используя относительный путь и другие данные, вы можете вставить запись в базу данных с помощью wp_insert_attachment
, ссылка содержит соответствующий пример. Эта функция добавит изображение в медиатеку.
Чтобы создать больше миниатюр, вы можете использовать функцию wp_generate_attachment_metadata
. Эта функция также обновит таблицу wp_postmeta со всеми подробностями изображения и эскизов.
После этого вы можете использовать функцию wp_delete_attachment
для удаления изображения из каталога и базы данных.
wp_handle_upload
Структура массива $ _FILES выглядит так:
array(5) { 'name' => string(8) "file name.extension" // file name with extension 'type' => string(0) "" // mime type of file, ie image/png 'tmp_name' => string(0) "" // absolute path of file on disk. 'error' => int(2) // 0 for no error 'size' => int(0) // size in bytes }
Вы можете создать массив, как указано выше, со всеми подробностями, использовать различные функции PHP для обработки файлов, чтобы получить размер и тип mime. Имя – это то, что вы хотите поместить, а tmp_name – это путь к файлу на сервере, где существует файл, в вашем случае местоположение папки, в которой вы сохраняете свой файл из строки base64.
См. Обновленную ссылку выше для функции, которая даст вам изображение из строки base64.
Я на самом деле сделал это, прежде чем увидел ответ здесь, поэтому я предлагаю решение здесь, если кто-то сталкивается с той же проблемой. Я использовал функцию ниже (первая), а также используя wp_delete_attachment после того, как все было удалено.
/** * Attempt at removing all images in uploads folder by providing an image url * Example: * - Provide http://img.ruphp.com/image/testImage.jpg * - this should remove all its images created when uploading: * - testImage-150x150.jpg, testImage-300x300.jpg etc and also the provided original image * * We'r doing this because wp_delete_attachment() will not remove an image that was uploaded via a * custom mytheme_upload_image() function (which is providing base64 image instead of file in $_FILES) * * TODO TODO mytheme_get_image_sizes() does not return ALL IMAGES THAT WERE CREATED (all sizes) */ function mytheme_remove_all_image_sizes_from_uploads($primary_image_url) { $pi = pathinfo($primary_image_url); $img_dirname = $pi['dirname']; $img_dirname_exploded = explode('/',$img_dirname); $last_dir = array_pop($img_dirname_exploded); // month usually (two digits) $second_last_dir = array_pop($img_dirname_exploded); // year usually (4 digits) $basename = $pi['basename']; // without trailing / $img_name = $pi['filename']; $img_extension = $pi['extension']; $uploads = wp_upload_dir(); $base_uploads_dir = $uploads['basedir']; // without trailing / $path_to_appropriate_uploads_dir = $base_uploads_dir.'/'.$second_last_dir.'/'.$last_dir.'/'; $img_name_to_remove = $img_name.'.'.$img_extension; // UNLINK if(!@unlink($path_to_appropriate_uploads_dir.$img_name_to_remove)) { // this image was not removed } $image_sizes = mytheme_get_image_sizes(); foreach($image_sizes as $size) { $img_name_to_remove = $img_name.'-'.$size.'.'.$img_extension; // UNLINK $img_path = $path_to_appropriate_uploads_dir.$img_name_to_remove; if(mytheme_image_on_url_exists($img_path) && !@unlink($img_path)) { // this image was not removed } } } /** * Get size information for all currently-registered image sizes. * Found an example of this on one of the wordpress' example pages .. * * @global $_wp_additional_image_sizes * @uses get_intermediate_image_sizes() * @return array $sizes Data for all currently-registered image sizes. * TODO TODO mytheme_get_image_sizes() does not return ALL IMAGES THAT WERE CREATED (all sizes) */ function mytheme_get_image_sizes() { global $_wp_additional_image_sizes; $sizes = array(); foreach ( get_intermediate_image_sizes() as $_size ) { if ( in_array( $_size, array( 'thumbnail', 'medium', 'large' ) ) ) { $width = get_option( "{$_size}_size_w" ); $height = get_option( "{$_size}_size_h" ); } elseif ( isset( $_wp_additional_image_sizes[ $_size ] ) ) { $width = $_wp_additional_image_sizes[ $_size ]['width']; $height = $_wp_additional_image_sizes[ $_size ]['height']; } $img_name_end = $width."x".$height; if(!in_array($img_name_end,$sizes)) { $sizes[] = $img_name_end; } } // ADD CUSTOM SIZES (this one is not returned otherwise?!) $sizes[] = '300x200'; return $sizes; }
Простое решение, вероятно, просто добавит мета-значение _wp_attached_file
к вашему вложению.
Установите его в файл, который вы хотите удалить, когда вложение будет удалено.
Логика этого в соответствии с https://core.trac.wordpress.org/browser/tags/4.4/src/wp-includes/post.php#L0 :
get_attached_file
возвращает это значение в wp_delete_attachment
которое устанавливает его как $file
И в конце wp_delete_attachment
он вызывает wp_delete_file($file)
Поэтому я предполагаю, что основная проблема заключается в том, что вы никогда не устанавливаете значение мета-ключа _wp_attached_file
.
Единственным недостатком является то, что я не уверен, что другие процессы в wp могут использовать это значение. Но вам может повезти, возможно, нет, и / или это ничего не испортит, установив его вручную.