বিভাগ এবং পোস্ট_ টাইপ অনুসারে পদ পান terms


17

আমার কাছে 2 টি কাস্টম পোস্ট প্রকারের 'বুকমার্ক' এবং 'স্নিপেটস' এবং একটি ভাগ করা ট্যাক্সনোমি 'ট্যাগ' রয়েছে। আমি get_terms () দিয়ে কর বিভাগে সমস্ত পদগুলির একটি তালিকা তৈরি করতে পারি, তবে কীভাবে তালিকাটি পোস্টের সীমাতে সীমাবদ্ধ করতে হবে তা আমি বুঝতে পারি না। আমি মূলত যা খুঁজছি তা হ'ল এইরকম:

get_terms(array('taxonomy' => 'tag', 'post_type' => 'snippet'));

এই অর্জন করার জন্য একটি উপায় আছে কি? আইডিয়াগুলি ব্যাপকভাবে প্রশংসা করা হয় !!

ওহ, আমি WP 3.1.1 এ আছি

উত্তর:


11

একটি এসকিউএল কোয়েরি সহ অনুরূপ কিছু করার এখানে অন্য উপায়:

static public function get_terms_by_post_type( $taxonomies, $post_types ) {

    global $wpdb;

    $query = $wpdb->prepare(
        "SELECT t.*, COUNT(*) from $wpdb->terms AS t
        INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id
        INNER JOIN $wpdb->term_relationships AS r ON r.term_taxonomy_id = tt.term_taxonomy_id
        INNER JOIN $wpdb->posts AS p ON p.ID = r.object_id
        WHERE p.post_type IN('%s') AND tt.taxonomy IN('%s')
        GROUP BY t.term_id",
        join( "', '", $post_types ),
        join( "', '", $taxonomies )
    );

    $results = $wpdb->get_results( $query );

    return $results;

}

হ্যাঁ! এটি আমি যা চাই ঠিক তাই করে।
গ্যাভিন হুইট

print_r(get_terms_by_post_type(array('category') , array('event') ));শোWarning: Missing argument 2 for wpdb::prepare()
ডিভো

আমি ভুল হতে পারি, তবে আমার মাথার উপরের দিক থেকে, আমি মনে করি না যে এই 'যোগদান' বিবৃতিগুলি কাজ করবে - যেমন, তারা কেবলমাত্র একক-মান অ্যারে পাস করলে কাজ করবে। এটি কারণ কারণ প্রস্তুত ফাংশনটি সমস্ত উত্পন্ন একক-উদ্ধৃতি থেকে রক্ষা পাবে এবং প্রত্যেকে পুরো 'একত্রিত' হিসাবে একটি স্ট্রিং বিবেচনা করবে।
কোডস্মিত

14

সুতরাং এটি ঠিক ঘটে যে আমি যে প্রকল্পে কাজ করছি তার জন্য আমার এর মতো কিছু দরকার ছিল। আমি কেবল একটি কাস্টম ধরণের সমস্ত পোস্ট নির্বাচন করার জন্য একটি ক্যোয়ারী লিখেছি, তারপরে আমি যাচাই করেছিলাম যে তারা আমার ব্যবহারযোগ্য বিভাগের প্রকৃত পদগুলি কী।

তারপরে আমি সেই ব্যবহারের সমস্ত শর্তাদি ব্যবহার করে পেয়েছি get_terms() এবং তারপরে আমি কেবলমাত্র দুটি তালিকায় করেছি, এটি একটি ফাংশনে আবদ্ধ করেছিলাম এবং আমার কাজ শেষ হয়েছিল।

তবে তারপরে আমার আরও বেশি প্রয়োজন তখন কেবল আইডি'র: আমার নামগুলির দরকার ছিল তাই আমি একটি নতুন যুক্তি যুক্ত $fieldsকরলাম যাতে ফাংশনটি কী ফিরে আসতে হবে তা বলতে পারি। তারপরে আমি অনুভব করেছি যে get_termsঅনেকগুলি আর্গুমেন্ট গ্রহণ করে এবং আমার ফাংশন কেবলমাত্র পদগুলির মধ্যে সীমাবদ্ধ ছিল যা পোস্ট ধরণের দ্বারা ব্যবহৃত হয় তাই আমি আরও একটি যুক্ত করেছিif বিবৃতি যুক্ত করেছি এবং আপনি সেখানে যান:

কাজ:

/* get terms limited to post type 
 @ $taxonomies - (string|array) (required) The taxonomies to retrieve terms from. 
 @ $args  -  (string|array) all Possible Arguments of get_terms http://codex.wordpress.org/Function_Reference/get_terms
 @ $post_type - (string|array) of post types to limit the terms to
 @ $fields - (string) What to return (default all) accepts ID,name,all,get_terms. 
 if you want to use get_terms arguments then $fields must be set to 'get_terms'
*/
function get_terms_by_post_type($taxonomies,$args,$post_type,$fields = 'all'){
    $args = array(
        'post_type' => (array)$post_type,
        'posts_per_page' => -1
    );
    $the_query = new WP_Query( $args );
    $terms = array();
    while ($the_query->have_posts()){
        $the_query->the_post();
        $curent_terms = wp_get_object_terms( $post->ID, $taxonomy);
        foreach ($curent_terms as $t){
          //avoid duplicates
            if (!in_array($t,$terms)){
                $terms[] = $c;
            }
        }
    }
    wp_reset_query();
    //return array of term objects
    if ($fields == "all")
        return $terms;
    //return array of term ID's
    if ($fields == "ID"){
        foreach ($terms as $t){
            $re[] = $t->term_id;
        }
        return $re;
    }
    //return array of term names
    if ($fields == "name"){
        foreach ($terms as $t){
            $re[] = $t->name;
        }
        return $re;
    }
    // get terms with get_terms arguments
    if ($fields == "get_terms"){
        $terms2 = get_terms( $taxonomies, $args );
        foreach ($terms as $t){
            if (in_array($t,$terms2)){
                $re[] = $t;
            }
        }
        return $re;
    }
}

ব্যবহার:

আপনার যদি কেবলমাত্র টার্ম আইডির একটি তালিকা প্রয়োজন তবে:

$terms = get_terms_by_post_type('tag','','snippet','ID');

আপনার যদি কেবলমাত্র পদ নামগুলির একটি তালিকা প্রয়োজন তবে:

$terms = get_terms_by_post_type('tag','','snippet','name');

আপনার যদি কেবলমাত্র শব্দ পদগুলির একটি তালিকা প্রয়োজন তবে:

$terms = get_terms_by_post_type('tag','','snippet');

এবং যদি আপনাকে get_terms এর মতো অতিরিক্ত যুক্তি ব্যবহার করার প্রয়োজন হয় যেমন: অর্ডারবাই, অর্ডার, শ্রেণিবদ্ধ ...

$args = array('orderby' => 'count', 'order' => 'DESC',  'hide_empty' => 1);
$terms = get_terms_by_post_type('tag',$args,'snippet','get_terms');

উপভোগ করুন!

হালনাগাদ:

নির্দিষ্ট পোস্টের পরিবর্তনের শর্ত গণনা স্থির করতে:

foreach ($current_terms as $t){
          //avoid duplicates
            if (!in_array($t,$terms)){
                $terms[] = $t;
            }
        }

প্রতি:

foreach ($current_terms as $t){
    //avoid duplicates
    if (!in_array($t,$terms)){
        $t->count = 1;
        $terms[] = $t;
    }else{
        $key = array_search($t, $terms);
        $terms[$key]->count = $terms[$key]->count + 1;
    }
}

আপনি যদি (array) $args4 $ ওয়ার্সের তালিকার পরিবর্তে ব্যবহার করেন তবে ভাল হয় না ? এটি আপনাকে আর্গুমেন্টগুলিতে যে অর্ডার দেয় তা যত্ন না করার অনুমতি দেয়, সুতরাং এর মতো কিছু get_terms_by_post_type( $args = array( 'taxonomies', 'args', 'post_type', 'fields' => 'all') )এবং এর সাথে ফাংশনের ভিতরে তাদের কল করুন $args['taxonomies']। এটি আপনাকে খালি মূল্য যুক্ত করতে এবং আপনার যুক্তির ক্রমটি মনে রাখতে দূরে থাকতে সহায়তা করবে। আমি ডাবলের পরিবর্তে একক উদ্ধৃতি ব্যবহার করার পরামর্শ দিই। আমি তাদের পাঁচগুণ দ্রুত মধুচক্র করতে দেখেছি।
কায়সার

