• Documentation
  • Support / Community
  • Products
    • Piklist Framework
    • Toolbox
    • Fields and Forms
    • WordPress Helpers
  • Log In
Piklist

Access your account, and post on the Support Forums

Retrieve Password | Register for account

Topic: Kevin, Steve, how much damage am I doing? :-)

Support Home » Topics » Piklist » Kevin, Steve, how much damage am I doing? :-)

Tagged: piklist meta get_post_meta

  • This topic has 9 replies, 2 voices, and was last updated 7 years, 5 months ago by Marcus.
Viewing 9 reply threads
  • Author
    Posts
    • September 5, 2014 at 5:16 am #2376
      Marcus
      Member

      Hi 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
      Jason
      Keymaster

      That’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
      Marcus
      Member

      Yeah, 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
      Jason
      Keymaster

      Hahah! 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
      Marcus
      Member

      Hahah, 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
      Marcus
      Member

      1221 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
      Jason
      Keymaster

      Wow.. 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
      Marcus
      Member

      Vim, 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. LOL

      Marcus

    • September 10, 2014 at 3:01 pm #2423
      Jason
      Keymaster

      You 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
      Marcus
      Member

      You 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

  • Author
    Posts
Viewing 9 reply threads
  • You must be logged in to reply to this topic.
Log In

Log in / Register

Register for an Account

Stay up-to-date with Piklist

About

  • Philosophy
  • Privacy Policy
  • Terms of Service
  • Contact Us
  • Register for an account

Resources

  • Community Forums
  • Documentation
  • Tutorials
  • Get involved

Follow Piklist

  • Like us on Facebook
  • Follow us on Twitter
  • Connect on Google +
  • Watch on YouTube

Rate Piklist


If you love Piklist leave us a 5 Star review on WordPress.org.

News

  • Piklist v0.9.9.8 is now available

    September 30, 2019

    In October of 2015, we released v0.9.9 of Piklist. Your help in testing lead to seven(7) m ...

  • Piklist is now on HackerOne

    September 30, 2019

    We built Piklist from the ground up with security as our top priority. While we’ve t ...

  • Read all News
  • Powered by Piklist & WordPress © 2009 – 2022 Piklist LLC.
    This website or its third-party tools use cookies, which are necessary to its functioning and required to achieve the purposes illustrated in the cookie policy. By closing this banner, scrolling this page, clicking a link or continuing to browse otherwise, you agree to the use of cookies. Find out more.