svnno****@sourc*****
svnno****@sourc*****
2009年 3月 24日 (火) 18:12:21 JST
Revision: 4 http://svn.sourceforge.jp/view?root=frameworkspider&view=rev&rev=4 Author: m_nakashima Date: 2009-03-24 18:12:21 +0900 (Tue, 24 Mar 2009) Log Message: ----------- Modified Paths: -------------- current/DATA/lib/spider/BuildInformation.class.php current/DATA/lib/spider/ExecutableFileCreator.class.php current/DATA/lib/spider/tags/Foreach.class.php current/DATA/lib/spider/tags/Module.class.php current/DATA/lib/spider/tags/PageTitle.class.php current/DATA/lib/spider/tags/TagBase.class.php current/DATA/lib/spider/tags/Widget.class.php current/DATA/lib/spider/tags/Write.class.php current/README.txt current/WWW_PUBLIC/index.php -------------- next part -------------- Modified: current/DATA/lib/spider/BuildInformation.class.php =================================================================== --- current/DATA/lib/spider/BuildInformation.class.php 2009-03-23 12:03:37 UTC (rev 3) +++ current/DATA/lib/spider/BuildInformation.class.php 2009-03-24 09:12:21 UTC (rev 4) @@ -169,11 +169,13 @@ function addExecModuleByString( $string ) { $string = trim( $string ); if( strlen($string) > 0 ) { - $info_array = explode(' ', $string); + $info_array = explode(' ', $string); // ひとつめの要素は必ずモジュール名 - $module_name = trim(array_shift($info_array)); - $info_hash = array(); - $info_hash['force'] = false; + $module_name = trim(array_shift($info_array)); + $info_hash = array(); + // モジュール名と強制実行パラメータを情報ハッシュに設定 + $info_hash['module_name'] = $module_name; + $info_hash['force'] = false; // 二つ目以降の要素を確認 foreach( $info_array as $info ) { $info = trim($info); @@ -201,7 +203,13 @@ } } } - $this->module_exec_info_hash[$module_name] = $info_hash; + // パラメータが異なる場合にキーを変更してハッシュに登録する。forceパラメータは参照しない + if( isset($info_hash['post']) || isset($info_hash['get']) || isset($info_hash['attribute_prefix'])) { + $keyname = implode('',$info_hash); + $this->module_exec_info_hash[$keyname] = $info_hash; + } else { + $this->module_exec_info_hash[$module_name] = $info_hash; + } } } /** Modified: current/DATA/lib/spider/ExecutableFileCreator.class.php =================================================================== --- current/DATA/lib/spider/ExecutableFileCreator.class.php 2009-03-23 12:03:37 UTC (rev 3) +++ current/DATA/lib/spider/ExecutableFileCreator.class.php 2009-03-24 09:12:21 UTC (rev 4) @@ -166,7 +166,8 @@ } // モジュール実行のスクリプト追加 - foreach( $build_information_object->module_exec_info_hash as $module_name => $info_hash ) { + foreach( $build_information_object->module_exec_info_hash as $key => $info_hash ) { + $module_name = $info_hash['module_name']; $force = 'false'; if( $info_hash['force'] ) { $force = 'true'; Modified: current/DATA/lib/spider/tags/Foreach.class.php =================================================================== --- current/DATA/lib/spider/tags/Foreach.class.php 2009-03-23 12:03:37 UTC (rev 3) +++ current/DATA/lib/spider/tags/Foreach.class.php 2009-03-24 09:12:21 UTC (rev 4) @@ -34,60 +34,169 @@ * コンストラクタ */ function spider_tags_Foreach() { + $this->tag_name = 'foreach'; } /** * コンバートメソッド */ function convert( &$result_strings, &$build_information ){ - $vars_tags_aray = array(); - preg_match_all( '/\\{foreach\\:[^\\}]*?}/' - , $result_strings - , $vars_tags_aray - , PREG_PATTERN_ORDER ); - $valiable_counter = 0; - foreach ( $vars_tags_aray as $vars_tags ) { - foreach ( $vars_tags as $vars_tag ) { - $var_name = preg_replace( '/\\{foreach\\:/','', $vars_tag ); - $var_name = preg_replace( '/\\}$/','', $var_name ); - $var_name = trim( $var_name ); - $var_name = str_replace( ' ',' ', $var_name ); - $var_name = str_replace( ' ',' ', $var_name ); - $at_name = null; - list( $var_name, $key_name, $val_name ) = explode( ' ', $var_name ); - if ( strpos( $var_name, '::' ) > 0 ) { - list( $var_name, $at_name ) = explode( '::', $var_name ); + parent::convert( $result_strings, $build_information ); + $result_strings = str_replace( '{end-foreach}', '<?php } } else { echo \'[target attribute is not array!]\'; } ?>', $result_strings ); + $result_strings = str_replace( '{/foreach}', '<?php } } else { echo \'[target attribute is not array!]\'; } ?>', $result_strings ); + } + /** + * 個々のタグ文字列の変換後文字列を取得します + */ + function getConvertedStrings( &$result_strings, &$build_information, $option_array=array(), $valiable_counter=0 ) { + // ループに必要なオプションを取り出し(順序固定) + $org_attribute_name = array_shift( $option_array ); + $loop_key_name = array_shift( $option_array ); + $loop_val_name = array_shift( $option_array ); + + // 属性名指定がない場合はエラー表示で返す + if( strlen( $org_attribute_name ) == 0 ) { + return 'echo \'[error: "foreach" need parameters!]\'; if(false){if(false) {'; + } + // ループのキー名と値名の取り出し + if ( strlen( $loop_key_name ) > 0 && strlen( $loop_val_name ) > 0 ) { + // キー名と値名の両方が指定されている場合には何もしない + } else if ( strlen( $loop_key_name ) > 0 ) { + // 片方しか入力がない場合、値名がひとつめでキー名は自動 + $loop_val_name = $loop_key_name; + $loop_key_name = 'key'; + } else { + // 両方とも入力がない場合はエラー表示 + return 'echo \'[error: "foreach" need parameters!]\'; if(false){if(false) {'; + } + + // ループカウンタ数字名の決定 + $counter_name = str_replace('::','_',str_replace('.','_',$org_attribute_name)).'_loop_counter'; + // 実際にループする変数名 + $real_loop_var_name = '$tmp_array_'.sprintf('%08d',$valiable_counter); + // 置換文字列作成 + $rep_string = '<?php '; + if( preg_match( '/\\-\\>/',$org_attribute_name ) > 0 || preg_match('/\\[.+\\]/',$org_attribute_name) > 0 ) { + // オブジェクトや配列の指定子が含まれている場合 + $real_var_string = $this->getAvailableVarName( $org_attribute_name ); + $rep_string .= $real_loop_var_name.'='.$real_var_string.'; '; + } else if ( strpos( $org_attribute_name, '::' ) > 0 ) { + // 従来の記述 属性名を::で分岐 + list( $attribute_name, $member_name ) = explode( '::', $org_attribute_name ); + // 対象属性値 + $target_attribute_name = '$GLOBALS[\''.$attribute_name.'\']'; + $rep_string .= $real_loop_var_name.'='.$target_attribute_name.'[\''.$member_name.'\']; '; + if( strlen( $member_name ) > 0 ) { + // メンバ指定がある場合は属性値がオブジェクトか配列かで分岐処理 + $rep_string .= 'if( is_array('.$target_attribute_name.') ){ '; + $rep_string .= $real_loop_var_name.'='.$target_attribute_name.'[\''.$member_name.'\']; '; + if( preg_match('/^[a-zA-Z\\_][0-9a-zA-Z\\_]*?/',$member_name) > 0 ) { + $rep_string .= ' } else if( is_object('.$target_attribute_name.') ) {'; + $rep_string .= $real_loop_var_name.'='.$target_attribute_name.'->'.$member_name.'; '; } - $k_name = 'key'; - $v_name = 'value'; - if ( strlen( $key_name ) > 0 && strlen( $val_name ) > 0 ) { - $k_name = $key_name; - $v_name = $val_name; - } else if ( strlen( $key_name ) > 0 ) { - $v_name = $key_name; + $rep_string .= ' } '; + } + } else { + // 属性名を特に区切る必要がない場合は + $target_attribute_name = '$GLOBALS[\''.$org_attribute_name.'\']'; + $rep_string .= $real_loop_var_name.'='.$target_attribute_name.'; '; + } + $rep_string .= 'if( is_array('.$real_loop_var_name.') ) { '; + $rep_string .= '$GLOBALS[\''.$counter_name.'\']=0; '; + $rep_string .= 'foreach ( '.$real_loop_var_name + .' as $GLOBALS[\''.$loop_key_name.'\'] => $GLOBALS[\''.$loop_val_name.'\'] ) {'; + $rep_string .= '$GLOBALS[\''.$counter_name.'\']++; '; + // 下位互換の為ループごとに属性設定 + $rep_string .= '$request_object->setAttribute("'.$loop_key_name.'",$GLOBALS[\''.$loop_key_name.'\']); '; + $rep_string .= '$request_object->setAttribute("'.$loop_val_name.'",$GLOBALS[\''.$loop_val_name.'\']); '; + $rep_string .= '$request_object->setAttribute("'.$counter_name.'",$GLOBALS[\''.$counter_name.'\']); '; + // 置換文字列終了 + $rep_string .= ' ?>'; + + return $rep_string; + } + /** + * 第一引数のループ対象指定文字列をPHP実行コードに変換して返します。 + */ + function getAvailableVarName( $org_attribute_name ) { + if( strlen( $org_attribute_name ) > 0 ) { + // オブジェクトや配列の指定子が含まれている場合全ての属性値候補を取り出し + $attribute_proposed_array = $this->getReverseSortedProposeAttributeHash( $org_attribute_name ); + // 属性名候補を変換する + $real_var_string = $org_attribute_name; + foreach( $attribute_proposed_array as $attribute_name => $prev_char ) { + if( preg_match('/^[0-9]+$/',$attribute_name) > 0 ) { + // 属性名候補が数字のみの場合変換しない + continue; + } else if( preg_match('/^\\$[^0-9][.]*$/',$attribute_name) > 0 ) { + // 属性名候補が$で始まる変数名なら変換しない + continue; + } else if( preg_match('/^\\\'[^\\\']*\\\'$/',$attribute_name) > 0 + || preg_match('/^\\"[^\\"]*\\"$/',$attribute_name) > 0 ) { + // 属性名候補がクォーテーションで囲まれていたら + if( '>' == $prev_char ) { + // 直前の文字がオブジェクトメンバ指定子の場合クォーテーションを除去して確認 + $name = preg_replace('/^\\\'/','',$attribute_name); + $name = preg_replace('/\\\'$/','',$name); + $name = preg_replace('/^\\"/','',$name); + $name = preg_replace('/\\"$/','',$name); + if( preg_match('/^[^0-9][0-9a-zA-Z\\_]*$/', $name ) > 0 ) { + // メンバ名として有効そうであればクォーテーションを除去した文字列へ変換 + $real_var_string = str_replace($attribute_name,$name,$real_var_string); + } else { + // 暫定:有効なメンバでない場合使い方が正しくないのでPHPのコアエラーとし何もしない + continue; + } + } else { + // 直前の文字列がオブジェクトメンバ指定子でない場合は変換しない + continue; + } + } else { + // それ以外の場合はグローバル変数名として変換 + $replacew = '$GLOBALS[\''.$attribute_name.'\']'; + $real_var_string = str_replace($attribute_name,$replacew,$real_var_string); } - $counter_name = str_replace('.','_',$var_name)."_".$at_name."_loop_counter"; - $rep_string = "<?php "; - $rep_string .= '$tmp_arry'.$valiable_counter.' = $request_object->getAttribute( "'.$var_name.'" ); '; - $rep_string .= '$type = gettype($tmp_arry'.$valiable_counter.'); '; - if ( strlen( trim($at_name ) ) > 0 ) { - $rep_string .= 'if(\'array\'==$type) { $tmp_arry'.$valiable_counter.'=$tmp_arry'.$valiable_counter.'[\''.$at_name.'\']; } '; - $rep_string .= 'if(\'object\'==$type) { $tmp_arry'.$valiable_counter.'=$tmp_arry'.$valiable_counter.'->'.$at_name.'; } '; - $rep_string .= '$type = gettype($tmp_arry'.$valiable_counter.'); '; + } + return $real_var_string; + } + return ''; + } + /** + * 属性名が配列要素指定やオブジェクトメンバ指定子を含む場合に変換候補属性名文字列を + * 文字列長の長い順番にハッシュにして返します + */ + function getReverseSortedProposeAttributeHash( $org_attribute_name ) { + $attribute_sort_array = array(); + if( preg_match( '/\\-\\>/',$org_attribute_name ) > 0 || preg_match('/\\[.+\\]/',$org_attribute_name) > 0 ) { + $attribute_proposed_array = array(); + $pos=0; + for( $i=0; $i<strlen($org_attribute_name); $i++ ) { + $char = substr($org_attribute_name,$i,1); + if( '-' == $char || '>' == $char + || '(' == $char || ')' == $char + || '[' == $char || ']' == $char ) { + // 演算子が登場したらひとつ前までを文字列切り出し + $str = trim(substr( $org_attribute_name, $pos, $i-$pos )); + $pos = $i+1; + if( '(' != $char && strlen( $str ) > 0 ) { + // 関数名でなければ変換対象として評価 + $attribute_sort_array[$str] = strlen($str); + $attribute_proposed_array[$str] = $char; + } } - $rep_string .= 'if(\'array\'==$type) { ' - . '$'.$counter_name.'=0; ' - . 'foreach( $tmp_arry'.$valiable_counter.' as $' . $k_name . '=>$' . $v_name . ' ) { ' - . '$'.$counter_name.'++; ' - . '$request_object->setAttribute("'.$counter_name.'",$'.$counter_name.'); ' - . '$request_object->setAttribute("'.$k_name.'",$'.$k_name.'); ' - . '$request_object->setAttribute("'.$v_name.'",$'.$v_name.'); ?>' - ; - $result_strings = str_replace( $vars_tag, $rep_string, $result_strings ); - $result_strings = str_replace( '{end-foreach}', '<?php } } ?>', $result_strings ); - $result_strings = str_replace( '{/foreach}', '<?php } } ?>', $result_strings ); - $valiable_counter++; } + // ループ最後のポジションから最後の要素を切り出し + $str = trim(substr( $org_attribute_name, $pos, $i-$pos )); + if( strlen( $str ) > 0 ) { + $attribute_sort_array[$str] = strlen($str); + } + // 変数配列を文字列の長い順にソート + arsort($attribute_sort_array); + // 直前の文字を代入 + foreach( $attribute_sort_array as $key => $value ) { + $attribute_sort_array[$key] = $attribute_proposed_array[$key]; + } } + return $attribute_sort_array; } } ?> \ No newline at end of file Modified: current/DATA/lib/spider/tags/Module.class.php =================================================================== --- current/DATA/lib/spider/tags/Module.class.php 2009-03-23 12:03:37 UTC (rev 3) +++ current/DATA/lib/spider/tags/Module.class.php 2009-03-24 09:12:21 UTC (rev 4) @@ -43,28 +43,19 @@ */ function spider_tags_Module() { $this->priority = 10; + $this->tag_name = 'module'; } /** - * コンバートメソッド + * 個々のタグ文字列の変換後文字列を取得します */ - function convert( &$result_strings, &$build_information ){ - // モジュール読み込みタグ - $vars_tags_aray = array(); - if( preg_match_all( '/\\{module\\:[^\\}]*?}/' - , $result_strings - , $vars_tags_aray - , PREG_PATTERN_ORDER ) > 0 ) { - foreach ( $vars_tags_aray as $vars_tags ) { - foreach ( $vars_tags as $vars_tag ) { - $module_name = preg_replace( '/\\{module\\:/','', $vars_tag ); - $module_name = preg_replace( '/\\}$/','', $module_name ); - $build_information->addExecModuleByString( $module_name ); - $result_strings = str_replace( $vars_tag - , '' - , $result_strings ); - } - } + function getConvertedStrings( &$result_strings, &$build_information, $option_array=array(), $valiable_counter=0 ) { + // モジュール追加の場合はオプションも含めた文字列をそのまま設定 + $module_string = implode(' ', $option_array); + if( strlen($module_string) > 0 ) { + $build_information->addExecModuleByString( $module_string ); } + // モジュールタグは削除する為空文字列を返す + return ''; } } ?> \ No newline at end of file Modified: current/DATA/lib/spider/tags/PageTitle.class.php =================================================================== --- current/DATA/lib/spider/tags/PageTitle.class.php 2009-03-23 12:03:37 UTC (rev 3) +++ current/DATA/lib/spider/tags/PageTitle.class.php 2009-03-24 09:12:21 UTC (rev 4) @@ -39,9 +39,7 @@ } } } - // 互換の為creatorに設定 - $build_information->page_title = $page_title; - // 前処理追加:互換性の為ページタイトルをセット + // 前処理追加:ページタイトルを属性にセット $process_code = '$page_title="'.str_replace("'","\\'",$page_title).'";'."\n"; $process_code .= '$request_object->setAttribute("page_title",$page_title );'."\n"; if( !is_array($build_information->preview_process_hash) ){ Modified: current/DATA/lib/spider/tags/TagBase.class.php =================================================================== --- current/DATA/lib/spider/tags/TagBase.class.php 2009-03-23 12:03:37 UTC (rev 3) +++ current/DATA/lib/spider/tags/TagBase.class.php 2009-03-24 09:12:21 UTC (rev 4) @@ -34,6 +34,7 @@ $tag_regx = CharUtility::escape_regx_str('{'.$this->tag_name); $tag_search_regx = $tag_regx.'[^\\}]*?\\}'; $tag_strings_array = array(); + $valiable_counter = 0; while( preg_match_all( '/'.$tag_search_regx.'/' , $result_strings , $tag_strings_array @@ -45,11 +46,15 @@ if( strlen(trim($options_string)) == 0 ) { // タグが終了しているようならオプション無で処理 $option_array = array(); - $converted_strings = $this->getConvertedStrings( &$result_strings, &$build_information, $option_array ); + $converted_strings = $this->getConvertedStrings( &$result_strings, &$build_information, $option_array, $valiable_counter ); $result_strings = str_replace( $target_tag, $converted_strings, $result_strings ); } else if( preg_match('/^\\:/', $options_string) > 0 ) { // :で始まっているならオプション文字列なのでオプションを取り出して処理 $options_string = preg_replace('/^\\:/','',$options_string); + // 2文字以上連続のスペースは1文字に統一 + while( preg_match('/\\s\\s/',$options_string) > 0 ) { + $options_string = str_replace( ' ',' ', $options_string ); + } $param_array = explode(' ', $options_string); $option_array = array(); foreach( $param_array as $param ) { @@ -58,11 +63,12 @@ array_push( $option_array, $param ); } } - $converted_strings = $this->getConvertedStrings( &$result_strings, &$build_information, $option_array ); + $converted_strings = $this->getConvertedStrings( &$result_strings, &$build_information, $option_array, $valiable_counter ); $result_strings = str_replace( $target_tag, $converted_strings, $result_strings ); } else { // 終了でも:でもないなら違うタグなので処理しない } + $valiable_counter++; } } } @@ -71,7 +77,7 @@ * 個々のタグ文字列の変換後文字列を取得します * 必要に応じて拡張したタグクラスで実装してください。 */ - function getConvertedStrings( &$result_strings, &$build_information, $option_array=array() ) { + function getConvertedStrings( &$result_strings, &$build_information, $option_array=array(), $valiable_counter=0 ) { return ''; } } Modified: current/DATA/lib/spider/tags/Widget.class.php =================================================================== (Binary files differ) Modified: current/DATA/lib/spider/tags/Write.class.php =================================================================== --- current/DATA/lib/spider/tags/Write.class.php 2009-03-23 12:03:37 UTC (rev 3) +++ current/DATA/lib/spider/tags/Write.class.php 2009-03-24 09:12:21 UTC (rev 4) @@ -149,7 +149,6 @@ $var_name_array[trim($str)] = ''; } - // 変数一時格納配列 $temporary_valiable_getter_array = array(); @@ -160,6 +159,9 @@ if( is_numeric( $key ) ) { // 変数が数字なら変換対象としない $var_name_array[$key] = $key; + } else if( preg_match( '/^$[^0-9][.]*$/', $key ) > 0 ) { + // 変数名なら変換対象としない + $var_name_array[$key] = $key; } else { // 変数が文字列の場合 $tmp_name = '$____tw__' . sprintf('%03d',$prefix) . sprintf('%03d',$vcounter); Modified: current/README.txt =================================================================== --- current/README.txt 2009-03-23 12:03:37 UTC (rev 3) +++ current/README.txt 2009-03-24 09:12:21 UTC (rev 4) @@ -4,3 +4,42 @@ ** このファイルにはコミットごとに変更点とファイル名を記述します。 ** +-- 2009-03-24 +1) モジュール呼び出しタグでGET/POST値の一時上書き指定があった場合に、同じモジュールでも複数回 + 呼び出しを行うよう修正しました。 + 【修正ファイル】 + DATA/lib/spider/BuildInformation.class.php + DATA/lib/spider/ExecutableFileCreator.class.php + +2)モジュールタグクラスを新TagBaseの書式に合わせてスリム化しました。 + 【修正ファイル】 + DATA/lib/spider/tags/Module.class.php + +3)ページタイトルタグクラスで不要コードを削除しコメントを適正化 + 【修正ファイル】 + DATA/lib/spider/tags/PageTitle.class.php + +4) タグベースクラスのメソッドgetConvertedStringsの第4引数に$valiable_counterを追加 + 標準で、何回目に発見したタグかの回数を0からスタートして渡します。 + これに伴いModuleタグとWidgetタグに記述されていた該当メソッドも引数追加しました。 + ・オプションの複数連続スペースをひとつにするよう処理を追加しました。 + 【修正ファイル】 + DATA/lib/spider/tags/TagBase.class.php + DATA/lib/spider/tags/Module.class.php + DATA/lib/spider/tags/Widget.class.php + +5) foreachタグをリファクタリングし、機能を強化しました + ループ対象として従来の::指定で配列属性値の要素やオブジェクト属性値のメンバにアクセスできた機能はそのままに + 対象がオブジェクトとわかっている場合は->指定子で + 対象が配列やハッシュとわかっている場合には[添え字]で + 要素やメンバに指定することができるようになりました。 + ::によるアクセスは一階層まででしたが、この記述を行えばアクセス可能な階層に制限はありません。 + 【修正ファイル】 + DATA/lib/spider/tags/Foreach.class.php + +6) writeタグの機能追加 + writeタグでタグ内に記述された$から始まるPHP変数は変換対象としないように変更しました。 + これにより、ページ内で宣言・初期化された変数をwriteタグ内で利用できます。 + 【修正ファイル】 + DATA/lib/spider/tags/Write.class.php + Modified: current/WWW_PUBLIC/index.php =================================================================== --- current/WWW_PUBLIC/index.php 2009-03-23 12:03:37 UTC (rev 3) +++ current/WWW_PUBLIC/index.php 2009-03-24 09:12:21 UTC (rev 4) @@ -4,4 +4,4 @@ {module:example.Hello force post(a="afds) get() attribute_prefix(media)} {module:example.Hello force} {dynamic-page} -{output-html:lifetime=300} \ No newline at end of file +{output-html} \ No newline at end of file