web-dev-qa-db-ja.com

W3 Total Cache CDN URLの書き換えはどのように行われますか?

W3 Total Cache S3 CDN(Origin Push)をセットアップしただけで、ほとんどのURLは正しく書き直されていますが、URLが書き換えられないカスタムプラグインがいくつかあります。別のプラグインからW3TCの書き換えられたURLを取得する方法私は現在、次のコードを使って画像を取得しています。

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

私は、元の "Origin" URLをS3バケットのアセットURLに置き換えるだけのある種のフィルタがあると思いますが、コード内のどこに見つけることができませんでした。

6
JSP

W3 Total Cacheプラグインは、* ob_callback *関数の /w3-total-cache/lib/W3/Plugin/Cdn.php にあるさまざまなファイルのURLを変更します。一連のコールバックを使って出力バッファを変更します。コードは次のように実行されます。

  • w3_total_cache.phpが$root->run();を呼び出します
  • W3_Root :: runは$this->_loaded_plugins内の各プラグインに対して$plugin->run()を呼び出します
  • W3_Plugin_TotalCache :: runはW3_Plugin_TotalCache :: ob_callbackを呼び出す出力バッファを起動する
  • W3_Plugin_TotalCache :: ob_callbackは、$GLOBALS['_w3tc_ob_callbacks']に格納されているすべてのコールバックを実行するw3tc_do_ob_callbacks()を呼び出します。
  • CDNはW3_Plugin_Cdn :: runでそのグローバルにそれ自身のコールバックを追加します。そのコールバックはW3_Plugin_Cdn :: ob_callbackです。

その後どのコールバックが実行されるかは残念ながらこの行にハードコーディングされています:$buffer = w3tc_do_ob_callbacks(array('minify', 'newrelic', 'cdn', 'browsercache', 'pagecache'), $buffer);

これはハードコーディングされているので、含まれているものと含まれていないものを変更する必要がある場合は、コールバックを変更する必要があります。

例:

私はJSONをエクスポートするプラグインを持っています、そしてW3 Total CacheのCDNの側面はJSONリクエストのためのURLを変更していませんでした。私の出力がw3_is_xml($buffer)テストに失敗していたことがわかります。

私はこれを直しました、このように彼らの単一のCDNコールバックを倍数に変えることによって:

// 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');
}

それから私が必要とする変更を行い、途中でそれらの元のコールバックを呼び出すようにしてください。

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.

テンプレートパーツをレンダリングするときにも同様の問題がありました。

プログラムでW3_Plugin_Cdnプラグインを起動しなければなりませんでした。

Tyler V.によって正しく述べられているように、$ bufferがHTMLやXMLのように見えなければw3_is_xml($buffer)は失敗するでしょう、それで私は<html>をテンプレート部分の始めに置いています。

これが私のやり方の例です。

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

私は同じ問題を抱えていたし、答えも得られませんでした。しかし、データベース内のどこにWPが添付された画像のエントリを格納しているのかを見つけ、それを使用して私自身の書き換えられたURLを作成しました。

_postmetaテーブルを見ると、添付画像へのフォルダパスを格納するmeta_key "_wp_attached_file"があります。この情報を使用して、S3バケットが配置されている場所のURL構造を追加するだけで済みました。

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