it-swarm.com.de

Abfrage von Zeichenfolgenparametern aus benutzerdefinierten Feldern, inkonsistente Ergebnisse

Ich habe einen benutzerdefinierten Beitragstyp namens course. Innerhalb eines Kurspostens gibt es eine Reihe von benutzerdefinierten Feldern (alle AFC-Dropdown-Listen): course_or_project, time_to_complete_project, time_to_complete_course und difficulty. Ich habe auch eine Taxonomie namens course_project_category.

Mein Ziel ist es, in der Lage zu sein, eine Reihe von Dropdowns/Schiebereglern zu erstellen, eine URL durch Lesen der Werte dieser Dropdowns/Schieberegler zu erstellen und beim Klicken auf eine Suchschaltfläche die von mir zusammengestellte Abfragezeichenfolge (jQuery) zu verwenden, um nur zu filtern die richtigen Beiträge. Diese Funktionalität funktioniert alles. Naja ... manchmal sind die Ergebnisse etwas verwirrt, d. H. Nur nach einigen Parametern filtern.

Weiter zum Code.

Ich habe eine Funktion hinzugefügt, um meine benutzerdefinierten Felder anzuzeigen:

function my_pre_get_posts( $query ) {

// do not modify queries in the admin
if( is_admin() ) {
    return $query;
}

// only modify queries for 'course' post type
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'course' ) {

    // allow the url to alter the query
    if( isset($_GET['course_or_project']) ) {
        $query->set('meta_key', 'course_or_project');
        $query->set('meta_value', $_GET['course_or_project']);
    } 

    if( isset($_GET['time_to_complete_project']) ) {
        $query->set('meta_key', 'time_to_complete_project');
        $query->set('meta_value', $_GET['time_to_complete_project']);
    } 

    if( isset($_GET['time_to_complete_course']) ) {
        $query->set('meta_key', 'time_to_complete_course');
        $query->set('meta_value', $_GET['time_to_complete_course']);    
    } 

    if( isset($_GET['difficulty']) ) {    
        $query->set('meta_key', 'difficulty');
        $query->set('meta_value', $_GET['difficulty']);
    } 

}

// return
return $query;

}

add_action('pre_get_posts', 'my_pre_get_posts');

Das Abfragen der Taxonomie scheint sofort zu funktionieren.

Ein Beispiel für meine vervollständigte URL könnte also sein:

http://localhost:3000/courses/?course_project_category=jokes&course_or_project=project&difficulty=easy&time_to_complete_project=15

Meine Ergebnisse sind zu diesem Zeitpunkt uneinheitlich.

Von der obigen Abfrage habe ich 2 Posts zurückgegeben, die größtenteils meinen Kriterien entsprechen, aber als spezielles Beispiel hat ein Post einen time_to_complete_project-Wert als 30, obwohl die Abfrage 15 angegeben hat.

Ich kann das nicht herausfinden. Ich kann sehen, dass alle Parameter dort sind, wie von den Chrome-Entwicklertools erwartet:

 enter image description here 

Irgendwelche Ideen?!

Update

Hier ist ein neuer Ansatz, der funktioniert (es mangelt jedoch an Validierung und Hygiene):

// array of filters (field key => field name)
    $GLOBALS['my_query_filters'] = array( 
        'field_1'   => 'course_or_project', 
        'field_2'   => 'difficulty',
        'field_3'   => 'time_to_complete_project',
        'field_4'   => 'time_to_complete_course'
    );
// action

add_action('pre_get_posts', 'my_pre_get_posts', 10, 1);

function my_pre_get_posts( $query ) {

    // bail early if is in admin
    if( is_admin() ) {

        return;

    }

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

        // get meta query
        $meta_query = $query->get('meta_query');


        // loop over filters
        foreach( $GLOBALS['my_query_filters'] as $key => $name ) {

            // continue if not found in url
            if( empty($_GET[ $name ]) ) {

                continue;

            }


            // get the value for this filter
            // eg: http://www.website.com/events?city=melbourne,sydney
            $value = explode(',', $_GET[ $name ]);


            // append meta query
            $meta_query[] = array(
                'key'       => $name,
                'value'     => $value,
                'compare'   => 'IN',
            );

        } 


        // update meta query
        $query->set('meta_query', $meta_query);

    }

}
1
lotech

