Làm cách nào để tạo một bản tóm tắt linh hoạt cho WP_Query?


8

Câu hỏi của tôi là về php nhưng nó liên quan đến wordpress khi tôi đang tạo một plugin. Trường hợp là tôi có 5 câu hỏi, mỗi câu hỏi có 6 lựa chọn và một lựa chọn để chọn từ mỗi câu hỏi. Bây giờ người đó sẽ chọn bất kỳ lựa chọn nào từ mỗi hoặc chỉ một vài. Tôi đã tạo ra điều kiện if hiện đang khiến tôi phát điên, vì nó đã đi quá lâu và sẽ làm thêm, giống như gần 100 kết hợp sẽ được thực hiện. Tôi không muốn điều đó, tôi biết có một cách của mảng đa chiều nhưng trong đó không phải là một plugin hoặc chuyên gia php cho wordpress. Vì vậy, nếu bất cứ ai có thể sắp xếp nó cho tôi.

$qs = $_POST['q1'];
$q2 = $_POST['q2'];
$q3 = $_POST['q3'];
$q4 = $_POST['q4'];
$q5 = $_POST['q5'];
$q6 = $_POST['q6'];



 $args = array(
  'post_type' => 'product',
  'posts_per_page' => -1,
  'tax_query' => array(
    'relation' => 'AND',
    array(
     'taxonomy' => 'product_cat',
     'field' => 'slug',
     'terms' => 'fashion-follower'
    ),
//    array(
//     'taxonomy' => 'product_cat',
//     'field' => 'slug',
//     'terms' => 'cheap-and-cheerful'
//    )
  )
);
 //The Fashionsia
 if (($qs ==='party') && ($q2 === 'clothes') && ($q3 === 'shopping') && ($q5 === 'Sunbathing') && ($q6 === 'mini')){

$query = new WP_Query( $args );
if( $query->have_posts()) : while( $query->have_posts() ) : $query->the_post();

     the_post_thumbnail('thumbnail');

endwhile;
    endif;      
}

//second question loop

$args2 = array(
  'post_type' => 'product',
  'posts_per_page' => -1,
  'tax_query' => array(
    'relation' => 'AND',
    array(
     'taxonomy' => 'product_cat',
     'field' => 'slug',
     'terms' => 'the-homemaker'
    ),
//    array(
//     'taxonomy' => 'product_cat',
//     'field' => 'slug',
//     'terms' => 'cheap-and-cheerful'
//    )
  )
);
 //The homemaker
 if (($qs ==='drink') && ($q2 === 'candles') && ($q3 === 'house') && ($q4 === 'diy')){

$query = new WP_Query( $args2 );
if( $query->have_posts()) : while( $query->have_posts() ) : $query->the_post();

     the_post_thumbnail('thumbnail');

endwhile;
    endif;      
}
//third loop

