Created
January 20, 2015 17:43
-
-
Save theMikeD/8c83a7743218901bd904 to your computer and use it in GitHub Desktop.
Manipulates the metadata for uploaded images at upload time to make better use of IPTC data that may be present.
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 | |
/* | |
Manipulates the metadata for uploaded images at upload time to make better use | |
of IPTC data that may be present. | |
An image is stored as an attachment, which is a special type of post. It is | |
handled the same way as any other post type. | |
As far as the meta goes, it's stored like this: | |
Image title is stored as post_title in wp_post, | |
Description is stored as post_content in wp_post, | |
Caption is stored as post_excerpt in wp_post | |
Alt Text is stored as _wp_attachment_image_alt in wp_postmeta | |
The rest of the meta data is stored as _wp_attachment_metadata as aa serialized | |
entry in wp_postmeta | |
When reading meta from the file during ingest, WP uses the following as its source, | |
in order of appearance: | |
Title: | |
1. IPTC:Headline | |
2. IPTC:Title | |
3. IPTC:Description if less than 80 characters | |
4. EXIF:Title (which doesn't actually exist) | |
5. EXIF:ImageDescription if less than 80 characters | |
6. Filename minus extension | |
Caption: | |
1. IPTC:Description | |
2. EXIF:UserComment if title is unset AND EXIF:ImageDescription is less than 80 characters | |
3. EXIF:ImageDescription if title is set OR EXIF:ImageDescription is more than 80 characters | |
4. EXIF:Comments if title !== EXIF:Comments | |
1. Image title = IPTC Headline | |
2. Image description = IPTC Description | |
Alt Text: | |
none | |
Description: | |
1. IPTC:Description if more than 80 characters | |
What this code does is the following: | |
1. Image title = IPTC Title if present, even if IPTC:Headline is set | |
2. Image caption = IPTC Headline | |
3. Image alt text = Image Caption (done is step 2) + comma-separated IPTC:Keywords | |
4. Image Description = IPTC:Description regardless of length | |
5. Add a new meta value called md_meta_update_complete to track whether these | |
adjustments have been done. | |
We can't do this at metadata collection time (such as by hoooking into | |
wp_read_image_metadata)because some of this info is stored as wp_post | |
and the entry doesn't exist at the time wp_read_image_metadata is running. | |
Logic Steps | |
1. Copy Title (post_title) to Caption (post_excerpt). Refer to default logic | |
above to understand why this is valid | |
2. If IPTC:Title, set Title (post_title) to IPTC:Title | |
3. Read in the IPTC Keywords and insert into Alt along with Caption | |
4. Readin IPTC:Description and insert into description (post_content) | |
*/ | |
// Hook into add_attachment at the very end | |
add_filter('add_attachment', 'md_force_image_metadata', 99, 2); | |
/******************************************************************************* | |
Wrapper to call the steps in order. | |
@param int $image_id, attachment ID | |
@return none | |
*/ | |
function md_force_image_metadata( $image_id ) { | |
$image_meta = wp_get_attachment_metadata( $image_id ); | |
// Only run if it hasn't already been run | |
if ( ! isset($image_meta['md_meta_update_complete']) || ! $image_meta['md_meta_update_complete'] ) { | |
// 1. Copy Title (post_title) to Caption (post_excerpt) | |
md_copy_title_to_caption( $image_id ); | |
// 2. Read in the IPTC:Title from the file and insert into post_title | |
md_insert_IPTC_title_as_title( $image_id ); | |
// 3. Read in the IPTC:Keywords from the file and insert into Alt | |
md_insert_IPTC_keywords_as_alt( $image_id ); | |
// 4. Read in IPTC:Description and put it into description (post_content) | |
md_insert_IPTC_description_as_description( $image_id ); | |
// 5. Insert the flag to indicate we're done | |
$image_meta = wp_get_attachment_metadata( $image_id ); | |
$image_meta['md_meta_update_complete'] = true; | |
update_post_meta($image_id, '_wp_attachment_metadata', $image_meta); | |
} | |
} | |
/******************************************************************************* | |
By default, the IPTC:Description is used as the title if it's less than 80 | |
characters long, which means that description would be empty. This forces | |
description to be IPTC:Description no matter how long it is. Overwrites | |
existing description if present. | |
@param int $image_id, attachment ID | |
@return none | |
*/ | |
function md_insert_IPTC_description_as_description( $image_id ) { | |
if ( wp_attachment_is_image( $image_id ) ) { | |
$desc = md_get_iptc_tag( $image_id, 'Description'); | |
md_log( "Desc is $desc" ); | |
if ( $desc ) { | |
// Update the post_content, which is used for the description | |
$updated_post = array( | |
'ID' => $image_id, | |
'post_content' => $desc, | |
); | |
wp_update_post( $updated_post ); | |
} | |
} | |
} | |
/******************************************************************************* | |
Copies the image title (post_title) WP did on its own (and used IPTC Headline | |
for) and copies into the caption (post_excerpt). Overwrites existing caption, | |
but at ingest time it'll be blank so who cares. | |
@param int $image_id, attachment ID | |
@return none | |
*/ | |
function md_copy_title_to_caption( $image_id ) { | |
if ( wp_attachment_is_image( $image_id ) ) { | |
$image_obj = get_post( $image_id ); | |
$image_meta = wp_get_attachment_metadata( $image_id ); | |
// First update the image meta | |
$image_meta['image_meta']['caption'] = $image_obj->post_title; | |
update_post_meta($image_id, '_wp_attachment_metadata', $image_meta); | |
// Then update the post_excerpt, which is used for the caption | |
$updated_post = array( | |
'ID' => $image_id, | |
'post_excerpt' => $image_obj->post_title, | |
); | |
wp_update_post( $updated_post ); | |
} | |
} | |
/******************************************************************************* | |
Inserts IPTC title as image title (post_title). Overwrites | |
existing title. | |
@param int $image_id, attachment ID | |
@return none | |
*/ | |
function md_insert_IPTC_title_as_title( $image_id ) { | |
if ( wp_attachment_is_image( $image_id ) && is_callable( 'iptcparse' ) ) { | |
$title = ''; | |
$title = md_get_iptc_tag( $image_id, 'Title'); | |
if ( $title ) { | |
// First update the image meta | |
$image_meta = wp_get_attachment_metadata( $image_id ); | |
$image_meta['image_meta']['title'] = $title; | |
update_post_meta($image_id, '_wp_attachment_metadata', $image_meta); | |
// Then update the post_title | |
$updated_post = array( | |
'ID' => $image_id, | |
'post_title' => $title, | |
); | |
wp_update_post( $updated_post ); | |
} | |
} | |
} | |
/******************************************************************************* | |
Inserts caption and IPTC keywords as comma separated string into Alt Text. | |
Overwrites existing Alt Text, but at ingest time it'll be blank so who cares. | |
@param int $image_id, attachment ID | |
@return none | |
*/ | |
function md_insert_IPTC_keywords_as_alt( $image_id ) { | |
if ( wp_attachment_is_image( $image_id ) && is_callable( 'iptcparse' ) ) { | |
$keywords = md_get_iptc_tag( $image_id, 'Keywords'); | |
$image_meta = wp_get_attachment_metadata( $image_id ); | |
$caption = $image_meta['image_meta']['caption']; | |
if ( $caption ) { $caption .= "; ";} | |
if ( $keywords || $caption ) { | |
update_post_meta($image_id, '_wp_attachment_image_alt', "$caption $keywords"); | |
} | |
} | |
} | |
/******************************************************************************* | |
Does the actual getting of the IPTC info from the file. | |
@param int $image_id, attachment ID | |
@param string $iptc_tag, tag to get, either 'Keywords' or 'Title' or 'Description' | |
@return string if tag is found and has contents, those contents; empty string otherwise | |
*/ | |
function md_get_iptc_tag( $image_id, $iptc_tag ) { | |
$tag = null; | |
$file = get_attached_file( $image_id ); | |
if ( ! file_exists( $file ) ) { return null; } | |
// Based on code in image.php in wp core | |
$size = getimagesize( $file, $info ); | |
if ( ! empty( $info['APP13'] ) && ( 'Title' === $iptc_tag || 'Keywords' === $iptc_tag || 'Description' === $iptc_tag ) ) { | |
$iptc = iptcparse( $info['APP13'] ); | |
// User var_dump on $iptc to see everything | |
switch ( $iptc_tag ) { | |
case 'Title': | |
if ( ! empty( $iptc['2#005'][0] ) ) { | |
// string | |
$tag = trim( $iptc['2#005'][0] ); | |
} | |
break; | |
case 'Keywords': | |
if ( ! empty( $iptc['2#025'][0] ) ) { | |
// array | |
$tag = implode( ', ', $iptc['2#025'] ); | |
} | |
break; | |
case 'Description': | |
if ( ! empty( $iptc['2#120'][0] ) ) { | |
// string | |
$tag = trim( $iptc['2#120'][0] ); | |
} | |
break; | |
default: | |
} | |
} | |
return $tag; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment