从shortcode atts数组值返回WP_Query对象

时间:2018-03-15 18:55:45

标签: php wordpress woocommerce shortcode product

希望返回在name中找到的每个匹配项(产品),其中name以逗号分隔,例如[woo_products_by_name name="shoe,shirt"]如果我没有explode name,则不会返回任何内容,因为只能看到shoe,shirt。如果使用explode,则查询不是选择性的,并且似乎返回了所有产品。如果仅使用'name' => $name并且指定了如上所述的两个产品,那么查询将按预期工作。想要为每个项目返回匹配项,因此在此示例中,将返回产品。

function woo_products_by_name_shortcode( $atts, $content = null ) {

        // Get attribuets
        extract(shortcode_atts(array(
        'name' => ''
        ), $atts));
        //$name = explode(",", $atts['name']);

        ob_start();
        // Define Query Arguments
        $loop = new  WP_Query( array(
                'post_type'      => 'product',
                'posts_per_page' => 10,
                'name'           => explode(",",$name)
        ));

        // Get products number
        $product_count = $loop->post_count;

        echo '<pre>'; print_r($loop->posts); echo '</pre>';
        return ob_get_clean();
}
add_shortcode("woo_products_by_name", "woo_products_by_name_shortcode");

2 个答案:

答案 0 :(得分:1)

理想情况下,您可以使用短代码中的id或其他可查询属性,如果您这样做,查询会更容易 - 但会违反get_by_name方法。

您可能正在考虑在foreach循环中运行两个单独的查询,或者更好的是放弃WP_Query而是使用get_page_by_path()

function woo_products_by_name_shortcode( $atts, $content = null ) {

    // Get attribuets
    extract(shortcode_atts(array(
    'name' => ''
    ), $atts));

    $name_array = explode(",", $atts['name']);

    ob_start();

    $products = array();
    foreach( $name_array as $product ){
        $products[$product] = get_page_by_path( $product, OBJECT, 'product' );
    }

    // Get products number
    $product_count = count( $name_array );

    echo '<pre>'; print_r($products); echo '</pre>';
    return ob_get_clean();
}
add_shortcode("woo_products_by_name", "woo_products_by_name_shortcode");

由于您提到需要使用WP_Query,因此您可以通过使用带有SQL查询的$wpdb类来获取id,然后使用这些ID运行WP_Query - 或者您可以从get_page_by_path获取ID并使用post__in参数查询这些ID(请注意双下划线)

function woo_products_by_name_shortcode( $atts, $content = null ) {

    // Get attribuets
    extract(shortcode_atts(array(
        'name' => ''
    ), $atts));

    $name_array  = explode(",", $atts['name']);
    $product_ids = array();

    foreach( $name_array as $product ){
        $product = get_page_by_path( $product, OBJECT, 'product' );
        $product_ids[] = $product->ID;
    }

    ob_start();
    // Define Query Arguments
    $loop = new WP_Query( array(
        'post_type'      => 'product',
        'posts_per_page' => 10,
        'post__in'       => $product_ids
    ));

    // Get products number
    $product_count = $loop->post_count;

    echo '<pre>'; print_r($loop->posts); echo '</pre>';
    return ob_get_clean();
}
add_shortcode("woo_products_by_name", "woo_products_by_name_shortcode");

答案 1 :(得分:1)

这可以使用非常轻的SQL请求来完成,该请求将为您的产品slug提供产品ID。然后使用WP_Query post__in参数,您将得到您期望的结果:

function woo_products_by_name_shortcode( $atts, $content = null ) {

    // Get attribuets
    extract(shortcode_atts(array(
        'name' => ''
    ), $atts));

    if( empty($name) ) return;

    // Format product slugs string
    $name = str_replace(",", "','", $name);

    global $wpdb;
    // Get the corresponding products ids
    $ids = $wpdb->get_col( "SELECT ID FROM {$wpdb->prefix}posts
        WHERE post_type = 'product' AND post_name IN('$name')" );

    ob_start();

    // Define Query Arguments
    $loop = new  WP_Query( array(
        'post_type'      => 'product',
        'posts_per_page' => -1,
        'post__in'       => $ids
    ));

    // Get products number
    $product_count = $loop->post_count;

    echo '<pre>'; print_r($loop->posts); echo '</pre>';

    return ob_get_clean();
}
add_shortcode("woo_products_by_name", "woo_products_by_name_shortcode");

代码进入活动子主题(或活动主题)的function.php文件。经过测试并正常工作。

在html / php中测试输出:

<?php echo do_shortcode( "[woo_products_by_name name='shoe,shirt']" ); ?>

在Wordpress文本编辑器中测试输出:

[woo_products_by_name name='shoe,shirt']