PEAK XOOPS - EMLHで英語と日本語でフォームを分ける(2) XCL2.1用preload編 in englishin japanese

Archive | RSS |
XOOPS
XOOPS : EMLHで英語と日本語でフォームを分ける(2) XCL2.1用preload編
Poster : GIJOE on 2008-06-22 17:39:28 (12925 reads)

in englishin japanese
EMLH-1.30相当の機能をpreloadで実現してみました。HDのpreload/disabledにもこっそり忍ばせてあったりします

preload/MultiLanguagePostMerger.class.php


<?php
if (!defined('XOOPS_ROOT_PATH')) exit();
@include_once XOOPS_ROOT_PATH . '/modules/cubeUtils/class/MultiLanguage.class.php';
class MultiLanguagePostMerger extends XCube_ActionFilter
{
    function preFilter()
    {
        if ( ! empty( $_POST ) && file_exists(XOOPS_ROOT_PATH.'/modules/cubeUtils/class/MultiLanguage.class.php')) {
            // just after MultiLanguagePreLoad
            $this->mController->mGetLanguageName->add(array(&$this, 'postMerger'),XCUBE_DELEGATE_PRIORITY_FINAL+1);
        }
    }

    function postMerger()
    {
        global $cubeUtilMlang ;

        if( is_object( $cubeUtilMlang ) ) $this->mergeRecursive( $_POST ) ;
    }

    function mergeRecursive( &$data )
    {
        global $cubeUtilMlang ;

        $merged_string = '' ;
        $langs_counter = 0 ;
        foreach( array_keys( $data ) as $index ) {
            if( is_array( $data[ $index ] ) ) {
                $this->mergeRecursive( $data[ $index ] ) ;
            } else if( in_array( $index , $cubeUtilMlang->mLanguages ) ) {
                $merged_string .= '['.$index.']'.$data[ $index ].'[/'.$index.']' ;
                $langs_counter ++ ;
            }
        }
    
        if( $langs_counter == sizeof( $cubeUtilMlang->mLanguages ) ) {
            $data = $merged_string ;
        }
    }
}

当たり前ですが、XCL2.1専用です。
XCL2.1のpreloadフォルダには以下の3つのファイルすべてが揃っている必要があります。

MultiLanguageCompatibleEMLH.class.php
MultiLanguagePostMerger.class.php
MultiLanguagePreLoad.class.php

使い方はEMLH版とまったく同じです。フォームのテンプレートを書き換えるだけです。

個人的には、XOOPSのML機能の大きな改革になるんじゃないかと思ってます。
最初から言語毎のフィールドを用意しているアプリケーション(例えばosCommerceなど)と同等の操作感になるわけですから。


なおこれらのコードでは、PHP5専用なら明らかにprivateにするだろうと思われるオブジェクトプロパティを参照のみならず、一時的に書き換えるなど、かなりアクロバティックなことをやってますが、なにとぞご容赦を

# cubeUtils側で取り込んでもらっても構いませんぜ >nobunobuさん


Related articles
Printer friendly page Send this story to a friend

Comments list

jidaikobo  Posted on 2008/6/24 11:10
GIJOE さん、ご反応ありがとうございます。
問題がわかりましたので、ご報告させていただきます。

Quote:
GIJOE wrotes:
とりあえず、
! empty( $_POST ) 
という判定条件を、
sizeof( @$_POST ) > 0
としたらどうなりますか?
やってみました。
        if ( sizeof( @$_POST ) > 0 && file_exists(XOOPS_ROOT_PATH.'/modules/cubeUtils/class/MultiLanguage.class.php')) {
echo 0;
としてみたんですが、やっぱり post をしてみても無反応でした。
が、ここで気づきました。あれですよね。redirect してるから、ただ var_dump() してもだめですよね。というわけで die() をあわせてやってみたところ、! empty( $_POST ) の条件式が有効になりました。

array(hoge) {
  ["cat_title"]=>
  array(2) {
    ["ja"]=>
    string(27) "日本語"
    ["en"]=>
    string(13) "English"
  }
}

ここまでこれたら解析できるぞ、と mergeRecursive() のところで $data を var_dump() してみました。

            } else if( in_array( $index , $cubeUtilMlang->mLanguages ) ) {
                $merged_string .= '['.$index.']'.$data[ $index ].'[/'.$index.']' ;
                $langs_counter ++ ;
            }
        }
