Serialized data fix for WordPress

over 6 years ago in News by luke

There is many solutions for this problem over the internet, but none of them are solving the problem automatically or without editing the WordPress core.

Lately i came up with the solution for this problem for Ether Builder plugin.

So, here it is, feel free to use it.

add_filter('get_post_metadata', 'ether_serialize_fix', 10, 4);

function meta_serialize_fix($null, $object_id, $meta_key, $single)
{
	$meta_type = 'post';

	if ($meta_key == 'YOUR_META_KEY')
	{
		$meta_cache = wp_cache_get($object_id, $meta_type.'_meta');

		if ( ! $meta_cache)
		{
			$meta_cache = update_meta_cache($meta_type, array($object_id));
			$meta_cache = $meta_cache[$object_id];
		}

		if (isset($meta_cache[$meta_key]))

		{
			if ($single)
			{
				if (is_serialized($meta_cache[$meta_key][0]) AND ! maybe_unserialize($meta_cache[$meta_key][0]))
				{
					return array(maybe_unserialize_fixed($meta_cache[$meta_key][0]));
				}
			} else
			{
				foreach ($meta_cache[$meta_key] as $k => $v)
				{
					if (is_serialized($v) AND ! maybe_unserialize($v))
					{
						return array_map('maybe_unserialize_fixed', $meta_cache[$meta_key]);
					}
				}
			}
		}
	}
}

add_filter('option_OPTION_NAME', 'option_serialize_fix', 10, 1);

function option_serialize_fix($option, $value)
{
	if (is_serialized($value) AND ! maybe_unserialize($value))
	{
		return maybe_unserialize_fix($value);
	}
}

function maybe_unserialize_fixed($data)
{
	return maybe_unserialize(preg_replace('!s:(\d+):"(.*?)";!e',"'s:'.strlen('$2').':\"$2\";'", $data));
}

Keep in mind that using this for every meta key / option name is not a good idea. Use conditional tag instead!

No comments.

Leave a reply