Workaround for querying non-serialized metadata in Wordpress

Workaround for querying non-serialized metadata in Wordpress

This articles shows how to filter query output on values used in a Wordpress meta-box. By default it contains not serialized data which makes it harder to filter but with a little workaround it can work.

Data structure post (excerpt, output from a php var_dump)

  ["id"]=>
  int(22033)
  ["ID"]=>
  int(22033)
  ["post_author"]=>
  string(1) "1"
  ["post_content"]=>
  string(0) ""
  ["post_date"]=>
  string(19) "2019-06-18 23:02:32"
  ["post_excerpt"]=>
  string(214) "..."
  ...
  ... more fields here ...
  ...
  ["vscc_zaak_metadata"]=>
  array(5) {
    ["show_in_widget"]=>
    string(1) "1"
    ["datum_zaak"]=>
    string(10) "18-06-2019"
    ["dossier_nr"]=>
    string(19) "ECLI:NL:HR:2019:572"
    ["url_hoge_raad"]=>
    string(71) "https://uitspraken.rechtspraak.nl/inziendocument?id=ECLI:NL:HR:2019:572"
    ["url_blog"]=>
    string(0) ""
  }
  ["_yoast_wpseo_primary_map"]=>
  string(3) "120"
  ...

The metabox is named vscc_zaak_metadata and where we are interested in is show_in_widget. For our purpose we want this value not to be 0. Simply put, we only want when the value equals 1 or doesn't exist.

How it is stored in MySQL

In the database there is a table named wp_postmeta that contains the metadata fitted to wp_posts table records. In our sample exists (or not) a metadata record with a metakey vscc_zaak_metadata that contains the following (not serialized) value.

a:5:{s:14:"show_in_widget";s:1:"0";s:10:"datum_zaak";s:10:"18-06-2019";s:10:"dossier_nr";s:19:"ECLI:NL:HR:2019:572";s:13:"url_hoge_raad";s:71:"https://uitspraken.rechtspraak.nl/inziendocument?id=ECLI:NL:HR:2019:572";s:8:"url_blog";s:0:"";}

How to query this?

The meta query we would like to execute. I have split this to have a better view for this article, but you can merge it with the *select in the next PHP sample code.

$metaQuery = [
    [
        'key' => 'vscc_zaak_metadata',
        'compare' => 'not like',
        'value'   => '"show_in_widget";s:1:"0"'
    ]
];

And the select itself:

$args = [
  'more' => 'args that come with the function',
  'showposts' => 20
];

$queryArgs = array_merge([
    'post_type'   => 'vscc-zaak', // <-- custom post
    'post_status' => 'publish',
    'orderby'     => 'date',
    'order'       => 'desc',
    'meta_query'  => $metaQuery // <--- notice this !!!
], $args);

$posts = get_posts($queryArgs);

More from same category