it-swarm.com.de

Deaktivieren Sie oEmbed für einen einzelnen Shortcode oder mindestens alle internen Links

Gibt es eine Möglichkeit, die Funktion oEmbed nur für einen bestimmten Aufruf der Funktion do_shortcode() in nur einem Skript zu deaktivieren, oder kann sie, falls dies nicht möglich ist, für alle internen Links auf einer Site deaktiviert werden, auf der WordPress 4.5.3 ausgeführt wird?

Ich habe versucht, diese Linie zu verwenden, aber sie hatte keine Wirkung:

wp_oembed_remove_provider( 'http://www.example.com/*' );

Bisher war nur die folgende Zeile nützlich:

remove_filter( 'the_content', array( $GLOBALS['wp_embed'], 'autoembed' ), 8 );

aber meines wissens deaktiviert es alle oEmbed-inhalte und nicht nur die internen links.

2
Sledge Hammer

Hier betrachten wir die Frage:

kann Einbettungen posten für alle internen Links auf einer Site, auf der WordPress 4.5.3 ausgeführt wird, deaktiviert werden?

Die Kurzgeschichte

Wenn wir nach dem Einbetten voninternen Linksdeaktivieren möchten, dies aber auf externen Websites zulassen möchten, können wir Folgendes verwenden:

/**
 * Disable post embeds for internal links but allow it on external sites
 */
add_filter( 'pre_oembed_result', function( $result, $url, $args )
{    
    if( parse_url( home_url(), PHP_URL_Host ) ===  parse_url( $url, PHP_URL_Host ) )
        $result = false;

    return $result;

}, PHP_INT_MAX, 3 );

Hier prüfen wir, ob der Link für den aktuellen Host ist. Dies kann weiter an unsere Bedürfnisse angepasst werden.

Diesen Filter-Callback brauchen wir dann nicht:

add_action( 'init', function()
{
    remove_filter( 'pre_oembed_result', 'wp_filter_pre_oembed_result', 10 );
} );

und wahrscheinlich auch andere.

Beachten Sie, dass die Einbettungen standardmäßig 24 Stunden lang zwischengespeichert werden. Hier sind einige Beispiele wie man es regeneriert.

Entschuldigung für den langen Teil hier unten, aber ich habe beschlossen, es aufzuschreiben, um es besser zu verstehen ;-)

Die längere Version

Wenn wir die Post-URL einfügen:

http://example.tld/hello-world

dann im visuellen Editor

[embed]http://example.tld/hello-world[/embed]

wird über eine Ajax-Anforderung an die Funktion wp_ajax_parse_embed() gesendet und ruft dort $wp_embed->run_shortcode() auf.

In ähnlicher Weise wird der Inhalt durch die $wp_embed->autoembed() und $wp_embed->run_shortcode() über den the_content-Filter gefiltert.

Beide basieren auf der Methode WP_Embed::shortcode() src.

Innerhalb der Shortcode-Methode

Wenn die Daten nicht im Post-Meta zwischengespeichert sind, wird wp_oembed_get() mit der folgenden Sequenz gestartet:

WP_oEmbed::get_html()
    WP_oEmbed::fetch()
        WP_oEmbed::_fetch_with_format()
            wp_safe_remote_get()
            wp_remote_retrieve_body()

und die Daten werden mit einer Anfrage abgerufen an:

http://example.tld/wp-json/oembed/1.0/embed?url=http%3A%2F%2Fexample.tld%2Fhello-world%2F&
maxwidth=900&maxheight=1000&format=json

Dieser Restendpunkt generiert Daten mit der Funktion get_oembed_response_data() und wendet auch den Filter oembed_request_post_id an src.

Dieser Filter wurde in # 36767 in WordPress Version 4.5.3 eingeführt.

