Удалите изображение, которое не было помещено в папку uploads через wp_handle_upload
Я сохраняю изображение для загрузки папки, но вместо wp_handle_upload - потому что я получаю изображение в base64, а не как файл в $_FILES.
Изображение и определенные данные сообщения сохраняются/обновляются, поскольку они должны использовать эти функции:
- wp_insert_attachment
- wp_update_attachment_metadatali >
Проблема заключается в том, когда я хочу удалить старое изображение (при сохранении нового).
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"?
Ответы
Ответ 1
как сказал @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, i.e. 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.
Ответ 2
Я действительно сделал это, прежде чем увидел ответ здесь, поэтому я предлагаю решение здесь, если кто-то сталкивается с той же проблемой. Я использовал функцию ниже (первая), а также используя wp_delete_attachment после, чтобы убедиться, что все материалы были удалены.
/**
* Attempt at removing all images in uploads folder by providing an image url
* Example:
* - Provide http://mypage.com/wp-content/themes/mytheme/uploads/2015/12/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([email protected]($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) && [email protected]($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;
}
Ответ 3
Простое решение, возможно, просто добавит метатеку _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 могут использовать это значение. Но вам может повезти, возможно, нет, и/или это ничего не испортит, установив его вручную.