web-dev-qa-db-fra.com

Comment les réécritures d'URL de CDN W3 Total Cache fonctionnent-elles?

Je viens de configurer CDN S3 W3 Total Cache (Origin Push) et la plupart des URL sont réécrites correctement, mais nous avons quelques plugins personnalisés dans lesquels les URL ne sont pas réécrites. Comment puis-je récupérer l'URL réécrite de W3TC depuis un autre plugin? J'utilise actuellement le code suivant pour récupérer l'image:

wp_get_attachment_image_src( get_post_thumbnail_id(), 'car-thumb');

Je suppose qu'il existe un type de filtre qui remplace simplement l'URL d'origine "Origin" par l'URL d'actif sur le compartiment S3, mais je n'ai pas pu trouver où dans le code.

6
JSP

Le plug-in W3 Total Cache modifie l'URL de divers fichiers dans /w3-total-cache/lib/W3/Plugin/Cdn.php dans la fonction * ob_callback *. Il utilise une série de rappels pour modifier un tampon de sortie. Le code fonctionne comme ceci:

  • w3_total_cache.php appelle $root->run();
  • W3_Root :: run appelle $plugin->run() pour chaque plugin dans $this->_loaded_plugins
  • W3_Plugin_TotalCache :: run démarre un tampon de sortie qui appelle W3_Plugin_TotalCache :: ob_callback
  • W3_Plugin_TotalCache :: ob_callback appelle w3tc_do_ob_callbacks () qui exécute tout rappel stocké dans $GLOBALS['_w3tc_ob_callbacks']
  • Le CDN ajoute son propre rappel à ce global dans W3_Plugin_Cdn :: run. Ce rappel est W3_Plugin_Cdn :: ob_callback

Les callbacks exécutés sont malheureusement codés en dur dans cette ligne: $buffer = w3tc_do_ob_callbacks(array('minify', 'newrelic', 'cdn', 'browsercache', 'pagecache'), $buffer);

Comme c'est codé en dur, si vous avez besoin de modifier ce qui est inclus et ce qui ne l'est pas, vous devrez changer leur rappel.

Exemple:

J'ai un plug-in qui exporte du JSON, et l'aspect CDN de W3 Total Cache ne modifiait aucune URL pour les requêtes JSON. Il s’avère que ma sortie a échoué au test w3_is_xml($buffer).

Je l'ai corrigé en transformant leur rappel CDN unique en multiples, comme ceci:

// Modify the output buffer callbacks of W3 Total Cache to work with the JSON API
if (!empty($GLOBALS['_w3tc_ob_callbacks']) && isset($GLOBALS['_w3tc_ob_callbacks']['cdn'])) {
    // Back-up the original value of $GLOBALS['_w3tc_ob_callbacks']['cdn']
    // This should be W3_Plugin_Cdn::ob_callback
    $this->cdn_ob_callback = $GLOBALS['_w3tc_ob_callbacks']['cdn'];

    // Replace $GLOBALS['_w3tc_ob_callbacks']['cdn'] with out own method
    // which will call the original callback in between two of our own
    $GLOBALS['_w3tc_ob_callbacks']['cdn'] = array($this, 'do_multiple_cdn_ob_callbacks');
}

Ensuite, en effectuant les modifications dont j'ai besoin, en veillant à appeler leur rappel original au milieu.

public function do_multiple_cdn_ob_callbacks(&$buffer) {
    // Frist run our own callback to add an XML string to the buffer
    // so that the content passes the w3_is_xml($buffer) test
    $buffer = $this->w3_total_cache_ob_callback_start($buffer);

    // Next run the original callback, which will replace the asset URLs
    $buffer = call_user_func($this->cdn_ob_callback, $buffer);

    // Finally, run another callback of our own to remove the XML string
    $buffer = $this->w3_total_cache_ob_callback_end($buffer);
    return $buffer;
}
5
Tyler V.

J'ai eu un problème similaire lors du rendu d'une partie de modèle.

Je devais appeler le plugin W3_Plugin_Cdn par programme.

Comme correctement déclaré par Tyler V., la w3_is_xml($buffer) échouera si $ buffer ne ressemble pas à HTML ou XML, c'est pourquoi je mets <html> au début de la partie modèle.

Voici un exemple sur comment j'ai fait.

if (class_exists('W3_Plugin_Cdn')) {
    $cdn_handler = new W3_Plugin_Cdn();
    ob_start();
    echo '<html>';
    get_template_part($templatepart, $templatepartdetail);
    $buffer = ob_get_contents();
    $cdn_handler->ob_callback($buffer);
    $buffer = substr($buffer, strlen('<html>'));
    ob_end_clean();
    echo $buffer;
}
1
ermannob

J'avais les mêmes problèmes et je ne pouvais pas obtenir de réponse non plus. Cependant, j'ai trouvé où dans la base de données WP, les entrées des images jointes étaient stockées et utilisées pour créer mes propres URL réécrites.

Si vous regardez dans la table _postmeta, il existe une méta_key "_wp_attached_file" qui stocke le chemin du dossier des images attachées. Avec cette information, je n’avais besoin que d’ajouter la structure d’URL pour indiquer où se trouvait notre compartiment S3.

global $postid;
$bucketName = "your_bucket_name_goes_here";
$postThumbNailID = get_post_meta($post->ID, '_thumbnail_id');
$postThumbNailUrl = get_post_meta($postThumbNailID[0], '_wp_attached_file');
$s3BucketURL = "http://".$bucketName.".s3.amazonaws.com/files/".$postThumbNailUrl[0];
0
Dak