web-dev-qa-db-fra.com

Désactiver oEmbed pour un seul Shortcode ou au moins tous les liens internes

Existe-t-il un moyen de désactiver la fonctionnalité oEmbed uniquement pour un appel spécifique de la fonction do_shortcode() dans un seul script ou, si cela n’est pas possible, peut-il être désactivé pour tous les liens internes d’un site exécutant actuellement WordPress 4.5.3?

J'ai essayé d'utiliser cette ligne mais cela n'a eu aucun effet:

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

Jusqu’à présent, la seule chose qui ait été utile est cette ligne:

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

mais pour autant que je sache, il désactive tout le contenu de oEmbed et pas seulement les liens internes.

2
Sledge Hammer

Ici nous considérons la question:

post embeds peut-il être désactivé pour tous les liens internes d'un site utilisant actuellement WordPress 4.5.3?

La petite histoire

Si nous voulons désactiver post embedded of liens internes, mais l'autorisons sur des sites externes, nous pouvons utiliser:

/**
 * 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 );

Ici, nous vérifions si le lien est pour l'hôte actuel. Cela peut être ajusté plus loin à nos besoins.

Nous n'avons alors pas besoin de ce rappel de filtre:

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

et probablement d'autres aussi.

Notez que les incorporations sont mises en cache pendant 24 heures par défaut. Voici quelques exemples comment le régénérer.

Désolé pour la longue partie ci-dessous, mais j'ai décidé de l'écrire pour mieux la comprendre ;-)

La version longue

Lorsque nous collons l'URL du message:

http://example.tld/hello-world

dans l'éditeur visuel, puis

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

est envoyé à la fonction wp_ajax_parse_embed() via une requête ajax, où il appelle $wp_embed->run_shortcode().

De même, le contenu est filtré via les fonctions $wp_embed->autoembed() et $wp_embed->run_shortcode() via le filtre the_content.

Les deux sont basés sur la méthode WP_Embed::shortcode() src.

Dans la méthode du shortcode

Si les données ne sont pas mises en cache dans le post-méta, alors wp_oembed_get() est activé, y compris la séquence suivante:

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

et les données sont récupérées avec une demande à:

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

Ce noeud final de repos génère des données avec la fonction get_oembed_response_data() et applique également le filtre oembed_request_post_idsrc.

Ce filtre a été introduit dans # 36767 dans WordPress version 4.5.3.

Par défaut, link discovery est actif. cela signifie que nous aurions une requête supplémentaire avec wp_safe_remote_get() pour pouvoir analyser les balises <link> pertinentes, à partir du site distant, afin de déterminer l'URL du fournisseur:

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

Le filtre pre_oembed_result} _

Un nouveau filtre a également été introduit dans # 36767 , dans WP_oEmbed::get_html() src:

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

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

éviter les requêtes HTTP externes pour les liens internes. Il va court-circuiter la wp_oembed_get() si le filtre renvoie autre chose que null.

En noyau, nous avons maintenant:

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

où la fonction de rappel wp_filter_pre_oembed_result() du filtre génère des données avec la fonction get_oembed_response_data(), exactement comme pour le point de terminaison du repos incorporé. Il est filtrable via le filtre oembed_response_data. Le callback get_oembed_response_data_rich() est relié à:

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

Il contient la fonction get_post_embed_html() qui génère les codes <blockquote>, <script> et <iframe>.

_ {Désactiver les publications internes

Pour désactiver la publication intégrée pour les liens internes, nous vous conseillons donc de vous assurer que le filtre pre_oembed_result renvoie false (différent de 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 );

où nous renvoyons false le plus tard possible, nous utilisons donc un grand priority like PHP_INT_MAX.

Ensuite, nous n’avons pas besoin du rappel wp_filter_pre_oembed_result() pour s'exécuter, nous pouvons donc également le supprimer avec:

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

où nous devons l'enlever avec la même priorité qu'il a été ajouté avec.

Une autre approche pourrait être d'utiliser:

add_filter( 'oembed_request_post_id', '__return_false' );

Cela signifierait que nous envoyons des requêtes HTTP au noeud final reste, ce qui provoquera une erreur, car l'identifiant de publication n'est pas valide.

Test simple

Voici un moyen de le tester. Nous avons d’abord besoin d’une instance d’objet de la classe WP_Embed:

$e = new WP_Embed(); 

ou utilisez l'objet global $wp_embed. Ensuite, nous configurons les liens de publication internes et externes:

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

et courir:

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

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

Nous pouvons également le tester sans shortcodes en utilisant:

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

Nous devons juste être conscients du cache oembed (post meta) et utiliser par exemple. un paramètre de contournement du cache pour les liens de test. Voici quelques exemples comment le régénérer.

3
birgire