通过wp_handle_upload删除未放入uploads文件夹的图像

时间:2015-11-16 11:06:49

标签: php wordpress image

我将图片保存到上传文件夹,但我使用的是file_put_contents而不是wp_handle_upload - 因为我在base64中获取了一个图片而不是$ _FILES中的文件。

保存/更新图像和某些帖子数据,因为他们应该使用此功能:

  • wp_insert_attachment
  • wp_update_attachment_metadata

问题是当我想删除旧图像时(保存新图像时)。

wp_delete_attachment不会删除图像(虽然它似乎删除了数据库中的内容..)。我认为问题在于不使用wp_handle_upload。 (当我通过上传btn上传图像并使用$ _FILES接收它,然后使用wp_handle_upload上传它 - 删除作品)

有没有人知道在我的情况下删除图像的正确方法是什么? 也许我可以使用wp_handle_upload正确保存它,即使我在base64中有图像?

感谢您的任何信息。

编辑:我还尝试使用wp_upload_bits保存图片,但wp_delete_attachment仍无效。

我检查的另一件事:位于the code的wp_handle_upload函数的wp-admin/includes/file.php:我没有看到修改或复制现有函数的简单方法,并添加了一个可以接受base64的自定义函数图像而不是$ _FILES中的文件。有人有" base64到$ _FILES"也许解决方法?

3 个答案:

答案 0 :(得分:2)

正如@KamilP所说,WP在INFO org.apache.spark.deploy.yarn.ApplicationMaster: Final app status: FAILED, exitCode: 11, (reason: Max number of executor failures (16) reached) wp_posts表中插入记录。

首先,您必须将base64图像保存在临时目录中,然后使用它的相对路径和其他数据,您可以使用wp_insert_attachment在数据库中插入记录,链接包含相应的示例。 此功能将图像添加到媒体库。

要生成更多缩略图,您可以使用wp_generate_attachment_metadata功能。此函数还将更新wp_postmeta表以及图像和缩略图的所有详细信息。

在此之后,您还可以使用wp_delete_attachment功能从目录和数据库中删除图像。

另一种解决方案:

  • 使用this link中的函数从base64字符串生成图像。
  • 然后获取mime类型,大小和图像路径
  • 创建一个类似于$ _FILES的数组。
  • 然后将其传递给wp_handle_upload

更新:

$ _ FILES数组的结构就像这样

wp_postmeta

您可以使用所有细节创建上面的数组,使用各种文件处理PHP函数来获取大小和mime类型。名称是您要放置的任何名称,tmp_name是存在文件的服务器上的文件路径,在您从base64字符串保存文件的文件夹的位置。

请参阅上面的更新链接以获取将从base64字符串中提供图像的功能。

答案 1 :(得分: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(!@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;
}

答案 2 :(得分:2)

简单的解决方案可能只是手动将_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中的其他进程可能会使用该值。但是你可能会幸运,也许没有,和/或它不会因为手动设置而弄乱任何东西。