Удалите изображение, которое не было помещено в папку uploads через wp_handle_upload

Я сохраняю изображение для загрузки папки, но я использую file_put_contents вместо wp_handle_upload – потому что я получаю изображение в base64, а не как файл в $ _FILES.

Изображение и определенные данные сообщения сохраняются / обновляются, поскольку они должны использовать следующие функции:

  • wp_insert_attachment
  • wp_update_attachment_metadata

Проблема в том, когда я хочу удалить старое изображение (при сохранении нового).

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 для удаления изображения из каталога и базы данных.

Другое решение:

  • Используйте функцию из этой ссылки для генерации изображения из строки base64.
  • затем введите тип, размер и путь изображения mime
  • создайте массив, похожий на $ _FILES.
  • затем передайте его на 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 могут использовать это значение. Но вам может повезти, возможно, нет, и / или это ничего не испортит, установив его вручную.