$args3 = array(
  'post_type' => 'product',
  'posts_per_page' => -1,
  'tax_query' => array(
    'relation' => 'AND',
    array(
     'taxonomy' => 'product_cat',
     'field' => 'slug',
     'terms' => 'entertainment'
    ),
//    array(
//     'taxonomy' => 'product_cat',
//     'field' => 'slug',
//     'terms' => 'cheap-and-cheerful'
//    )
  )
);
 //The Entertainer
 if (($qs ==='party-babe') && ($q2 === 'winer')&& ($q4 === 'storm') && ($q6 === 'limo')){

$query = new WP_Query( $args3 );
if( $query->have_posts()) : while( $query->have_posts() ) : $query->the_post();

     the_post_thumbnail('thumbnail');

endwhile;
    endif;      
}
//fourth loop
$args4 = array(
  'post_type' => 'product',
  'posts_per_page' => -1,
  'tax_query' => array(
    'relation' => 'AND',
    array(
     'taxonomy' => 'product_cat',
     'field' => 'slug',
     'terms' => 'family-fanatic'
    ),
//    array(
//     'taxonomy' => 'product_cat',
//     'field' => 'slug',
//     'terms' => 'cheap-and-cheerful'
//    )
  )
);
 //The family-fanatic
 if (($qs ==='movie') && ($q2 === 'kids')&& ($q6 === 'volvo')){

$query = new WP_Query( $args4 );
if( $query->have_posts()) : while( $query->have_posts() ) : $query->the_post();

     the_post_thumbnail('thumbnail');

endwhile;
    endif;      
}
//fifth loop
//fourth loop
$args4 = array(
  'post_type' => 'product',
  'posts_per_page' => -1,
  'tax_query' => array(
    'relation' => 'AND',
    array(
     'taxonomy' => 'product_cat',
     'field' => 'slug',
     'terms' => 'family-fanatic'
    ),
//    array(
//     'taxonomy' => 'product_cat',
//     'field' => 'slug',
//     'terms' => 'cheap-and-cheerful'
//    )
  )
);
 //The romantic
 if (($qs ==='Dinner-show') && ($q5 === 'cruiser')){

$query = new WP_Query( $args4 );
if( $query->have_posts()) : while( $query->have_posts() ) : $query->the_post();

     the_post_thumbnail('thumbnail');

endwhile;
    endif;      
}

Sự khác biệt cho câu hỏi trước đó của bạn là gì?
fuxia

@toscho sự khác biệt là ở chỗ Q. có câu hỏi về tái cấu trúc nhưng bây giờ tôi đang hỏi về việc tối ưu hóa mã cùng với vòng lặp wp hoặc thực hiện trong mảng.
Nofel

Câu trả lời:


18

Câu hỏi của bạn không thực sự về WordPress, nó là về PHP và tái cấu trúc. Nhưng chúng ta thấy rất nhiều mã xấu ở đây và mẫu tôi sẽ giải thích bên dưới (MVC) có thể giúp nhiều nhà phát triển khác, vì vậy tôi quyết định viết một câu trả lời nhỏ. Hãy nhớ rằng, có một trang web dành riêng cho các câu hỏi như vậy trong mạng của chúng tôi: Đánh giá mã . Thật không may, rất ít nhà phát triển WordPress đang hoạt động ở đó.


Cách mã hóa lại

  1. Xóa mã vô dụng. Làm đẹp phần còn lại.
  2. Tìm tất cả các biểu thức lặp lại và tạo các thường trình (hàm hoặc lớp) để trừu tượng hóa và gói gọn chúng.
  3. Xử lý dữ liệu riêng biệt, mô hình (lưu trữ, tìm nạp, chuyển đổi, giải thích), từ đầu ra, chế độ xem (HTML, CSV, bất cứ điều gì).

1. Xóa mã vô dụng. Làm đẹp phần còn lại.

Đầu ra

Bạn có đoạn lặp lại này:

if( $query->have_posts()) : while( $query->have_posts() ) : $query->the_post();

the_post_thumbnail('thumbnail');

endwhile;
endif;

Bạn chạy khá tốn kém the_post()mỗi lần để có được hình thu nhỏ bài đăng. Nhưng điều đó không cần thiết, bạn chỉ có thể gọi:

echo get_the_post_thumbnail( $post_id, 'post-thumbnail' );

Truy vấn

Vì vậy, tất cả những gì bạn cần là ID bài đăng, và điều này có sẵn mà không cần gọi the_post(). Thậm chí tốt hơn: bạn có thể hạn chế truy vấn chỉ tìm nạp ID.

Một ví dụ đơn giản:

$post_ids = array();
$args     = array(
    'post_type'      => 'post',
    'posts_per_page' => 10,
    'fields'         => 'ids'
);
$query    = new WP_Query( $args );

if ( ! empty ( $query->posts ) )
    $post_ids = $query->posts; // just the post IDs

Bây giờ bạn có ID và bạn có thể viết:

