[Frameworkspider-svn] spider-commit [10]

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2009年 3月 26日 (木) 21:01:45 JST


Revision: 10
          http://svn.sourceforge.jp/view?root=frameworkspider&view=rev&rev=10
Author:   m_nakashima
Date:     2009-03-26 21:01:45 +0900 (Thu, 26 Mar 2009)

Log Message:
-----------


Modified Paths:
--------------
    current/DATA/lib/spider/tags/If.class.php
    current/DATA/lib/spider/tags/OutputHtml.class.php
    current/DATA/lib/spider/tags/TagBase.class.php
    current/README.txt


-------------- next part --------------
Modified: current/DATA/lib/spider/tags/If.class.php
===================================================================
--- current/DATA/lib/spider/tags/If.class.php	2009-03-25 09:03:06 UTC (rev 9)
+++ current/DATA/lib/spider/tags/If.class.php	2009-03-26 12:01:45 UTC (rev 10)
@@ -43,6 +43,7 @@
 	 * コンバートメソッド
 	 */
 	function convert( &$result_strings, &$build_information ){
+		// ifの変換
 		$vars_tags_aray			= array();
 		preg_match_all( '/\\{if\\:[^\\}]*?}/'
 			, $result_strings
@@ -51,19 +52,139 @@
 		$valiable_counter	= 0;
 		foreach ( $vars_tags_aray as $vars_tags ) {
 			foreach ( $vars_tags as $vars_tag ) {
-				$var_name	= preg_replace( '/\\{if\\:/','', $vars_tag );
-				$var_name	= preg_replace( '/\\}$/','', $var_name );
-				$var_name	= trim( $var_name );
-				$repstr		= $this->parseCondition( $var_name, $valiable_counter );
+				$option_string	= preg_replace( '/\\{if\\:/','', $vars_tag );
+				$option_string	= preg_replace( '/\\}$/','', $option_string );
+				$option_string	= trim( $option_string );
+				// 下位互換の為::を含むなら旧ロジック
+				$repstr		= '';
+				if( preg_match('/\\:\\:/',$option_string) > 0 ) {
+					$repstr	= $this->parseCondition( $option_string, $valiable_counter );
+				} else {
+					$repstr	= '<?php if( '.$this->condition2code( $option_string ).' ) { ?>';
+				}
 				$result_strings	= str_replace( $vars_tag, $repstr, $result_strings );
 				$valiable_counter++;
 			}
 		}
+		// else-ifの変換
+		$vars_tags_aray			= array();
+		preg_match_all( '/\\{else\\-if\\:[^\\}]*?}/'
+			, $result_strings
+			, $vars_tags_aray
+			, PREG_PATTERN_ORDER );
+		$valiable_counter	= 0;
+		foreach ( $vars_tags_aray as $vars_tags ) {
+			foreach ( $vars_tags as $vars_tag ) {
+				$option_string	= preg_replace( '/\\{else\\-if\\:/','', $vars_tag );
+				$option_string	= preg_replace( '/\\}$/','', $option_string );
+				$option_string	= trim( $option_string );
+				$repstr			= '<?php } else if( '.$this->condition2code( $option_string ).' ) { ?>';
+				$result_strings	= str_replace( $vars_tag, $repstr, $result_strings );
+				$valiable_counter++;
+			}
+		}
+		
 		$result_strings = str_replace( '{else}', '<?php } else { ?>', $result_strings );
 		$result_strings = str_replace( '{end-if}', '<?php } ?>', $result_strings );
 		$result_strings = str_replace( '{/if}', '<?php } ?>', $result_strings );
 	}
 	/**
+	 * ifタグ内の条件式を解析します。
+	 */
+	function condition2code( $strings ) {
+		// 演算時の正規表現
+		$signiture_regx	= '\\+\\-\\/\\*\\%\\=\\<\\>\\&\\|\\(\\)\\!\\,\\[\\]';
+		
+		// 2文字以上連続のスペースは1文字に統一
+		while( preg_match('/\\s\\s/',$strings) > 0 ) {
+			$strings	= str_replace( '  ',' ', $strings );
+		}
+
+		// 下位互換の為、and/orは演算子に置換する
+		$strings	= str_replace(' and ', ' && ', $strings );
+		$strings	= str_replace(' or ', ' || ', $strings );
+		// 下位互換の為、is null / is not nullを置換する
+		$strings	= preg_replace('/(|\\s)([^\\s'.$signiture_regx.']*)\\sis\\snull/','$1is_null( $2 )',$strings);
+		$strings	= preg_replace('/(|\\s)([^\\s'.$signiture_regx.']*)\\sis\\snot\\snull/','$1!is_null( $2 )',$strings);
+		// 下位互換の為inも置換する
+		$strings	= preg_replace('/(|\\s)([^\\s]*)\\sin\\s([^\\s\\}'.$signiture_regx.']*)/','$1in_array( $2 )',$strings);
+		// 下位互換の為連続していない=は連続=に変換しておく(if文中で代入が利用できなくなる為要検討)
+		$strings	= preg_replace('/([^\\+\\-\\/\\*\\%\\=\\<\\>])\\=([^\\=])/','$1==$2',$strings);
+
+		$converted_strings	= '';
+		$element_array		= preg_split('/([\\s'.$signiture_regx.'])/', $strings, -1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE );
+		$element_data		= '';
+		$prev_data			= '';
+		foreach( $element_array as $key => $element ) {
+			$element_data		.= $element;
+			if( preg_match('/^\\\'/',$element_data) > 0 && substr_count( $element_data, "'" ) % 2 == 1 ) {
+				// 'から始まって'の数が偶数個なら次のカラムとつなげる
+				continue;
+			} else if( preg_match('/^\\\'/',$element_data) > 0 && substr_count( $element_data, "'" ) % 2 == 1 ) {
+				// 'から始まって'の数が偶数個なら次のカラムとつなげる
+				continue;
+			} else {
+				if( preg_match('/([\\s'.$signiture_regx.'])/',$element_data) == 0 ) {
+					// 演算子でない場合のみ処理
+					if( preg_match('/^\\$/',$element_data ) > 0 ) {
+						// $から始まるなら変換しないでそのまま追加
+						$converted_strings	.= $element_data;
+					} else if( preg_match('/^\\\'/',$element_data ) > 0 && preg_match('/\\\'$/',$element_data ) > 0 ) {
+						// クォートされているなら文字列
+						if( $key > 2 && $element_array[$key-1] == '>' &&  $element_array[$key-2] == '-'){
+							// 前の要素が->オブジェクトメンバ指定子の場合クォートを除去して追加
+							$converted_strings	.= preg_replace('/(^\'|\'$)/','',$element_data);
+						} else {
+							// ただの文字列の場合はそのまま追加
+							$converted_strings	.= $element_data;
+						}
+					} else if( preg_match('/^\\\"/',$element_data ) > 0 && preg_match('/\\\"$/',$element_data ) > 0 ) {
+						// クォートされているなら文字列
+						if( $key > 2 && $element_array[$key-1] == '>' &&  $element_array[$key-2] == '-'){
+							// 前の要素が->オブジェクトメンバ指定子の場合
+							$converted_strings	.= preg_replace('/(^\\"|\\"$)/','',$element_data);
+						} else {
+							// ただの文字列の場合はそのまま追加
+							$converted_strings	.= $element_data;
+						}
+					} else if( preg_match('/^[0-9]+$/',$element_data ) > 0 ) {
+						// 数字だけならそのまま追加
+						$converted_strings	.= $element_data;
+					} else {
+						// 次の演算子以外の要素が(なら関数なので次の空でない要素をチェック
+						$is_method	= false;
+						for( $i=$key+1;$i<count($element_array);$i++){
+							$val	= trim($element_array[$i]);
+							if( strlen($val) > 0 ) {
+								if( $val == '(' ) {
+									$is_method	= true;
+								}
+								break;
+							}
+						}
+						if( $is_method ) {
+							// 関数名・メソッド名の場合はそのまま追加
+							$converted_strings	.= $element_data;
+						} else if( $key > 2 && $element_array[$key-1] == '>' &&  $element_array[$key-2] == '-'){
+							// メソッドでなくて前の要素が->の場合オブジェクトメンバも変換(要検討...)
+							$converted_strings	.= '$GLOBALS[\''.$element_data.'\']';
+						} else {
+							// それ以外は$GLOBALSへ変換
+							$converted_strings	.= '$GLOBALS[\''.$element_data.'\']';
+						}
+					}
+				} else {
+					// 演算子はそのまま追加
+					$converted_strings	.= $element_data;
+				}
+				$prev_data			= $element_data;
+				$element_data		= '';
+			}
+		}
+
+		return $converted_strings;
+	}
+	/**
 	 * if条件文の式を解析する
 	 * 定義済み文字列: and / or / = / != / > / < / + / - / * // is null /is not null/in
 	 */

Modified: current/DATA/lib/spider/tags/OutputHtml.class.php
===================================================================
--- current/DATA/lib/spider/tags/OutputHtml.class.php	2009-03-25 09:03:06 UTC (rev 9)
+++ current/DATA/lib/spider/tags/OutputHtml.class.php	2009-03-26 12:01:45 UTC (rev 10)
@@ -78,6 +78,7 @@
 			// コード追加
 			$html_path		= preg_replace('/\\.php$/','.html',$build_information->execute_file_path);
 			$html_path		= str_replace('"','\\"',$html_path);
+			$html_path		= str_replace('\\','\\\\',$html_path);
 			$process_code	= 'if( !file_exists("'.$html_path.'") || time() - filemtime("'.$html_path.'") > '.$lifetime.' ){'."\n";
 				$process_code	.= '$fp = fopen("'.$html_path.'","w");'."\n";
 				$process_code	.= 'if($fp){'."\n";

Modified: current/DATA/lib/spider/tags/TagBase.class.php
===================================================================
--- current/DATA/lib/spider/tags/TagBase.class.php	2009-03-25 09:03:06 UTC (rev 9)
+++ current/DATA/lib/spider/tags/TagBase.class.php	2009-03-26 12:01:45 UTC (rev 10)
@@ -27,6 +27,17 @@
 	 * コンバートメソッド
 	 */
 	function convert( &$result_strings, &$build_information ){
+		// デフォルト動作は設定済みタグ名称でのシングルタグ全変換
+		$this->convertSingleTagAll( $result_strings, $build_information );
+	}
+	/**
+	 * 要素のみのシングルタグ変換を実行します
+	 */
+	function convertSingleTagAll( &$result_strings, &$build_information, $tag_name=null ) {
+		// タグ名称が渡された場合のみ設定
+		if( !is_null($tag_name) && strlen($tag_name) > 0 ) {
+			$this->tag_name	= $tag_name;
+		}
 		// タグ名称が設定されていないなら処理をしない
 		if( is_null($this->tag_name) || strlen($this->tag_name) == 0 ) {
 			return;
@@ -51,11 +62,7 @@
 					} 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);
+						$param_array	= $this->splitOptionBySpace( $options_string );
 						$option_array	= array();
 						foreach( $param_array as $param ) {
 							$param	= trim($param);
@@ -72,6 +79,7 @@
 				}
 			}
 		}
+		return;
 	}
 	/**
 	 * 個々のタグ文字列の変換後文字列を取得します
@@ -80,5 +88,39 @@
 	function getConvertedStrings( &$result_strings, &$build_information, $option_array=array(), $valiable_counter=0 ) {
 		return '';
 	}
+	//
+	// タグ解析全般で利用するユーティリティメソッド
+	//
+	/**
+	 * オプション文字列をオプション配列にします。
+	 */
+	function splitOptionBySpace( $string ) {
+		// 2文字以上連続のスペースは1文字に統一
+		while( preg_match('/\\s\\s/',$string) > 0 ) {
+			$string	= str_replace( '  ',' ', $string );
+		}
+		// 分割
+		$column_array	= explode(' ', $string);
+		// 最終的なオプション文字列配列
+		$option_array	= array();
+		// クォートを維持してオプション文字列配列にいれる
+		$data			= '';
+		foreach( $column_array as $column ) {
+			$data		.= $column;
+			if( preg_match('/^\\\'/',$data) > 0 && substr_count( $data, "'" ) % 2 == 1 ) {
+				// 'から始まって'の数が偶数個なら次のカラムとつなげる
+				continue;
+			} else if( preg_match('/^\\\"/',$data) > 0 && substr_count( $data, '"' ) % 2 == 1 ) {
+				// "から始まって"の数が偶数個なら次のカラムとつなげる
+				continue;
+			} else {
+				// そうでない場合はカラムがデータとして完結しているので配列に追加
+				array_push( $option_array, $data );
+				// 次のデータに備えてデータを空文字で新しく設定
+				$data	= '';
+			}
+		}
+		return $option_array;
+	}
 }
 ?>
