私はこのようにWP_QueryでREGEXPを使用できることを知っています。
$query = new WP_Query(array(
'posts_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => 'custom_fields',
'value' => 'foo[(][0-9][)]', // with regex stuff
'compare' => 'REGEXP',
),
),
));
しかし、私も鍵の中に正規表現が必要です。このような:
$query = new WP_Query(array(
'posts_per_page' => -1,
'post_status' => 'publish',
'meta_query' => array(
array(
'key' => 'custom_fields[(][0-9][)]', // with regex stuff
'value' => 'foo',
'compare' => 'REGEXP',
),
),
));
フィルタでこれを実現する方法はありますか?それとも、自分自身でSQLクエリを作成しなければなりませんか。
これは実験的なアイデアです。
我々が得たと仮定します。
カスタムフィールド
location1
をUK - Londonにしてpost _ a _post _ b _ カスタムフィールド
location2
にフランス - パリを付けて_post _ c _ カスタムフィールド
location3
をUSA - New Yorkとして
それでは、例えば、
$args = [
'meta_query' => [
'relation' => 'OR',
[
'key' => "^location[0-9]",
'_key_compare' => 'REGEXP',
'value' => 'London',
'compare' => 'LIKE',
],
[
'key' => 'location%',
'_key_compare' => 'LIKE',
'value' => 'Paris',
'compare' => 'LIKE'
],
[
'key' => 'location3',
'value' => 'New York',
'compare' => 'LIKE'
]
]
];
次のプラグインでカスタムの_key_compare
引数をサポートします。
<?php
/**
* Plugin Name: Extended Meta Key Search In WP_Query
* Description: Custom '_key_compare' argument as REGEXP, RLIKE or LIKE
* Plugin URI: http://wordpress.stackexchange.com/a/193841/26350
* Plugin Author: Birgir Erlendsson (birgire)
* Version: 0.0.3
*/
add_action( 'pre_get_posts', function( $q )
{
// Check the meta query:
$mq = $q->get( 'meta_query' );
if( empty( $mq ) )
return;
// Init:
$marker = '___tmp_marker___';
$rx = [];
// Collect all the sub meta queries, that use REGEXP, RLIKE or LIKE:
foreach( $mq as $k => $m )
{
if( isset( $m['_key_compare'] )
&& in_array( strtoupper( $m['_key_compare'] ), [ 'REGEXP', 'RLIKE', 'LIKE' ] )
&& isset( $m['key'] )
) {
// Mark the key with a unique string to secure the later replacements:
$m['key'] .= $marker . $k; // Make the appended tmp marker unique
// Modify the corresponding original query variable:
$q->query_vars['meta_query'][$k]['key'] = $m['key'];
// Collect it:
$rx[$k] = $m;
}
}
// Nothing to do:
if( empty( $rx ) )
return;
// Get access the generated SQL of the meta query:
add_filter( 'get_meta_sql', function( $sql ) use ( $rx, $marker )
{
// Only run once:
static $nr = 0;
if( 0 != $nr++ )
return $sql;
// Modify WHERE part where we replace the temporary markers:
foreach( $rx as $k => $r )
{
$sql['where'] = str_replace(
sprintf(
".meta_key = '%s' ",
$r['key']
),
sprintf(
".meta_key %s '%s' ",
$r['_key_compare'],
str_replace(
$marker . $k,
'',
$r['key']
)
),
$sql['where']
);
}
return $sql;
});
});
ここで、文字列の置換のために各メタキーに一意のマーカーを追加します。
\(
や\\
のように、これは正規表現文字エスケープをサポートしていないことに注意してください。
あなたの答えは最初の配列lvlで完璧に働くことです、例えば:
$args['meta_query'][] = array(
'key' => 'tour_itinerario_ciudades_repeater_%_tour_ciudades_nombre',
'_key_compare' => 'LIKE',
'value' => 'MEXICO',
'compare' => 'LIKE',
);
私は配列の2番目のlvlで作業するためにいくつかの修正をする必要があります。
$args['meta_query'][] = array(
'relation' => 'OR',
array(
'key' => 'tour_itinerario_ciudades_repeater_%_tour_ciudades_nombre',
'_key_compare' => 'LIKE',
'value' => 'CONDESA',
'compare' => 'LIKE',
),
array(
'key' => 'tour_itinerario_ciudades_repeater_%_tour_ciudades_nombre',
'_key_compare' => 'LIKE',
'value' => 'Ciudad 1',
'compare' => 'LIKE',
)
);
今、
add_action('pre_get_posts', function( $q ) {
// Check the meta query:
$mq = $q->get('meta_query');
if (empty($mq))
return;
// Init:
$marker = '___tmp_marker___';
$rx = [];
// Collect all the sub meta queries, that use REGEXP, RLIKE or LIKE:
// Only works for 1st level in array
foreach ($mq as $k => $m) {
if (isset($m['_key_compare']) && in_array(strtoupper($m['_key_compare']), [ 'REGEXP', 'RLIKE', 'LIKE']) && isset($m['key'])
) {
// Mark the key with a unique string to secure the later replacements:
$m['key'] .= $marker . $k; // Make the appended tmp marker unique
// Modify the corresponding original query variable:
$q->query_vars['meta_query'][$k]['key'] = $m['key'];
// Collect it:
$rx[$k] = $m;
}
}
// custom code to make it work with arguments on Multidimensional array
foreach ($mq as $k => $m) {
foreach ($m as $k_i => $m_i) {
if (count($m_i) >= 3) {
if (isset($m_i['_key_compare']) && in_array(strtoupper($m_i['_key_compare']), [ 'REGEXP', 'RLIKE', 'LIKE']) && isset($m_i['key'])
) {
// Mark the key with a unique string to secure the later replacements:
$m_i['key'] .= $marker . $k_i; // Make the appended tmp marker unique
// Modify the corresponding original query variable:
$q->query_vars['meta_query'][$k][$k_i]['key'] = $m_i['key'];
// Collect it:
$rx[$k][$k_i] = $m_i;
}
}
}
}
// Nothing to do:
if (empty($rx))
return;
// Get access the generated SQL of the meta query:
add_filter('get_meta_sql', function( $sql ) use ( $rx, $marker ) {
// Only run once:
static $nr = 0;
if (0 != $nr++)
return $sql;
// Modify WHERE part where we replace the temporary markers:
//PRIMER NIVEL
foreach ($rx as $k => $r) {
$sql['where'] = str_replace(
sprintf(
".meta_key = '%s' ", $r['key']
), sprintf(
".meta_key %s '%s' ", $r['_key_compare'], str_replace(
$marker . $k, '', $r['key']
)
), $sql['where']
);
}
//SECOND NIVEL
foreach ($rx as $k => $r) {
//TODO: test with several cases since may have bugs
if (!isset($r['key'])) {//FORZO LA ENTRADA
foreach ($r as $k_i => $r_i) {
$sql['where'] = str_replace(
sprintf(
".meta_key = '%s' ", $r_i['key']
), sprintf(
".meta_key %s '%s' ", $r_i['_key_compare'], str_replace(
$marker . $k_i, '', $r_i['key']
)
), $sql['where']
);
}
}
}
var_dump($sql);
return $sql;
});
;));同様の答えが必要な場合に備えて、
THK AGAIN