foreach ( $post_ids as $post_id )
    echo get_the_post_thumbnail( $post_id, 'post-thumbnail' );

Không có phí, mã của bạn đã nhanh hơn và dễ đọc hơn.

Cú pháp

Lưu ý cách tôi căn chỉnh = ? Điều này giúp hiểu mã, bởi vì tâm trí con người chuyên về nhận dạng mẫu. Hỗ trợ điều đó và chúng tôi có thể làm những điều tuyệt vời. Tạo một mớ hỗn độn, và chúng ta bị mắc kẹt rất nhanh.

Đây cũng là lý do tại sao tôi loại bỏ endwhileendif. Các cú pháp thay thế là lộn xộn và khó đọc. Thêm vào đó, nó làm cho việc làm việc trong một IDE khó hơn nhiều: gấp và nhảy từ đầu đến cuối một biểu thức dễ dàng hơn với niềng răng.

Các giá trị mặc định

$argsMảng của bạn có một số lĩnh vực bạn sử dụng ở mọi nơi. Tạo một mảng mặc định và viết các trường đó chỉ một lần :

$args = array(
    'post_type'      => 'product',
    'posts_per_page' => 100,
    'fields'         => 'ids',
    'tax_query'      => array(
        array(
            'taxonomy' => 'product_cat',
            'field'    => 'slug',
        )
    )
);

Một lần nữa, lưu ý sự liên kết. Và cũng lưu ý cách tôi thay đổi posts_per_pagegiá trị. Không bao giờ yêu cầu-1 . Điều gì xảy ra khi có một triệu bài viết phù hợp? Bạn không muốn giết kết nối cơ sở dữ liệu của mình mỗi khi truy vấn này chạy, phải không? Và ai nên đọc tất cả những bài viết này? Luôn đặt giới hạn hợp lý.

Bây giờ tất cả bạn phải thay đổi là lĩnh vực $args[ 'tax_query' ][ 'terms' ]. Chúng tôi sẽ đề cập đến điều đó trong một thời điểm.

2. Tìm tất cả các biểu thức lặp lại và tạo thói quen

Chúng tôi đã dọn sạch một số mã lặp lại, bây giờ là phần khó: đánh giá các tham số POST. Rõ ràng, bạn đã thực hiện một số nhãn là kết quả của một số tham số. Tôi đề nghị đổi tên chúng thành một cái gì đó dễ hiểu hơn, nhưng bây giờ chúng tôi sẽ làm việc với sơ đồ đặt tên của bạn.

Tách các nhóm này khỏi phần còn lại, tạo một mảng bạn có thể quản lý riêng sau:

$groups = array(
    'fashion-follower' => array(
        'q1' => 'party',
        'q2' => 'clothes',
        'q3' => 'shopping',
        'q4' => FALSE,
        'q5' => 'sunbathing',
        'q6' => 'mini',
    ),
    'the-homemaker' => array(
        'q1' => 'drink',
        'q2' => 'candles',
        'q3' => 'house',
        'q4' => 'diy',
        'q5' => FALSE,
        'q6' => FALSE,
    )
);

Để điền vào trường bị thiếu termstrong mảng mặc định của bạn, bạn chạy qua $groupsmảng cho đến khi bạn tìm thấy kết quả khớp:

function get_query_term( $groups )
{
    foreach ( $groups as $term => $values )
    {
        if ( compare_group_values( $values ) )
            return $term;
    }

    return FALSE;
}

function compare_group_values( $values )
{
    foreach ( $values as $key => $value )
    {
        // Key not sent, but required
        if ( empty ( $_POST[ $key ] ) and ! empty ( $value ) )
            return FALSE;

        // Key sent, but wrong value
        if ( ! empty ( $_POST[ $key ] ) and $_POST[ $key ] !== $value )
            return FALSE;
    }

    // all keys matched the required values
    return TRUE;
}