\ No newline at end of file

Modified: current/README.txt
===================================================================
--- current/README.txt	2009-03-25 09:03:06 UTC (rev 9)
+++ current/README.txt	2009-03-26 12:01:45 UTC (rev 10)
@@ -3,6 +3,29 @@
 **
 ** このファイルにはコミットごとに変更点とファイル名を記述します。
 **
+-- 2009-03-26
+1) OutputHtmlタグで出力するファイルパスがWindowsで不具合を起こす問題の修正
+
+2) TagBaseクラスのリファクタリング
+   今後に備え、デフォルト動作のシングルタグ用ロジックを別メソッドに切り分け
+   オプション文字列をスペース区切りクォート配慮して配列に分割するユーティリティメソッドsplitOptionBySpaceを追加
+
+3) ifタグのリファクタリングと機能強化
+   ifタグに新しい解析ロジックを導入。これにより{else-if:}機能を実装
+   新しいロジックでは[オブジェクト]::[メンバ名]もしくは[ハッシュ]::[要素名]での変数指定が行えない。
+   オブジェクトの場合は->メンバ指定子で、ハッシュや配列の場合は[添え字]で指定する必要がある。
+   この為、下位互換目的で::が条件文字列に含まれていると旧ロジックで解析するようにしてあります。
+   
+   ::で要素やメンバ指定を行わない書式であれば
+
+   ・ グローバル関数及びオブジェクトメソッド、オブジェクトメンバは自由に呼び出せます。
+      ただし、オブジェクトメンバ変数を明示的に呼び出す場合は[オブジェクト]->'メンバ名'のように
+      メンバ変数名をシングルクォーテーションで囲む必要があります。
+   ・ and,orの記述を、 &&,||に変更しました。and,orも使えますが推奨しません。
+   ・ 一致の比較演算子=ひとつでOKでしたが、==で比較するよう変更することを推奨とします。
+   ・ 固定文字列は''シングルクォートする必要があります。クォートしていないものは文字列として扱わず
+     request属性に登録されている属性名とみなします。
+
 -- 2009-03-25
 1)ビルドファイル作成前に行いたい処理スクリプトを指定する機能を追加しました。
    グローバル変数として配列$GLOBALS['SPIDER_PREVIOUS_SCRIPT_FILE_PATH_ARRAY']を定義し、



Frameworkspider-svn メーリングリストの案内
Back to archive index