Welcome to EasyCodingWithAI!

Before you dive into coding with AI, take a moment to consider some valuable insights. Our articles cover the pros and cons of using AI in development, the importance of having a development environment, and how AI empowers hobbyists and small businesses:

Post Icon

Tutorial : WordPress – Unused Image Finder

Posted by Richard Robins on October 29, 2024 - Last modified on October 30, 2024.

Overview

The EasyCodingWithAI -Unused Image Finder plugin checks which images are used in posts, widgets, custom fields, and featured images. It filters unused images in the media manager for easy management.

Example Prompt.

Help me create a WordPress plugin that identifies and displays unused images in the media library. The plugin should check which images are used in posts, widgets, custom fields, and featured images, and provide an option to filter and delete unused images. Additionally, it should display the unused images in a grid format with their thumbnails and titles.

Features

  • Check which images are currently in use.
  • Filter and display unused images in the media library.
  • Bulk delete unused images.

Getting Started

To create the EasyCodingWithAI – Unused Image Finder plugin, follow the steps below:

1. Create the Plugin Folder

Create a new folder in the wp-content/plugins directory and name it easycoding-image-usage.

2. Create the Main Plugin File

Inside the plugin folder, create a file named easycoding-image-usage.php and add the following code:

<?php
/*
Plugin Name: EasyCodingWithAI - Unused Image Finder
Description: Check which images are used in posts, widgets, custom fields, featured images, and which are not. Filter unused images in the media manager.
Version: 1.3
Author: Your Name
*/

if (!defined('ABSPATH')) {
exit; // Exit if accessed directly.
}

class easycoding_Image_Usage {
public function __construct() {
add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts'));
add_action('wp_ajax_get_unused_images', array($this, 'get_unused_images'));

// Media Library Integration
add_action('restrict_manage_posts', array($this, 'add_unused_images_filter'));
add_action('pre_get_posts', array($this, 'filter_media_by_unused_images'));

// Media Actions
add_filter('media_row_actions', array($this, 'add_media_action'), 10, 2);

// Bulk Actions
add_action('bulk_actions-upload', array($this, 'register_bulk_action_unused_images'));
add_filter('handle_bulk_actions-upload', array($this, 'handle_bulk_action_unused_images'), 10, 3);
}

public function enqueue_scripts($hook) {
// Enqueue scripts for the Media Library and other parts of admin
wp_enqueue_style('easycoding-image-usage-css', plugins_url('css/easycoding-image-usage.css', __FILE__));
wp_enqueue_script('easycoding-image-usage-js', plugins_url('js/easycoding-image-usage.js', __FILE__), array('jquery'), null, true);
wp_localize_script('easycoding-image-usage-js', 'EasyCodingWithAIImageUsage', array('ajaxurl' => admin_url('admin-ajax.php')));
}

public function get_unused_images() {
$used_images = $this->get_all_used_images();

// Get all attachments
$attachments = get_posts(array(
'post_type' => 'attachment',
'post_status' => 'inherit',
'posts_per_page' => -1,
));

// Identify unused images
$unused_images = array();
foreach ($attachments as $attachment) {
if (!in_array($attachment->ID, $used_images)) {
$unused_images[] = array(
'id' => $attachment->ID,
'url' => wp_get_attachment_url($attachment->ID),
'title' => $attachment->post_title
);
}
}

wp_send_json($unused_images);
}

public function add_media_action($actions, $post) {
if (strpos($post->post_mime_type, 'image') !== false) {
$actions['check_image_usage'] = '<a href="' . admin_url('admin.php?page=easycoding-image-usage&image_id=' . $post->ID) . '">Check Usage</a>';
}
return $actions;
}

public function add_unused_images_filter() {
$screen = get_current_screen();
if ($screen->post_type !== 'attachment') return;

$selected = isset($_GET['unused_images']) ? $_GET['unused_images'] : 0;
echo '<select name="unused_images">
<option value="0">All Images</option>
<option value="1" ' . selected($selected, '1', false) . '>Unused Images</option>
</select>';
}

public function filter_media_by_unused_images($query) {
if (!is_admin() || !$query->is_main_query() || $query->get('post_type') !== 'attachment') {
return;
}

if (isset($_GET['unused_images']) && $_GET['unused_images'] == '1') {
$used_images = $this->get_all_used_images();
if (!empty($used_images)) {
$query->set('post__not_in', $used_images);
}
}
}

public function register_bulk_action_unused_images($bulk_actions) {
$bulk_actions['delete_unused_images'] = 'Delete Unused Images';
return $bulk_actions;
}

public function handle_bulk_action_unused_images($redirect_to, $doaction, $post_ids) {
if ($doaction !== 'delete_unused_images') return $redirect_to;

foreach ($post_ids as $post_id) {
wp_delete_attachment($post_id);
}

$redirect_to = add_query_arg('bulk_deleted_images', count($post_ids), $redirect_to);
return $redirect_to;
}

private function get_all_used_images() {
$used_images = array_merge(
$this->get_used_image_ids(), // From post content
$this->get_used_images_in_widgets(), // From widgets
$this->get_used_images_in_custom_fields(), // From custom fields
$this->get_featured_image_ids() // From featured images
);

return array_unique($used_images);
}

private function get_used_image_ids() {
global $wpdb;
$used_images = array();

$posts = $wpdb->get_results("SELECT post_content FROM $wpdb->posts WHERE post_status = 'publish'");
foreach ($posts as $post) {
preg_match_all('/wp-image-([0-9]+)/', $post->post_content, $matches);
if (!empty($matches[1])) {
$used_images = array_merge($used_images, $matches[1]);
}
}
return array_unique($used_images);
}

private function get_used_images_in_widgets() {
$used_images = array();
$sidebars = get_option('sidebars_widgets');
foreach ($sidebars as $widgets) {
if (is_array($widgets)) {
foreach ($widgets as $widget) {
$widget_data = get_option('widget_' . $widget);
if (is_array($widget_data)) {
foreach ($widget_data as $data) {
if (isset($data['text'])) {
preg_match_all('/wp-image-([0-9]+)/', $data['text'], $matches);
if (!empty($matches[1])) {
$used_images = array_merge($used_images, $matches[1]);
}
}
}
}
}
}
}
return array_unique($used_images);
}

private function get_used_images_in_custom_fields() {
global $wpdb;
$used_images = array();

$meta_values = $wpdb->get_results("SELECT meta_value FROM $wpdb->postmeta");
foreach ($meta_values as $meta) {
preg_match_all('/wp-image-([0-9]+)/', $meta->meta_value, $matches);
if (!empty($matches[1])) {
$used_images = array_merge($used_images, $matches[1]);
}
}
return array_unique($used_images);
}

private function get_featured_image_ids() {
global $wpdb;
$featured_image_ids = $wpdb->get_col("
SELECT meta_value
FROM $wpdb->postmeta
WHERE meta_key = '_thumbnail_id'
");
return array_unique($featured_image_ids);
}
}

new easycoding_Image_Usage();

3. Create the CSS File

Create a directory named css inside the plugin folder and create a file named easycoding-image-usage.css. Add the following CSS code:

.image-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 20px;
margin-top: 20px;
}

.image-grid-item {
border: 1px solid #ccc;
padding: 10px;
text-align: center;
background-color: #f9f9f9;
border-radius: 4px;
}

.image-grid-item img {
max-width: 100%;
height: auto;
display: block;
margin-bottom: 10px;
}

.image-grid-item h4 {
font-size: 14px;
margin: 0;
word-break: break-word;
}

4. Create the JavaScript File

Create a directory named js inside the plugin folder and create a file named easycoding-image-usage.js. Add the following JavaScript code:

jQuery(document).ready(function($) {
$.post(EasyCodingWithAIImageUsage.ajaxurl, { action: 'get_unused_images' }, function(response) {
console.log(response); // Debugging output

if (response.length > 0) {
var gridContent = '<div class="image-grid">';
$.each(response, function(index, image) {
console.log(image.url); // Check the image URLs
gridContent += '<div class="image-grid-item">';
gridContent += '<img src="' + image.url + '" alt="' + image.title + '" style="max-width: 100px; height: auto;">';
gridContent += '<h4>' + image.title + '</h4>';
gridContent += '<a href="' + image.url + '" target="_blank">View Full Size</a>';
gridContent += '</div>';
});
gridContent += '</div>';
$('#unused-images').html(gridContent);
} else {
$('#unused-images').html('<p>All images are in use.</p>');
}
$('#loading-message').hide(); // Hide loading message after images are loaded
}).fail(function() {
$('#unused-images').html('<p>An error occurred while fetching the data.</p>');
$('#loading-message').hide(); // Hide loading message in case of an error
});
});

5. Testing the Plugin

  1. Activate the EasyCodingWithAI – Image Usage plugin from the WordPress admin dashboard.
  2. Navigate to the media library to see the new functionality.

Richard Robins

Richard Robins

Richard is passionate about sharing how AI resources such as ChatGPT and Microsoft Copilot can be used to create addons and write code, saving small website owners time and money, freeing them to focus on making their site a success.


Disclaimer

The coding tips and guides provided on this website are intended for informational and educational purposes only. While we strive to offer accurate and helpful content, these tips are meant as a starting point for your own coding projects and should not be considered professional advice.

We do not guarantee the effectiveness, security, or safety of any code or techniques discussed on this site. Implementing these tips is done at your own risk, and we encourage you to thoroughly test and evaluate any code before deploying it on your own website or application.

By using this site, you acknowledge that we are not responsible for any issues, damages, or losses that may arise from your use of the information provided herein.