qTranslateでループエラー-が発生(Wordpress 3.0)
WordPress3.0がリリースされ、時間的にも、随分、プラグインの対応が進みました。
そこで、Wordpress3.0へアップデート!!としたいところですが、実際に、いろいろと試してみると、うまくいかないことも多いです。
その中で、今回は、qTranslateでCookiesを使用不可にすると、リダイレクトのループが発生し、表示できない問題の対処をやってみました。
同じ問題で苦しんでおられる方のヒントになれば幸いです。
症状
ホームページへアクセスしたとき、以下のような画面が表示されることがあります。

これは、ブラウザの設定が、Cookiesと使わないようになっていて、qTransrateの設定が以下のようになっている場合に発生するようです。
■ Checked – Detect the language of the browser and redirect accordingly.
□ Unchecked Hide URL language information for default language.

このことから、例えば、ブラウザの設定が、Cookiesを使うようになっていた場合、特に問題は、発生しないようです。
原因
上記のことからも分かるように、例えば、日本語がデフォルト言語とした場合、単純に以下のURLへリダイレクトしようとしているみたいです。
http://wwww.example.com/
|
V
http://wwww.example.com/ja
|
V
http://wwww.example.com/
上記からもわかるように完全にループしてますね。
これを回避するためにCookiesが使われてるみたいな感じがしますね。(全コードを追っていないの本当のところはわかりません。)
対処
qtranslate_core.phpの以下の処理が、直接の原因のようです。
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
| // detect language and forward if needed
if($q_config['detect_browser_language'] && $q_config['url_info']['redirect'] && !isset($_COOKIE['qtrans_cookie_test']) && $q_config['url_info']['language'] == $q_config['default_language']) {
$prefered_languages = array();
if(isset($_SERVER["HTTP_ACCEPT_LANGUAGE"]) && preg_match_all("#([^;,]+)(;[^,0-9]*([0-9\.]+)[^,]*)?#i",$_SERVER["HTTP_ACCEPT_LANGUAGE"], $matches, PREG_SET_ORDER)) {
$priority = 1.0;
foreach($matches as $match) {
if(!isset($match[3])) {
$pr = $priority;
$priority -= 0.001;
} else {
$pr = floatval($match[3]);
}
$prefered_languages[$match[1]] = $pr;
}
arsort($prefered_languages, SORT_NUMERIC);
foreach($prefered_languages as $language => $priority) {
if(qtrans_isEnabled($language)) {
if($q_config['hide_default_language'] && $language == $q_config['default_language']) break;
$target = qtrans_convertURL(get_option('home'),$language);
header("Location: ".$target);
exit;
}
}
}
}
|
87行目の条件が、そのまま、症状で設定している条件と同じになります。
!isset($_COOKIE[‘qtrans_cookie_test’])
= ブラウザのCookie拒否の設定を意味します。
$q_config[‘detect_browser_language’]
= ■ Checked – Detect the language of the browser and redirect accordingly.
を意味します。
$q_config[‘url_info’][‘redirect’]
= □ Unchecked Hide URL language information for default language.
を意味します。
ここでの問題は、現在のリクエストURLとリダイレクトしようとするURL(105行目の$target)が同じかどうかのチェックをしていないところだろうと思います。
では、簡単にチェックを入れてみましょう。
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
| // detect language and forward if needed
if($q_config['detect_browser_language'] && $q_config['url_info']['redirect'] && !isset($_COOKIE['qtrans_cookie_test']) && $q_config['url_info']['language'] == $q_config['default_language']) {
$prefered_languages = array();
if(isset($_SERVER["HTTP_ACCEPT_LANGUAGE"]) && preg_match_all("#([^;,]+)(;[^,0-9]*([0-9\.]+)[^,]*)?#i",$_SERVER["HTTP_ACCEPT_LANGUAGE"], $matches, PREG_SET_ORDER)) {
$priority = 1.0;
foreach($matches as $match) {
if(!isset($match[3])) {
$pr = $priority;
$priority -= 0.001;
} else {
$pr = floatval($match[3]);
}
$prefered_languages[$match[1]] = $pr;
}
arsort($prefered_languages, SORT_NUMERIC);
foreach($prefered_languages as $language => $priority) {
if(qtrans_isEnabled($language)) {
if($q_config['hide_default_language'] && $language == $q_config['default_language']) break;
$target = qtrans_convertURL(get_option('home'),$language);
$http = $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$npos = strpos($target,'//');
if($npos!==false) {
$target_chk = substr($target,$npos+2);
} else {
$target_chk = $target;
}
if($target_chk == $http) break;
header("Location: ".$target);
exit;
}
}
}
}
|
105 – 114 行目までを追加してみました。
単純に現在のURLとリダイレクトのURLが同じなら、リダイレクト処理をしないようにしています。
実際に動作させて見るとうまくいきました。
もちろん、ソースコードの変更などしたくない方は、
■ Checked – Detect the language of the browser and redirect accordingly.
□ Unchecked Hide URL language information for default language.
のいずれかを反転させれば良いはずですので、お困りの方は、試されてみるのも良いかもしれません。
この記事を読んだ人は、こんな記事も読んでいます。:
コメント
2011年10月07日 @ 23:04:40
Hi,
Thank you for your post – I’m surprised to be first to say thank you.
I’m using qTranslate in version 2.5.24 and there is slight difference in the code of qtranslate_core.php.
Basically the Redirect itself (and exit) is done after the loop so break does not work anymore to prevent redirect. Simple fix is to introduce a flag (I call it $redirect_corrupt), which is risen once the faulty redirect is detected by your code. Then the flag is being checked when redirect is about to be applied.
Cheers & thanks,
Adam