Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Small WordPress plugin to display and test image meta and creation of missing image sub-sizes
<?php
/**
* Plugin Name: Image Meta Tests (Do not use in production!)
* Description: A small plugin to enable displaying and testing of image attachment meta data. The data is displayed on the Media Library list view screen.
* Version: 0.0.1-private-plugin
* Author: Andrew Ozz
* License: GPLv2 or later
* License URI: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU
* General Public License version 2, as published by the Free Software Foundation. You may NOT assume
* that you can use any other version of the GPL.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
// Add few more sizes to test with.
add_action( 'admin_init', 'test__add_additional_image_sizes' );
function test__add_additional_image_sizes() {
add_image_size( 'test-1600x1600', 1600, 1600 );
add_image_size( 'test-1920x1920', 1920, 1920 );
add_image_size( 'test-2560x2560', 2560, 2560 );
add_image_size( 'test-3840x3840', 3840, 3840 );
// Try to overload it :)
for ( $i = 0; $i < 42; $i++ ) {
$size = 1000 + ( $i * 10 );
$size_name = "test-{$size}x0";
add_image_size( $size_name, $size, 0 );
}
/*
add_image_size( 'test-2560x0', 2560, 0 );
add_image_size( 'test-3840x0', 3840, 0 );
add_image_size( 'test-0x2560', 0, 2560 );
*/
}
// Bump the size restriction on srcset.
add_filter( 'max_srcset_image_width', 'test__bump_restriction_on_srcset_sizes', 100 );
function test__bump_restriction_on_srcset_sizes( $max ) {
return 4000;
}
// Add a link to the Media screen in list table view.
add_filter( 'plugin_action_links', 'test__add_link_to_media_list_view', 10, 2 );
function test__add_link_to_media_list_view( $links, $file ) {
$links = (array) $links;
if ( plugin_basename( __FILE__ ) === $file ) {
$links['test__media_list_link'] = '<a href="' . esc_url( admin_url( 'upload.php?mode=list' ) ) . '">Media Library (list view)</a>';
}
return $links;
}
add_filter( 'manage_upload_columns', 'test__set_attachment_meta_columns' );
function test__set_attachment_meta_columns( $columns ) {
return array_merge( array( 'cb' => 1, 'title' => 1, 'test__meta' => 'Meta' ), $columns );
}
add_action( 'manage_media_custom_column', 'test_add_attachment_meta_html', 10, 2 );
function test_add_attachment_meta_html( $column_name, $attachment_id ) {
static $show_info = true;
static $supported = true;
if ( $column_name !== 'test__meta' || ! $supported ) {
return;
}
$attachment_id = (int) $attachment_id;
if ( wp_attachment_is_image( $attachment_id ) ) {
if ( ! function_exists( 'wp_get_missing_image_subsizes' ) ) {
echo 'The image meta testing plugin requires the patch from <a href="https://core.trac.wordpress.org/ticket/40439">https://core.trac.wordpress.org/ticket/40439</a> in order to work.';
$supported = false;
return;
}
$missing_sizes = array_keys( wp_get_missing_image_subsizes( $attachment_id ) );
$nonce = wp_create_nonce( 'update_image_sizes' . $attachment_id );
$image_meta = wp_get_attachment_metadata( $attachment_id );
// unset( $image_meta['image_meta'] );
if ( isset( $image_meta['sizes'] ) && is_array( $image_meta['sizes'] ) ) {
$sizes = $image_meta['sizes'];
} else {
$sizes = array();
}
?>
<div style="margin: 0 0 1em;">
<button type="button" class="button button-small test__show-image-meta">Image meta</button>
<pre class="test__image-meta hidden"><?php
echo esc_html( print_r( $image_meta, true ) );
?></pre>
</div>
<?php
if ( ! empty( $missing_sizes ) ) {
$existing = array_diff( array_keys( $sizes ), $missing_sizes );
if ( empty( $existing ) ) {
$existing = array( 'None' );
}
?>
<div class="update-image-sizes">
<div style="margin: 1em 0;">
<pre><b>Existing sub-sizes:</b><br><?php echo esc_html( join( "\n", $existing ) ); ?></pre>
</div>
<div class="message" style="margin: 1em 0;">
<pre><b>Missing sub-sizes:</b><br><?php echo esc_html( join( "\n", $missing_sizes ) ); ?></pre>
</div>
<button type="button" class="button button-small wp-update-image-sizes" data-wp-nonce="<?php echo esc_attr( $nonce ); ?>" data-wp-attachment-id="<?php echo $attachment_id; ?>">
Recreate image sub-sizes
</button>
<span class="spinner"></span>
</div>
<?php
} else {
// Add a button to delete couple of sizes for testing
?>
<div>
<p>
<?php
if ( $show_info ) {
echo 'To test: Select few image sub-sizes and delete them. Then reload the page and recreate them.';
$show_info = false;
}
?>
</p>
<?php
if ( ! empty( $sizes ) ) {
foreach( $sizes as $size_name => $size_data ) {
$id = esc_attr( "{$size_name}-{$attachment_id}" );
?>
<input type="checkbox" id="<?php echo $id; ?>" data-size-name="<?php echo esc_attr( $size_name ); ?>">
<label for="<?php echo $id; ?>" style="vertical-align: bottom;line-height: 1.7;"><?php echo esc_html( $size_name ); ?></label>
<br>
<?php
}
} else {
echo 'Error: no sub-sizes exist for this image in the image meta.';
}
?>
<br>
<button type="button" class="button button-small wp-test-delete-image-sizes" data-wp-nonce="<?php echo esc_attr( $nonce ); ?>" data-wp-attachment-id="<?php echo $attachment_id; ?>">
Delete
</button>
<div class="deleted-message"></div>
</div>
<?php
}
}
}
// Ajax handler for updating or deleting image sub-sizes.
add_action( 'wp_ajax_test__update_image_sizes', 'test__update_image_sizes' );
function test__update_image_sizes() {
if ( empty( $_POST['attachment_id'] ) ) {
wp_send_json_error( 'Missing attachment ID.' );
}
$attachment_id = (int) $_POST['attachment_id'];
if ( ! current_user_can( 'edit_post', $attachment_id ) || ! wp_verify_nonce( $_POST['update_sizes_nonce'], 'update_image_sizes' . $attachment_id ) ) {
wp_send_json_error( 'Invalid request.' );
}
if ( ! function_exists( 'wp_get_missing_image_subsizes' ) ) {
wp_send_json_error( 'This plugin requires the patch from https://core.trac.wordpress.org/ticket/40439 in order to work.' );
}
if ( ! empty( $_POST['test_delete'] ) ) {
$meta = wp_get_attachment_metadata( $attachment_id );
$selected = $_POST['test_delete'];
if ( empty( $meta['sizes'] ) ) {
wp_send_json_error( 'Error: no sub-sizes in the image meta.' );
}
if ( ! is_array( $selected ) ) {
wp_send_json_error( 'Error: no sub-sizes selected.' );
}
$uploadpath = wp_get_upload_dir();
$file = get_attached_file( $attachment_id );
$intermediate_dir = path_join( $uploadpath['basedir'], dirname( $file ) );
$deleted = array();
foreach ( $meta['sizes'] as $size => $sizeinfo ) {
if ( in_array( $size, $selected, true ) ) {
$intermediate_file = str_replace( wp_basename( $file ), $sizeinfo['file'], $file );
if ( ! empty( $intermediate_file ) ) {
$intermediate_file = path_join( $uploadpath['basedir'], $intermediate_file );
if ( wp_delete_file_from_directory( $intermediate_file, $intermediate_dir ) ) {
$deleted[] = "$size ({$sizeinfo['file']})";
unset( $meta['sizes'][ $size ] );
}
}
}
}
if ( empty( $deleted ) ) {
wp_send_json_error( 'Error: no sub-sizes were deleted.' );
}
wp_update_attachment_metadata( $attachment_id, $meta );
$response = strip_tags( join( ',', $deleted ) );
} else {
$image_meta = wp_get_attachment_metadata( $attachment_id );
$new_meta = wp_update_image_subsizes( $attachment_id );
$result = array();
if ( is_array( $image_meta['sizes'] ) && is_array( $new_meta['sizes'] ) ) {
$result = array_diff_key( $new_meta['sizes'], $image_meta['sizes'] );
}
if ( empty( $result ) ) {
wp_send_json_error( 'New image sub-sizes were not created. All sub-sizes already exist.' );
} else {
$response = strip_tags( join( ',', array_keys( $result ) ) );
}
}
wp_send_json_success( $response );
}
add_action( 'admin_footer-upload.php', 'test__add_attachment_meta_test_js' );
function test__add_attachment_meta_test_js() {
?>
<script>
// Handle button clicks to test image sub-sizes.
jQuery( document ).ready( function( $ ) {
$( document ).on( 'click.wp-update-image-sizes', function( event ) {
var $target = $( event.target );
if ( $target.is( 'button.wp-update-image-sizes' ) ) {
var $parent = $target.parent();
var $message = $parent.find( 'div.message' );
var $spinner = $parent.find( 'span.spinner' );
var msgText = '';
$spinner.addClass( 'is-active' );
$.ajax({
type: 'post',
url: window.ajaxurl,
dataType: 'json',
data: {
action: 'test__update_image_sizes',
update_sizes_nonce: $target.attr( 'data-wp-nonce' ),
attachment_id: $target.attr( 'data-wp-attachment-id' )
}
}).always( function() {
$spinner.removeClass( 'is-active' );
}).done( function( response ) {
if ( response.data ) {
if ( ! response.success ) {
$message.text( response.data );
} else {
msgText = response.data.replace( /,/g, '</code>\n<code>' );
$message.html( '<pre><b>Created:</b>\n<code>' + msgText + '</code></pre>' );
}
} else {
$message.text( 'Error: invalid response data. Look in the browser tools for more info.' );
}
}).fail( function() {
$message.text( 'Error: invalid response from the server. Look in the browser tools for more info.' );
});
} else if ( $target.is( 'button.wp-test-delete-image-sizes' ) ) {
var $parent = $target.parent();
var $message = $parent.find( 'div.deleted-message' );
var selected = [];
var msgText = '';
$parent.find( 'input:checked' ).each( function( i, node ) {
selected.push( $( node ).attr( 'data-size-name' ) );
} );
if ( selected.length < 1 ) {
$message.text( 'Please select some sub-sizes to delete.' );
return;
}
$.ajax({
type: 'post',
url: window.ajaxurl,
dataType: 'json',
data: {
action: 'test__update_image_sizes',
update_sizes_nonce: $target.attr( 'data-wp-nonce' ),
attachment_id: $target.attr( 'data-wp-attachment-id' ),
test_delete: selected
}
}).done( function( response ) {
if ( response.data ) {
if ( ! response.success ) {
// Error message.
$message.text( response.data );
} else {
msgText = response.data.replace( /,/g, '</code>\n<code>' );
msgText = '<pre><b>Deleted:</b>\n<code>' + msgText + '</code></pre>';
$message.html( msgText + '<p>Please reload to test.</p>' );
}
$target.hide();
} else {
$message.text( 'Error: invalid response data. Look in the browser tools for more info.' );
}
}).fail( function() {
$message.text( 'Error: invalid response from the server. Look in the browser tools for more info.' );
});
} else if ( $target.is( 'button.test__show-image-meta' ) ) {
$target.parent().find( 'pre' ).toggleClass( 'hidden' );
}
} );
} );
</script>
<?php
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.