Tôi đã phân tách ngay cả việc chạy qua danh sách thuật ngữ và so sánh các giá trị, bởi vì đây là các hoạt động khác nhau. Mỗi phần trong mã của bạn chỉ nên làm một điều và bạn phải giữ mức thụt lề phẳng để dễ đọc hơn.

Bây giờ chúng ta có tất cả các bộ phận, hãy gắn chúng lại với nhau.

3. Tổ chức: Tách mô hình khỏi chế độ xem

Khi tôi viết mô hìnhkhung nhìn , tôi có một ý tưởng: cách tiếp cận MVC. Nó là viết tắt của Model View Controller , một mẫu nổi tiếng để tổ chức các thành phần phần mềm. Phần còn thiếu cho đến nay là bộ điều khiển, chúng ta sẽ thấy cách chúng ta sử dụng nó sau này.

Bạn nói, bạn không biết nhiều về PHP, vì vậy tôi hy vọng bạn biết nhiều hơn về đầu ra. :) Hãy bắt đầu với điều đó:

class Thumbnail_List
{
    protected $source;

    public function set_source( Post_Collector_Interface $source )
    {
        $this->source = $source;
    }

    public function render()
    {
        $post_ids = $this->source->get_post_ids();

        if ( empty ( $post_ids ) or ! is_array( $post_ids ) )
            return print 'Nothing found';

        foreach ( $post_ids as $post_id )
            echo get_the_post_thumbnail( $post_id, 'post-thumbnail' );
    }
}

Đẹp và đơn giản: chúng tôi có hai phương pháp: một để đặt nguồn cho ID bài đăng của chúng tôi, một để hiển thị hình thu nhỏ.

Bạn có thể tự hỏi đây Post_Collector_Interfacelà gì . Chúng tôi nhận được điều đó trong một khoảnh khắc.

Bây giờ nguồn cho quan điểm của chúng tôi, mô hình.

class Post_Collector implements Post_Collector_Interface
{
    protected $groups = array();

    public function set_groups( Array $groups )
    {
        $this->groups = $groups;
    }

    public function get_post_ids()
    {
        $term = $this->get_query_term();

        if ( ! $term )
            return array();

        return $this->query( $term );
    }

    protected function query( $term )
    {
        $args = array(
            'post_type'      => 'product',
            'posts_per_page' => 100,
            'fields'         => 'ids',
            'tax_query'      => array(
                array(
                    'taxonomy' => 'product_cat',
                    'field'    => 'slug',
                    'terms'    => $term
                )
            )
        );

        $query = new WP_Query( $args );

        if ( empty ( $query->posts ) )
            return array();

        return $query->posts;
    }

    protected function get_query_term()
    {
        foreach ( $this->groups as $term => $values )
        {
            if ( compare_group_values( $values ) )
                return $term;
        }

        return FALSE;
    }

    protected function compare_group_values( $values )
    {
        foreach ( $values as $key => $value )
        {
            // Key not sent, but required
            if ( empty ( $_POST[ $key ] ) and ! empty ( $value ) )
                return FALSE;

            // Kent sent, but wrong value
            if ( ! empty ( $_POST[ $key ] ) and $_POST[ $key ] !== $value )
                return FALSE;
        }

        // all keys matched the required values
        return TRUE;
    }
}

Điều này không còn tầm thường nữa, nhưng chúng tôi đã có hầu hết các phần. Các protected phương thức (hàm) không thể truy cập được từ bên ngoài, vì chúng ta chỉ cần chúng cho logic bên trong.

Các publicphương thức rất đơn giản: cái đầu tiên lấy $groupmảng của chúng ta từ phía trên, cái thứ hai trả về một mảng ID bài. Và một lần nữa chúng ta gặp điều đáng ngờ này Post_Collector_Interface.

Một giao diện là một hợp đồng . Nó có thể được ký (thực hiện) bởi các lớp. Yêu cầu một giao diện, giống như lớp của chúng tôi Thumbnail_List, có nghĩa là: lớp mong đợi một số lớp khác với các phương thức công khai này.