OK, hier ist, was ich am Ende arbeiten bekam. Ich bin mir ehrlich gesagt nicht sicher, ob ich die Parameter korrekt bereinigt habe. Ansonsten funktioniert alles wie vorgesehen. Vielen Dank an Pieter Goosen!

// action
add_action('pre_get_posts', 'my_pre_get_posts', 10, 1);

function my_pre_get_posts( $query ) {

    // bail early if is in admin
    if( is_admin() ) {
        return;
    }

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

        // array of filters (field key => field name)
        $GLOBALS['my_query_filters'] = array( 
            'field_1'   => 'course_or_project', 
            'field_2'   => 'difficulty',
            'field_3'   => 'time_to_complete_project',
            'field_4'   => 'time_to_complete_course'
        );

        // get meta query
        $meta_query = $query->get('meta_query');

        // loop over filters
        foreach( $GLOBALS['my_query_filters'] as $key => $name ) {

            // sanitize parameter
            $name = filter_input( INPUT_GET, $name, FILTER_SANITIZE_STRING );

            // continue if not found in url
            if( empty($_GET[ $name ]) ) {
                continue;
            }

            // get the value for this filter
            // eg: http://www.website.com/events?city=melbourne,sydney
            $value = explode(',', $_GET[ $name ]);

            // append meta query
            $meta_query[] = array(
                'key'       => $name,
                'value'     => $value,
            );

        } 

        // update meta query
        $query->set('meta_query', $meta_query);

    }

}
1
lotech

Sie müssen einen richtigen meta_query erstellen. Ihr Code funktioniert nur, wenn Sie einen meta_key gesetzt haben. Wenn Sie mehr als 1 haben, wird alles durcheinander sein.

Beachten Sie auch, dass Sie niemals nicht bereinigte, nicht validierte Werte aus einer $_GET -Variablen verwenden sollten (und für diesen Fall jeden Wert, der von irgendwoher kommt). Es ist extrem einfach, bösartigen Code in Ihre Website einzufügen, indem Sie ein Skript in Ihre URL einfügen. Validierung und Hygiene haben zwar nur einen sehr geringen Einfluss auf die Leistung, sind aber definitiv die Mühe wert.

Versuchen Sie, Ihre Aktion neu zu codieren, um Ihr Problem zu beheben. Ich habe wo nötig kommentiert.

add_action( 'pre_get_posts', function ( $q )
{
    if (    !is_admin() // Do this only on the front end
         && $q->is_main_query() // Targets the main query only
    ) {

        if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'course' ) { // Not sure about this, can be $q->is_post_type_archive( 'course' )
            // Get all our $_GET variables and sanitize and validate them
            $course_or_project        = filter_input( INPUT_GET, 'course_or_project',        FILTER_SANITIZE_STRING );
            $time_to_complete_project = filter_input( INPUT_GET, 'time_to_complete_project', FILTER_SANITIZE_STRING ); 
            $time_to_complete_course  = filter_input( INPUT_GET, 'time_to_complete_course',  FILTER_SANITIZE_STRING );
            $difficulty               = filter_input( INPUT_GET, 'difficulty',               FILTER_VALIDATE_INT    ); 

            // Set our variable to hold the meta_query
            $meta_query = [];

            // Now we build our meta_query
            if( $course_or_project ) {
                $meta_query[] = [
                    'key'   => 'course_or_project',
                    'value' => $course_or_project
                ];
            } 

            if( $time_to_complete_project ) {
                $meta_query[] = [
                    'key'   => 'time_to_complete_project',
                    'value' => $time_to_complete_project
                ];
            } 

            if( $time_to_complete_course ) {
                $meta_query[] = [
                    'key'   => 'time_to_complete_course',
                    'value' => $time_to_complete_course    
                ];
            } 

            if( $difficulty ) {
                $meta_query[] = [
                'key'   => 'difficulty',
                'value' => $difficulty
                ];
            }

            // Make sure we have something in $meta_query before setting it
            if ( $meta_query ) 
                $q->set( 'meta_query', $meta_query );

        }
    }
});

Sie können die Abfrage nach Bedarf verfeinern, dies sollte jedoch die Grundvoraussetzung sein

1
Pieter Goosen