Standardmäßig ist Linkerkennung aktiv. Das bedeutet, wir würden eine zusätzliche Anfrage mit wp_safe_remote_get() erhalten, um in der Lage zu sein, die relevanten <link> -Tags von der entfernten Site aus zu analysieren, um die URL des Prüfers zu bestimmen:

http://example.tld/wp-json/oembed/1.0/embed?url=http%3A%2F%2Fexample.tld%2Fhello-world%2F

Der pre_oembed_result Filter

Ein neuer Filter wurde auch in # 36767 innerhalb von WP_oEmbed::get_html() eingeführt. src:

$pre = apply_filters( 'pre_oembed_result', null, $url, $args ); 

if ( null !== $pre ) { 
    return $pre; 
}    

um externe HTTP-Anfragen für interne Links zu vermeiden. Es wird die wp_oembed_get() kurzschließen, wenn der Filter etwas anderes als null zurückgibt.

Im Kern haben wir jetzt:

add_filter( 'pre_oembed_result', 'wp_filter_pre_oembed_result', 10, 3 );

wobei der Rückruf des Filters wp_filter_pre_oembed_result() Daten mit der Funktion get_oembed_response_data() generiert, genau wie für den eingebetteten Restendpunkt. Es kann durch den oembed_response_data-Filter gefiltert werden. Der get_oembed_response_data_rich() Callback ist eingebunden in:

add_filter( 'oembed_response_data',   'get_oembed_response_data_rich', 10, 4 ); 

Es enthält die Funktion get_post_embed_html(), die den Code <blockquote>, <script> und <iframe> generiert.

Interne Post-Einbettungen deaktivieren

Um Post-Einbettungen für interne Links zu deaktivieren, empfehlen wir daher, sicherzustellen, dass der Filter pre_oembed_resultfalse zurückgibt (anders als null):

/**
 * Disable post embeds for internal links but allow it on external sites
 */
add_filter( 'pre_oembed_result', function( $result, $url, $args )
{    
    if( parse_url( home_url(), PHP_URL_Host ) ===  parse_url( $url, PHP_URL_Host ) )
        $result = false;
    return $result;

}, PHP_INT_MAX, 3 );

wenn wir so spät wie möglich false zurückgeben, verwenden wir ein großes priority like PHP_INT_MAX.

Dann brauchen wir nicht wp_filter_pre_oembed_result() callback um zu laufen, also können wir es auch entfernen mit:

remove_filter( 'pre_oembed_result', 'wp_filter_pre_oembed_result', 10 );

wo wir es mit der gleichen Priorität entfernen müssen, mit der es hinzugefügt wurde.

Ein anderer Ansatz könnte sein:

add_filter( 'oembed_request_post_id', '__return_false' );

Dies würde bedeuten, dass wir HTTP-Anforderungen an den Rest-Endpunkt erhalten, die durch einen Fehler verursacht werden, da die Post-ID nicht gültig ist.

Einfaches Testen

Hier ist eine Möglichkeit, es zu testen. Zuerst benötigen wir eine Objektinstanz der Klasse WP_Embed:

$e = new WP_Embed(); 

oder verwenden Sie das globale Objekt $wp_embed. Dann richten wir die internen und externen Post-Links ein:

$internal = 'http://internal.tld/hello-world/';
$external = 'http://external.tld/hello-world/';

und Renn:

$internal_is_embeddable = $internal !== $e->run_shortcode( 
    sprintf( '[embed]%s[/embed]', 
    $internal 
);

$external_is_embeddable = $external !== $e->run_shortcode( 
    sprintf( '[embed]%s[/embed]', 
    $external 
);

Wir können es auch ohne Shortcodes testen mit:

$internal_is_embeddable = $internal !== $e->autoembed( $internal );
$external_is_embeddable = $external !== $e->autoembed( $external );

Wir müssen uns nur des oembed (Post-Meta) -Caches bewusst sein und z. ein Cache-Busting-Parameter für die Testlinks. Hier sind einige Beispiele wie man es regeneriert.

3
birgire