Hãy xây dựng giao diện đó. Nó thực sự đơn giản:

interface Post_Collector_Interface
{
    public function set_groups( Array $groups );

    public function get_post_ids();
}

Yup, đó là tất cả. Mã dễ dàng phải không?

Những gì chúng tôi đã làm ở đây: chúng tôi làm cho quan điểm của chúng tôi Thumbnail_Listđộc lập với một lớp cụ thể trong khi chúng tôi vẫn có thể dựa vào các phương thức của lớp chúng tôi có $source. Nếu bạn đổi ý sau này, bạn có thể viết một lớp mới để lấy ID bài đăng hoặc sử dụng một ID có giá trị cố định. Miễn là bạn thực hiện giao diện, chế độ xem sẽ được thỏa mãn. Bạn thậm chí có thể kiểm tra chế độ xem ngay bây giờ với một đối tượng giả:

class Mock_Post_Collector implements Post_Collector_Interface
{
    public function set_groups( Array $groups ) {}

    public function get_post_ids()
    {
        return array ( 1 );
    }
}

Điều này rất hữu ích khi bạn muốn kiểm tra xem. Bạn không muốn kiểm tra cả hai lớp cụ thể với nhau, bởi vì bạn sẽ không thấy lỗi xuất phát từ đâu. Đối tượng giả quá đơn giản cho các lỗi, lý tưởng cho các bài kiểm tra đơn vị.

Bây giờ chúng ta phải kết hợp các lớp học của chúng tôi bằng cách nào đó. Đây là nơi bộ điều khiển bước vào giai đoạn.

class Thumbnail_Controller
{
    protected $groups = array(
        'fashion-follower' => array(
            'q1' => 'party',
            'q2' => 'clothes',
            'q3' => 'shopping',
            'q4' => FALSE,
            'q5' => 'sunbathing',
            'q6' => 'mini',
        ),
        'the-homemaker' => array(
            'q1' => 'drink',
            'q2' => 'candles',
            'q3' => 'house',
            'q4' => 'diy',
            'q5' => FALSE,
            'q6' => FALSE,
        )
    );
    public function __construct()
    {
        // not a post request
        if ( 'POST' !== $_SERVER[ 'REQUEST_METHOD' ] )
            return;

        // set up the model
        $model = new Post_Collector;
        $model->set_groups( $this->groups );

        // prepare the view
        $view = new Thumbnail_List;
        $view->set_source( $model );

        // finally render the tumbnails
        $view->render();
    }
}

Bộ điều khiển là một phần duy nhất thực sự của một ứng dụng; mô hình và khung nhìn có thể được sử dụng lại ở đây và ở đó, ngay cả ở những phần hoàn toàn khác nhau. Nhưng bộ điều khiển tồn tại cho mục đích duy nhất này, đây là lý do tại sao chúng tôi đặt $groupở đây.

Và bây giờ bạn phải làm một điều duy nhất:

// Let the dogs out!
new Thumbnail_Controller;

Gọi dòng này bất cứ nơi nào bạn cần đầu ra.

Bạn có thể tìm thấy tất cả các mã từ câu trả lời này trong ý chính này trên GitHub .


6
Số ISBN của câu trả lời đó là gì?
kaiser

Sách giáo khoa trả lời thực sự: p
Manny Fleurmond

1
"Không bao giờ yêu cầu -1." Tôi sẽ nói: đặt một bộ lọc vào-1 để người dùng có các trang web lớn có thể thay đổi nó nếu họ cần.
chrisguitarguy

@chrisguitarguy Tôi muốn đặt mặc định an toàn và cho phép người dùng cần -1thêm bộ lọc đó vào mỗi bộ lọc. Điều này đã có thể với một bộ lọc trên truy vấn.
fuxia
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.