WP_Query मेटा_क्वेरी कुंजी में REGEXP का उपयोग करें


10

मुझे पता है कि मैं इस तरह से 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 क्वेरी के साथ बनाना है?

जवाबों:


9

यहाँ एक प्रयोगात्मक विचार है:

हमने मान लिया:

यूके - लंदन के रूप में कस्टम फ़ील्ड के साथ A पोस्ट करेंlocation1

पोस्ट बी कस्टम फ़ील्ड के साथ location2के रूप में फ्रांस - पेरिस

पोस्ट सी कस्टम फ़ील्ड के साथ location3के रूप में संयुक्त राज्य अमेरिका - न्यूयॉर्क

फिर हम उदाहरण के लिए उपयोग कर सकते हैं:

$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;
    });

});

जहां हम स्ट्रिंग प्रतिस्थापन के लिए प्रत्येक मेटा कुंजी पर अद्वितीय मार्कर जोड़ते हैं।

ध्यान दें कि यह रेगेक्स चरित्र को भागने , जैसे \(और समर्थन का समर्थन नहीं करता है \\


मुझे आपके द्वारा जोड़े जा रहे इस मज़ेदार अतिरिक्त कस्टम मापदंडों का आनंद मिलता है। ;-)
पीटर गोयन ने

1
शायद सांता के छोटे सहायकों की तरह - वे आम तौर पर अंत में सभी जादुई रूप से काम करते हैं ;-) @PieterGoosen
birgire

1
धन्यवाद, मैंने यह तय किया। बस $count++एक स्ट्रिंग निर्माण में उपयोग किया जाता है जब मैं भूल गया था कि मुझे $countदो बार उपयोग करना था ;-) मैं अंडरस्कोर के अलावा अन्य महत्वपूर्ण नामों में विशेष वर्णों का उपयोग करने की सिफारिश नहीं करूंगा । आप अपनी कुंजी में कोष्ठक का उपयोग कर रहे हैं। नियमित अभिव्यक्तियों के साथ उनका एक विशेष अर्थ है। आप उन लोगों के साथ से बचने के लिए होता है तो \(और \)में REGEXPया RLIKE, लेकिन बचाव मेरी प्लगइन में समर्थित नहीं है। आप LIKEइसके बजाय कोशिश कर सकते हैं custom_field_language(%)language। @ फिलिपकुन्ह
बिरजायर

1
प्रतिभा! एक जादू की तरह काम करता है!
फिलिप कुहन

1
अहा, अच्छी बात है, शायद मैं इसे आने वाले हफ्तों में गीथहब पर रखूंगा और इसे आगे बढ़ाने की कोशिश करूंगा; ;-) @ फिलीपीन
21

1

उदाहरण के लिए आपका जवाब पहले सरणी lvl में सही काम कर रहा है:

$args['meta_query'][] = array(

  'key' => 'tour_itinerario_ciudades_repeater_%_tour_ciudades_nombre',
  '_key_compare' => 'LIKE',
  'value' => 'MEXICO',
  'compare' => 'LIKE',
  );

मुझे सरणी में दूसरे 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;
});

}); बस अगर किसी को इसी तरह के उत्तर की आवश्यकता है,

फिर से


साझा करने के लिए धन्यवाद, लेकिन यह सराहना की जाएगी यदि कोड टिप्पणी अंग्रेजी में थी, धन्यवाद।
बीरगीर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.