1

I have developed a plugin to insert posts using cron jobs. I am creating post thumbnails using this function:

function Generate_Featured_Image( $image_url, $post_id  ){
    $upload_dir = wp_upload_dir();
    $image_data = file_get_contents($image_url);
    $filename   = basename($image_url);

    if(wp_mkdir_p($upload_dir['path']))
        $file = $upload_dir['path'] . '/' . $filename;
    else
        $file = $upload_dir['basedir'] . '/' . $filename;

    file_put_contents($file, $image_data);

    $wp_filetype = wp_check_filetype($filename, null );
    $attachment = array(
        'post_mime_type' => $wp_filetype['type'],
        'post_title' => sanitize_file_name($filename),
        'post_content' => '',
        'post_status' => 'inherit'
    );

    $attach_id = wp_insert_attachment( $attachment, $file, $post_id );
    require_once(ABSPATH . 'wp-admin/includes/image.php');
    $attach_data = wp_generate_attachment_metadata( $attach_id, $file );
    $res1 = wp_update_attachment_metadata( $attach_id, $attach_data );
    $res2 = set_post_thumbnail( $post_id, $attach_id );
}

How can I check if the image is already inside my media library and if so, how can I save a copy inside the uploads folder and attach it to the post?

1 Answer 1

1

Look, as far I understood, the thing you are asking can be done primarily two ways-

First is to go through the uploads directory recursively and search for the file with filename and type. If the file is found then copy it form there and then no need to download it. But it's very costly regarding the resource and power it'll use. Of course you can implement it, but the solution is kinda long to answer here at this field. The main idea for the recursive searching is, there are libraries for PHP by which you can list the files of a directory recursively and check if your file is there or not.

Second is the WP way, which will not be that helpful for your condition I think. It'll just check if the image is registered in the DB or not. The function code is here-

/**
 * If the image file is there.
 *
 * @param string $img The image name with extension after dot.
 *
 * @return bool|int
 */
function codemascot_if_the_image_is_there( $img ) {
    global $wpdb;
    $img = '%/' . $img;
    $sql = $wpdb->prepare(
        "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attached_file' AND meta_value = %s",
        $img
    );
    return $wpdb->get_var( $sql ) !== null ? $wpdb->get_var( $sql ) : false;
}

Use this function like codemascot_if_the_image_is_there('test.jpg'). It'll give you a post ID or false based on the query it runs. For your case pass the $filename as the parameter. If the file is inside you'll get an integer otherwise false. If you get an integer then I prefer no need to copy. You can directly attach it to a post. This will save you some space in your server.

Hope this above answer helps.

NB: I haven't tested the function code. Please test it before putting it to production. Better give a feedback here at comments.

2
  • Thanks for the answer, and it is very interesting that the wordpress function, could you help me to understand by modifying the function I use since it also adds the image to the post? Thanks for your help Sep 4, 2018 at 14:37
  • I think it needs curly braces around the table name in the select statement {$wpdb->postmeta} Jun 13, 2019 at 11:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.