echo '<pre>' ;
var_dump( str_replace( '[','-',$merged_string ) ) ;
echo '</pre>' ;
die();
#cubeUtils の出力制御って、var_dump() のときにも有効なんですね。str_replace() で、ブラケットをマイナスにしないと中身が見られないことになかなか気づけませんでした。
ともあれ、上述の処理で、foreach() もうまく機能していることがわかり、じゃあ何がいけないのか……。
次の行を見てやっとわかりました。

        if( $langs_counter == sizeof( $cubeUtilMlang->mLanguages ) ) {

言語の数を確認してたんですね! 適用しようとしていたサイトでは4カ国語を使う予定でした。でも、ほかの2カ国語の翻訳のアテがなく、とりあえず英語だけやっとこ、と input のフィールドを、日本語と英語の2つだけにしていたのです。他の予定言語についても空のフィールドを足しておきましたところ、みごとにうごきました。
レアケースかとは思いますが、ご報告まで。

Quote:
あと、テンプレートは見るからにおかしいですよね。
<snip>
じゃないと、マージした意味がありません。
name 属性を間違えるなんて、そんなルーキーのようなミスはしてないだろうとおもっていたら、ほんとだ、間違ってました orz 。
マイナーからやり直してきます……
GIJOE  Posted on 2008/6/24 5:58
う〜ん、おかしいですね。

とりあえず、
! empty( $_POST ) 
という判定条件を、
sizeof( @$_POST ) > 0
としたらどうなりますか?

あと、テンプレートは見るからにおかしいですよね。
<{*
		<tr valign="top" align="left">
			<th class="head"><label for="category_title"><{$smarty.const._MD_PICO_TH_CATEGORYTITLE}></label></th>
			<td class="even">
				<input type="text" name="cat_title" id="category_title" size="50" maxlength="255" value="<{$category.title}>" />
			</td>
		</tr>
*}>
		<tr valign="top" align="left">
			<th class="head"><label for="title[ja]">日本語タイトル</label></th>
			<td class="even">
				<input type="text" name="cat_title[ja]" id="title[ja]" size="35" maxlength="255" value="<{$category.title|easiestml:"ja"}>" />
			</td>
		</tr>
		<tr valign="top" align="left">
			<th class="head"><label for="title[en]">英語タイトル</label></th>
			<td class="even">
				<input type="text" name="cat_title[en]" id="title[en]" size="35" maxlength="255" value="<{$category.title|easiestml:"en"}>" />
			</td>
		</tr>
じゃないと、マージした意味がありません。
jidaikobo  Posted on 2008/6/23 15:43
待ってました〜とばかりに入れてみたんですが、うまく動きませんでした T_T
どうかオタスケくださいませ。
php のバージョンは 5.2.5 です。

まずは下記位置に echo をかけてみました。


    function preFilter()
    {
echo 0;

ページの先頭には 0 が表示されます。
つぎに下記位置です。

    function preFilter()
    {
        if ( ! empty( $_POST ) && file_exists(XOOPS_ROOT_PATH.'/modules/cubeUtils/class/MultiLanguage.class.php')) {
echo 0;

$_POST があって、MultiLanguage.class.php があるという条件なので、普通は出てこないんですが、MultiLanguage.class.php はあるので、POST してみます。でも、0 が出てきません。
アレレと思い、次のような処理。

    function preFilter()
    {
        if ( file_exists(XOOPS_ROOT_PATH.'/modules/cubeUtils/class/MultiLanguage.class.php')) {
echo 0;
        }

ファイルの存在確認だけしてみると、ちゃんと 0 がでてくる。
じゃあ post か。下記のように直して post してみる。

    function preFilter()
    {
        if ( ! empty( $_POST ) ) {
echo 0;
        }

あれー、POST しても出てこない。
なんでかしらと $_POST を var_dump() して、ふたたび post。
POST 内容がでるものの、以下のような Warning が出てストップ。

Quote:
Warning: Cannot modify header information - headers already sent by (output started at /***/preload/MultiLanguagePostMerger.class.php:8) in /***/modules/cubeUtils/class/MultiLanguage.class.php on line 72
Warning: Cannot modify header information - headers already sent by (output started at /***/preload/MultiLanguagePostMerger.class.php:8) in /***/modules/cubeUtils/class/MultiLanguage.class.php on line 76
Warning [PHP]: Cannot modify header information - headers already sent by (output started at /***/preload/MultiLanguagePostMerger.class.php:8) in file /****/xoops_trust_path/modules/wizmobile/class/WizMobile.class.php line 152
Warning [PHP]: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at /***/preload/MultiLanguagePostMerger.class.php:8) in file core/XCube_Session.class.php line 78
#まあ、headers already sent by ということなので、僕が書いた var_dump() がマズいということだと思うのですが……。

なんで var_dump() すると post がきているのに条件判定では false になるのかわからないんですが、なにか preload がバッティングしているのかなともおもったんですが、下記状態から

Quote:
HdServerEnvironment.class.php
HdXoopsTplHook.class.php
LegacyRenderAssignMytrustdirname.class.php
MultiLanguageCompatibleEMLH.class.php
MultiLanguagePostMerger.class.php
MultiLanguagePreLoad.class.php
SetupAltsysLangMgr.class.php

以下の3つだけの状態にしてみてもやっぱりだめみたいでした。

Quote:
MultiLanguageCompatibleEMLH.class.php
MultiLanguagePostMerger.class.php
MultiLanguagePreLoad.class.php

ちなみにテンプレートの状態はこんな感じです。

<{*
		<tr valign="top" align="left">
			<th class="head"><label for="category_title"><{$smarty.const._MD_PICO_TH_CATEGORYTITLE}></label></th>
			<td class="even">
				<input type="text" name="cat_title" id="category_title" size="50" maxlength="255" value="<{$category.title}>" />
			</td>
		</tr>
*}>
		<tr valign="top" align="left">
			<th class="head"><label for="title[ja]">日本語タイトル</label></th>
			<td class="even">
				<input type="text" name="title[ja]" id="title[ja]" size="35" maxlength="255" value="<{$category.title|easiestml:"ja"}>" />
			</td>
		</tr>
		<tr valign="top" align="left">
			<th class="head"><label for="title[en]">英語タイトル</label></th>
			<td class="even">
				<input type="text" name="title[en]" id="title[en]" size="35" maxlength="255" value="<{$category.title|easiestml:"en"}>" />
			</td>
		</tr>

テンプレートを書き換えてリロードしたところ、 [ja]日本語[/ja][en]English[/en] となっていた入力欄はきれいに分割されましたので、こっち側は大丈夫だと思うのですが。
あとどこを疑ってみる手があるでしょうか?
Login
Username or e-mail:

Password:

Remember Me

Lost Password?

Register now!