Last active
September 4, 2021 13:24
-
-
Save rmpel/8b103a5dd360a5000e4d4f9aa22e2787 to your computer and use it in GitHub Desktop.
Get WordPress Post Meta by RegExp, a regular expression variant of get_post_meta
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Retrieve post meta field for a post, by Regular Expression match on the key. | |
* | |
* @since 0.0.1 | |
* | |
* @param int $post_id Post ID. | |
* @param string $regexp The regexp to match the meta key against. One capture-group | |
* allowed for key-ing the results. Full meta_key is used if no | |
* capture-groups in the expression | |
* @param bool $single_sub_values Optional. Whether to return an array of single values. Default false. | |
* @return WP_Error|array(mixed) Will be an array with either scalars or arrays based on $single_sub_values. | |
* contains the individual meta_value results of get_post_meta. | |
* Will be WP_Error in case the regular expression fails to validate. | |
*/ | |
function get_post_meta_regexp($post_id, $regexp, $single_sub_values = false) { | |
global $wpdb; | |
if (preg_match($regexp, null) === false) { | |
return new WP_Error('regexp_invalid', 'Please supply a valid regexp, the current expression is missing boundaries', array($regexp)); | |
} | |
$regexp_boundary = substr($regexp, 0, 1); | |
$regexp_boundary_end = strrpos($regexp, $regexp_boundary); // position of closing boundary | |
$regexp_options = substr($regexp, $regexp_boundary_end + 1); // just the part between the boundaries | |
$trimmed_regexp = substr($regexp, 1, $regexp_boundary_end - 1); // just the part between the boundaries | |
// notes: | |
// MYSQL regexp is always case insensitive, so in case of no /i flag, MYSQL might report too many rows, these are then filtered by PHP, | |
// flags m and s are for multi-line matching. meta_keys are never multiline, do, we can ignore those | |
// flag x modified the way whitepsace is handled, sinde meta_keys cannot have whitespace, we ignore those too | |
// flag e (eval) makes no sense whatsoever in this context, do we ignore that as well. | |
$regexp_options = (false !== strpos($regexp_options, 'i')) ? 'i' : ''; | |
$regexp = $regexp_boundary . $trimmed_regexp . $regexp_boundary . $regexp_options; | |
$meta_keys = $wpdb->get_col( $wpdb->prepare("SELECT meta_key FROM {$wpdb->postmeta} WHERE meta_key REGEXP %s AND post_id = %d", $trimmed_regexp, $post_id ) ); | |
$meta = array(); | |
foreach ($meta_keys as $key) { | |
if (preg_match($regexp, $key, $m)) { | |
$meta[ isset($m[1]) ? $m[1] : $m[0] ] = get_post_meta($post_id, $m[0], $single_sub_values); | |
} | |
} | |
return $meta; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment