Tagged: piklist meta get_post_meta
- This topic has 9 replies, 2 voices, and was last updated 7 years, 5 months ago by
Marcus.
-
AuthorPosts
-
-
September 5, 2014 at 5:16 am #2376
MarcusMemberHi guys.
I have a recurring problem.
Everytime I use a get_post_meta(pid,mkey,single) on any field that is a select field (single select not multiple) and I use single=true in the get_post_meta.
An array is ALWAYS returned instead of a single value.So for a single get_post_meta call, instead of
$tmp = get_post_meta($pid,$key,true);$tmp != ‘string’;
But
$tmp = array (
‘string’
);So I’m always having to do this to all get_post_meta vars, just in case I can’t remember if its a select or not. π
$tmp = get_post_meta($pid,$key,true); $tmp = (is_array($tmp) && count($tmp)==1) ? $tmp[0] : $tmp;Which I hate, as get_post_meta for singles, should return singles, not arrays.
So I decided to do a little hacking on Kevins magnificent code. (it is, I’m not kidding)
So in class-piklist-meta.php in the get_metadata function I changed it from:public static function get_metadata($value, $meta_type, $object_id, $meta_key, $single) { global $wpdb; self::$reserved_meta_keys = apply_filters('piklist_reserved_meta_keys',self::$reserved_meta_keys); if ((isset(self::$reserved_meta_keys[$meta_type]) && in_array($meta_key, self::$reserved_meta_keys[$meta_type])) || !$meta_key) { return $value; } $meta_key = '_' . piklist::$prefix . $meta_key; switch ($meta_type) { case 'post': $meta_table = $wpdb->postmeta; $meta_id_field = 'meta_id'; $meta_id = 'post_id'; break; case 'term': $meta_table = $wpdb->termmeta; $meta_id_field = 'meta_id'; $meta_id = 'term_id'; break; case 'user': $meta_table = $wpdb->usermeta; $meta_id_field = 'umeta_id'; $meta_id = 'user_id'; break; } $is_group = $wpdb->get_var($wpdb->prepare("SELECT $meta_id_field FROM $meta_table WHERE meta_key = %s AND $meta_id = %d", $meta_key, $object_id)); if ($is_group) { if ($meta_ids = get_metadata($meta_type, $object_id, $meta_key)) { foreach ($meta_ids as &$group) { foreach ($group as &$meta_id) { $meta_id = $wpdb->get_var($wpdb->prepare("SELECT meta_value FROM $meta_table WHERE $meta_id_field = %d", $meta_id)); } } $value = $meta_ids; } } return $value; }to this (I added just before the final value, a simple routine that checks to see if its single, and the value is an array and has a count of 1)
public static function get_metadata($value, $meta_type, $object_id, $meta_key, $single) { global $wpdb; self::$reserved_meta_keys = apply_filters('piklist_reserved_meta_keys',self::$reserved_meta_keys); if ((isset(self::$reserved_meta_keys[$meta_type]) && in_array($meta_key, self::$reserved_meta_keys[$meta_type])) || !$meta_key) { return $value; } $meta_key = '_' . piklist::$prefix . $meta_key; switch ($meta_type) { case 'post': $meta_table = $wpdb->postmeta; $meta_id_field = 'meta_id'; $meta_id = 'post_id'; break; case 'term': $meta_table = $wpdb->termmeta; $meta_id_field = 'meta_id'; $meta_id = 'term_id'; break; case 'user': $meta_table = $wpdb->usermeta; $meta_id_field = 'umeta_id'; $meta_id = 'user_id'; break; } $is_group = $wpdb->get_var($wpdb->prepare("SELECT $meta_id_field FROM $meta_table WHERE meta_key = %s AND $meta_id = %d", $meta_key, $object_id)); if ($is_group) { if ($meta_ids = get_metadata($meta_type, $object_id, $meta_key)) { foreach ($meta_ids as &$group) { foreach ($group as &$meta_id) { $meta_id = $wpdb->get_var($wpdb->prepare("SELECT meta_value FROM $meta_table WHERE $meta_id_field = %d", $meta_id)); } } $value = $meta_ids; } } if ($single==true && is_array($value) && count($value)==1) { $value = $value[0]; } return $value; }So a couple of questions. What damage will I be doing to the piklist forms I’m creating? (and other than having to repeat this fix every time a new version comes out is it ok to do this?)
And is there any way we can have this as a permanent fix? Or is there a specific reason why it will stay like this that I am not smart enough to figure out? (which is totally possible)
Thanks guys.
Marcus
-
September 8, 2014 at 11:51 am #2381
JasonKeymasterThat’s definitely a thought. I’ve run into that one before. I’m not sure I’d agree that single should always return a single, though. Technically, it does return a single database row, it’s just serialized. Groups, for example, ought to be retrieved as a single row, but certainly aren’t a single value.
I’ve mentioned this to Steve in the past, but I feel the proper solution would be to provide field qualifiers (implicitly, one called “multiple” is already used). This would also help build a foundation for custom fields down the road.
Maybe I’m over-complicating, but I’d be leery to return a string every time an array had a single value (even in the circumstance that $single === true). I think it’d be better to handle this sort of thing on insertion, rather than retrieval.
-
September 8, 2014 at 2:37 pm #2392
MarcusMemberYeah, Jason. I agree with that.
After all WordPress API even states:$single (boolean) (optional) If set to true then the function will return a single result, as a string. If false, or not set, then the function returns an array of the custom fields. This may not be intuitive in the context of serialized arrays. If you fetch a serialized array with this method you want $single to be true to actually get an unserialized array back. If you pass in false, or leave it out, you will have an array of one, and the value at index 0 will be the serialized string.So I guess my problem is that I have a lot of old data from piklist 0.??? versions mixed with data from the new piklist versions, and the old always returned singles for single select, and the new version, arrays for single selects. π
My problem is I have about 1000 places I need to check and fix this, so I was trying to lazy way of fixing an old problem.
There is a better solution, I just haven’t thought of it yet, or haven’t googled it yet. π
Thanks.
Marcus
-
September 8, 2014 at 2:54 pm #2395
JasonKeymasterHahah! Yeah.. I hear that. Piklist is super awesome.. but still in beta. π
I think what I would do is make my own little function for handling this issue personally:
function get_single_post_meta($id, $key) { $meta = get_post_meta($id, $key, true); return ( is_array($meta) && count($meta) == 1 ) ? $meta[0] : $meta; }That will at least save you a line of code wherever you have the issue. π
-
September 8, 2014 at 7:00 pm #2398
MarcusMemberHahah, you’re awesome.
It doesn’t change the fact I still have to change those 1000 places. But at least now I don’t have to write another function. LOL
Thanks Jason.
I’ll shorten it to gspm so I won’t get any hand cramps. LOL
Marcus
-
September 9, 2014 at 4:06 am #2399
MarcusMember1221 variables updated and changed.
Because many of them had associated functions to fix little things, I had to do them one by one.Gonna need glasses after that.
Hope I never have to do that again.
Thanks Jason. π
Marcus
-
September 9, 2014 at 2:03 pm #2420
JasonKeymasterWow.. well done. That kind of tedium makes my brain demand an automated form. If you use vim, I probably would’ve at least made a macro for the task. Hopefully you did something like that.
But! It’s done now! π
-
September 9, 2014 at 8:09 pm #2421
MarcusMemberVim, thats for oldtimers. <g>
Just kidding. I’m an old vim user, but I use Sublime Text 3 now.
I love the interface, and how easy it is to add my own tools to it.
It’s also got a great community. It has increased my productivity dramatically, but on this last process of 1221 variables, I couldn’t create a macro to fix, only a macro to find. LOLMarcus
-
September 10, 2014 at 3:01 pm #2423
JasonKeymasterYou know, I’ve used Sublime Text 3 a number of times now, and I really like it. I just wish it had better vim support (the modes and such). There’s a plugin that tries valiantly (https://github.com/guillermooo/Vintageous), but isn’t quite there yet.
Especially when it comes to quickly splitting the window into multiple files and navigating buffers, I just find it slow. For all it’s super cool tricks, I find vim can do almost all of it faster (just not as cool looking).
Currently I use gvim on Ubuntu 14.04. It works well. π
-
September 10, 2014 at 6:32 pm #2425
MarcusMemberYou know what Jason, if I was still on ubuntu I’d be using vim again.
The speed was always amazing.On windows however I find sublime runs about the same. (maybe a tiny bit slower to do what I need)
But thats the price I paid moving back to winblows.Marcus
-
-
AuthorPosts
- You must be logged in to reply to this topic.