Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save woodyhayday/0c1c81803f89944b5ef97b01ce48ac09 to your computer and use it in GitHub Desktop.
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)
<?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