Created
May 13, 2024 10:53
-
-
Save woodyhayday/0c1c81803f89944b5ef97b01ce48ac09 to your computer and use it in GitHub Desktop.
WordPress Image ALT generator (fills in empty alt attributes based on image filenames)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Plugin Name: Image alt updater | |
Plugin URI: http://woodyhayday.com | |
Description: Brutal image alt attribute updater - finds images without alt's and does its best (read before using, demo only) | |
Version: 0.1 | |
Author: <a href="http://woodyhayday.com">Woody Hayday</a> | |
*/ | |
#} Exit if accessed directly | |
if ( ! defined( 'ABSPATH' ) ) exit; | |
// Works through attachment images and checks all published | |
// posts to see if each image has an `alt` attribute | |
// ... where they don't it makes one up from filename or post title | |
// Use with caution, and always backup your database before running! | |
function wordPress_alt_image_updater(){ | |
// HAVE YOU BACKED UP YOUR DB? RLY? | |
if ( isset( $_GET['i_swear_i_backed_it_up'] ) ){ | |
// got rights? | |
if (!current_user_can('manage_options')) { wp_die( __('You do not have sufficient permissions to access this page.','projectpages') ); } | |
// get image attachments | |
echo '<h2>Image alt attribute updater</h2>'; | |
$args = array( | |
'post_type' => 'attachment', | |
'post_mime_type' => 'image', | |
'numberposts' => -1 | |
); | |
$attachments = get_posts( $args ); | |
echo 'Found '.count($attachments).' image attachments<br>'; | |
if ( !isset( $_GET['doit'] ) ){ | |
echo 'Add `?doit=1` to your url when you\'re ready, and your database has been backed up.<br>'; | |
} else { | |
// general counts | |
$updated_count = 0; | |
$filled_alt_count = 0; | |
$empty_alt_count = 0; | |
echo '<h2>Processing...</h2>'; | |
global $wpdb; | |
// if you have LOTS of images, put paging in here | |
foreach ( $attachments as $attachment_post ){ | |
$image_url = $attachment_post->guid; | |
echo '<strong>'.$image_url.'</strong><br>'; | |
// get post content of posts with this image | |
$sql_results = $wpdb->get_results( | |
$wpdb->prepare( " | |
SELECT * | |
FROM $wpdb->posts | |
WHERE post_content | |
LIKE %s | |
AND post_status = 'publish' | |
" | |
,'%' . like_escape( $image_url ) . '%' | |
) | |
); | |
// got posts with this image url in? | |
if ( is_array( $sql_results ) && count( $sql_results ) > 0 ){ | |
echo 'Found in '. count( $sql_results ) . ' posts.<br>'; | |
// this is only hitting first instance, doesn't allow for repeat images | |
// you may need to tweak, depending on your image use case | |
foreach ( $sql_results as $post ){ | |
echo '<hr>Post: '.$post->ID.'...<br>'; | |
$alt = ''; | |
// pull the <img> string | |
$img_src_pos = strpos( $post->post_content, 'src="' . $image_url . '"' ); | |
if ( $img_src_pos ){ | |
// working backwards, find <img | |
$img_opening_tag_pos = strrpos( substr( $post->post_content, 0, $img_src_pos ), '<img ' ); | |
if ( $img_opening_tag_pos ){ | |
// get closing tag | |
$img_closing_tag_pos = strpos( substr( $post->post_content, $img_src_pos ), "/>" ) + 2 + $img_src_pos; | |
if ( $img_closing_tag_pos ){ | |
$image_html = substr( $post->post_content, $img_opening_tag_pos, ($img_closing_tag_pos - $img_opening_tag_pos) ); | |
echo 'Got image html...<br>'; | |
//echo '<pre>' . esc_html( $image_html ) . '</pre>'; | |
// check for alt | |
$alt_opening_pos = strpos( $image_html, 'alt="' ) + 5; | |
if ( $alt_opening_pos ){ | |
// get the alt | |
$alt = substr( $image_html, $alt_opening_pos, strpos( substr( $image_html, $alt_opening_pos ), '"' ) ); | |
echo 'Image already has a value for alt..."' . $alt . '"<br>'; | |
} | |
if ( empty( $alt ) ){ | |
$new_alt = ''; | |
$empty_alt_count++; | |
echo 'Found an image with an empty, or no alt...<br><pre>' . esc_html( $image_html ) . '</pre>'; | |
// try and generate a new alt | |
$src_opening_pos = ( strpos( $image_html, 'src="' ) + 5 ); | |
// filename | |
$image_file_url = substr( $image_html, $src_opening_pos, strpos( substr( $image_html, $src_opening_pos ), '"' ) ); | |
// parsed path | |
$path = parse_url($image_file_url, PHP_URL_PATH); | |
$image_file_name = basename($path); | |
$image_file_slug = substr($image_file_name, 0 , (strrpos($image_file_name, "."))); | |
// split by, and remove - + _ + . | |
$image_file_slug = str_replace( '_', ' ', str_replace( '-', ' ', str_replace( '.', ' ', $image_file_slug ) ) ); | |
if ( !empty( $image_file_slug ) ){ | |
$new_alt = ucwords( $image_file_slug ); | |
} | |
// remove any trailing -1 -2 etc. | |
if ( substr( $new_alt, -2 ) == ' 1' ){ $new_alt = substr( $new_alt, 0, strlen( $new_alt ) - 2 ); } | |
if ( substr( $new_alt, -2 ) == ' 2' ){ $new_alt = substr( $new_alt, 0, strlen( $new_alt ) - 2 ); } | |
// (+-) post title | |
/*$post_title = $post->post_title; | |
if ( !empty( $post->post_title ) ){ | |
if ( !empty( $new_alt ) ){ | |
// append break | |
$new_alt .= ' - '; | |
} | |
$new_alt .= $post->post_title; | |
} */ | |
// any last minute proj-specific tweaks: | |
$new_alt = str_replace( 'Cfs ', 'CFS ', $new_alt ); | |
$new_alt = str_replace( 'Me ', 'ME ', $new_alt ); | |
echo 'New alt generated: "' . $new_alt . '"<br>'; | |
// slice and dice, inject the new <img> html with alt | |
$new_img_html = $image_html; | |
if ( strpos( $image_html, 'alt=""' ) ){ | |
// straight replace | |
$new_img_html = str_replace( 'alt=""', 'alt="' . esc_attr( $new_alt ) . '"', $image_html ); | |
} else { | |
// not found, inject | |
$new_img_html = str_replace( '/>', ' alt="' . esc_attr( $new_alt ) . '"/>', $image_html ); | |
} | |
echo 'This:<pre>' . esc_html( $image_html ) . '</pre><br>Will be replaced with:<pre>' . esc_html( $new_img_html ) . '</pre>'; | |
// update it, if changed | |
if ( $new_img_html !== $image_html ){ | |
$post_to_update = $post; | |
$post_to_update->post_content = str_replace( $image_html, $new_img_html, $post->post_content ); | |
$outcome = wp_update_post( $post_to_update ); | |
echo 'Updated post ' . $post->ID . ': <a href="'.$post->guid.'" target="_blank">View</a><br>'; | |
} | |
$updated_count++; | |
} else { | |
$filled_alt_count++; | |
} | |
} | |
} | |
// useful stop, if you want to step through :) | |
//if ( $updated_count > 5 ) exit(); | |
} | |
echo '<hr>'; | |
} | |
} else { | |
echo 'Not found in any post html.<br><hr>'; | |
} | |
} | |
// summary | |
echo '<hr><hr><h1>Summary</h1>'; | |
echo count( $attachments ) . ' attachments processed<br>'; | |
echo $filled_alt_count . ' images found with alt already present<br>'; | |
echo $empty_alt_count . ' images found with no alt<br>'; | |
echo $updated_count . ' alt updates made to post html<br>'; | |
echo 'Note! This script is flawed! It was written quickly for a specific use case, it may miss some alts, or mangle your db. Please triple check your data.'; | |
} | |
exit(); | |
} | |
} add_action( 'init' , 'wordPress_alt_image_updater'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment