Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何按分类术语从自定义WordPress MySQL查询中排除结果_Php_Mysql_Wordpress_Custom Taxonomy - Fatal编程技术网

Php 如何按分类术语从自定义WordPress MySQL查询中排除结果

Php 如何按分类术语从自定义WordPress MySQL查询中排除结果,php,mysql,wordpress,custom-taxonomy,Php,Mysql,Wordpress,Custom Taxonomy,我只想展示分类法“产品品牌”中没有“品牌鼻涕虫”一词的帖子 我当前的查询未应用筛选器: SELECT DISTINCT * FROM $wpdb->posts AS p LEFT JOIN $wpdb->postmeta AS meta ON p.ID = meta.post_id LEFT JOIN $wpdb->term_relationships AS rel ON rel.object_id = p.ID LEFT JOIN $wpdb->term_t

我只想展示分类法“产品品牌”中没有“品牌鼻涕虫”一词的帖子

我当前的查询未应用筛选器:

SELECT DISTINCT * FROM $wpdb->posts AS p
  LEFT JOIN $wpdb->postmeta AS meta ON p.ID = meta.post_id
  LEFT JOIN $wpdb->term_relationships AS rel ON rel.object_id = p.ID
  LEFT JOIN $wpdb->term_taxonomy AS tax ON tax.term_taxonomy_id = rel.term_taxonomy_id
  LEFT JOIN $wpdb->terms AS term ON tax.term_id = term.term_id
WHERE 1=1
    AND p.post_type = 'product' 
    AND p.post_status = 'publish' 
    AND p.post_title LIKE '%$trimmed%' OR (meta.meta_key = 'product_model' AND meta.meta_value LIKE '%$trimmed%') 
    AND (tax.taxonomy = 'product-brand' AND term.slug NOT IN ('$protected'))
在上述查询中,分类法和slug条件似乎都不起作用

感谢您的帮助

注: 看起来您没有使用
$wpdb->prepare()
,因此您有SQL注入的风险

我还认为,您在相关的或部分周围缺少括号,因此您最终不会显示草稿

备选方案: 我们应该能够使用
WP\u query
类,通过钩子/过滤器进行一些修改,而不是编写硬编码的SQL查询

下面是一个示例(PHP 5.4+):

其中自定义的
\u meta\u或类似的\u title
参数由我为另一个插件编写的稍加修改的插件支持

插件:
我写了同样的方法(中途放弃了),因为我一直在按标题或自定义字段搜索帖子。实际上,我使用了
posts.*
过滤方式。就像你的自定义方法比我的好:-)我们需要设法处理整个元查询,因此
posts.*
过滤器不如
get\u meta\u sql
过滤器合适。但是也许有一种方法可以使用
posts.*
过滤器,通过添加一个优先级为
0
的过滤器和另一个优先级为
PHP\u INT\u MAX
的过滤器?但是我们仍然需要识别元查询,所以我想我们需要更多的东西来使用这种方法;-)@皮耶特古森也许是可能的,但过了一段时间,情况变得相当混乱。我尝试了几种方法,但没有成功。正如我所说的,你的方法肯定更好,而且麻烦更少。这里的可重用性非常好。您有一个简单的函数,一个额外的参数,可以在数百个自定义查询中重复使用,而无需复制和修改自定义筛选器是的,这听起来是一个更困难的挑战;-)我曾经扩展了
WP\u查询
类来获取额外的内容。但现在我更喜欢通过自定义参数添加新功能,如果插件被删除,这不会破坏代码,并且通过在自定义参数名称中使用前缀
wpse\u
\u
,我们应该能够避免名称冲突。但这种方法的优点在于,我们也可以通过
pre_get_posts
;-)在主查询中使用它@PieterGoosenI必须说,你让我迷上了这种方法;-)
$args = [ 
    '_meta_or_like_title' => $trimmed,        // Our new custom argument!
    'post_type'           => 'product',
    'post_status'         => 'publish',
    'meta_query'          => [
        [
            'key'     => 'product_model',
            'value'   => $trimmed,            // Your meta value
            'compare' => 'LIKE'
        ]
    ],
    'tax_query'    => [
        [
            'taxonomy'  => 'product-brand',
            'field'     => 'slug',
            'terms'     => $protected,        // Your terms array
            'operator'  => 'NOT IN'
        ]
    ]
];
<?php
/**
 *  Plugin Name:   Meta OR LIKE Title query in WP_Query
 *  Description:   Activated through the '_meta_or_like_title' argument of WP_Query 
 *  Plugin URI:    http://stackoverflow.com/a/31241416/2078474
 *  Plugin Author: Birgir Erlendsson (birgire)
 *  Version:       0.0.1
 */

add_action( 'pre_get_posts', function( $q )
{
    if( $title = $q->get( '_meta_or_like_title' ) )
    {
        add_filter( 'get_meta_sql', function( $sql ) use ( $title )
        {
            global $wpdb;

            // Only run once:
            static $nr = 0; 
            if( 0 != $nr++ ) return $sql;

            // Modify WHERE part:
            $sql['where'] = sprintf(
                " AND ( %s OR %s ) ",
                $wpdb->prepare( 
                    "{$wpdb->posts}.post_title LIKE '%%%s%%'", 
                     $wpdb->esc_like( $title ) 
                ),
                mb_substr( $sql['where'], 5, mb_strlen( $sql['where'] ) )
            );
            return $sql;
        });
    }
}, PHP_INT_MAX );