it-swarm.com.de

haken, um die Suchzeichenfolge vor der Verarbeitung abzurufen (und zu ändern)

Ich versuche die Suchanfrage abzufangen, bevor sie in Wordpress ausgeführt wird. Ich habe ein paar Dinge ausprobiert, aber es funktioniert einfach nicht.

So gibt beispielsweise ein Benutzer den Suchbegriff RED SHOES ein. Ich möchte, dass alle Vorkommen von RED in ROSSO geändert werden (es ist komplexer als dies, aber Sie haben die Idee, es hat mit Übersetzen zu tun).

Ich schaue mir so etwas an:

function modify_search_vars($search_vars) {

    $change_to = array(
        "blue"  => "blu",
        "red"   => "rosso",
    );

    if ( !empty($search_vars['s']) ) {
        $search_vars['s'] = str_ireplace(array_keys($change_to), array_values($change_to), $search_vars['s']);
    }
    return $search_vars;

}
add_filter('request', 'modify_search_vars', 99);

Jede Hilfe oder Ideen hier wäre sehr dankbar! Vielen Dank!

1
arathra

Um einen tieferen Einblick in die Suche zu erhalten und das Gesuchte so schnell wie möglich zu erfassen, müssen wir uns die Klasse WP_Query ansehen und herausfinden, wie eine Abfrage nach Beiträgen behandelt wird:

In seiner Funktion parse_query signalisiert er der gesamten Klasse mithilfe eines Flags, dass es sich bei der Abfrage tatsächlich um eine "Suche" handelt. Es überrascht nicht, dass er in der Abfrage nach s sucht:

if ( isset( $this->query['s'] ) ) {
    $this->is_search = true;
}

Großartig, aber es gibt keine Aktionen wie do_action( 'super_important_hook' . $handle_that_we_could_use, $query), bei denen wir uns mit WordPress "per name" in diesen großen, lebenswichtigen Prozess einklinken können. Was können wir also tun?

Wir haben parse_query, der vor pre_get_posts ausgelöst wird:

function replace_search( $query_object )
{
    if( $query_object->is_search() ) {
        $raw_search = $query_object->query['s'];

        $replacement = str_replace( 'red', 'rosso', $raw_search );

        if( $replacement ) {
            $query_object->set( 's', $replacement );
        }
    }
}

add_action( 'parse_query', 'replace_search' );

...und es funktioniert! Wir arbeiten so früh wie möglich daran und ändern die Abfrage, sobald dies geschieht. Die Funktion set macht genau das, was sie sagt. Sie ist ein Setter für alle internen Variablen, die für die Klasse verwendet werden.

Übrigens wird der Hook parse_tax_query vor parse_queryausgelöst, da $this->parse_tax_query(), der parse_tax_query enthält, innerhalb der parse_query()-Funktion von WP_Query aufgerufen wird, die denselben WP_Query Object an die Aktion weitergibt. Aber hier kommt meine Meinung, die sehr falsch sein könnte: Ich würde diesen Hook nicht verwenden, da parse_query für diese Art von Verhalten weitaus populärer zu sein scheint.

Erstens: Denken Sie daran, dass Plugins, die diesen Hook nicht auch zur Suche nach der Suchzeichenfolge verwenden, möglicherweise nach $_REQUEST['s'] suchen, der vor diesen Hooks steht, und an diesem Punkt möglicherweise geändert werden. Unabhängig davon ist der früheste Punkt, an dem die Suche des Benutzers in das System eingeht, $_REQUEST['s']. Sie müssen sich also so früh wie möglich in diesen Wert einklinken. Meine Antwort ist hier ziemlich gut, aber ich denke, es gibt viel mehr Dinge zu beachten, wenn Sie damit spielen Suche, und natürlich, wenn ihre Funktionen eine höhere Priorität haben und sie die Zeichenfolge in etwas anderes verwandeln, sind Sie zum Scheitern verurteilt.

Natürlich haben Sie einen ausgeklügelten "Ersatz" -Mechanismus, aber das soll nur zeigen, welche Haken Sie benötigen.

Zweitens ist ein interessanter Punkt bei diesen Aktionen, dass sie ihre Objekte als Referenz übergeben:

/**
 * Fires after the main query vars have been parsed.
 *
 * @since 1.5.0
 *
 * @param WP_Query $this The WP_Query instance (passed by reference).
 */
do_action_ref_array( 'parse_query', array( &$this ) );

Was dies bedeutet und es ist gut zu beachten - jede einzelne Änderung, die Sie vornehmen, wenn sich Ihre Skripte in parse_query einbinden, wirkt sich auf die eigentliche Klasse aus, die an das nächste Skript weitergeleitet wird, an das sie angebunden sind, oder, naja, Ihre Änderungen werden berücksichtigt den gesamten Lebenszyklus der genannten Klasse. Ich kann nicht sagen, ob dies eine gute Design-Wahl war oder nicht. Ich möchte Sie nur wissen lassen, falls Sie eine Frage haben: "Warum wird diese Variable nicht zurückgesetzt? Es ist eine neue Klasseninstanz." Die Klasse verhält sich wie ein Singleton, aber Denken Sie also daran, dass Sie mit der gleichen Klasse spielen, bis WP damit fertig ist und alle Änderungen, die Sie daran vornehmen, von dem verwendet werden, was nach Ihnen kommt, kurz gesagt: Seien Sie sehr aufmerksam Was Sie tun, gibt es eine Menge Prozesse/Plugins, die dies verwenden, da WP_Query der eigentliche Kern von WP selbst ist.


Wenn Sie so spät wie möglich "einbinden" möchten, wird die Abfrage dadurch zwar geändert, aber (glaube ich) zu spät, sodass das Theme/Plug-in mit diesem Wert spielen kann, bevor Sie ihn sehen:

add_filter( 'get_search_query', function( $user_search_query ) {
    $replacement = str_replace( 'red', 'rosso', $user_search_query );

    if( $replacement ) {
        return $replacement;
    }

    return $user_search_query;
}, 999);

Der Haken, den Sie suchen, ist get_search_query. Aber bitte wissen Sie, dass es eine Menge Plugins/Dinge gibt, die damit spielen. Seien Sie sich also der Auswirkungen bewusst, die sich daraus ergeben, wenn Sie dies ändern. Die Hauptfunktion, die es verwendet, ist:

/**
 * Displays the contents of the search query variable.
 *
 * The search query string is passed through esc_attr() to ensure that it is safe
 * for placing in an html attribute.
 *
 * @since 2.1.0
 */
function the_search_query() {
    /**
     * Filters the contents of the search query variable for display.
     *
     * @since 2.3.0
     *
     * @param mixed $search Contents of the search query variable.
     */
    echo esc_attr( apply_filters( 'the_search_query', get_search_query( false ) ) );
}

Von general-template.php in WP Core. Dieser Parameter wird von get_search_query an unseren Filter übergeben. Hierbei handelt es sich lediglich um einen einfachen Wrapper zum Abrufen des Inhalts von $_REQUEST['s'].

2
coolpasta