Skip to content

Instantly share code, notes, and snippets.

@azaozz
Last active June 20, 2019 13:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save azaozz/91101d686127137b0f5b850f0d269972 to your computer and use it in GitHub Desktop.
Save azaozz/91101d686127137b0f5b850f0d269972 to your computer and use it in GitHub Desktop.
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