1
@ কেজার - ডাবল উদ্ধৃত স্ট্রিংগুলি বিশ্লেষণ করতে হবে, যেখানে একক উদ্ধৃত মান হিসাবে সর্বদা আক্ষরিক হিসাবে বিবেচিত হয়। আপনি যখন স্ট্রিংয়ে ভেরিয়েবল ব্যবহার করছেন তখন এটি বোধগম্য হয় এবং ডাবল কোট ব্যবহার করা পুরোপুরি ঠিক আছে তবে অ-পরিবর্তনশীল স্ট্রিংয়ের মানগুলির জন্য একক উদ্ধৃতি আরও আদর্শ (কারণ তাদের পার্স করার প্রয়োজন হবে না) এবং কিছুটা দ্রুত (আমরা ' বেশিরভাগ ক্ষেত্রে মিলিসেকেন্ড সম্পর্কে কথা বলছি)।
t31os

@ t31os - একেবারে সঠিক। আমি এখনও পঠনযোগ্যতার কারণে 'this is my mood: '.$valueবেশি পছন্দ করি "this is my mood: $value"। যখন এটি গতিতে আসে: এটি সামান্য নয় - আমি পাঁচ বার পর্যন্ত পরিমাপ করেছি। এবং আপনি যখন আপনার পুরো থিমটিতে ডাবল কোটগুলি সর্বত্র ব্যবহার করবেন তখন আপনার প্রচুর অনুরোধ পেলে তা দ্রুত যোগ হয়ে যায়। যাইহোক ভাল আপনি যে পরিষ্কার করেছেন।
কায়সার

@ t31os আউট আলোচনার গতি আমি পুনরায় meassured "বনাম 'আমি ভুল ছিল। পার্থক্যটি যে কারও নজরে আসবে তার বাইরে অনেক বেশি।
কায়সার

1
+1 দুর্দান্ত ফাংশন! 2 টি টাইপস: $ টেকনোমিগুলি ফাংশনটিতে ব্যবহৃত হয় $ ট্যাক্সোনমি এবং $ পদগুলি [] = $ সি; $ পদ হতে হবে [] = $ t;
রব ভার্মীর

8

আমি একটি ফাংশন আপনি পাস করার অনুমতি দেয় যে লিখেছে post_typeমধ্যে $argsঅ্যারের get_terms()ফাংশন:

এসকিউএল লেখার জন্য @ ব্র্যাডনে এইচটি।

 /**
 * terms_clauses
 *
 * filter the terms clauses
 *
 * @param $clauses array
 * @param $taxonomy string
 * @param $args array
 * @return array
**/
function terms_clauses($clauses, $taxonomy, $args)
{
    global $wpdb;

    if ($args['post_type'])
    {
        $clauses['join'] .= " INNER JOIN $wpdb->term_relationships AS r ON r.term_taxonomy_id = tt.term_taxonomy_id INNER JOIN $wpdb->posts AS p ON p.ID = r.object_id";
        $clauses['where'] .= " AND p.post_type='{$args['post_type']}'"; 
    }
    return $clauses;
}
add_filter('terms_clauses', 'terms_clauses', 10, 3);

7

দুর্দান্ত প্রশ্ন এবং কঠিন উত্তর।

আমি @ জেসিকার দ্বারা পদ__ ক্লাউজ ফিল্টারটি ব্যবহার করে সত্যই পছন্দ করেছি, কারণ এটি get_terms ফাংশনটি খুব যুক্তিসঙ্গতভাবে প্রসারিত করে।

আমার কোডটি তার ধারণার ধারাবাহিকতা, ডাবলিকেটগুলি হ্রাস করার জন্য @ ব্রায়ডন থেকে কিছু বর্গক্ষেত্র সহ। এটি পোস্ট_ টাইপগুলির একটি অ্যারের জন্যও অনুমতি দেয়:

/**
 * my_terms_clauses
 *
 * filter the terms clauses
 *
 * @param $clauses array
 * @param $taxonomy string
 * @param $args array
 * @return array
 **/
function my_terms_clauses($clauses, $taxonomy, $args)
{
  global $wpdb;

  if ($args['post_types'])
  {
    $post_types = $args['post_types'];

    // allow for arrays
    if ( is_array($args['post_types']) ) {
      $post_types = implode("','", $args['post_types']);
    }
    $clauses['join'] .= " INNER JOIN $wpdb->term_relationships AS r ON r.term_taxonomy_id = tt.term_taxonomy_id INNER JOIN $wpdb->posts AS p ON p.ID = r.object_id";
    $clauses['where'] .= " AND p.post_type IN ('". esc_sql( $post_types ). "') GROUP BY t.term_id";
  }
  return $clauses;
}
add_filter('terms_clauses', 'my_terms_clauses', 99999, 3);

কারণ get_terms এর গ্রুপের জন্য একটি ধারা নেই, আমাকে এটি পুরো দফাটির শেষে যুক্ত করতে হয়েছিল। লক্ষ্য করুন যে আমার ফিল্টার অগ্রাধিকারটি খুব উচ্চ-স্থিত রয়েছে, আশা করি এটি সর্বদা শেষ হয়।


3

গ্যাভিনের উপরের কোডটির সংস্করণ নিয়ে কাজ করতে আমি get_terms আর্গুমেন্ট তৈরি করতে অক্ষম ছিলাম, তবে শেষ পর্যন্ত পরিবর্তনের মাধ্যমে করেছি

$terms2 = get_terms( $taxonomy );

প্রতি

$terms2 = get_terms( $taxonomy, $args );

যেমন এটি বেন্টারনেট থেকে মূল ফাংশনে ছিল।


1
এটি বর্তমান সংস্করণে স্থির করে
গ্যাভিন হুইট

0

@ বেনারনেট: ধন্যবাদ! আমাকে কিছুটা পরিবর্তন করতে হয়েছিল কারণ এটি কাজ করছে না (কিছু টাইপস)। এখন একমাত্র সমস্যা হ'ল শব্দ গণনা বন্ধ। গণনা পোস্টের ধরণটিকে বিবেচনায় নিচ্ছে না তাই আমি মনে করি না আপনি এতে get_terms () ব্যবহার করতে পারেন।

function get_terms_by_post_type($post_type,$taxonomy,$fields='all',$args){
    $q_args = array(
        'post_type' => (array)$post_type,
        'posts_per_page' => -1
    );
    $the_query = new WP_Query( $q_args );

    $terms = array();

    while ($the_query->have_posts()) { $the_query->the_post();

        global $post;

        $current_terms = get_the_terms( $post->ID, $taxonomy);

        foreach ($current_terms as $t){
            //avoid duplicates
            if (!in_array($t,$terms)){
                $t->count = 1;
                $terms[] = $t;
            }else{
                $key = array_search($t, $terms);
                $terms[$key]->count = $terms[$key]->count + 1;
            }
        }
    }
    wp_reset_query();

    //return array of term objects
    if ($fields == "all")
        return $terms;
    //return array of term ID's
    if ($fields == "ID"){
        foreach ($terms as $t){
            $re[] = $t->term_id;
        }
        return $re;
    }
    //return array of term names
    if ($fields == "name"){
        foreach ($terms as $t){
            $re[] = $t->name;
        }
        return $re;
    }
    // get terms with get_terms arguments
    if ($fields == "get_terms"){
        $terms2 = get_terms( $taxonomy, $args );

        foreach ($terms as $t){
            if (in_array($t,$terms2)){
                $re[] = $t;
            }
        }
        return $re;
    }
}

সম্পাদনা: সংশোধন (এস) যুক্ত হয়েছে। তবে একরকম এটি এখনও আমার পক্ষে কাজ করছে না। গণনাটি এখনও ভুল মান দেখায়।


এটি একটি ভিন্ন গল্প, তবে আপনি যখন লুপটিতে ডুপ্লিকেটগুলি এড়িয়ে যাবেন তখন আপনি গণনা করতে পারেন।
বেন্টারনেট

আমি আমার উত্তরটি একটি টার্ম কাউন্ট ফিক্সের সাথে আপডেট করেছি।
বেন্টারনেট

1
দয়া করে উত্তর হিসাবে ফলো-আপগুলি যুক্ত করবেন না, যদি না আপনি নির্দিষ্টভাবে নিজের প্রশ্নের উত্তর দিয়ে থাকেন , পরিবর্তে মূল প্রশ্নের সাথে সংযোজন করা উচিত।
t31os

1
@ t31os: হ্যাঁ হ্যাঁ, আমি কীভাবে যুক্ত করব তা ভাবছিলাম। আমার প্রশ্নটি সম্পাদনা করার কথা ভাবেননি। ধন্যবাদ!
গ্যাভিন হুইট

আমি এই কল করতে পারেন কিভাবে? print_r(get_terms_by_post_typea(array('event','category','',array()));এই এক দেয় Warning: Invalid argument supplied for foreach()লাইন জন্যforeach ($current_terms as $t){
devo

0

সদৃশগুলি এড়িয়ে চলুন:

//avoid duplicates
    $mivalor=$t->term_id;
    $arr=array_filter($terms, function ($item) use ($mivalor) {return isset($item->term_id) && $item->term_id == $mivalor;});

    if (empty($arr)){
    $t->count=1;
            $terms[] = $t;
        }else{
            $key = array_search($t, $terms);
            $terms[$key]->count = $terms[$key]->count + 1;
        }

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