2

I want to display data based on query parameters passed through URL: https://example.com/?make=nike&model=shox&colour=white&body_type=slim.

  1. I can browse "nike" stock by accessing https://example.com/?make=nike.

  2. I can browse "nike shox" by accessing https://example.com/?make=nike&model=shox.

  3. I can't browse "nike shox white" https://example.com/?make=nike&model=shox&colour=white as I'm getting mixed results not related with query.

  4. I can't browse "nike shox white slim" https://example.com/?make=nike&model=shox&colour=white&body_type=slim as I'm getting mixed results not related with query.

  5. I can access "white" https://example.com/?colour=white.

  6. I can access "slim" https://example.com/?body_type=slim.

I'm using following code:

if ( isset( $query->query_vars['post_type'] ) && $query->query_vars['post_type'] == 'post' ) {

    // allow the url to alter the query
    if ( isset( $_GET['make'] ) ) {

        $query->set( 'meta_key', 'make' );
        $query->set( 'meta_value', $_GET['make'] );

    } 

    if ( isset( $_GET['model'] ) ) {

        $query->set( 'meta_key', 'model' );
        $query->set( 'meta_value', $_GET['model'] );

    } 
    if ( isset( $_GET['colour'] ) ) {

        $query->set( 'meta_key', 'colour' );
        $query->set( 'meta_value', $_GET['colour'] );

    }

    if ( isset( $_GET['body_type'] ) ) {

        $query->set( 'meta_key', 'body_type' );
        $query->set( 'meta_value', $_GET['body_type'] );

    } 

}

What am I doing wrong? Cheers!

1
  • 1
    For security, you should consider filter_var() to filter each $_GET request. Whilst also looking into get_query_var(). Commented Jan 29, 2019 at 22:07

1 Answer 1

3

Each time you call $query->set( 'key', 'value' ); the previous value gets overwritten.

If I am guessing right, the parameters ?make=nike&model=shox are only "working" because shox is the last parameter, and there are only shox models with make=nike.

You could do something like this:

$metaQuery = [];

if ( isset( $_GET['make'] ) ) {
    $metaQuery[] = [
        'key'     => 'make',
        'value'   => $_GET['make'],
        'compare' => '=',
    ];
}
if ( isset( $_GET['model'] ) ) {
    $metaQuery[] = [
        'key'     => 'model',
        'value'   => $_GET['model'],
        'compare' => '=',
    ];
}
if ( isset( $_GET['colour'] ) ) {
    $metaQuery[] = [
        'key'     => 'colour',
        'value'   => $_GET['colour'],
        'compare' => '=',
    ]; 
}
if ( isset( $_GET['body_type'] ) ) { 
    $metaQuery[] = [
        'key'     => 'body_type',
        'value'   => $_GET['body_type'],
        'compare' => '=',
    ];
}

$query->set( 'meta_query', $metaQuery );

You could do it even cleaner using a foreach() loop on the $_GET superglobal.

$metaQuery = [];

foreach ( $_GET as $metaKey => $metaValue ) {
    $metaQuery[] = [
        'key'     => $metaKey,
        'value'   => $metaValue,
        'compare' => '=',
    ];
}

if ( count( $metaQuery ) > 0 ) {
    $query->set( 'meta_query', $metaQuery );
} 
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.