WP_Query meta_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',
    ),
  ),
));

ফিল্টার দিয়ে এটি অর্জন করার কোনও উপায় আছে কি? বা আমার নিজের এসকিউএল কোয়েরি নিয়ে এগুলি নিজেই তৈরি করতে হবে?

উত্তর:


9

এখানে একটি পরীক্ষামূলক ধারণা:

ধরুন আমরা পেয়েছি:

ইউ কে হিসাবে কাস্টম ক্ষেত্রের সাথে একটি পোস্ট করুন - লন্ডন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
সান্তার ছোট সহায়কদের মতো - তারা সাধারণত এগুলি সব শেষ পর্যন্ত জাদুকরীভাবে কাজ করে তোলে ;-) @ পিটারগুসেন
বার্জায়ার

1
ধন্যবাদ, আমি এটি ঠিক করেছি। $count++একটি স্ট্রিং নির্মাণে সবেমাত্র ব্যবহৃত হয়েছিল যখন আমি ভুলে গিয়েছিলাম যে আমাকে $countদুবার ব্যবহার করতে হবে ;-) আমি আন্ডারস্কোর বাদে মূল নামগুলিতে বিশেষ অক্ষর ব্যবহার করার পরামর্শ দেব না । আপনি আপনার কীতে প্রথম বন্ধনী ব্যবহার করছেন। নিয়মিত প্রকাশের সাথে তাদের একটি বিশেষ অর্থ রয়েছে। আপনি তাদের সঙ্গে অব্যাহতি হবে তাই \(এবং \)REGEXPবা RLIKE, কিন্তু পলায়নপর আমার প্লাগইন সমর্থিত নয়। আপনি এর LIKEপরিবর্তে চেষ্টা করতে পারেন custom_field_language(%)language। @ ফিলিপাহ্ন
বার্জায়ার

1
প্রতিভা! একটি যাদুমন্ত্র মত কাজ করে!
ফিলিপ কাহন

1
আহা, ভালো কথা, সম্ভবত আমি আসন্ন সপ্তাহগুলিতে গিটহাবের উপরে এটি রাখব এবং সেখানে এটি প্রসারিত করার চেষ্টা করব ;-) @ ফিলিপাহ্ন
বার্গিরে

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

}); যদি কোনও অনুরূপ উত্তর প্রয়োজন হয় তবেই,

আবারও


ভাগ করে নেওয়ার জন্য ধন্যবাদ, তবে কোড কোডটি ইংরাজীতে থাকলে এটি প্রশংসা হবে, ধন্যবাদ।
বিরগিরে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.