Conditional Image Sizes for Use via Theme Customizer Upload Only

I’m looking for a way to add image sizes that are only generated by uploads happening in the Theme Customizer, any suggestions or direction on how this could be done?

I’ve already worked with the intermediate_image_sizes_advanced filter, which gives me the images I want, the problem is that they don’t appear in the media library so they can’t be deleted by the user. This is for a Multisite network so I don’t want to create an infinite accumulation of images that the users can’t access for cleanup, and create a situation where the sysadmin has no way of knowing which images should be deleted and are not in use.

Read More

Here is the current code, which does not work simply because the intermediate_image_sizes_advanced filter does not hook these new sizes the same way that add_image_size() does, and so they become “orphaned” as I mentioned above.

add_filter('intermediate_image_sizes_advanced','responsive_customizer_bg_images');
function responsive_customizer_bg_images( $image_sizes ){

    // quit if the theme is not pure - only PURE gets responsive images, add new themes with responsive images  here
    if ( ! isset( $_POST['post_data'] ) ) {
        return false;
    } else {
        if ( $_POST['post_data']['theme'] != 'pure' )
            return false;
    }

    $sizes = array(
            '1024' => array(
                    'width' => 1024,
                    'height' => 768,
                    'crop' => true,
                ),
            '1680' => array(
                    'width' => 1680,
                    'height' => 1050,
                    'crop' => true,
                ),
            '2560' => array(
                    'width' => 2560,
                    'height' => 1440,
                    'crop' => true,
                ),
        );

    $image_sizes = [];
    $custom_sizes = [];
    foreach ($sizes as $key => $value) {
        $image_sizes[ 'artsite-bg-' . $value['width'] . 'x' .$value['height'] ] = array(
                'width' => $value['width'],
                'height' => $value['height'],
                'crop' => $value['crop']
            );
        $custom_sizes[] = array(
                'artsite-bg-' . $value['width'] . 'x' .$value['height'] => __('Background ' . $value['width'] . 'x' .$value['height'] )
            );
    }

    return $image_sizes;
}

EDIT – for what it’s worth, this question solves a similar problem, however the OP is not trying to spy on $_POST like I am to determine whether the incoming upload is from the Customizer or not:
Add custom image sizes to media uploader

EDIT 2 – Here’s a fun version that creates an infinite loop where each responsive image gets inserted as an attachment at the end, in turn causing the function to trigger itself and create an infinite loop. Is there a different hook I could grab that would avoid the self-invoking loop?

add_filter('add_attachment','generate_responsive_sizes');

function generate_responsive_sizes( $attachment_id ) {

    $image_post_data = get_post( $attachment_id );

    error_log(print_r($image_post_data,true));

    // quit if the post_type is not attachment and mime_type is not jpeg/jpg/gif
    if ( $image_post_data->post_type != 'attachment' || $image_post_data->post_mime_type != ( 'image/jpeg' || 'image/png' || 'image/gif' ) )
        return false;

    // quit if the theme is not pure - only PURE gets responsive images, add new themes with responsive images  here
    if ( ! isset( $_POST['post_data'] ) ) {
        return false;
    } else {
        if ( $_POST['post_data']['theme'] != 'pure' )
            return false;
    }

    $upload_dir = wp_upload_dir();
    $file = substr( strrchr( $image_post_data->guid, '/' ), 1 );
    $filepath = $upload_dir['path'] . '/' . $file;
    $file_arr = preg_split( '/./', $file );
    $filename = $file_arr[0];
    $file_ext = $file_arr[1];
    error_log(print_r($upload_dir,true));

    $sizes = array(
            '1024' => array(
                    'width' => 1024,
                    'height' => 768,
                    'crop' => true,
                ),
            '1680' => array(
                    'width' => 1680,
                    'height' => 1050,
                    'crop' => true,
                ),
            '2560' => array(
                    'width' => 2560,
                    'height' => 1440,
                    'crop' => true,
                ),
        );

    $new_sizes_generated = [];

    // first create the images
    if ( ! is_wp_error( $image_post_data ) ) {
        foreach ($sizes as $key => $value) {
            $image = wp_get_image_editor( $filepath );
            $new_img_filepath = $upload_dir['path'] . '/' . $filename . '-' . $value['width'] . 'x' . $value['height'] . '.' . $file_ext;

            error_log(print_r($value,true));
            error_log(print_r($image,true));
            error_log(print_r($new_img_filepath,true));
            $dimensions = $image->get_size();
            // if the image new size is not bigger than the original, we will
            // continue and not save a new version of this image
            if ( $dimensions['width'] < $value['width'] && $dimensions['height'] < $value['height'] ) {
                continue;
            }
            $image->resize( $value['width'], $value['height'], $value['crop'] );
            $image->save( $new_img_filepath );
        }
    }

    // now attach them, we do this separately to avoid an infinite loop of files added,
    // which in turn triggers this entire function from start, since it's hooked to
    // `add_attachment`.
    if ( ! is_wp_error( $image_post_data ) ) {
        foreach ($sizes as $key => $value) {

            $new_img_filepath = $upload_dir['path'] . '/' . $filename . '-' . $value['width'] . 'x' . $value['height'] . '.' . $file_ext;

            // Check for existence of an attachment with the same GUID to avoid
            // infinite loop as noted at the opening of the above foreach loop
            global $wpdb;
            $prefix = $wpdb->prefix;
            $attachment = $wpdb->get_col($wpdb->prepare("SELECT ID FROM " . $prefix . "posts" . " WHERE guid='%s';", $new_img_filepath ));

            if ( ! empty( $attachment ) ) {
                error_log(print_r('there already is an attachment for ' . $new_img_filepath, true ));
                return false;
            } else {
                error_log(print_r('there is NO attachment for ' . $new_img_filepath, true ));

                $wp_filetype = wp_check_filetype(basename($new_img_filepath), null );
                error_log(print_r($wp_filetype,true));
                $attachment = array(
                    'guid' => $new_img_filepath,
                    'post_mime_type' => $wp_filetype['type'],
                    'post_title' => preg_replace('/.[^.]+$/', '', basename($new_img_filepath)),
                    'post_content' => '',
                    'post_status' => 'inherit'
                );
                error_log(print_r($attachment,true));

                wp_insert_attachment( $attachment, $new_img_filepath, 37 );

            }

        }
    }
}

Related posts