Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

In the course of converting a blog from Blogger to WP and running a script to grab hot-linked images for hosting, I ended up with some funky images names like

act%252Bapandas-210x290.png

These image names prevent the image from displaying on a webpage, due the url encoding ending up in the file name itself (don't ask!). I renamed them on the file server, no prob, but the names are also in the attachment metadata for each post.

How can I remove the "%" from all the image references in the wp_postmeta table? *Most of them occur in serialized arrays in meta_values for the meta_keys of _wp_attachment_metadata*. I've had no luck finding a plugin, and am unsure how to institute a pure SQL/PHP solution.

Here is an example of a serialized array entry (further gummed up by the Smush.it plugin, ugh):

a:7:{s:5:"width";s:3:"210";s:6:"height";s:3:"339";s:14:"hwstring_small";s:22:"height='96' width='59'";s:4:"file";s:27:"2011/02/act%252Bapandas.png";s:5:"sizes";a:6:{s:9:"thumbnail";a:4:{s:4:"file";s:27:"act%252Bapandas-210x290.png";s:5:"width";s:3:"210";s:6:"height";s:3:"290";s:10:"wp_smushit";s:271:"Smush.it error: Could not get the image while processing http://new.xxxxx.com/wp-content/uploads/2011/02/act%252Bapandas-210x290.png (/home/xxxxxxxxx/new.xxxxx.com/wp-content/uploads/2011/02/act%252Bapandas-210x290.png)";}s:14:"soft-thumbnail";a:4:{s:4:"file";s:27:"act%252Bapandas-179x290.png";s:5:"width";s:3:"179";s:6:"height";s:3:"290";s:10:"wp_smushit";s:271:"Smush.it error: Could not get the image while processing http://new.xxxxx.com/wp-content/uploads/2011/02/act%252Bapandas-179x290.png (/home/xxxxxxxxx/new.xxxxx.com/wp-content/uploads/2011/02/act%252Bapandas-179x290.png)";}s:14:"mini-thumbnail";a:4:{s:4:"file";s:25:"act%252Bapandas-60x60.png";s:5:"width";s:2:"60";s:6:"height";s:2:"60";s:10:"wp_smushit";s:267:"Smush.it error: Could not get the image while processing http://new.xxxxx.com/wp-content/uploads/2011/02/act%252Bapandas-60x60.png (/home/xxxxxxxxx/new.xxxxx.com/wp-content/uploads/2011/02/act%252Bapandas-60x60.png)";}s:5:"slide";a:4:{s:4:"file";s:27:"act%252Bapandas-210x290.png";s:5:"width";s:3:"210";s:6:"height";s:3:"290";s:10:"wp_smushit";s:271:"Smush.it error: Could not get the image while processing http://new.xxxxx.com/wp-content/uploads/2011/02/act%252Bapandas-210x290.png (/home/xxxxxxxxx/new.xxxxx.com/wp-content/uploads/2011/02/act%252Bapandas-210x290.png)";}s:10:"soft-slide";a:4:{s:4:"file";s:27:"act%252Bapandas-179x290.png";s:5:"width";s:3:"179";s:6:"height";s:3:"290";s:10:"wp_smushit";s:271:"Smush.it error: Could not get the image while processing http://new.xxxxx.com/wp-content/uploads/2011/02/act%252Bapandas-179x290.png (/home/xxxxxxxxx/new.xxxxx.com/wp-content/uploads/2011/02/act%252Bapandas-179x290.png)";}s:10:"mini-slide";a:4:{s:4:"file";s:27:"act%252Bapandas-210x145.png";s:5:"width";s:3:"210";s:6:"height";s:3:"145";s:10:"wp_smushit";s:271:"Smush.it error: Could not get the image while processing http://new.xxxxx.com/wp-content/uploads/2011/02/act%252Bapandas-210x145.png (/home/xxxxxxxxx/new.xxxxx.com/wp-content/uploads/2011/02/act%252Bapandas-210x145.png)";}}s:10:"image_meta";a:10:{s:8:"aperture";s:1:"0";s:6:"credit";s:0:"";s:6:"camera";s:0:"";s:7:"caption";s:0:"";s:17:"created_timestamp";s:1:"0";s:9:"copyright";s:0:"";s:12:"focal_length";s:1:"0";s:3:"iso";s:1:"0";s:13:"shutter_speed";s:1:"0";s:5:"title";s:0:"";}s:10:"wp_smushit";s:255:"Smush.it error: Could not get the image while processing http://new.xxxxx.com/wp-content/uploads/2011/02/act%252Bapandas.png (/home/xxxxxxxxx/new.xxxxx.com/wp-content/uploads/2011/02/act%252Bapandas.png)";}

The issue is changing or removing the "%" character AND updating the array so it reports the correct number of characters (ie the s:13 would indicate yoursite.com is 13 char[]) I'm also open to using a php solution! Whatever can help me fix this mess.

FINAL SOLUTION

See my answer below.

share|improve this question
    
Please move your solution to separate answer, that is how content should be structured per site's mechanics. –  Rarst Apr 3 '11 at 17:03

2 Answers 2

up vote 2 down vote accepted

General idea would be to loop through all attachments to retrieve, modify and write back their meta.

Something like this (test thoroughly before using on anything important):

$posts = get_posts(array(
    'post_type' => 'attachment',
    'numberposts' => -1,
));

foreach( $posts as $post ) {

    // retrieve data, unserialized automatically
    $meta = get_post_meta($post->ID,'_wp_attachment_metadata', true);

    // do stuff with $meta array

    // write it back
    update_post_meta($post->ID, '_wp_attachment_metadata', $meta);
}
share|improve this answer
    
This is great - I've not had much experience dealing with serialized data, so any help with that would be most appreciated and instructive. Also, the first function unserializes automatically; does the the second serialize automatically? –  two7s_clash Apr 1 '11 at 1:50
1  
@two7s_clash yes, these will automatically determine type of data you are retrieving or writing and (un)serialize it if necessary. This is handled by internal use of maybe_serialize() and maybe_unserialize() functions. –  Rarst Apr 1 '11 at 10:31
  $posts = get_posts(array(
                'post_type' => 'attachment',
                'numberposts' => -1,
            ));

    // Recursive String Replace - recursive_array_replace(mixed, mixed, array);
    function recursive_array_replace($find, $replace, $array){
    if (!is_array($array)) {
    return str_replace($find, $replace, $array);
    }
    $newArray = array();
    foreach ($array as $key => $value) {
    $newArray[$key] = recursive_array_replace($find, $replace, $value);
    }
    return $newArray;
    }

    foreach ($posts as $post) {
        // retrieve data, unserialized automatically
        $meta = get_post_meta($post->ID, '_wp_attachment_metadata', true);
        // see if file name has "%" in it
        if (strpos($meta[file], "%")) {
        //recursively scrub "%"
        $meta = recursive_array_replace('%', '', $meta);
        }

        // write it back
        update_post_meta($post->ID, '_wp_attachment_metadata', $meta);
    }
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.