svnno****@sourc*****
svnno****@sourc*****
2010年 4月 21日 (水) 01:08:16 JST
Revision: 97 http://sourceforge.jp/projects/frameworkspider/svn/view?view=rev&revision=97 Author: m_nakashima Date: 2010-04-21 01:08:15 +0900 (Wed, 21 Apr 2010) Log Message: ----------- 初期コミット たたき台 Added Paths: ----------- db/current/.project db/current/README.txt db/current/htdocs/ db/current/htdocs/index.php db/current/htdocs/spider.inc.php db/current/spider/ db/current/spider/data/ db/current/spider/define.inc.php db/current/spider/lib/ db/current/spider/lib/db/ db/current/spider/lib/db/AbstractConnection.class.php db/current/spider/lib/db/AbstractData.class.php db/current/spider/lib/db/Connect.class.php db/current/spider/lib/db/Connection.class.php db/current/spider/lib/db/Transaction.class.php db/current/spider/lib/db/connection/ db/current/spider/lib/db/connection/Mysql.class.php db/current/spider/lib/db/connection/Pgsql.class.php db/current/spider/lib/db/define.inc.php db/current/spider/lib/example/ db/current/spider/lib/example/Hello.class.php db/current/spider/lib/spider/ db/current/spider/lib/spider/BuildInformation.class.php db/current/spider/lib/spider/Builder.class.php db/current/spider/lib/spider/Controller.class.php db/current/spider/lib/spider/HttpOutput.class.php db/current/spider/lib/spider/HttpRequest.class.php db/current/spider/lib/spider/ModuleBase.class.php db/current/spider/lib/spider/functions.inc.php db/current/spider/lib/spider/module/ db/current/spider/lib/spider/module/AutoEncode.class.php db/current/spider/lib/spider/module/AutoFormat.class.php db/current/spider/lib/spider/module/NoCache.class.php db/current/spider/lib/spider/tags/ db/current/spider/lib/spider/tags/Charset.class.php db/current/spider/lib/spider/tags/DynamicPage.class.php db/current/spider/lib/spider/tags/Foreach.class.php db/current/spider/lib/spider/tags/If.class.php db/current/spider/lib/spider/tags/Module.class.php db/current/spider/lib/spider/tags/OutputHtml.class.php db/current/spider/lib/spider/tags/PageTitle.class.php db/current/spider/lib/spider/tags/RewriteDocumentRoot.class.php db/current/spider/lib/spider/tags/SetAttribute.class.php db/current/spider/lib/spider/tags/SetRequestParam.class.php db/current/spider/lib/spider/tags/TagBase.class.php db/current/spider/lib/spider/tags/Template.class.php db/current/spider/lib/spider/tags/UseSession.class.php db/current/spider/lib/spider/tags/Widget.class.php db/current/spider/lib/spider/tags/Write.class.php db/current/spider/lib/spider/tags/externals.conf db/current/spider/lib/util/ db/current/spider/lib/util/CharUtility.class.php db/current/spider/lib/util/Date.class.php db/current/spider/lib/util/File.class.php db/current/spider/lib/util/GetHTTPResponse.class.php db/current/spider/lib/util/LockProcess.class.php db/current/spider/lib/util/Mail.class.php db/current/spider/lib/util/MobileTerminal.class.php db/current/spider/lib/util/ValidateFunctions.class.php db/current/spider/lib/util/XMLNode.class.php db/current/spider/lib/util/mail/ db/current/spider/lib/util/mail/Mime.class.php db/current/spider/lib/util/mail/PHP.class.php db/current/spider/lib/util/mail/SMTP.class.php db/current/spider/lib/util/mail/SendMail.class.php db/current/spider/messages.inc.php db/current/spider/pages/ db/current/spider/pages/default/ db/current/spider/pages/default/index.php db/current/spider/spider_command.inc.php db/current/spider/spider_main.inc.php db/current/spider/templates/ db/current/spider/templates/default/ db/current/spider/templates/default/public_default.tpl db/current/spider/unique_setting.inc.php db/current/spider/widgets/ db/current/spider/widgets/default/ db/current/spider/widgets/default/example.tpl db/current/spider/widgets/default/example.tpl.index.php db/current/spider/work/ -------------- next part -------------- Added: db/current/.project =================================================================== --- db/current/.project (rev 0) +++ db/current/.project 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>framework_spider_db_current</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>net.sourceforge.phpeclipse.parserbuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>net.sourceforge.phpeclipse.phpnature</nature> + </natures> +</projectDescription> Added: db/current/README.txt =================================================================== --- db/current/README.txt (rev 0) +++ db/current/README.txt 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,234 @@ +** +** README +** +** このファイルにはコミットごとに変更点とファイル名を記述します。 +** +-- 2010-03-29 +1) グローバルエラー機能を使えるように実装しました。 + spider_HttpRequestクラスのaddGlobalError($message)メソッドで追加したエラーメッセージは次回 + リクエスト時までセッションに保存されて復元されます。 + 再リクエスト時にセッションからは削除されます。 +2) util_Mailのreturn_path不具合を修正しました。 + return_pathが未設定の場合にfromのメールアドレス部分だけがアドレスが設定されるように修正しました。 + +-- 2010-03-26 +1) リバースプロキシ経由の場合のリダイレクト不具合を修正しました。 +2) テンプレート内でのXML宣言をechoしなくても記述できるように自動置換機能を追加しました。 + テンプレートの拡張子はなんでも構いませんので開発上の都合からphpから一般的なtplに変更することにしました。 +3) ダイナミックウィジェットに関する機能の変更 + ページダイレクト指定のウィジェットをウィジェット名.ページ名のファイルとするように変更しました。 +4) 時流に従って配布版のドキュメントルート用フォルダ名をhtdocsに変更しました + +-- 2010-01-20 +1) GETパラメータによるデバッグコマンドを実装しました + spiderdebugcmd=viewmoduletime + モジュール実行時間がダンプされます。 +2) binファイルの起点パスを設置上位フォルダからに変更しました。 + define.inc.phpのSPIDER_USE_ABSOLUTE_BIN_PATHをtrueにするとこれまでどおりの動作となります。 +3) movaサービスの終了に伴い配布版からDoCoMo1.0分岐の記述を削除しました。 +4) php.iniのbase_dirで読み込み階層が制限されていた場合の対策として + spiderフォルダ検索をspider.inc.php設置の上位ディレクトリまでとしました。 +5) spider_HttpRequestのwriteLogメソッドでログURIを記述できるように引数追加しました。 +6) RewriteDocumentRootの実装不具合を修正しました。 +7) setタグの記述方法でオブジェクトのメンバ指定子を許可するよう変更しました。 + +-- 2009-07-01 +1) PHP5.1.6でDoCoMoのxhtmlヘッダが正しく送信されない問題の修正 + PHP5.1.6だと、ob_get_clean()呼び出し時に勝手にContent-Type: text/html;がセットされ、 + 以降の行にheader関数でContent-Typeを指定する記述をしても上書きできていなかった為 + DoCoMoのxhtml指定ヘッダを送信する行をビルドファイル冒頭に移動するよう修正 + 【変更ファイル】 + lib/spider/Builder.class.php + lib/spider/tags/Charset.class.php +-- 2009-06-29 +1) util_Mailクラスの添付ファイル名のエンコーディングが正しく行われていなかった問題の修正 + +-- 2009-06-25 +1) suPHPなどの特殊環境に対応する為、spiderが動的に作成する一時ファイルや一時フォルダのパーミッションを + define.inc.phpで定義できるようにしました。 +2) DATAフォルダをspiderに名称変更しました。これまで通りDATAでも動作します + +-- 2009-04-22 +1) spiderのDATAフォルダをspider.inc.php配置フォルダからさかのぼって自動認識するようにしました。 +2) HttpRequestのセッションの適正化メソッドで、セッションスコープの判断をREQUEST_URIで行っており + ディレクトリインデックスにファイル名なしでアクセスした場合のセッション挙動が同フォルダ内にも関わらずひとつ + 上の階層と判断されてしまい問題が発生する為PHP_SELFで判断するよう修正しました。 + +-- 2009-04-21 +1) HttpRequestにてセッション取得メソッドで無限ループが発生する不具合を修正しました。 + 併せてセッション変数を削除するメソッドを追加しました。 + +-- 2009-04-17 +バージョン番号を1.0.00とし正式リリースとします。 +以降の機能追加・変更はマイナーバージョンアップとしバグフィックス対応をメジャー・マイナーバージョンをあげない +メンテナンスフェーズに入ります。 + +-- 2009-04-17 +1) ログ出力周りの整理を行いました。ModuleBaseにあったログ出力機能をHttpRequestに移しました。 +2) ログ出力レベルの定義を追加・変更しました。 + 併せてsyslogdへのログ出力にも対応しました。定数SYSTEM_LOG_TYPEを定義してSPIDER_LOG_TYPE_SYSLOGを設定すれば + システムログへのログ送出へ切り替わります。unique_setting.inc.php内もしくは他ファイルを読み込ませて定義してください。 + 本バージョンではsyslogdへのident文字列はspiderで固定です。 + +-- 2009-04-16 +1) 公開フォルダ直下に配置した.defaultファイルが有効にならない問題の修正 + lib/spider/Builder.class.phpを修正しました。 + +-- 2009-04-15 +1) コアのエラーメッセージをDATA/messages.inc.phpにハッシュで定義しました。 + +-- 2009-04-14 +1) spider_HttpRequestクラスにセッション制御メソッドを追加しました + リクエストURIの階層ごとにセッションの有効無効を自動で制御できます。 + フォルダ階層を抜けた場合はセッションを無効化します。 + これによりモジュールで利用するセッション記憶域の無制限な増大を避けることができます。 + +-- 2009-04-13 +1) setタグでハッシュ、メンバの値がクォートされていた場合に正しく判別できていなかった問題を修正しました。 + lib/spider/tags/SetAttribute.class.php + +-- 2009-04-10 +1) 本体とはあまり関係ありませんがphp5でフォーム名からハッシュを入力できていない問題があるため + lib/util/Mail.class.php + lib/util/mail/PHP.class.php + lib/util/mail/Sendmail.class.php + lib/util/mail/SMTP.class.php + を変更しました。 + +2) 本体とはあまり関係ありませんが + lib/spider/module/AutoEncode.class.phpで配列入力をエンコード出来ていなかった問題を修正しました。 + lib/spider/module/AutoFormat.class.phpを追加しました。 + +3) ModuleBase.class.phpのログ出力をdefineで定義して整えました。 + +-- 2009-04-07 +1) ModuleBaseクラスの名称をspider_ModuleBaseクラスに変更しました。 + +-- 2009-04-06 +1) spider.inc.phpでユーザー公開ディレクトリに設置した場合にドキュメントルートの判別を + ホストのドキュメントルートにしていた為設置URIを正しく認識できなかった問題の修正 + +-- 2009-03-31 +1) .defaultファイルのタイムスタンプ比較及び存在確認がホットビルドから漏れていたので追加 + DATA/lib/spider/Builder.class.php + +2) presetタグをSetAttribute.class.phpに追加 + モジュール実行前処理として、固定文字列、固定数値をrequest属性に設定してページを実行できます。 + 例) {preset:database.name 'framework spider !'} + 固定文字列はシングルクォーテーションで囲ってください。 + +3) TagBase.class.phpのsplitOptionBySpaceメソッドでクォート文字列内の文字列連結時にスペースを + 復元していなかった問題の修正 + +-- 2009-03-30 +1) ページ内で$request->setAttributeメソッドで値をセットした場合に$GLOBALSに設定しない為 + if/foreach/writeで問題が発生する不具合を修正 + +2) Noticeの修正 + PHP5のerror_reportingをE_ALLで実行した際にNoticeやWarningが出る箇所を修正 + +-- 2009-03-27 +1)この機会しかないと思ったのでクラス名の変更を行いました。 + ・ExecutableFileCreator.class.php -> Builder.class.php + ・Conttoller -> spider_Controller + ・HttpOutput -> spider_HttpOutput + ・HttpRequest -> spider_HttpRequest + + 内部的な変更なのでコアなプログラム変更を行っているユーザ以外には影響ありません。 + +2) TagBaseクラスでタグコードをネイティブコードに変更するメソッドを修正しました。 + +3) writeタグの修正をおこないました。::で配列要素やオブジェクトメンバを指定する場合をは旧ロジックで + 呼び出しを->メンバ名、['添え字']で指定する場合は、階層に関係なくPHPネイティブコードの許す限り記述できる + ように機能を変更しました。 + +-- 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']を定義し、 + スクリプトファイルの絶対パスを記述すれば、常にスクリプトを実行します。 + + この配列宣言はアプリケーションごとの指定の為、define.inc.phpではなく、unique_setting.inc.php内で記述してください。 + + スクリプトファイルの中で標準出力を行ってはいけません。 + ページ表示イベントに対するフックスクリプトのようなイメージで利用してください。 + +2)1)に伴い、Controller.class.phpのコンストラクタに引数を追加し、リクエストとアウトプットオブジェクトを渡せるようにしました。 + フックスクリプトでControllerクラスのloadModuleメソッドを呼ぶことができます。 + コントローラオブジェクトは$GLOBALS['controller']で宣言されています。 + +3)utilライブラリにファイルシステム用ユーティリティメソッドクラスであるutil_Fileクラスを追加しました。 + クラスコードはDATA/util/File.class.phpに記述しています。 + +4)新しいforeachタグの作成する実行ファイルがPHP5.1.6にて動作不具合を起こす問題を修正 + +-- 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 + +7) setタグにて属性だけでなく$GLOBALSにも同じ名前で登録するよう追加 + 【修正ファイル】 + DATA/lib/spider/tags/SetAttribute.class.php + +8) ウィジェットタグにリンク機能を追加しました。 + ウィジェットファイル内に{widget-link:参照したいウィジェットファイル名}のみ記述することで + ウィジェットファイル名のファイルを参照します。 + これにより、複数同じウィジェットを階層ごとに作成するようなケースを避けることができます。 + Added: db/current/htdocs/index.php =================================================================== --- db/current/htdocs/index.php (rev 0) +++ db/current/htdocs/index.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,8 @@ +<?php include_once( "./spider.inc.php" ); ?> +{charset:UTF-8} +{template:public_default.tpl} +{page-title:framework-sipder example page!} +{module:example.Hello force post(a="afds) get() attribute_prefix(media)} +{module:example.Hello force} +{dynamic-page} +{output-html} \ No newline at end of file Added: db/current/htdocs/spider.inc.php =================================================================== --- db/current/htdocs/spider.inc.php (rev 0) +++ db/current/htdocs/spider.inc.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,162 @@ +<?php +/* + * spider.inc.php + * @version 1.0.01 + * + * if you need, change $DIR_PATH_SPIDER_DATA for your Env. + */ +/* Data Directory Absolute Path force */ +//$DIR_PATH_SPIDER_DATA = ''; +/* Base URI force definition */ +//$SPIDER_DEFINE_BASE_URI = ''; +/* active page file folder */ +define('DIR_NAME_PAGES', 'pages'); + +/* + * Common Process. you need not to edit. + */ +$script_filename = str_replace( '/', DIRECTORY_SEPARATOR, $_SERVER['SCRIPT_FILENAME'] ); +if ( $script_filename == __FILE__ ) { + header( 'Content-type: text/plain;charset=UTF-8' ); + die( 'You can\'t access this file direct!' ); +} +/* + * application base path + */ +define( 'APPLICATION_BASE_PATH', dirname(__FILE__ ) ); +/* + * If spider folder is not defined, search spider folder. + */ +if( !isset( $DIR_PATH_SPIDER_DATA ) || strlen( trim( $DIR_PATH_SPIDER_DATA ) ) == 0 ) { + $DIR_PATH_SPIDER_DATA = null; + $targetDir = dirname(__FILE__); + $rootPathLength = 1; + if(isset($_ENV) && isset($_ENV['OS']) && preg_match('/[wW][iI][nN]/',$_ENV['OS'] ) > 0 ) { + $rootPathLength = 3; + } + while( strlen($targetDir) > $rootPathLength ) { + $DIR_PATH_SPIDER_DATA = $targetDir.DIRECTORY_SEPARATOR.'spider'; + if( is_dir( $DIR_PATH_SPIDER_DATA ) ) { + break; + } else { + $DIR_PATH_SPIDER_DATA = null; + } + $targetDir = dirname($targetDir); + } + if( is_null($DIR_PATH_SPIDER_DATA) ) { + $targetDir = dirname(__FILE__); + while( strlen($targetDir) > $rootPathLength ) { + $DIR_PATH_SPIDER_DATA = $targetDir.DIRECTORY_SEPARATOR.'DATA'; + if( is_dir( $DIR_PATH_SPIDER_DATA ) ) { + break; + } else { + $DIR_PATH_SPIDER_DATA = null; + } + $targetDir = dirname($targetDir); + } + } + unset($targetDir); + unset($rootPathLength); + if( is_null( $DIR_PATH_SPIDER_DATA ) ) { + header( 'Content-type: text/plain;charset=UTF-8' ); + die( 'Spider DATA Folder is not found!' ); + } else { + define ( 'DIR_PATH_SPIDER_DATA', $DIR_PATH_SPIDER_DATA ); + } +} else { + define ( 'DIR_PATH_SPIDER_DATA', $DIR_PATH_SPIDER_DATA ); +} +/* + * If spider folder is found, require define.inc.php + */ +$spiderDefinePath = DIR_PATH_SPIDER_DATA.DIRECTORY_SEPARATOR.'define.inc.php'; +if( defined('DIR_PATH_SPIDER_DATA') && is_dir(DIR_PATH_SPIDER_DATA) && file_exists($spiderDefinePath) ) { + require_once( $spiderDefinePath ); +} else { + header( 'Content-type: text/plain;charset=UTF-8' ); + die( 'Spider DATA Folder is invalid!' ); +} +/* + * folder & uri + */ +$request_uri = $_SERVER['REQUEST_URI']; +$document_root = $_SERVER['DOCUMENT_ROOT']; + +/* formart user document root */ +if( preg_match('/^\\/\\~[0-9a-zA-Z\\_]+\\//',$request_uri) > 0 ) { + $user_request_uri = preg_replace('/^\\/\\~[^\\/]+\\//','/',$_SERVER['PHP_SELF'] ); + $document_root = str_replace( '/',DIRECTORY_SEPARATOR, dirname($script_filename) ); + $document_root = str_replace( str_replace( '/',DIRECTORY_SEPARATOR, dirname($user_request_uri) ), '', $document_root ); +} +/* + * if not defined, create application base uri. + */ +if( defined('APPLICATION_PROXY_REV_HOST') && strlen(APPLICATION_PROXY_REV_HOST) > 0 + && ( APPLICATION_PROXY_REV_HOST == $_SERVER['HTTP_X_FORWARDED_HOST'] + || APPLICATION_PROXY_REV_HOST == $_SERVER['HTTP_X_FORWARDED_SERVER'] ) ) { + // リバースプロキシホスト名が設置されていてそこからのアクセスの場合 + define( 'APPLICATION_BASE_URL', APPLICATION_PROXY_REV_BASE_URL ); + define( 'APPLICATION_NML_URL', APPLICATION_PROXY_REV_NML_URL ); + define( 'APPLICATION_SSL_URL', APPLICATION_PROXY_REV_SSL_URL ); + define( 'APPLICATION_BASE_URI', APPLICATION_PROXY_REV_BASE_URI ); +} else if( !defined('APPLICATION_BASE_URI') ) { + $app_base_uri = null; + if( isset($SPIDER_DEFINE_BASE_URI) && strlen($SPIDER_DEFINE_BASE_URI) > 0 ) { + $app_base_uri = $SPIDER_DEFINE_BASE_URI; + } else { + $spider_inc_path = str_replace( DIRECTORY_SEPARATOR, '/', __FILE__ ); + $app_base_uri = dirname(str_replace( $document_root, '', $spider_inc_path )); + if( preg_match('/^\\/\\~[0-9a-zA-Z\\_]+\\//',$request_uri) > 0 ) { + // if user dir, unshift first folder + $dirname_array = explode('/',$request_uri); + $app_base_uri = '/'.$dirname_array[1].$app_base_uri; + } + if( preg_match('/^\\./',$app_base_uri) > 0 ) { + // if first char is '.', remove. + $app_base_uri = preg_replace('/^\\./','',$app_base_uri); + } + } + if( !preg_match('/\\/$/', $app_base_uri ) ) { + $app_base_uri .= '/'; + } + if ( !preg_match( '/\\/$/', $app_base_uri ) ) { + $app_base_uri .= '/'; + } + define( 'APPLICATION_BASE_URI', $app_base_uri ); + unset($app_base_uri); +} + +$request_protocol = $_SERVER['SERVER_PROTOCOL']; +$request_port = $_SERVER['SERVER_PORT']; +$request_server_name = $_SERVER['SERVER_NAME']; +$is_ssl = false; +if( isset($_SERVER['HTTPS']) && preg_match('/[oO][fF][fF]/', $_SERVER['HTTPS'] ) == 0 ) { + $is_ssl = true; +} +$prtcl = 'http://'; +if( $is_ssl ) { + $prtcl = 'https://'; +} +$target_port = ''; +if ( $request_port != 80 && $request_port != 443 ) { + $target_port = ':' . $request_port; +} +if( !defined('APPLICATION_BASE_URL') ) { + $app_base_url = $prtcl . $request_server_name . $target_port . APPLICATION_BASE_URI; + define( 'APPLICATION_BASE_URL', $app_base_url ); +} +if( !defined('APPLICATION_NML_URL') ) { + $app_nomal_url = 'http://' . $request_server_name . $target_port . APPLICATION_BASE_URI; + define( 'APPLICATION_NML_URL', $app_nomal_url ); +} +if( !defined('APPLICATION_SSL_URL') ) { + $app_ssl_url = 'https://' . $request_server_name . $target_port . APPLICATION_BASE_URI; + define( 'APPLICATION_SSL_URL', $app_ssl_url ); +} + +unset($app_base_url); +unset($app_nomal_url); +unset($app_ssl_url); +require_once( DIR_PATH_SPIDER_DATA . DIRECTORY_SEPARATOR . 'spider_main.inc.php' ); + +?> \ No newline at end of file Added: db/current/spider/define.inc.php =================================================================== --- db/current/spider/define.inc.php (rev 0) +++ db/current/spider/define.inc.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,154 @@ +<?php +/* + * framework-spider: 基本設定記述ファイル + */ +// セッション機能 ( true=spiderのセッションID発行機能を使う / false=PHP標準を使う ) +// ※PHPのセッションID発行機能はIDが重複するバグがありますが、spiderの発行機能は環境によっては利用できません。 +define( 'SPIDER_USE_SPIDER_SESSION_ID', false ); +// 実行ファイル作成のURIを絶対パスから始める場合 +define( 'SPIDER_USE_ABSOLUTE_BIN_PATH', false ); + +/* + * アプリケーション設置位置設定 + * 自動判別で正しく動作しない場合や自動判別しない場合に設定 + */ +//define( 'APPLICATION_BASE_URL', '' ); +//define( 'APPLICATION_NML_URL', '' ); +//define( 'APPLICATION_SSL_URL', '' ); +//define( 'APPLICATION_BASE_URI', '' ); + +/* + * リバースプロキシサーバーなど経由してアクセスする場合の強制位置設定 + * ホスト名を設定した場合以下5項目は全て正しく記述する必要があります + */ +define( 'APPLICATION_PROXY_REV_HOST', '' ); +define( 'APPLICATION_PROXY_REV_BASE_URL', '' ); +define( 'APPLICATION_PROXY_REV_NML_URL', '' ); +define( 'APPLICATION_PROXY_REV_SSL_URL', '' ); +define( 'APPLICATION_PROXY_REV_BASE_URI', '' ); + +/* + * ユーザーエージェント分岐定義 + */ +// 分岐タイプ定義 分類ID=>分類名称 +$GLOBALS['SPIDER_USER_AGENT_CLASS_HASH'] = array( + 'au' => 'au', + 'softbank' => 'SoftBank', + 'docomo2' => 'DoCoMo', + 'default' => 'PC', +); +// 分岐タイプにファイルが存在しなかった場合の代替タイプ定義 +$GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'] = array( + 'au' => 'docomo2', + 'softbank' => 'docomo2', +); +// ユーザーエージェント正規表現による分岐タイプ 正規表現=>分類ID +$GLOBALS['SPIDER_USER_AGENT_CLASS_REGX_HASH'] = array( + '/^KDDI\\-/' => 'au', + '/^UP\\.Browser\\/[0-9\\.]+\\-/' => 'au', + '/^J\\-PHONE/' => 'softbank', + '/^Vodafone/' => 'softbank', + '/^SoftBank/' => 'softbank', + '/^DoCoMo\\/2/' => 'docomo2', +); +// 携帯メールアドレスドメイン名の正規表現による分岐タイプ 正規表現=>分類ID +$GLOBALS['MOBILE_MAIL_DOMAIN_CLASS_REGX_HASH'] = array( + '/\\@docomo\\.ne\\.jp$/' => 'docomo2' + ,'/\\@ezweb\\.ne\\.jp$/' => 'au' + ,'/\\@yy.ezweb\\.ne\\.jp$/' => 'au' + ,'/\\@[a-z].vodafone\\.ne\\.jp$/' => 'softbank' + ,'/\\@softbank\\.ne\\.jp$/' => 'softbank' + ,'/\\@disney\\.ne\\.jp$/' => 'softbank' + ,'/\\@i\\.softbank\\.jp$/' => 'softbank' +); +// ユーザーエージェントごとに出力文字セットを指定する場合 +$GLOBALS['SPIDER_USER_AGENT_CLASS_OUTPUT_CHARSET'] = array( + 'docomo2' => 'SJIS-win', + 'au' => 'SJIS-win', + 'softbank' => 'SJIS-win', + 'default' => 'UTF-8', +); +/* + * 拡張設定 + */ +// spiderコアが自動生成するファイルの標準パーミッション +define ( 'SPIDER_FILE_CREATE_PERMITTION', 0666 ); +// spiderコアが自動生成するフォルダの標準パーミッション +define ( 'SPIDER_FOLDER_CREATE_PERMITTION', 0777 ); + +// ライブラリディレクトリ名 +define ( 'DIR_NAME_LIB', 'lib' ); +// テンプレート配置ディレクトリ名 +define ( 'DIR_NAME_TEMPLATES', 'templates' ); +// Pウィジェットディレクトリ名 +define ( 'DIR_NAME_PWIDGETS', 'pwidgets' ); +// ウィジェットディレクトリ名 +define ( 'DIR_NAME_WIDGETS', 'widgets' ); +// データ保存ディレクトリ名 +define ( 'DIR_NAME_DATA', 'data' ); +// ワークディレクトリ名 +define ( 'DIR_NAME_WORK', 'work' ); +// アプリケーションログ保存ディレクトリ +define ( 'DIR_NAME_LOG', 'logs' ); + +// ビルドファイル配置ディレクトリ名 +define ( 'DIR_NAME_BIN', 'bin' ); +// ロックディレクトリ名 +define ( 'DIR_NAME_LOCK', 'lock' ); +// キャッシュディレクトリ名 +define ( 'DIR_NAME_CACHE', 'cache' ); +// テンポラリディレクトリ名 +define ( 'DIR_NAME_TMP', 'tmp' ); + +/* + * 基本定義 + */ +// ライブラリフォルダの絶対パス +define( 'DIR_PATH_LIB', DIR_PATH_SPIDER_DATA.DIRECTORY_SEPARATOR.DIR_NAME_LIB ); +// テンプレートディレクトリパス +define( 'DIR_PATH_TEMPLATES', DIR_PATH_SPIDER_DATA.DIRECTORY_SEPARATOR.DIR_NAME_TEMPLATES ); +// Pウィジェットディレクトリパス +define( 'DIR_PATH_PWIDGETS',DIR_PATH_SPIDER_DATA.DIRECTORY_SEPARATOR.DIR_NAME_PWIDGETS); +// ウィジェットディレクトリパス +define( 'DIR_PATH_WIDGETS',DIR_PATH_SPIDER_DATA.DIRECTORY_SEPARATOR.DIR_NAME_WIDGETS); +// データ保存ディレクトリ +define( 'DIR_PATH_DATA', DIR_PATH_SPIDER_DATA . DIRECTORY_SEPARATOR . DIR_NAME_DATA ); +// ワークディレクトリパス +define( 'DIR_PATH_WORK', DIR_PATH_SPIDER_DATA . DIRECTORY_SEPARATOR . DIR_NAME_WORK ); + +// アプリケーションログ保存ディレクトリパス +define( 'DIR_PATH_LOG', DIR_PATH_DATA . DIRECTORY_SEPARATOR . DIR_NAME_LOG ); +// バイナリディレクトリパス +define( 'DIR_PATH_BIN', DIR_PATH_WORK . DIRECTORY_SEPARATOR . DIR_NAME_BIN ); +// プロセスロックの一時フォルダ +define ( 'DIR_PATH_LOCK', DIR_PATH_WORK . DIRECTORY_SEPARATOR . DIR_NAME_LOCK ); +// キャッシュディレクトリパス +define( 'DIR_PATH_CACHE', DIR_PATH_WORK . DIRECTORY_SEPARATOR . DIR_NAME_CACHE ); +// 全体で利用する一時フォルダ +define ( 'DIR_PATH_TMP', DIR_PATH_WORK . DIRECTORY_SEPARATOR . DIR_NAME_TMP ); + +// ページ振り分けファイル配置ディレクトリ +if( defined('DIR_NAME_PAGES') && strlen(DIR_NAME_PAGES) > 0 ) { + define( 'DIR_PATH_PAGES', DIR_PATH_SPIDER_DATA.DIRECTORY_SEPARATOR.DIR_NAME_PAGES ); +} + +/* + * システムレポートとメール通知設定 + */ +// ログ出力レベルの定義 +define('SPIDER_LOG_LEVEL_FATAL', 0); +define('SPIDER_LOG_LEVEL_ERROR', 10); +define('SPIDER_LOG_LEVEL_WARNING', 20); +define('SPIDER_LOG_LEVEL_NOTICE', 30); +define('SPIDER_LOG_LEVEL_INFO', 40); +define('SPIDER_LOG_LEVEL_DEBUG', 50); +// ログ出力先の定義 +define('SPIDER_LOG_TYPE_FILE', 0); +define('SPIDER_LOG_TYPE_SYSLOG', 10); + +// システムメール定義ファイル名 +define ( 'FILE_NAME_SYSTEM_DEFINITION', 'system.inc.php' ); +// システムメール定義ファイルパス +define ( 'FILE_PATH_SYSTEM_DEFINITION', DIR_PATH_DATA.DIRECTORY_SEPARATOR.FILE_NAME_SYSTEM_DEFINITION ); + +?> \ No newline at end of file Added: db/current/spider/lib/db/AbstractConnection.class.php =================================================================== --- db/current/spider/lib/db/AbstractConnection.class.php (rev 0) +++ db/current/spider/lib/db/AbstractConnection.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,462 @@ +<?php +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'AbstractData.class.php'); +/** + * 単一のデータベースコネクションを保持するデータベース接続の抽象クラスです。 + */ +class db_AbstractConnection { + + /** spider_HttpRequestオブジェクトへの参照 */ + var $request = null; + /** DBリソース */ + var $resource_id = null; + /** データベース文字コード */ + var $db_encoding = null; + /** 取り出し文字コード */ + var $encoding = 'UTF-8'; + /** queryAllのlimit */ + var $limit = null; + /** queryAllのoffset */ + var $offset = null; + + /** + * setRequest + */ + function _setHttpRequest( & $request ) { + $this->request = $request; + } + /** + * データベースに接続します + * @return boolean + * @access public + */ + function _connect( $databaseName, $databaseUser, $databasePass, $host=null, $port=null, $dbencoding='auto' ) { + return false; + } + /** + * データベース切断します + * @param boolean $force + * @return + * @access public + */ + function _disconnect( $force = true ) { + return false; + } + /** + * 文字列をquoteします + * @param string $value 文字列 + * @param string $type カラム型 + * @param boolean $quote quoteする場合はtrue、しない場合はfalse + * @param boolean $escape_wildcards ワイルドカードをquoteする場合はtrue、しない場合はfalse + * @return string quoteした文字列 + * @access public + */ + function _quote( $value, $type = null, $quote = true, $escape_wildcards = false ) { + return false; + } + /** + * 文字列をエスケープします + * @param string $text + * @param boolean $escape_wildcards + * @return + * @access public + */ + function _escape($text, $escape_wildcards = false){ + return false; + } + /** + * Transactionを開始します + * @param string $savepoint savepoint名 + * @return + * @access public + */ + function _beginTransaction( $savepoint = null ) { + return false; + } + /** + * トランザクションをコミットします + * @param string $savepoint savepoint名 + * @return + * @access public + */ + function _commit( $savepoint = null ) { + return false; + } + /** + * トランザクションをロールバックします + * @param string $savepoint savepoint名 + * @return + * @access public + */ + function _rollback( $savepoint = null ) { + return false; + } + /** + * 問い合わせ結果レコードの行数とオフセットを設定します + * @param string $limit + * @param string $offset + * @return + * @access public + */ + function _setLimit( $limit, $offset = null ) { + $this->limit = $limit; + $this->offset = $offset; + } + /** + * 渡されたSQLクエリ文を実行します + * @param string $query SQLクエリ + * @return + * @access public + */ + function _query( $query ) { + return false; + } + /** + * 渡されたSQLクエリ文を実行して全ての結果を取得します + * @param string $query SQLクエリ + * @param mixed $fetchtype 使用する取得モード。0=ハッシュ, 1=配列, AbstractDataの拡張クラス=オブジェクト配列 + * @return mixed 入れ子状の配列、あるいは失敗した場合にMDB_Errorを返します。 + * @access public + */ + function _queryAll( $query, $fetchtype=null, $setOrg=true ) { + return false; + } + /** + * 渡されたSQLクエリ文を実行して1レコードのみ結果を取得します + * レコードがなかった場合または、1レコードに絞り込めなかった場合はfalseを返します + * @param string $query SQLクエリ + * @param mixed $fetchtype 使用する取得モード。0=ハッシュ, 1=配列, AbstractDataの拡張クラス=オブジェクト + * @return + * @access public + */ + function _queryRow( $query, $fetchtype=null, $setOrg=true ) { + return false; + } + /** + * 渡されたSQLクエリ文を実行して1カラム分のみ結果を取得します + * @param string $query SQLクエリ + * @return + * @access public + */ + function _queryOne( $query ) { + return false; + } + /** + * ハッシュに格納された一行のデータをオブジェクトメンバ値に格納します。 + */ + function _setRowToFields( $row, & $daoBase, $setOrg=true ) { + if( is_array($row) ) { + if( !is_array($daoBase->baseUniqueKeyFiledNames) ) { + $this->_setUniqueFieldInfo( $daoBase ); + } + foreach( $row as $key=>$val ) { + if( is_array($daoBase->baseUniqueKeyFiledNames) && in_array( $key, $daoBase->baseUniqueKeyFiledNames ) ) { + $val = trim($val); + } + $daoBase->$key = $val; + if( $setOrg ) { + $fname = $key . '_org'; + $daoBase->$fname = $val; + } + // 日付フィールド・時間フィールド・日時フィールドの処理 + if ( preg_match( '/^[0-9]{4}\\-[0-9]{2}\\-[0-9]{2}$/', $val ) ) { + // DATE型 + $name_year = $key.'_year'; + $name_month = $key.'_month'; + $name_day = $key.'_day'; + list( $daoBase->$name_year, $daoBase->$name_month, $daoBase->$name_day ) + = explode( '-', $val ); + } else if ( preg_match( '/^[0-9]{2}:[0-9]{2}:[0-9]{2}$/', $val ) + || preg_match( '/^[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]+$/', $val ) ) { + // TIME型 + $name_hour = $key.'_hour'; + $name_min = $key.'_min'; + $name_sec = $key.'_sec'; + list( $daoBase->$name_hour, $daoBase->$name_min, $daoBase->$name_sec ) + = explode( ':', $val ); + } else if ( preg_match( '/^[0-9]{4}\\-[0-9]{2}\\-[0-9]{2}\\s[0-9]{2}:[0-9]{2}:[0-9]{2}$/', $val ) + || preg_match( '/^[0-9]{4}\\-[0-9]{2}\\-[0-9]{2}\\s[0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]+$/', $val ) ) { + list( $date_str, $time_str ) = explode(' ', $val ); + $name_year = $key.'_year'; + $name_month = $key.'_month'; + $name_day = $key.'_day'; + list( $daoBase->$name_year, $daoBase->$name_month, $daoBase->$name_day ) + = explode( '-', $date_str ); + $name_hour = $key.'_hour'; + $name_min = $key.'_min'; + $name_sec = $key.'_sec'; + list( $daoBase->$name_hour, $daoBase->$name_min, $daoBase->$name_sec ) + = explode( ':', $time_str ); + } + } + return true; + } else { + return false; + } + } + /** + * データアクセスオブジェクトにフィールドキー情報のリファレンスを設定します + */ + function _setUniqueFieldInfo( & $daoBase ) { + $baseSerialFieldName = $this->_getInformationPool( 'tableCache', 'serial', $daoBase->getTableName() ); + $baseUniqueKeyFiledNames = $this->_getInformationPool( 'tableCache', 'unique', $daoBase->getTableName() ); + if( is_null($baseSerialFieldName) || is_null($baseSerialFieldName) ) { + $baseSerialFieldName = null; + $baseUniqueKeyFiledNames = array(); + $tableInformationHash = $this->getTableInformationHash( $daoBase ); + if( false !== $tableInformationHash ) { + foreach ( $tableInformationHash as $fieldName => $fieldInformation ) { + if( isset($fieldInformation['key']) && preg_match('/[uU][nN][iI][qQ][uU][eE]/',$fieldInformation['key']) > 0 ) { + // ユニークキーなら + array_push( $baseUniqueKeyFiledNames, $fieldName ); + } else if( isset($fieldInformation['is_serial']) && $fieldInformation['is_serial'] ) { + // シリアル番号なら + $baseSerialFieldName = $fieldName; + } + } + $this->_setInformationPool( 'tableCache', 'serial', $daoBase->getTableName(), $baseSerialFieldName ); + $this->_setInformationPool( 'tableCache', 'unique', $daoBase->getTableName(), $baseUniqueKeyFiledNames ); + $baseSerialFieldName = $this->_getInformationPool( 'tableCache', 'serial', $daoBase->getTableName() ); + $baseUniqueKeyFiledNames = $this->_getInformationPool( 'tableCache', 'unique', $daoBase->getTableName() ); + } else { + return false; + } + } + $daoBase->baseSerialFieldName = $baseSerialFieldName; + $daoBase->baseUniqueKeyFiledNames = $baseUniqueKeyFiledNames; + return true; + } + /** + * 渡されたデータ抽象オブジェクトに該当するテーブル情報ハッシュを取得します。 + * 【テーブル情報ハッシュの構造】 + * array( [フィールド名] => [フィールド詳細情報ハッシュ] ) + * + * 【フィールド詳細情報ハッシュの構造】 + * array( + * 'type' => 'int/char/varchar/text...', + * 'size' => 数値 + * 'not_null' => true/false + * 'key' => 'primary/unique' + * 'is_serial' => true/false + * 'has_default' => true/false + * ) + */ + function getTableInformationHash( $daoBase ) { + return $this->getTableInformationHashByName( $daoBase->getTableName() ); + } + /** + * テーブル名称を指定して該当するテーブル情報ハッシュを取得します。 + * 【テーブル情報ハッシュの構造】 + * array( [フィールド名] => [フィールド詳細情報ハッシュ] ) + * + * 【フィールド詳細情報ハッシュの構造】 + * array( + * 'type' => 'int/char/varchar/text...', + * 'size' => 数値 + * 'not_null' => true/false + * 'key' => 'primary/unique' + * 'is_serial' => true/false + * 'has_default' => true/false + * ) + */ + function getTableInformationHashByName( $tableName ) { + $infoHash = false; + if( !is_null($infoHash = $this->_getInformationPool( 'tableCache', 'tableInformation', $tableName ) ) ) { + $ref = & $infoHash; + return $ref; + } + $cachePath = $this->_getTableInformationCachePath( $tableName ); + if( file_exists($cachePath) && filemtime($cachePath) > time() - (60*60*24) ) { + // 一日以内のキャッシュがあるならキャッシュを利用 + $str = file_get_contents($cachePath); + $infoHash = unserialize($str); + } else { + // キャッシュがないなら問い合わせ + $infoHash = $this->_getTableInformationHashByName( $tableName ); + // キャッシュを作成 + $fp = @fopen($cachePath,'w'); + if( $fp ) { + if (@flock($fp, LOCK_EX)) { + @fwrite( $fp, serialize($infoHash) ); + @flock($fp, LOCK_UN); + } + @fclose( $fp ); + @chmod( $cachePath, SPIDER_FILE_CREATE_PERMITTION ); + } + } + // グローバル変数にプール + $this->_setInformationPool( 'tableCache', 'tableInformation', $tableName, $infoHash ); + $ref = & $infoHash; + return $ref; + } + /** + * 渡されたデータ抽象オブジェクトに該当するテーブル情報ハッシュを取得します。 + * 【テーブル情報ハッシュの構造】 + * array( [フィールド名] => [フィールド詳細情報ハッシュ] ) + * + * 【フィールド詳細情報ハッシュの構造】 + * array( + * 'type' => 'int/char/varchar/text...', + * 'size' => 数値 + * 'not_null' => true/false + * 'key' => 'primary/unique' + * 'is_serial' => true/false + * 'has_default' => true/false + * ) + */ + function _getTableInformationHash( $daoBase ) { + $tableName = $daoBase->getTableName(); + return $this->_getTableInformationHashByName( $tableName ); + } + /** + * テーブル名称を指定して該当するテーブル情報ハッシュを取得します。 + * 各DBへの接続実装クラスでオーバーライドする必要があります。 + * 【テーブル情報ハッシュの構造】 + * array( [フィールド名] => [フィールド詳細情報ハッシュ] ) + * + * 【フィールド詳細情報ハッシュの構造】 + * array( + * 'type' => 'int/char/varchar/text...', + * 'size' => 数値 + * 'not_null' => true/false + * 'key' => 'primary/unique' + * 'is_serial' => true/false + * 'has_default' => true/false + * ) + */ + function _getTableInformationHashByName( $tableName ) { + return false; + } + /** + * 指定名称のデータベーステーブルが存在するか確認します + */ + function _existsTable( $tableName ) { + return false; + } + /** + * 指定名称のデータベースが存在するか確認します + */ + function _existsDatabase( $databaseName ) { + return false; + } + /** + * 指定データベースのエンコード設定を取得します。 + */ + function _selectDatabaseEncoding($databaseName) { + return false; + } + /** + * データベースに問い合わせた情報プールからデータを取得します。 + */ + function _getInformationPool( $class, $name, $key, $reference=true ) { + $poolKey = 'db_connection_data_pool'; + if( !isset($GLOBALS[$poolKey]) || !is_array($GLOBALS[$poolKey]) ) { + return null; + } + if( !isset($GLOBALS[$poolKey][$class]) || !is_array($GLOBALS[$poolKey][$class]) ) { + return null; + } + if( !isset($GLOBALS[$poolKey][$class][$name]) || !is_array($GLOBALS[$poolKey][$class][$name]) ) { + return null; + } + if( !isset($GLOBALS[$poolKey][$class][$name][$key]) ) { + return null; + } else { + if( $reference ) { + $ref = & $GLOBALS[$poolKey][$class][$name][$key]; + return $ref; + } else { + return $GLOBALS[$poolKey][$class][$name][$key]; + } + } + } + /** + * データベースに問い合わせた情報を一つの接続で何度も問い合わせない為にグローバル変数にプールします。 + */ + function _setInformationPool( $class, $name, $key, $values ) { + $poolKey = 'db_connection_data_pool'; + if( !isset($GLOBALS[$poolKey]) || !is_array($GLOBALS[$poolKey]) ) { + $GLOBALS[$poolKey] = array(); + } + if( !isset($GLOBALS[$poolKey][$class]) || !is_array($GLOBALS[$poolKey][$class]) ) { + $GLOBALS[$poolKey][$class] = array(); + } + if( !isset($GLOBALS[$poolKey][$class][$name]) || !is_array($GLOBALS[$poolKey][$class][$name]) ) { + $GLOBALS[$poolKey][$class][$name] = array(); + } + $GLOBALS[$poolKey][$class][$name][$key] = $values; + } + /** + * テーブル情報キャッシュファイルパスを取得します + */ + function _getTableInformationCachePath( $tableName ) { + $path = DIR_PATH_CACHE.DIRECTORY_SEPARATOR.get_class($this); + if( !file_exists($path) ) { + if( @mkdir($path,SPIDER_FOLDER_CREATE_PERMITTION) ) { + @chmod($path,SPIDER_FOLDER_CREATE_PERMITTION); + } + } + $path .= DIRECTORY_SEPARATOR.'tables'; + if( !file_exists($path) ) { + if( @mkdir($path,SPIDER_FOLDER_CREATE_PERMITTION) ) { + @chmod($path,SPIDER_FOLDER_CREATE_PERMITTION); + } + } + $path .= DIRECTORY_SEPARATOR.$tableName; + return $path; + } + /** + * Fatalレベルのログを出力します。 + * @param $message ログメッセージ + */ + function fatal($message){ + if( !is_null($this->request) ) { + $this->request->fatal($message); + } + } + /** + * Errorレベルのログを出力します。 + * @param $message ログメッセージ + */ + function error($message){ + if( !is_null($this->request) ) { + $this->request->error($message); + } + } + /** + * Warningレベルのログを出力します。 + * @param $message ログメッセージ + */ + function warn($message){ + if( !is_null($this->request) ) { + $this->request->warn($message); + } + } + /** + * Noticeレベルのログを出力します。 + * @param $message ログメッセージ + */ + function notice($message){ + if( !is_null($this->request) ) { + $this->request->notice($message); + } + } + /** + * Infoレベルのログを出力します。 + * @param $message ログメッセージ + */ + function info($message){ + if( !is_null($this->request) ) { + $this->request->info($message); + } + } + /** + * Debugレベルのログを出力します。 + * @param $message ログメッセージ + */ + function debug($message){ + if( !is_null($this->request) ) { + $this->request->debug($message); + } + } +} +?> \ No newline at end of file Added: db/current/spider/lib/db/AbstractData.class.php =================================================================== --- db/current/spider/lib/db/AbstractData.class.php (rev 0) +++ db/current/spider/lib/db/AbstractData.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,160 @@ +<?php +require_once(dirname(dirname(__FILE__)) + .DIRECTORY_SEPARATOR.'system' + .DIRECTORY_SEPARATOR.'AbstractData.class.php'); +/** + * データアクセスオブジェクトの基底抽象クラス + * + * テーブルレコードに対応したデータアクセスオブジェクトクラスの基底クラスです。 + * 本クラスの拡張クラスとしてデータアクセスオブジェクトクラスを実装することで + * 様々な機能を提供します。 + * 本オブジェクトの実装で扱うクラスは必ずひとつの自動番号フィールドと + * ひとつ以上のユニークフィールドを保持する必要があります。 + * + * @package database2 データベースパッケージ + * @version 2.0.0 + * @author Multimedia Digital Contents Systems.Co.,Ltd. <info****@md-sy*****> + * @since PHP 4.0 + */ +class db_AbstractData extends system_AbstractData { + /** シリアル番号フィールド名 */ + var $baseSerialFieldName = null; + /** ユニークキーフィールド名 */ + var $baseUniqueKeyFiledNames = null; + /** + * 本オブジェクトが保持するデータのデータベーステーブル名を取得します。 + * テーブル名は実装クラス名を_で区切った末尾文字列に対して大文字部分を_[小文字]に置き換えた文字列です。 + * 例えばDaoAdminMemberならadmin_memberとなります。 + */ + function getTableName() { + if( preg_match('/^4/',phpversion()) > 0 || preg_match('/^3/',phpversion()) > 0 ) { + // phpのバージョンが3か4の場合 + list( $packageName, $baseName ) = explode('_',get_class($this)); + $baseDir = DIR_PATH_LIB.DIRECTORY_SEPARATOR.$packageName; + // パッケージライブラリ直下のDaoファイルを検索 + if (is_dir($baseDir)) { + if ($dh = opendir($baseDir)) { + while (($fileName = readdir($dh)) !== false) { + if( preg_match('/^Dao/',$fileName) > 0 ) { + $fileClass = str_replace('.class.php','',$fileName); + if( strtolower($fileClass) == $baseName ) { + // クラス名部分と一致したら該当ファイル + $tableName = preg_replace('/([A-Z])/','_${0}',$fileClass); + $tableName = preg_replace('/^(.)*Dao\\_/','',$tableName); + break; + } + } + } + closedir($dh); + } + } + } else { + // phpが5以上の場合 + $elements = explode('_',get_class($this)); + $baseName = array_pop($elements); + $tableName = preg_replace('/([A-Z])/','_${0}',$baseName); + $tableName = preg_replace('/^(.)*Dao\\_/','',$tableName); + } + return strtolower($tableName); + } + /** + * インサート前に行いたい処理を記述する抽象メソッドです。 + * @param MDBObject $dbo オブジェクト互換オブジェクト + * @return boolean 成功したらtrue + */ + function pre_insert( $dbo ) { + return true; + } + /** + * インサート後に行いたい処理を記述する抽象メソッドです。 + * @param MDBObject $dbo オブジェクト互換オブジェクト + * @return boolean 成功したらtrue + */ + function post_insert( $dbo, $result ) { + return true; + } + /** + * アップデート前に行いたい処理を記述する抽象メソッドです。 + * @param MDBObject $dbo オブジェクト互換オブジェクト + * @return boolean 成功したらtrue + */ + function pre_update( $dbo ) { + return true; + } + /** + * アップデート後に行いたい処理を記述する抽象メソッドです。 + * @param MDBObject $dbo オブジェクト互換オブジェクト + * @return boolean 成功したらtrue + */ + function post_update( $dbo, $result ) { + return true; + } + /** + * デリート前に行いたい処理を記述する抽象メソッドです。 + * @param MDBObject $dbo オブジェクト互換オブジェクト + * @return boolean 成功したらtrue + */ + function pre_delete( $dbo ) { + return true; + } + /** + * デリート後に行いたい処理を記述する抽象メソッドです。 + * @param MDBObject $dbo オブジェクト互換オブジェクト + * @return boolean 成功したらtrue + */ + function post_delete( $dbo, $result ) { + return true; + } + /** + * ロードされた時の状態と差分があるか確認します + */ + function is_changed( $dbo ) { + $this->error_messages = array(); + $table_info_hash = $dbo->getTableInformation( $this ); + $is_changed = false; + foreach( $table_info_hash as $fname => $info_hash ) { + $fname_org = $fname.'_org'; + if( trim($this->$fname) != trim($this->$fname_org) ) { + $is_changed = true; + break; + } + } + return $is_changed; + } + // + // AbstractDataの実装 + // + /** + * データ保存区分名を取得する抽象メソッド + */ + function getDataClassName(){ + return $this->getTableName(); + } + /** + * データの保存区分名を設定する抽象メソッド + */ + function setDataClassName( $dataClassName ) { + return true; + } + /** + * データ固有のIDを取得する抽象メソッド + */ + function getUniqueId(){ + $uniqueStrings = ''; + if( is_array( $this->baseUniqueKeyFiledNames ) ) { + foreach( $this->baseUniqueKeyFiledNames as $fieldName ) { + $uniqueStrings .= $this->$fieldName; + } + return $uniqueStrings; + } else { + return false; + } + } + /** + * データ固有のIDを設定する抽象メソッド + */ + function setUniqueId( $uniqueId ) { + return true; + } +} +?> \ No newline at end of file Added: db/current/spider/lib/db/Connect.class.php =================================================================== --- db/current/spider/lib/db/Connect.class.php (rev 0) +++ db/current/spider/lib/db/Connect.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,77 @@ +<?php +require_once( dirname(dirname(__FILE__)) + .DIRECTORY_SEPARATOR.'spider' + .DIRECTORY_SEPARATOR.'ModuleBase.class.php'); +require_once( dirname(__FILE__) + .DIRECTORY_SEPARATOR.'Connection.class.php'); +/** + * spider : データベース接続用アクションモジュールクラス + * + * spiderのページから呼び出して実行します。 + * 設定ファイルdefine.inc.phpに記述したデータベース接続情報を元に + * database.Connection実装クラスのインスタンスを作成してデータベースに接続し + * リクエスト属性「database.connection」として登録します。 + * + * @package database データベースパッケージ + * @version 2.0.0 + * @author Multimedia Digital Contents Systems.Co.,Ltd. <info****@md-sy*****> + * @since PHP 4.0 + */ +class db_Connect extends spider_ModuleBase { + function db_Connect() { + } + function execute( & $request ) { + $databaseType = $request->getAttribute('database.type'); + $databaseName = $request->getAttribute('database.name'); + $databaseUser = $request->getAttribute('database.user'); + $databasePass = $request->getAttribute('database.pass'); + $databaseHost = $request->getAttribute('database.host'); + $databasePort = $request->getAttribute('database.port'); + $connection = false; + if( file_exists(DIR_PATH_DATA.DIRECTORY_SEPARATOR.'database2.define.inc.php') ) { + require_once(DIR_PATH_DATA.DIRECTORY_SEPARATOR.'database2.define.inc.php'); + } + if( strlen( $databaseType ) > 0 + && strlen($databaseName) > 0 + && strlen($databaseUser) > 0 + && strlen($databasePass) > 0 + ) { + // 接続情報が属性登録されているなら属性情報指定のデータベースに接続 + $connection = new db_Connection( $request, $databaseName, + $databaseUser, $databasePass, $databaseType, $databaseHost, $databasePort ); + } else if( defined('DATABASE_DATABASE_TYPE') + && defined('DATABASE_DATABASE_NAME') + && defined('DATABASE_DATABASE_USER') + && defined('DATABASE_DATABASE_PASSWORD') + ){ + // 接続情報が属性にないならdefine値にあれば接続 + $host = null; + if( defined('DATABASE_DATABASE_HOST') ) { + $host = DATABASE_DATABASE_HOST; + } else if( is_array($GLOBALS['DATABASE_DATABASE_HOST']) ) { + $host = $GLOBALS['DATABASE_DATABASE_HOST']; + } + $port = null; + if( defined('DATABASE_DATABASE_PORT') ) { + $port = DATABASE_DATABASE_PORT; + } else if( is_array($GLOBALS['DATABASE_DATABASE_PORT']) ) { + $port = $GLOBALS['DATABASE_DATABASE_PORT']; + } + $connection = new db_Connection( $request, DATABASE_DATABASE_NAME, + DATABASE_DATABASE_USER, DATABASE_DATABASE_PASSWORD, DATABASE_DATABASE_TYPE, $host, $port ); + } + if( $connection === false ) { + $request->addError('データベース接続情報が指定されていません。'); + } else { + $request->setAttribute('dbo', $connection ); + $request->setAttribute('database.connection', $connection ); + } + } + function post_process( & $request ) { + $connection = $request->getAttribute( 'database.connection' ); + if( !is_null( $connection ) ) { + $connection->disconnect(); + } + } +} +?> \ No newline at end of file Added: db/current/spider/lib/db/Connection.class.php =================================================================== --- db/current/spider/lib/db/Connection.class.php (rev 0) +++ db/current/spider/lib/db/Connection.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,1246 @@ +<?php +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'AbstractData.class.php'); +require_once(dirname(dirname(__FILE__)) + .DIRECTORY_SEPARATOR.'util' + .DIRECTORY_SEPARATOR.'CharUtility.class.php'); +/** + * AbstractConnectionの実装クラスオブジェクトのラッパークラスです。 + */ +class db_Connection { + + /** spider_HttpRequestオブジェクトへの参照 */ + var $request = null; + + /** データベースホスト配列: 0番目の要素が更新可能接続ホストで固定とする */ + var $databaseHostArray = array(); + /** データベースポート配列 0番目の要素が更新可能接続ポートで固定とする */ + var $databasePortArray = array(); + + /** データベースタイプ マスタ・スレーブ共通 */ + var $databaseType = null; + /** データベース名称 マスタ・スレーブ共通 */ + var $databaseName = null; + /** 接続ユーザ名 マスタ・スレーブ共通 */ + var $databaseUser = null; + /** 接続パスワード マスタ・スレーブ共通 */ + var $databasePass = null; + + /** AbstractConnection実装オブジェクト:マスタ接続インスタンス */ + var $connectionWritable = null; + /** AbstractConnection実装オブジェクト:スレーブ接続インスタンス */ + var $connectionReadOnly = null; + + /** トランザクション中フラグ */ + var $inTransaction = false; + + /** + * コンストラクタ + */ + function db_Connection( & $request, $databaseName, $databaseUser, $databasePass, $databaseType, $hosts, $ports ) { + $this->request = $request; + $this->databaseName = $databaseName; + $this->databaseUser = $databaseUser; + $this->databasePass = $databasePass; + $this->databaseType = $databaseType; + if( !is_array($hosts) ) { + $this->databaseHostArray = array(); + array_push( $this->databaseHostArray, $hosts ); + } else { + $this->databaseHostArray = $hosts; + } + if( !is_array($ports) ) { + $this->databasePortArray = array(); + array_push( $this->databasePortArray, $ports ); + } else { + $this->databasePortArray = $ports; + } + } + /** + * 更新可能なマスタ接続を取得します。 + * @access private + */ + function _connectWritable() { + if( !is_null( $this->connectionWritable ) ) { + return $this->connectionWritable; + } + $host = $this->databaseHostArray[0]; + $port = $this->databasePortArray[0]; + $connection = $this->_connect( $host, $port ); + if( $connection === false ) { + return false; + } else { + return $this->connectionWritable = & $connection; + } + } + /** + * 読み取りのみのスレーブ接続を取得します + * @access private + */ + function _connectReadOnly() { + if( !is_null( $this->connectionReadOnly ) ) { + return $this->connectionReadOnly; + } + $slaveHosts = $this->databaseHostArray; + $slavePorts = $this->databasePortArray; + $host = null; + $port = null; + if( count($slaveHosts) > 1 ) { + array_shift($slaveHosts); + array_shift($slavePorts); + $key = array_rand($slaveHosts); + $host = $slaveHosts[$key]; + if( isset( $slavePorts[$key]) ) { + $port = $slavePorts[$key]; + } + } else if( count($slaveHosts) == 1 ) { + $host = $slaveHosts[0]; + if( isset( $slavePorts[0]) ) { + $port = $slavePorts[0]; + } + } else { + return false; + } + $connection = $this->_connect( $host, $port ); + if( $connection === false ) { + return false; + } else { + return $this->connectionReadOnly = & $connection; + } + } + /** + * ホストとポートを指定してデータベース接続を取得します + * @access private + */ + function _connect( $host, $port ) { + // 利用するクラスの決定 + $className = 'db_connection_'.ucwords($this->databaseType); + if( !class_exists($className) ) { + $filePathClassFile = dirname(__FILE__).DIRECTORY_SEPARATOR + .'connection'.DIRECTORY_SEPARATOR.ucwords($this->databaseType).'.class.php'; + if( !file_exists($filePathClassFile) ) { + $this->request->addError('データベースタイプの接続クラスファイルがありません。'.$filePathClassFile); + return false; + } else { + require_once( $filePathClassFile ); + if( !class_exists($className) ) { + $this->request->addError('データベースタイプの接続クラスが定義されていません。'.$filePathClassFile); + return false; + } + } + } + $connection = new $className; + $connection->_setHttpRequest( $this->request ); + if( !is_a($connection,'db_AbstractConnection') ) { + $this->request->addError('データベースタイプの接続クラスの定義が正しくありません。'); + return false; + } + if( $connection->_connect( $this->databaseName, $this->databaseUser, $this->databasePass, $host, $port ) ) { + return $connection; + } + return false; + } + /** + * データベースから切断します + */ + function disconnect() { + if( !is_null( $this->connectionReadOnly ) ) { + $this->connectionReadOnly->_disconnect(); + } + if( !is_null( $this->connectionWritable ) ) { + $this->connectionWritable->_disconnect(); + } + } + /** + * トランザクション状態に応じて適切なデータベース接続を取得します + */ + function _getProperConnection() { + $connection = false; + if( $this->inTransaction ) { + $connection = $this->_connectWritable(); + } else { + $connection = $this->_connectReadOnly(); + } + return $connection; + } + /** + * 文字列をquoteします + * @param string $value 文字列 + * @param string $type カラム型 + * @param boolean $quote quoteする場合はtrue、しない場合はfalse + * @param boolean $escape_wildcards ワイルドカードをquoteする場合はtrue、しない場合はfalse + * @return string quoteした文字列 + * @access public + */ + function quote( $value, $type = null, $quote = true, $escape_wildcards = false ) { + $connection = $this->_getProperConnection(); + if( $connection === false ) { + return false; + } else { + return $connection->_quote( $value, $type, $quote, $escape_wildcards ); + } + } + /** + * 文字列をエスケープします + * @param string $text + * @param boolean $escape_wildcards + * @return + * @access public + */ + function escape( $text, $escape_wildcards = false ){ + $connection = $this->_getProperConnection(); + if( $connection === false ) { + return false; + } else { + return $connection->_escape( $text, $escape_wildcards ); + } + } + /** + * Transactionを開始します + * @param string $savepoint savepoint名 + * @return + * @access public + */ + function beginTransaction( $savepoint = null ) { + $this->inTransaction = true; + $connection = $this->_connectWritable(); + if( $connection === false ) { + return false; + } else { + return $connection->_beginTransaction( $savepoint ); + } + } + /** + * トランザクションをコミットします + * @param string $savepoint savepoint名 + * @return + * @access public + */ + function commit( $savepoint = null ) { + $this->inTransaction = false; + $connection = $this->_connectWritable(); + if( $connection === false ) { + return false; + } else { + return $connection->_commit( $savepoint ); + } + } + /** + * トランザクションをロールバックします + * @param string $savepoint savepoint名 + * @return + * @access public + */ + function rollback( $savepoint = null ) { + $this->inTransaction = false; + $connection = $this->_connectWritable(); + if( $connection === false ) { + return false; + } else { + return $connection->_rollback( $savepoint ); + } + } + /** + * 渡されたSQLクエリ文を実行します + * @param string $query SQLクエリ + * @param array $types 指定した場合は、結果セットのカラムの型が取得したものに設定されます。 + * @param boolean $result_class + * @param boolean $result_wrap_class + * @return + * @access public + */ + function query( $query, $types = null, $result_class = true, $result_wrap_class = false ) { + $query = trim( $query ); + $connection = false; + if( preg_match('/^[sE][eE][lL][eE][cC][tT]/',$query) > 0 || preg_match('/^[sS][hH][oO][wW]/',$query) > 0 ) { + // 問い合わせ系SQL文の場合にはトランザクション状態に応じた適切なコネクションを取得 + $connection = $this->_getProperConnection(); + } else { + // 更新系SQL文の場合にはマスタコネクションを取得 + $connection = $this->_connectWritable(); + } + if( $connection === false ) { + return false; + } else { + return $connection->_query( $query ); + } + } + /** + * 渡されたSQLクエリ文を実行して全ての結果を取得します + * @param string $query SQLクエリ + * @param array $types 指定した場合は、結果セットのカラムの型が取得したものに設定されます。 + * @param integer $fetchmode 使用する取得モード。 + * @param boolean $rekey trueを指定すると、配列は以下のように変更されます。 + * 結果セットのカラム数が二つより多い場合は、値はカラム2からカラムnまでの値の配列となります。 + * 結果セットのカラムが二つだけの場合は、戻り値は二番目のカラムの値を表すスカラー値になります。 + * ($force_arrayパラメータで配列を強制している場合は除きます) + * @param boolean $force_array クエリの返すカラム数が二つである場合にのみ使用します。 + * trueを設定すると、戻り値の配列の値がスカラー値ではなく一要素の配列となります。 + * @param boolean $group trueを設定すると、戻り値の配列の値が別の配列でラップされます。 + * 同一のキー(最初のカラムの値)が複数表れた場合に、それが既存の値を上書きせずに配列に追加されるようになります。 + * @return mixed 入れ子状の配列、あるいは失敗した場合にMDB_Errorを返します。 + * @access public + */ + function queryAll( $query, $fetchtype=null, $loadRelation=false, $setOrg=true ) { + $connection = $this->_getProperConnection(); + if( $connection === false ) { + return false; + } else { + $result = $connection->_queryAll( $query, $fetchtype, $setOrg ); + $this->releaseLimit(); + if( $result !== false ) { + if( $loadRelation ) { + foreach( $result as $key => $row ) { + if( is_object( $row ) ) { + // オプション情報読み込みメソッドがあるならコール + if( $loadRelation === true ) { + if( method_exists($result[$key],'loadRelation') ) { + $result[$key]->loadRelation($this); + } else if( method_exists($result[$key],'_load_optional_data') ) { + $result[$key]->_load_optional_data($this); + } else if( method_exists($result[$key],'_load_optional_relation') ) { + $result[$key]->_load_optional_relation($this); + } + } else if( strlen(trim($loadRelation)) > 0 ) { + // オプション読み込みメソッドが指定されているならコール + if( strpos($loadRelation,'(') != false && strpos($loadRelation,')') != false ) { + // メソッド呼び出しプログラム記述 + eval($loadRelation); + } else if( method_exists($result[$key],$loadRelation) ) { + $result[$key]->$loadRelation($this); + } + } + } + } + } + return $result; + } else { + return false; + } + } + } + /** + * 渡されたSQLクエリ文を実行して1レコードのみ結果を取得します + * @param string $query SQLクエリ + * @param array $types 指定した場合は、結果セットのカラムの型が取得したものに設定されます。 + * @param integer $fetchmode 使用する取得モード。 + * @return + * @access public + */ + function queryRow( $query, $fetchtype=null, $loadRelation=false, $setOrg=true ) { + $connection = $this->_getProperConnection(); + if( $connection === false ) { + return false; + } else { + $result = $connection->_queryRow( $query, $fetchtype, $setOrg ); + if( $result !== false ) { + if( $loadRelation && is_object( $result ) ) { + // オプション情報読み込みメソッドがあるならコール + if( $loadRelation === true ) { + if( method_exists($result,'loadRelation') ) { + $result->loadRelation($this); + } else if( method_exists($result,'_load_optional_data') ) { + $result->_load_optional_data($this); + } else if( method_exists($result,'_load_optional_relation') ) { + $result->_load_optional_relation($this); + } + } else if( strlen(trim($loadRelation)) > 0 ) { + // オプション読み込みメソッドが指定されているならコール + if( strpos($loadRelation,'(') != false && strpos($loadRelation,')') != false ) { + // メソッド呼び出しプログラム記述 + eval($loadRelation); + } else if( method_exists($result,$loadRelation) ) { + $result->$loadRelation($this); + } + } + } + return $result; + } else { + return false; + } + } + } + /** + * 渡されたSQLクエリ文を実行して1カラム分のみ結果を取得します + * @param string $query SQLクエリ + * @param string $type 指定した場合は、結果セットのカラムの型が取得したものに設定されます。 + * @param integer $column + * @return + * @access public + */ + function queryOne( $query ) { + $connection = $this->_getProperConnection(); + if( $connection === false ) { + return false; + } else { + return $connection->_queryOne( $query ); + } + } + /** + * 問い合わせ結果レコードの行数とオフセットを設定します + * @param string $limit + * @param string $offset + * @return + * @access public + */ + function setLimit( $limit, $offset = null ) { + if( $this->connectionWritable ) { + $this->connectionWritable->_setLimit( $limit, $offset ); + } + if( $this->connectionReadOnly ) { + $this->connectionReadOnly->_setLimit( $limit, $offset ); + } + } + /** + * 問い合わせ結果レコードの行数とオフセットを全て解除します + * @return + * @access public + */ + function releaseLimit() { + if( $this->connectionWritable ) { + $this->connectionWritable->limit = null; + $this->connectionWritable->offset = null; + } + if( $this->connectionReadOnly ) { + $this->connectionReadOnly->limit = null; + $this->connectionReadOnly->offset = null; + } + } + /** + * 問い合わせ結果レコードの行数とオフセットを設定します + * @param string $limit + * @param string $offset + * @return + * @access public + */ + function setRowToFields( $row, & $daoBase, $setOrg=true ) { + $connection = $this->_getProperConnection(); + if( $connection === false ) { + return false; + } else { + return $connection->_setRowToFields( $row, $daoBase, $setOrg ); + } + } + /** + * ユニークキーから一意のデータをオブジェクトに設定します。 + * @param object &$daoBase database_AbstractDataオブジェクト + * @param mixed $uniqueId スカラー値またはハッシュ + * @return boolean 渡されたユニークIDでデータを一意に絞り込んで取得出来たらtrue + */ + function loadById( & $daoBase, $uniqueId, $loadRelation=true, $ignoreFieldNames=array() ) { + $tableInformationHash = $this->getTableInformationHash( $daoBase ); + if( false !== $tableInformationHash ) { + // フィールド一覧を取得できたらユニークキーフィールドを探す + $this->_setUniqueFieldInfo( $daoBase ); + if( count($daoBase->baseUniqueKeyFiledNames) == 0 ) { + // ユニークフィールドがない場合はロードできない + $this->warn('[warning][loadById] '.$daoBase->getTableName().' don\'t have unique fields!'); + return false; + } else if( is_object($uniqueId) ) { + // ユニークフィールドのオブジェクト渡しは非対応 + $this->warn('[warning][loadById] '.$daoBase->getTableName().'. uniqueId must be hash or scaler!'); + return false; + } else { + $conditionArray = array(); + if( is_array($uniqueId) ) { + // ハッシュで渡されていることとする + foreach( $uniqueId as $key => $value ) { + if( in_array( $key, $daoBase->baseUniqueKeyFiledNames ) ) { + $condition = $key.'='.$this->quote($value); + array_push($conditionArray,$condition); + } + } + } else { + // スカラー値なら最初の要素の値として設定 + $condition = $daoBase->baseUniqueKeyFiledNames[0].'='.$this->quote($uniqueId); + array_push($conditionArray,$condition); + } + // SELECT 対象のフィールドを確認 + $selectTargetStrings = '*'; + if( is_array($ignoreFieldNames) && count($ignoreFieldNames) > 0 ) { + $targetFields = array(); + foreach( $tableInformationHash as $fieldName => $fieldInfo ) { + if( !in_array($fieldName,$ignoreFieldNames) ) { + // 無視するフィールド以外なら追加 + array_push($targetFields,$fieldName); + } + } + if( count($targetFields) > 0 ) { + $selectTargetStrings = implode(',',$targetFields); + } else { + $this->request->addError('[warning][loadById] all fields is ignored!', true); + return false; + } + } + $sql = 'SELECT '.$selectTargetStrings.' FROM '.$daoBase->getTableName().' WHERE '.implode(' AND ',$conditionArray); + $result = $this->queryAll( $sql, null, 'hash' ); + if ( $result === false ) { + $this->request->addError('[warning][loadById] select failed! '.$this->error_message.':'.$sql, true); + return false; + } else if(count($result)==0){ + $this->warn('[warning][loadById] '.$daoBase->getTableName().' has no data!:'.$sql); + return false; + } else if(count($result)>1){ + $this->warn('[warning][loadById] '.$daoBase->getTableName().' has '.count($result).' datas!:'.$sql); + return false; + } else { + $result = $this->setRowToFields( $result[0], $daoBase ); + if( $result && $loadRelation ) { + // オプション情報読み込みメソッドがあるならコール + if( $loadRelation === true ) { + if( method_exists($daoBase,'loadRelation') ) { + $daoBase->loadRelation($this); + } else if( method_exists($daoBase,'_load_optional_data') ) { + $daoBase->_load_optional_data($this); + } else if( method_exists($daoBase,'_load_optional_relation') ) { + $daoBase->_load_optional_relation($this); + } + } else if( strlen(trim($loadRelation)) > 0 ) { + // オプション読み込みメソッドが指定されているならコール + if( strpos($loadRelation,'(') != false && strpos($loadRelation,')') != false ) { + // メソッド呼び出しプログラム記述 + eval($loadRelation); + } else if( method_exists($daoBase,$loadRelation) ) { + $daoBase->$loadRelation($this); + } + } + } + return $result; + } + } + } + return false; + } + /** + * プライマリキーから一意のデータをオブジェクトに設定します。 + * @param object &$daoBase database_AbstractDataオブジェクト + * @param number $number スカラー値 + * @return boolean 渡されたプライマリ番号でデータを一意に絞り込んで取得出来たらtrue + */ + function loadByNumber( & $daoBase, $number, $loadRelation=true, $ignoreFieldNames=array() ) { + $tableInformationHash = $this->getTableInformationHash( $daoBase ); + if( false !== $tableInformationHash ) { + // フィールド一覧を取得できたら自動番号フィールドを探す + $this->_setUniqueFieldInfo( $daoBase ); + if( is_null($daoBase->baseSerialFieldName) ) { + // 自動番号フィールドがない場合はロードできない + $this->warn('[warning][loadByNumber] '.$daoBase->getTableName().' don\'t have serial fields!'); + return false; + } else if( is_object($number) ) { + // 自動番号フィールドのオブジェクト渡しは非対応 + $this->warn('[warning][loadByNumber] '.$daoBase->getTableName().'. $number needs to numeric strings!'); + return false; + } else if( is_array($number) ) { + // 自動番号フィールドの配列渡しは非対応 + $this->warn('[warning][loadByNumber] '.$daoBase->getTableName().'. $number needs to numeric strings!'); + return false; + } else if( !is_numeric($number) ) { + // 自動番号フィールドが数字でない場合は非対応 + $this->warn('[warning][loadByNumber] '.$daoBase->getTableName().'. $number needs to numeric strings!'); + return false; + } else { + // SELECT 対象のフィールドを確認 + $selectTargetStrings = '*'; + if( is_array($ignoreFieldNames) && count($ignoreFieldNames) > 0 ) { + $targetFields = array(); + foreach( $tableInformationHash as $fieldName => $fieldInfo ) { + if( !in_array($fieldName,$ignoreFieldNames) ) { + // 無視するフィールド以外なら追加 + array_push($targetFields,$fieldName); + } + } + if( count($targetFields) > 0 ) { + $selectTargetStrings = implode(',',$targetFields); + } else { + $this->request->addError('[warning][loadById] all fields is ignored!', true); + return false; + } + } + $sql = 'SELECT '.$selectTargetStrings.' FROM '.$daoBase->getTableName().' WHERE '.$daoBase->baseSerialFieldName.'='.$number; + $result = $this->queryAll( $sql, null, 'hash' ); + if ( $result === false ) { + $this->request->addError('[warning][loadById] select failed! '.$this->error_message.':'.$sql, true); + return false; + } else if(count($result)==0){ + $this->warn('[warning][loadById] '.$daoBase->getTableName().' has no data!:'.$sql); + return false; + } else if(count($result)>1){ + $this->warn('[warning][loadById] '.$daoBase->getTableName().' has '.count($result).' datas!:'.$sql); + return false; + } else { + $result = $this->setRowToFields( $result[0], $daoBase ); + if( $result && $loadRelation ) { + // オプション情報読み込みメソッドがあるならコール + if( $loadRelation === true ) { + if( method_exists($daoBase,'loadRelation') ) { + $daoBase->loadRelation($this); + } else if( method_exists($daoBase,'_load_optional_data') ) { + $daoBase->_load_optional_data($this); + } else if( method_exists($daoBase,'_load_optional_relation') ) { + $daoBase->_load_optional_relation($this); + } + } else if( strlen(trim($loadRelation)) > 0 ) { + // オプション読み込みメソッドが指定されているならコール + if( strpos($loadRelation,'(') != false && strpos($loadRelation,')') != false ) { + // メソッド呼び出しプログラム記述 + eval($loadRelation); + } else if( method_exists($daoBase,$loadRelation) ) { + $daoBase->$loadRelation($this); + } + } + } + return $result; + } + } + } + return false; + } + /** + * 渡されたデータ抽象オブジェクトのデータをレコードとしてデータベースに追加します + * 本メソッドは拡張クラスにて必ずオーバーライドして実装する抽象メソッドとします。 + * @param object &$daoBase データ抽象オブジェクト + * @return boolean 成功したらtrue,失敗したらfalseを返します + * @abstract + * @access public + */ + function insert( & $daoBase, & $request = null ) { + $tableInformationHash = $this->getTableInformationHash( $daoBase ); + $insertFieldHash = array(); + if( false !== $tableInformationHash ) { + // フィールド一覧を取得できたら + if( !is_null($request) + && 'spider_httprequest' == strtolower(get_class($request)) + && method_exists($daoBase,'preInsert') ) { + // Requestオブジェクトが渡されていてpreInsertメソッドがあるなら実行 + if( !$daoBase->preInsert($request,$this) ) { + return false; + } + } + if( method_exists($daoBase,'pre_insert') ) { + $daoBase->pre_insert($this); + } + foreach ( $tableInformationHash as $fieldName => $fieldInformation ) { + if( isset($fieldInformation['is_serial']) && $fieldInformation['is_serial'] === true ) { + // オートナンバーのフィールドはインサートしない + } else { + // それ以外のフィールドはインサート対象 + $insertFieldHash[$fieldName] = $this->quote( $daoBase->$fieldName ); + } + } + // INSERT文作成 + if ( count( $insertFieldHash ) > 0 ) { + $sql = 'INSERT INTO '.$daoBase->getTableName() + .'('.implode(',', array_keys($insertFieldHash) ).')' + .' VALUES (' + . implode(',', $insertFieldHash).')'; + // 実行 + $result = $this->query( $sql ); + if ( $result === false ) { + $this->error($this->error_message.':'.$sql); + return false; + } + $this->debug('[EXECUTE INSERT]'.$sql); + if( !is_null($request) + && 'spider_httprequest' == strtolower(get_class($request)) + && method_exists($daoBase,'postInsert') ) { + // Requestオブジェクトが渡されていてpreInsertメソッドがあるなら実行 + $daoBase->postInsert($request,$this); + } + if( method_exists($daoBase,'post_insert') ) { + return $daoBase->post_insert($this,$result); + } + return true; + } else { + return false; + } + } else { + return false; + } + } + /** + * 渡されたデータ抽象オブジェクトのデータに該当するレコードを更新します + * 本メソッドは拡張クラスにて必ずオーバーライドして実装する抽象メソッドとします。 + * @param object &$daoBase データ抽象オブジェクト + * @param array $historyLimitDays 0の場合は履歴登録しない, マイナス値の場合は履歴を登録して消さない, +値は履歴保存日数 + * @return boolean 成功したらtrue,失敗したらfalseを返します + * @access public + */ + function update( & $daoBase, $historyLimitDays=false, & $request = null ) { + if( true === $historyLimitDays ) { + $historyLimitDays = 180; + } + $tableInformationHash = $this->getTableInformationHash( $daoBase ); + $updatedFieldHash = array(); + $updatedConditionHash = array(); + if( false !== $tableInformationHash ) { + // フィールド一覧を取得できたら + if( !is_null($request) + && 'spider_httprequest' == strtolower(get_class($request)) + && method_exists($daoBase,'preUpdate') ) { + // Requestオブジェクトが渡されていてpreUpdateメソッドがあるなら実行 + if( !$daoBase->preUpdate($request,$this) ){ + return false; + } + } + if( method_exists($daoBase,'pre_update') ) { + $daoBase->pre_update($this); + } + foreach ( $tableInformationHash as $fieldName => $fieldInformation ) { + if( isset($fieldInformation['is_serial']) && $fieldInformation['is_serial'] === true ) { + // オートナンバーのフィールドは更新条件 + $updatedConditionHash[$fieldName] = $this->quote( $daoBase->$fieldName ); + } else { + // それ以外のフィールドは値が異なるなら更新対象 + $fieldNameOrg = $fieldName.'_org'; + if( $daoBase->$fieldNameOrg != $daoBase->$fieldName ) { + $updatedFieldHash[$fieldName] = $this->quote( $daoBase->$fieldName ); + } + } + } + // UPDATE文作成 + if ( count($updatedFieldHash) > 0 && count($updatedConditionHash) > 0 ) { + // 差分があるなら更新処理を行う + if( false !== $historyLimitDays && is_numeric($historyLimitDays) && $historyLimitDays!=0 ) { + // 最初に履歴登録が必要なら登録 + $this->history( $daoBase, true, date('Y-m-d H:i:s'), $historyLimitDays ); + } + // データベース更新実行 + $sql = 'UPDATE '.$daoBase->getTableName().' SET'; + $counter = 0; + foreach( $updatedFieldHash as $fieldName => $value ) { + if( $counter == 0 ) { + $sql .= ' '. $fieldName.'='.$value; + } else { + $sql .= ', '. $fieldName.'='.$value; + } + $counter++; + } + $sql .= ' WHERE '; + $counter = 0; + foreach( $updatedConditionHash as $fieldName => $value ) { + if( $counter == 0 ) { + $sql .= ' '. $fieldName.'='.$value; + } else { + $sql .= ' AND '. $fieldName.'='.$value; + } + $counter++; + } + // 実行 + $result = $this->query( $sql ); + if ( $result === false ) { + $this->error('[ERROR][update]:'.$sql); + return false; + } + $this->debug('[EXECUTE UPDATE]'.$sql); + if( !is_null($request) + && 'spider_httprequest' == strtolower(get_class($request)) + && method_exists($daoBase,'postUpdate') ) { + // Requestオブジェクトが渡されていてpostUpdateメソッドがあるなら実行 + $daoBase->postUpdate($request,$this); + } + if( method_exists($daoBase,'post_update') ) { + return $daoBase->post_update($this,$result); + } + return true; + } else { + return true; + } + } + return false; + } + /** + * 渡されたデータ抽象オブジェクトのデータに該当するレコードを削除します + * 本メソッドは拡張クラスにて必ずオーバーライドして実装する抽象メソッドとします。 + * @param object &$daoBase データ抽象オブジェクト + * @param array $historyLimitDays 0の場合は履歴登録しない, マイナス値の場合は履歴を登録して消さない, +値は履歴保存日数 + * @return boolean 成功したらtrue,失敗したらfalseを返します + * @access public + */ + function delete( & $daoBase, $historyLimitDays=false, & $request = null ) { + if( true === $historyLimitDays ) { + $historyLimitDays = 180; + } + $tableInformationHash = $this->getTableInformationHash( $daoBase ); + $deleteConditionHash = array(); + if( false !== $tableInformationHash ) { + // フィールド一覧を取得できたら + if( !is_null($request) + && 'spider_httprequest' == strtolower(get_class($request)) + && method_exists($daoBase,'preDelete') ) { + // Requestオブジェクトが渡されていてpreDeleteメソッドがあるなら実行 + if( !$daoBase->preDelete($request,$this) ) { + return false; + } + } + if( method_exists($daoBase,'pre_delete') ) { + $daoBase->pre_delete($this); + } + foreach ( $tableInformationHash as $fieldName => $fieldInformation ) { + if( isset($fieldInformation['is_serial']) && $fieldInformation['is_serial'] === true ) { + // オートナンバーのフィールドが削除条件 + $deleteConditionHash[$fieldName] = $this->quote( $daoBase->$fieldName ); + } + } + // DELETE文作成 + if ( count($deleteConditionHash) > 0 ) { + // 差分があるなら更新処理を行う + if( false !== $historyLimitDays && is_numeric($historyLimitDays) && $historyLimitDays!=0 ) { + // 最初に履歴登録が必要なら登録 + $this->history( $daoBase, true, date('Y-m-d H:i:s'), $historyLimitDays ); + } + // データベース削除実行 + $sql = 'DELETE FROM '.$daoBase->getTableName(); + $sql .= ' WHERE '; + $counter = 0; + foreach( $deleteConditionHash as $fieldName => $value ) { + if( $counter == 0 ) { + $sql .= ' '. $fieldName.'='.$value; + } else { + $sql .= ' AND '. $fieldName.'='.$value; + } + $counter++; + } + // 実行 + $result = $this->query( $sql ); + if ( $result === false ) { + $this->error($this->error_message.':'.$sql); + return false; + } + $this->debug('[EXECUTE DELETE]'.$sql); + if( !is_null($request) + && 'spider_httprequest' == strtolower(get_class($request)) + && method_exists($daoBase,'postDelete') ) { + // Requestオブジェクトが渡されていてpostDeleteメソッドがあるなら実行 + $daoBase->postDelete($request,$this); + } + if( method_exists($daoBase,'post_delete') ) { + return $daoBase->post_delete($this,$result); + } + return true; + } else { + return false; + } + } + return false; + } + /** + * 渡されたAbstractDataオブジェクトの情報をデータ履歴テーブルに登録します。 + * @param $daoBase Daoオブジェクト + * @param $historyId 履歴ID,trueにすると自動発行,falseだとIDなしでインサート + * @param $historyDatetime 履歴登録日,trueなら現在日時,falseなら日時なしでインサート + * @param $historyLimitDays 履歴保存日数。falseなら消さない + * @param $fieldSuffix インサートするフィールド名に対するメンバ変数名のフィールドサフィックス。デフォルトは'_org' + */ + function history( & $daoBase, $historyId=true, $historyDatetime=true, $historyLimitDays=false, $fieldSuffix='_org' ) { + $historyTableName = $daoBase->getTableName().'_history'; + $tableInformationHash = $this->getTableInformationHash( $daoBase ); + $insertFieldHash = array(); + if( false !== $tableInformationHash ) { + if( $this->existsTable( $historyTableName ) ) { + // フィールド一覧を取得できたら + foreach ( $tableInformationHash as $fieldName => $fieldInformation ) { + // 全てのフィールドがインサート対象 + $orgFieldName = $fieldName.$fieldSuffix; + if( !is_null($daoBase->$orgFieldName) && strlen($daoBase->$orgFieldName) > 0 ) { + $insertFieldHash[$fieldName] = $this->quote( $daoBase->$orgFieldName ); + } + } + // 履歴IDの生成 + if( true === $historyId ) { + // trueなら自動生成 + $historyId = $this->createUniqueKey( $historyTableName, 'history_id', 'history_number', date('YmdHis').'{num:4}' ); + $insertFieldHash['history_id'] = $this->quote( $historyId ); + } else if( strlen($historyId) > 0 ) { + // 入力があるなら指定IDで登録 + $insertFieldHash['history_id'] = $this->quote( $historyId ); + } else { + // それ以外は登録しない + } + // 履歴IDをAbstractDataオブジェクトに格納する + $daoBase->history_id = $historyId; + // 履歴登録日 + if( true === $historyDatetime ) { + // trueの場合は自動で現在日時 + $insertFieldHash['history_date'] = $this->quote( date('Y-m-d H:i:s') ); + } else if( strlen($historyDatetime) > 0 + && preg_match('/^[0-9]{4}\\-[0-9]{1,2}\\-[0-9]{1,2}\\s[0-9]{1,2}\\:[0-9]{1,2}\\:[0-9]{1,2}$/',$historyDatetime) > 0 ) { + // Y-m-d H:i:s形式の場合はそのまま登録 + $insertFieldHash['history_date'] = $this->quote( $historyDatetime ); + } else { + // 日時フォーマットにマッチしない場合は日時を登録しない + } + // INSERT文作成 + if ( count( $insertFieldHash ) > 0 ) { + $sql = 'INSERT INTO '.$historyTableName + .'('.implode(',', array_keys($insertFieldHash) ).')' + .' VALUES (' + . implode(',', $insertFieldHash).')'; + // 実行 + $result = $this->query( $sql ); + if ( $result === false ) { + $this->error('[history]['.$daoBase->getTableName().'] fail to regist history! : '.$sql); + return false; + } + $this->debug('[EXECUTE INSERT]'.$sql); + // 履歴期限日カラムがあるテーブルの場合期限を過ぎた履歴を消去 + if( preg_match('/^[0-9]{1,4}$/',$historyLimitDays) > 0 && $historyLimitDays > 0 ) { + $sql = 'DELETE FROM '.$historyTableName + .' WHERE history_date<'.$this->quote(date('Y-m-d H:i:s',strtotime('-'.$historyLimitDays.' day'))); + $result = $this->query( $sql ); + if ( $result === false ) { + $this->error('[history]['.$daoBase->getTableName().'] fail to delete old history! : '.$sql); + return false; + } + } + return true; + } else { + return false; + } + } + } else { + return false; + } + } + /** + * 指定のDaoObjectを履歴IDの状態に復元します + */ + function recover( & $daoBase, $historyId, $historyPrev=false, $deleteUseHistory=false ) { + $historyTableName = $daoBase->getTableName().'_history'; + $tableInformationHash = $this->getTableInformationHash( $daoBase ); + $insertFieldHash = array(); + if( false !== $tableInformationHash ) { + if( $this->existsTable( $historyTableName ) ) { + // 履歴テーブルが存在するなら履歴を探す + $keyConditionArray = array(); + foreach ( $tableInformationHash as $fieldName => $fieldInformation ) { + if( isset($fieldInformation['is_serial']) && $fieldInformation['is_serial'] === true ) { + // オートナンバーのフィールドは追加条件 + $str = $fieldName.'='.$this->quote( $daoBase->$fieldName ); + array_push( $keyConditionArray, $str ); + break; + } + } + $sql = 'SELECT * FROM '.$historyTableName + .' WHERE history_id='.$this->quote($historyId) + .' AND '.implode(' AND ', $keyConditionArray ) + ; + $result = $this->queryAll($sql,'hash'); + if( false === $result ) { + return false; + } else if( count( $result ) != 1 ){ + return false; + } else { + foreach ( $tableInformationHash as $fieldName => $fieldInformation ) { + $daoBase->$fieldName = $result[0][$fieldName]; + } + if( $this->update( $daoBase, $historyPrev ) ) { + if( $deleteUseHistory ) { + $sql = 'DELETE FROM '.$historyTableName.' WHERE history_id='.$this->quote($historyId); + $dbo->query( $sql ); + } + return true; + } else { + return false; + } + } + } + } + } + /** + * 指定DAOオブジェクトのユニーク識別子フィールドに次のデータのIDを発行して設定します。 + * @param $daoBase DAOオブジェクトへの参照 + * @param $format 連続識別子のフォーマット文字列。連番箇所は{num:桁数}で指定できる。 + */ + function setNextId( & $daoBase, $format='ID{num:6}' ) { + if( $this->_setUniqueFieldInfo( $daoBase ) === false ) { + $this->error('[setNextId]['.$daoBase->getTableName().'] fail to get table information!'); + return false; + } else { + // フィールド一覧を取得できたら + if( is_null($daoBase->baseSerialFieldName) ) { + $this->error('[setNextId]['.$daoBase->getTableName().'] target table has no serial!'); + return false; + } else if( count($daoBase->baseUniqueKeyFiledNames) == 0 ) { + $this->error('[setNextId]['.$daoBase->getTableName().'] target table has no unique key!'); + return false; + } + // ユニークフィールドごとに設定されていなければ発行 + foreach( $daoBase->baseUniqueKeyFiledNames as $uniqueName ) { + if( strlen(trim($daoBase->$uniqueName)) == 0 ) { + $nextId = $this->createUniqueKey( $daoBase->getTableName(), $uniqueName, $daoBase->baseSerialFieldName, $format ); + if( false === $nextId ) { + return false; + } else { + $daoBase->$uniqueName = $nextId; + } + } + } + return true; + } + } + /** + * 指定テーブル指定フィールドの連続識別子の次の値の文字列を指定フォーマットで取得します。 + * @param $tableName 対象テーブル名 + * @param $targetFieldName 対象フィールド名 + * @param $sortFieldName 最後のインサートを抽出する為のDESCソートフィールド名。通常はシリアルフィールド名を渡す + * @param $format 連続識別子のフォーマット文字列。連番箇所は{num:桁数}で指定できる。 + * @return 次の連続識別子文字列 + */ + function createUniqueKey( $tableName, $targetFieldName, $sortFieldName, $format='IDAA{num:4}' ) { + // フォーマットのSQL問い合わせ用文字列を発行 + $regx = $format; + if( preg_match_all( '/\\{num\\:([0-9]+)\\}/', $regx, $matches, PREG_PATTERN_ORDER ) > 0 ) { + foreach( $matches[0] as $key => $matchString ) { + $numLen = $matches[1][$key]; + $repStr = ''; + for( $i=0; $i<$numLen;$i++ ) { + $repStr .= '_'; + } + $regx = str_replace($matchString,$repStr,$regx); + } + } + $sql = 'SELECT '.$targetFieldName.' FROM '.$tableName + .' WHERE '.$targetFieldName.' LIKE '.$this->quote($regx) + .' ORDER BY '.$targetFieldName.' DESC'; + $this->setLimit( 1, 0 ); + $result = $this->queryAll( $sql ); + if ( $result === false ) { + // 問い合わせに失敗した場合 + $this->error('[createUniqueKey]['.$tableName.']['.$targetFieldName.']'.$sql); + return false; + } else { + // 最後の行を取得出来たら + if( count($result) > 0 ) { + // 行が挿入されている場合は挿入済みの行に合わせる + $lastId = trim($result[0][$targetFieldName]); + $lastIdElms = util_CharUtility::explodeAN($lastId,1); + $nextElms = $lastIdElms; + for( $i=count($nextElms)-1; $i>=0; $i-- ) { + $elm = $nextElms[$i]; + if( preg_match('/[0-9]+/',$elm) > 0 ) { + // 数字要素ならインクリメント + $elm++; + if( strlen($elm) > strlen($nextElms[$i]) ) { + // 桁数がオーバーフローする場合は1に戻してひとつ前の要素処理 + $elm = 1; + $nextElms[$i] = sprintf('%0'.strlen($nextElms[$i]).'d',$elm); + } else { + // 桁がオーバーフローしていない場合は数値をインクリメントしてbreak + $nextElms[$i] = sprintf('%0'.strlen($nextElms[$i]).'d',$elm); + break; + } + } else if( preg_match('/[A-Z]/',$elm) > 0 ) { + // アルファベット大文字の場合 + $charNumArray = unpack('C*',$elm); + $charNum = $charNumArray[0]; + $charNum++; + if( $charNum > 90 ) { + // 桁数オーバーフロー + $nextElms[$i] = 'A'; + } else { + // オーバーフローなし + $nextElms[$i] = pack('C*',$charNum); + break; + } + } + } + return implode('',$nextElms); + } else { + // 行がまだ挿入されていない場合は連番初期値で発行 + $nextId = $format; + if( preg_match_all( '/\\{num\\:([0-9]+)\\}/', $nextId, $matches, PREG_PATTERN_ORDER ) > 0 ) { + foreach( $matches[0] as $key => $matchString ) { + $numLen = $matches[1][$key]; + $numStr = sprintf('%0'.$numLen.'d',1); + $nextId = str_replace($matchString,$numStr,$nextId); + } + } + return $nextId; + } + } + } + /** + * データアクセスオブジェクトにフィールドキー情報のリファレンスを設定します + */ + function _setUniqueFieldInfo( & $daoBase ) { + $connection = $this->_getProperConnection(); + if( $connection === false ) { + return false; + } else { + return $connection->_setUniqueFieldInfo( $daoBase ); + } + } + /** + * 渡されたデータ抽象オブジェクトに該当するテーブル情報ハッシュを取得します。 + * 【テーブル情報ハッシュの構造】 + * array( [フィールド名] => [フィールド詳細情報ハッシュ] ) + * + * 【フィールド詳細情報ハッシュの構造】 + * array( + * 'type' => 'int/char/varchar/text...', + * 'size' => 数値 + * 'not_null' => true/false + * 'key' => 'primary/unique' + * 'is_serial' => true/false + * 'has_default' => true/false + * ) + */ + function getTableInformationHash( $daoBase ) { + return $this->getTableInformationHashByName( $daoBase->getTableName() ); + } + /** + * テーブル名称を指定して該当するテーブル情報ハッシュを取得します。 + * 【テーブル情報ハッシュの構造】 + * array( [フィールド名] => [フィールド詳細情報ハッシュ] ) + * + * 【フィールド詳細情報ハッシュの構造】 + * array( + * 'type' => 'int/char/varchar/text...', + * 'size' => 数値 + * 'not_null' => true/false + * 'key' => 'primary/unique' + * 'is_serial' => true/false + * 'has_default' => true/false + * ) + */ + function getTableInformationHashByName( $tableName ) { + $connection = $this->_getProperConnection(); + if( $connection === false ) { + return false; + } else { + return $connection->getTableInformationHashByName( $tableName ); + } + } + /** + * 指定の名称のテーブルが存在するか確認します + */ + function existsTable( $tableName ) { + $connection = $this->_getProperConnection(); + if( $connection === false ) { + return false; + } else { + return $connection->_existsTable( $tableName ); + } + } + /** + * 指定の名称のデータベースが存在するか確認します + */ + function existsDatabase( $databaseName ) { + $connection = $this->_getProperConnection(); + if( $connection === false ) { + return false; + } else { + return $connection->_existsDatabase( $databaseName ); + } + } + /** + * SQLファイルからSQL文を配列で取得します + */ + function getQueryArrayFromFile( $file_path ) { + if( $str = db_Connection::getQuerysStringsFromFile( $file_path ) ) { + return db_Connection::explodeQuerysStrings( $str ); + } + return false; + } + /** + * SQL記述ファイルの内容からコメントを除去して文字列として返します + */ + function getQuerysStringsFromFile( $file_path ) { + if( file_exists($file_path) ) { + $strings = file_get_contents( $file_path ); + if( 'UTF-8' != mb_detect_encoding($strings) ) { + $strings = mb_convert_encoding( $strings, 'UTF-8', 'auto' ); + } + $strings = str_replace("\r\n","\n", $strings ); + $strings = str_replace("\r","\n", $strings ); + $lines = explode("\n",$strings); + $new_lines = array(); + foreach( $lines as $line ) { + if( strlen(trim($line)) > 0 ) { + if( strpos( $line, '--') === false ) { + array_push($new_lines, $line ); + } else { + $line = substr( $line, 0, strpos( $line, '--') ); + if( strlen($line) > 0 ) { + $line .= "\n"; + array_push($new_lines, $line ); + } + } + } + } + return implode( "", $new_lines ); + } + return false; + } + /** + * 複数のSQL文がまとまった文字列を個々のSQL文に分割して返します + */ + function explodeQuerysStrings( $query_string ) { + $query_array = explode( ';', $query_string ); + $new_array = array(); + foreach( $query_array as $key => $value ) { + $value = str_replace("\r\n"," ", $value ); + $value = str_replace("\r"," ", $value ); + $value = str_replace("\n"," ", $value ); + $value = str_replace("\t"," ", $value ); + $value = preg_replace('/[\\s]+/',' ', $value ); + $value = trim( $value ); + if( strlen( $value ) > 0 ) { + array_push( $new_array, $value ); + } + } + return $new_array; + } + /** + * ログを出力します + * @param $message ログメッセージ + */ + function writeLog( $message, $log_level=SPIDER_LOG_LEVEL_INFO ) { + if( !is_null($this->request) ) { + $message = '[database_Connection]'.$message; + $this->request->writeLog($message,$log_level); + } + } + /** + * Fatalレベルのログを出力します。 + * @param $message ログメッセージ + */ + function fatal($message){ + $this->writeLog( $message, SPIDER_LOG_LEVEL_FATAL ); + } + /** + * Errorレベルのログを出力します。 + * @param $message ログメッセージ + */ + function error($message){ + $this->writeLog( $message, SPIDER_LOG_LEVEL_ERROR ); + } + /** + * Warningレベルのログを出力します。 + * @param $message ログメッセージ + */ + function warn($message){ + $this->writeLog( $message, SPIDER_LOG_LEVEL_WARNING ); + } + /** + * Noticeレベルのログを出力します。 + * @param $message ログメッセージ + */ + function notice($message){ + $this->writeLog( $message, SPIDER_LOG_LEVEL_NOTICE ); + } + /** + * Infoレベルのログを出力します。 + * @param $message ログメッセージ + */ + function info($message){ + $this->writeLog( $message, SPIDER_LOG_LEVEL_INFO ); + } + /** + * Debugレベルのログを出力します。 + * @param $message ログメッセージ + */ + function debug($message){ + $this->writeLog( $message, SPIDER_LOG_LEVEL_DEBUG ); + } +} +?> \ No newline at end of file Added: db/current/spider/lib/db/Transaction.class.php =================================================================== --- db/current/spider/lib/db/Transaction.class.php (rev 0) +++ db/current/spider/lib/db/Transaction.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,36 @@ +<?php +require_once( dirname(dirname(__FILE__)) + .DIRECTORY_SEPARATOR.'spider' + .DIRECTORY_SEPARATOR.'ModuleBase.class.php'); +require_once( dirname(__FILE__) + .DIRECTORY_SEPARATOR.'Connection.class.php'); +/** + * spider : データベーストランザクション開始用アクションモジュールクラス + * + * spiderのページから呼び出して実行します。 + * 設定ファイルpackage_define.inc.phpに記述したデータベース接続情報を元に + * database.Connection実装クラスのインスタンスを作成してデータベースに接続し + * リクエスト属性「database.connection」として登録します。 + * + * @package database データベースパッケージ + * @version 2.0.0 + * @author Multimedia Digital Contents Systems.Co.,Ltd. <info****@md-sy*****> + * @since PHP 4.0 + */ +class db_Transaction extends spider_ModuleBase { + function db_Transaction() { + } + function execute( & $request ) { + $dbo = $request->getAttribute( 'dbo' ); + $dbo->beginTransaction(); + } + function post_process( & $request ) { + $dbo = $request->getAttribute( 'dbo' ); + if ( $request->isError() ) { + $dbo->rollback(); + } else { + $dbo->commit(); + } + } +} +?> \ No newline at end of file Added: db/current/spider/lib/db/connection/Mysql.class.php =================================================================== --- db/current/spider/lib/db/connection/Mysql.class.php (rev 0) +++ db/current/spider/lib/db/connection/Mysql.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,452 @@ +<?php +require_once ( dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'AbstractConnection.class.php' ); +/** + * データベース接続オブジェクトクラス - MySQL用 + * + * 抽象クラスdatabase_Connectionの実装クラスです。 + * MySQLに接続して接続情報を保持し、各種インターフェースを提供します。 + * + * @package database データベースパッケージ + * @subpackage connection データベースコネクションパッケージ + * @version 2.0.0 + * @author Multimedia Digital Contents Systems.Co.,Ltd. <info****@md-sy*****> + * @since PHP 4.0 + * @access protected + * @see database_Connection + */ +$GLOBALS['DEF_DATABASE2_CONNECTION_MYSQL_ENCODINGS'] = array( + 'sjis' => 'SJIS-win', + 'ujis' => 'EUC-JP', + 'utf8' => 'UTF-8', + 'cp932' => 'SJIS-win', + 'ucs2' => 'UCS-2', + 'eucjpms' => 'EUC-JP', +); +class db_connection_Mysql extends db_AbstractConnection { + + /** + * コンストラクタ + * + * database_Connectionクラスのget_instanceメソッドでインスタンスを生成して利用します。 + * 本メソッドで直接インスタンスを生成して利用しないでください。 + * @access protected + */ + function db_connection_Mysql() { + } + /** + * データベースに接続します + * @return boolean + * @access public + */ + function _connect( $databaseName, $databaseUser, $databasePass, $host=null, $port=null, $dbencoding='auto' ) { + if( is_null( $host ) || strlen(trim($host)) == 0 ) { + $host = 'localhost'; + } + if( is_null($port) || strlen(trim($port)) == 0 ) { + $port = '3306'; + } + if( !function_exists('mysql_connect') ) { + $error = 'データベースに接続できませんでした。mysql_connect関数が定義されていません。'; + $this->error($error); + return false; + } else { + // @ホスト名を削除 + if( strpos($databaseUser,'@') !== false ) { + $databaseUser = substr($databaseUser,0,strpos($databaseUser,'@')); + } + if( $this->resource_id = @mysql_connect($host.':'.$port, $databaseUser, $databasePass) ) { + if( strlen($databaseName) > 0 ) { + if( @mysql_select_db( $databaseName, $this->resource_id ) ) { + if( $dbencoding == 'auto' ) { + $this->db_encoding = $this->_selectDatabaseEncoding($databaseName); + } else if( strlen($dbencoding) > 0 ) { + $this->db_encoding = $dbencoding; + } + $sql = 'set names \'utf8\''; + if( false === $this->_query($sql) ) { + $this->error('接続は成功しましたがデータベースクライアント文字セット変更に失敗しました '.mysql_error($this->resource_id)); + return false; + } + return true; + } else { + $this->error('データベースに接続できませんでした '.mysql_error($this->resource_id)); + return false; + } + } else { + return false; + } + } else { + $error = 'データベースサーバに接続できませんでした '; + $this->error($error); + return false; + } + } + } + /** + * データベースから切断します + * @param boolean $force + * @return + * @access public + */ + function _disconnect() { + if( $this->resouce_id ) { + return @mysql_close( $this->resource_id ); + } + return false; + } + /** + * 文字列をquoteします + * @param string $value 文字列 + * @param string $type カラム型 + * @param boolean $quote quoteする場合はtrue、しない場合はfalse + * @param boolean $escape_wildcards ワイルドカードをquoteする場合はtrue、しない場合はfalse + * @return string quoteした文字列 + * @access public + */ + function _quote( $value, $type = null, $quote = true, $escape_wildcards = false ) { + if( is_null($value) || strlen($value) == 0 ) { + return 'NULL'; + } else { +// if( $this->db_encoding && $this->db_encoding != $this->encoding ) { +// $value = mb_convert_encoding( $value, $this->db_encoding, $this->encoding ); +// } + $value = mysql_real_escape_string($value,$this->resource_id); + if( $escape_wildcards ) { + $value = str_replace('%','\\%',$value); + $value = str_replace('_','\\_',$value); + } + if( $quote ) { + $value = "'".$value."'"; + } + return $value; + } + } + /** + * Transactionを開始します + * @param string $savepoint savepoint名 + * @return + * @access public + */ + function _beginTransaction($savepoint = null){ + if ($this->in_transaction) { + return true; + } + $result =& $this->_query('BEGIN'); + $this->in_transaction = true; + return true; + } + + /** + * トランザクションをコミットします + * @param string $savepoint savepoint名 + * @return + * @access public + */ + function _commit( $savepoint = null ) { + $result =& $this->_query('COMMIT'); + $this->in_transaction = false; + return true; + } + /** + * トランザクションをロールバックします + * @param string $savepoint savepoint名 + * @return + * @access public + */ + function _rollback( $savepoint = null ) { + $result =& $this->_query('ROLLBACK'); + $this->in_transaction = false; + return true; + } + /** + * 渡されたSQLクエリ文を実行します + * @param string $query SQLクエリ + * @return + * @access public + */ + function _query( $query ) { + $result = @mysql_query($query); + if( false === $result ) { + $this->error( mysql_error($this->resource_id).':' . $query ); + } + return $result; + } + /** + * 渡されたSQLクエリ文を実行して全ての結果を取得します + * @param string $query SQLクエリ + * @param mixed $fetchtype 使用する取得モード。0=ハッシュ, 1=配列, AbstractDataの拡張クラス=オブジェクト配列 + * @return mixed 入れ子状の配列、あるいは失敗した場合にMDB_Errorを返します。 + * @access public + */ + function _queryAll( $query, $fetchtype=null, $setOrg=true ) { + if( preg_match('/^[sS][eE][lL][eE][cC][tT]/',trim($query)) > 0 + || preg_match('/^[sS][hH][oO][wW]/',trim($query)) > 0 ) { + // limitの設定 + if( preg_match('/^[0-9]+$/',$this->limit ) > 0 ) { + // offset + if( preg_match('/^[0-9]+$/',$this->offset ) == 0 ) { + $this->offset = '0'; + } + $query .= ' LIMIT ' .$this->offset . ' ,' . $this->limit; + } + } else { + $this->error_message .= 'queryAllはSELECT文でしか利用できません。'; + $this->error($this->error_message. ' : ' . $query); + return false; + } + $result = $this->_query( $query ); + if( false === $result ) { + $this->error(mysql_error($this->resource_id).':'.$query); + return false; + } else { + $this->limit = null; + $this->offset = null; + if( is_object( $fetchtype ) && ( is_a( $fetchtype, 'db_AbstractData' ) || is_a( $fetchtype, 'db_AbstractUser' ) ) ) { + // Daoオブジェクトが指定されていた場合 + $className = get_class( $fetchtype ); + $objectArray = array(); + while ($row = mysql_fetch_assoc($result)) { +// if( $this->db_encoding && $this->db_encoding != $this->encoding ) { +// mb_convert_variables($this->encoding,$this->db_encoding,$row); +// } + $object = new $className; + $this->_setRowToFields( $row, $object, $setOrg ); + array_push( $objectArray, $object ); + } + mysql_free_result( $result ); + return $objectArray; + } else if( 1 == $fetchtype ) { + // 配列で取得 + $rows = array(); + while ($row = mysql_fetch_row($result)) { +// if( $this->db_encoding && $this->db_encoding != $this->encoding ) { +// mb_convert_variables($this->encoding,$this->db_encoding,$row); +// } + array_push( $rows, $row ); + } + mysql_free_result( $result ); + return $rows; + } else { + // デフォルトはハッシュで取得 + $rows = array(); + while ($row = mysql_fetch_assoc($result)) { +// if( $this->db_encoding && $this->db_encoding != $this->encoding ) { +// mb_convert_variables($this->encoding,$this->db_encoding,$row); +// } + array_push( $rows, $row ); + } + mysql_free_result( $result ); + return $rows; + } + } + } + /** + * 渡されたSQLクエリ文を実行して1レコードのみ結果を取得します + * @param string $query SQLクエリ + * @param array $types 指定した場合は、結果セットのカラムの型が取得したものに設定されます。 + * @param integer $fetchmode 使用する取得モード。 + * @return + * @access public + */ + function _queryRow( $query, $fetchtype=null, $setOrg=true ) { + $result = $this->_query( $query ); + if( false === $result ) { + $this->error(mysql_error($this->resource_id).':'.$query); + return false; + } else { + $count = mysql_num_rows( $result ); + if( -1 == $count ) { + $this->error(mysql_error($this->resource_id).':'.$query); + return false; + } else if( 0 == $count ){ + $this->error('該当するデータが存在しませんでした:'.$query); + return false; + } else if( 1 == $count ){ + $row = null; + if( is_object( $fetchtype ) && ( is_a( $fetchtype, 'db_AbstractData' ) || is_a( $fetchtype, 'db_AbstractUser' ) ) ) { + $row = mysql_fetch_assoc($result); +// if( $this->db_encoding && $this->db_encoding != $this->encoding ) { +// mb_convert_variables($this->encoding,$this->db_encoding,$row); +// } + // Daoオブジェクトが指定されていた場合 + $className = get_class( $fetchtype ); + $object = new $className; + $this->_setRowToFields( $row, $object, $setOrg ); + return $object; + } else if( 1 == $fetchtype ) { + // 配列で取得 + $row = mysql_fetch_row($result); +// if( $this->db_encoding && $this->db_encoding != $this->encoding ) { +// mb_convert_variables($this->encoding,$this->db_encoding,$row); +// } + mysql_free_result( $result ); + return $row; + } else { + // デフォルトはハッシュで取得 + $row = mysql_fetch_assoc($result); +// if( $this->db_encoding && $this->db_encoding != $this->encoding ) { +// mb_convert_variables($this->encoding,$this->db_encoding,$row); +// } + mysql_free_result( $result ); + return $row; + } + } else { + $this->error('該当するデータを一意に絞り込めませんでした:'.$query); + return false; + } + } + } + /** + * 渡されたSQLクエリ文を実行して1カラム分のみ結果を取得します + * @param string $query SQLクエリ + * @return + * @access public + */ + function _queryOne( $query ) { + $result = $this->_query( $query ); + if( false === $result ) { + $this->error(mysql_error($this->resource_id).':'.$query); + return false; + } else { + if( mysql_num_rows($result) > 0 && mysql_num_fields($result) > 0 ) { + // 結果が一つ以上あるなら + $str = mysql_result( $result, 0, 0 ); +// if( $this->db_encoding != $this->encoding ) { +// $str = mb_convert_encoding( $str, $this->encoding, $this->db_encoding ); +// } + mysql_free_result( $result ); + return $str; + } else { +// $this->error('該当するデータが存在しませんでした:'.$query); +// mysql_free_result( $result ); +// return false; + return ''; + } + } + } + /** + * テーブル名称を指定して該当するテーブル情報ハッシュを取得します。 + * 【テーブル情報ハッシュの構造】 + * array( [フィールド名] => [フィールド詳細情報ハッシュ] ) + * + * 【フィールド詳細情報ハッシュの構造】 + * array( + * 'type' => 'int/char/varchar/text...', + * 'size' => 数値 + * 'not_null' => true/false + * 'key' => 'primary/unique' + * 'is_serial' => true/false + * 'has_default' => true/false + * ) + */ + function _getTableInformationHashByName( $tableName ) { + if( strlen(trim($tableName)) == 0 ) { + return false; + } + $sql = 'SHOW FIELDS FROM ' . $tableName; + $result = $this->_queryAll( $sql, null, 'hash' ); + if ( $result === false ) { + $this->error('データベーステーブル情報の取得に失敗しました。:'.mysql_error($this->resource_id).':'.$sql); + return false; + } else { + $this->debug( '[EXECUTED SELECT] ' . $sql ); + // フィールド一覧を取得できたら + $fieldHash = array(); + foreach( $result as $row ) { + $fieldName = $row['Field']; + $type = substr($row['Type'],0,strpos($row['Type'],'(')); + $size = substr($row['Type'],strpos($row['Type'],'('),strpos($row['Type'],')')); + $notNull = false; + if( preg_match('/[yY][eE][sS]/',$row['Null']) > 0 ) { + $notNull = true; + } + $key = ''; + if( preg_match('/[pP][rR][iI]/',$row['Key']) > 0 ) { + $key = 'primary'; + } else if( preg_match('/[uU][nN][iI]/',$row['Key']) > 0 ) { + $key = 'unique'; + } + $isSerial = false; + if( preg_match('/[aA][uU][tT][oO]\\_[iI][nN][cC][rR][eE][mM][eE][nN][tT]/',$row['Extra']) > 0 ) { + $isSerial = true; + } + $hasDefault = false; + if(strlen(trim($row['Default'])) > 0 && $row['Default'] != NULL ) { + $hasDefault = true; + } + $fieldHash[$fieldName] = array( + 'type' => $type, + 'size' => $size, + 'not_null' => $notNull, + 'key' => $key, + 'is_serial' => $isSerial, + 'has_default' => $hasDefault + ); + } + return $fieldHash; + } + } + /** + * テーブル存在確認メソッド + */ + function _existsTable( $tableName ) { + $sql = 'SHOW TABLES'; + $result = $this->_queryALL( $sql, null, 'hash' ); + if( false === $result || $result == 0 ) { + $this->error('データベーステーブル情報の取得に失敗しました。:'.mysql_error($this->resource_id).':'.$sql); + return false; + } else { + $this->debug( '[EXECUTED SELECT] ' . $sql ); + foreach( $result as $row ) { + foreach( $row as $col ) { + if( $col == $tableName ) { + return true; + } + } + } + return false; + } + } + /** + * データベース存在確認メソッド + */ + function _existsDatabase( $databaseName ) { + $sql = 'SHOW DATABASES'; + $result = $this->_queryALL( $sql, null, 'hash' ); + if( false === $result || $result == 0 ) { + $this->error('データベース情報の取得に失敗しました。:'.mysql_error($this->resource_id).':'.$sql); + return false; + } else { + $this->debug( '[EXECUTED SELECT] ' . $sql ); + foreach( $result as $row ) { + foreach( $row as $col ) { + if( $col == $databaseName ) { + return true; + } + } + } + return false; + } + } + /** + * 指定データベースのエンコード設定を取得します。 + */ + function _selectDatabaseEncoding($databaseName) { + $sql = 'show create database '.$databaseName; + $result = $this->_queryRow( $sql ); + if( false === $result || $result == 0 ) { + $this->error('データベース文字コードの確認に失敗しました。:'.mysql_error($this->resource_id).':'.$sql); + return false; + } else { + $str = $result['Create Database']; + $str = preg_replace('/(.)+\\s[cC][hH][aA][rR][aA][cC][tT][eE][rR]\\s[sS][eE][tT]\\s/','',$str); + $str = trim(preg_replace('/\\s\\*\\//','',$str)); + $this->debug( '[EXECUTED SELECT] ' . $sql ); + if( isset($GLOBALS['DEF_DATABASE2_CONNECTION_MYSQL_ENCODINGS'][$str]) ) { + return $GLOBALS['DEF_DATABASE2_CONNECTION_MYSQL_ENCODINGS'][$str]; + } + return $str; + } + } +} +?> \ No newline at end of file Added: db/current/spider/lib/db/connection/Pgsql.class.php =================================================================== --- db/current/spider/lib/db/connection/Pgsql.class.php (rev 0) +++ db/current/spider/lib/db/connection/Pgsql.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,445 @@ +<?php +require_once ( dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'AbstractConnection.class.php' ); +$GLOBALS['DEF_DATABASE2_CONNECTION_PG_ENCODINGS'] = array( + 'EUC_JP' => 'EUC-JP', + 'SJIS' => 'SJIS-win', + 'UTF8' => 'UTF-8', +); +/** + * データベース接続オブジェクトクラス - PostgreSQL用 + * + * 抽象クラスdatabase_Connectionの実装クラスです。 + * MySQLに接続して接続情報を保持し、各種インターフェースを提供します。 + * + * @package database データベースパッケージ + * @subpackage connection データベースコネクションパッケージ + * @version 2.0.0 + * @author Multimedia Digital Contents Systems.Co.,Ltd. <info****@md-sy*****> + * @since PHP 4.0 + * @access protected + * @see database_Connection + */ +class db_connection_Pgsql extends db_AbstractConnection { + + /** + * コンストラクタ + * + * database_Connectionクラスのget_instanceメソッドでインスタンスを生成して利用します。 + * 本メソッドで直接インスタンスを生成して利用しないでください。 + * @access protected + */ + function db_connection_Pgsql() { + } + /** + * データベースに接続します + * @return boolean + * @access public + */ + function _connect( $databaseName, $databaseUser, $databasePass, $host=null, $port=null, $dbencoding='auto' ) { + if( is_null( $host ) || strlen(trim($host)) == 0 ) { + $host = 'localhost'; + } + if( is_null($port) || strlen(trim($port)) == 0 ) { + $port = '5432'; + } + $connect_strings = 'host='.$host + . ' port=' .$port + . ' dbname=' . $databaseName + . ' user=' . $databaseUser + . ' password=' . $databasePass + ; + if( !function_exists('pg_connect') ) { + $error = 'データベースに接続できませんでした。pg_connect関数が定義されていません。'; + $this->error($error); + return false; + } else { + if( $this->resource_id = @pg_connect($connect_strings) ) { + if( $dbencoding == 'auto' ) { + $this->db_encoding = $this->_selectDatabaseEncoding($databaseName); + } else if( strlen($dbencoding) > 0 ) { + $this->db_encoding = $dbencoding; + } + return true; + } else { + $error = 'データベースに接続できませんでした '; + $this->error($error); + return false; + } + } + } + /** + * データベースから切断します + * @param boolean $force + * @return + * @access public + */ + function _disconnect() { + if( $this->resource_id ) { + return @pg_close( $this->resource_id ); + } + return false; + } + /** + * 文字列をquoteします + * @param string $value 文字列 + * @param string $type カラム型 + * @param boolean $quote quoteする場合はtrue、しない場合はfalse + * @param boolean $escape_wildcards ワイルドカードをquoteする場合はtrue、しない場合はfalse + * @return string quoteした文字列 + * @access public + */ + function _quote( $value, $type = null, $quote = true, $escape_wildcards = false ) { + if( is_null($value) || strlen($value) == 0 ) { + return 'NULL'; + } else { + if( $this->db_encoding && $this->db_encoding != $this->encoding ) { + $value = mb_convert_encoding( $value, $this->db_encoding, $this->encoding ); + } + $value = pg_escape_string($value); + if( $escape_wildcards ) { + $value = str_replace('%','\\%',$value); + $value = str_replace('_','\\_',$value); + } + if( $quote ) { + $value = "'".$value."'"; + } + return $value; + } + } + /** + * Transactionを開始します + * @param string $savepoint savepoint名 + * @return + * @access public + */ + function _beginTransaction($savepoint = null){ + if ($this->in_transaction) { + return true; + } + $result =& $this->_query('BEGIN'); + $this->in_transaction = true; + return true; + } + + /** + * トランザクションをコミットします + * @param string $savepoint savepoint名 + * @return + * @access public + */ + function _commit( $savepoint = null ) { + $result =& $this->_query('COMMIT'); + $this->in_transaction = false; + return true; + } + /** + * トランザクションをロールバックします + * @param string $savepoint savepoint名 + * @return + * @access public + */ + function _rollback( $savepoint = null ) { + $result =& $this->_query('ROLLBACK'); + $this->in_transaction = false; + return true; + } + /** + * 渡されたSQLクエリ文を実行します + * @param string $query SQLクエリ + * @return + * @access public + */ + function _query( $query ) { + $result = @pg_query($query); + if( false === $result ) { + $this->error( pg_last_error($this->resource_id).':' . $query ); + } + return $result; + } + /** + * 渡されたSQLクエリ文を実行して全ての結果を取得します + * @param string $query SQLクエリ + * @param mixed $fetchtype 使用する取得モード。0=ハッシュ, 1=配列, AbstractDataの拡張クラス=オブジェクト配列 + * @return mixed 入れ子状の配列、あるいは失敗した場合にMDB_Errorを返します。 + * @access public + */ + function _queryAll( $query, $fetchtype=null, $setOrg=true ) { + if( preg_match('/^[sS][eE][lL][eE][cC][tT]/',trim($query)) > 0 ) { + // offsetの設定 + if( preg_match('/^[0-9]+$/',$this->offset ) > 0 ) { + $query .= ' OFFSET ' . $this->offset; + } + // limitの設定 + if( preg_match('/^[0-9]+$/',$this->limit ) > 0 ) { + $query .= ' LIMIT ' . $this->limit; + } + } else { + $this->error('queryAllはSELECT文でしか利用できません。:' . $query); + return false; + } + $result = $this->_query( $query ); + if( false === $result ) { + $this->error(pg_last_error($this->resource_id).':'.$query); + return false; + } else { + $this->limit = null; + $this->offset = null; + if( is_object( $fetchtype ) && ( is_a( $fetchtype, 'db_AbstractData' ) || is_a( $fetchtype, 'db_AbstractUser' ) ) ) { + // Daoオブジェクトが指定されていた場合 + $className = get_class( $fetchtype ); + $objectArray = array(); + while ($row = pg_fetch_assoc($result)) { + if( $this->db_encoding && $this->db_encoding != $this->encoding ) { + mb_convert_variables($this->encoding,$this->db_encoding,$row); + } + $object = new $className; + $this->_setRowToFields( $row, $object, $setOrg ); + array_push( $objectArray, $object ); + } + pg_free_result( $result ); + return $objectArray; + } else if( 1 == $fetchtype ) { + // 配列で取得 + $rows = array(); + while ($row = pg_fetch_row($result)) { + if( $this->db_encoding && $this->db_encoding != $this->encoding ) { + mb_convert_variables($this->encoding,$this->db_encoding,$row); + } + array_push( $rows, $row ); + } + pg_free_result( $result ); + return $rows; + } else { + // デフォルトはハッシュで取得 + $rows = array(); + while ($row = pg_fetch_assoc($result)) { + if( $this->db_encoding && $this->db_encoding != $this->encoding ) { + mb_convert_variables($this->encoding,$this->db_encoding,$row); + } + array_push( $rows, $row ); + } + pg_free_result( $result ); + return $rows; + } + } + } + /** + * 渡されたSQLクエリ文を実行して1レコードのみ結果を取得します + * レコードがなかった場合または、1レコードに絞り込めなかった場合はfalseを返します + * @param string $query SQLクエリ + * @param mixed $fetchtype 使用する取得モード。0=ハッシュ, 1=配列, AbstractDataの拡張クラス=オブジェクト + * @return + * @access public + */ + function _queryRow( $query, $fetchtype=null, $setOrg=true ) { + $result = $this->_query( $query ); + if( false === $result ) { + $this->error(pg_last_error($this->resource_id).':'.$query); + return false; + } else { + $count = pg_num_rows( $result ); + if( -1 == $count ) { + $this->error(pg_last_error($this->resource_id).':'.$query); + return false; + } else if( 0 == $count ){ + $this->error('該当するデータが存在しませんでした:'.$query); + return false; + } else if( 1 == $count ){ + $row = null; + if( is_object( $fetchtype ) && ( is_a( $fetchtype, 'db_AbstractData' ) || is_a( $fetchtype, 'db_AbstractUser' ) ) ) { + $row = pg_fetch_assoc($result); + if( $this->db_encoding && $this->db_encoding != $this->encoding ) { + mb_convert_variables($this->encoding,$this->db_encoding,$row); + } + // Daoオブジェクトが指定されていた場合 + $className = get_class( $fetchtype ); + $object = new $className; + $this->_setRowToFields( $row, $object, $setOrg ); + return $object; + } else if( 1 == $fetchtype ) { + // 配列で取得 + $row = pg_fetch_row($result); + if( $this->db_encoding && $this->db_encoding != $this->encoding ) { + mb_convert_variables($this->encoding,$this->db_encoding,$row); + } + pg_free_result( $result ); + return $row; + } else { + // デフォルトはハッシュで取得 + $row = pg_fetch_assoc($result); + if( $this->db_encoding && $this->db_encoding != $this->encoding ) { + mb_convert_variables($this->encoding,$this->db_encoding,$row); + } + pg_free_result( $result ); + return $row; + } + } else { + $this->error('該当するデータを一意に絞り込めませんでした:'.$query); + return false; + } + } + } + /** + * 渡されたSQLクエリ文を実行して1カラム分のみ結果を取得します + * @param string $query SQLクエリ + * @return + * @access public + */ + function _queryOne( $query ) { + $result = $this->_query( $query ); + if( false === $result ) { + $this->error(pg_last_error($this->resource_id).':'.$query); + return false; + } else { + if( pg_num_rows($result) > 0 && pg_num_fields($result) > 0 ) { + // 結果が一つ以上あるなら + $str = pg_fetch_result( $result, 0, 0 ); + if( $this->db_encoding && $this->db_encoding != $this->encoding ) { + $str = mb_convert_encoding( $str, $this->encoding, $this->db_encoding ); + } + pg_free_result( $result ); + return $str; + } else { +// $this->error('該当するデータが存在しませんでした:'.$query); +// pg_free_result( $result ); +// return false; + return ''; + } + } + } + /** + * テーブル名称を指定して該当するテーブル情報ハッシュを取得します。 + * 【テーブル情報ハッシュの構造】 + * array( [フィールド名] => [フィールド詳細情報ハッシュ] ) + * + * 【フィールド詳細情報ハッシュの構造】 + * array( + * 'type' => 'int/char/varchar/text...', + * 'size' => 数値 + * 'not_null' => true/false + * 'key' => 'primary/unique' + * 'is_serial' => true/false + * 'has_default' => true/false + * ) + */ + function _getTableInformationHashByName( $tableName ) { + $sql = 'SELECT ' + .'pg_attribute.attname AS field_name, ' + .'CASE ' + .'WHEN pg_type.typname LIKE \'int%\' THEN \'int\' ' + .'WHEN pg_type.typname LIKE \'bpchar%\' THEN \'char\' ' + .'ELSE pg_type.typname ' + .'END AS type, ' + .'pg_attribute.attlen AS size, ' + .'pg_attribute.attnotNULL AS not_null, ' + .'CASE ' + .'WHEN pg_constraint.contype=\'p\' THEN \'primary\' ' + .'WHEN pg_constraint.contype=\'u\' THEN \'unique\' ' + .'ELSE null ' + .'END AS key, ' + .'CASE ' + .'WHEN pg_attrdef.adsrc LIKE \'%\' || pg_attribute.attname || \'%\' THEN \'t\' ' + .'ELSE \'f\' ' + .'END AS is_serial, ' + .'pg_attribute.atthasdef AS has_default ' + .'FROM pg_attribute ' + .'INNER JOIN pg_type ON pg_type.oid=pg_attribute.atttypid ' + .'INNER JOIN pg_class ON pg_class.oid=pg_attribute.attrelid ' + .'LEFT OUTER JOIN pg_attrdef ON pg_attrdef.adrelid=pg_class.oid AND pg_attrdef.adsrc LIKE \'nextval%\' ' + .'LEFT OUTER JOIN pg_indexes ON pg_indexes.indexdef LIKE \'CREATE UNIQUE INDEX%\' AND pg_indexes.indexname LIKE '.$this->_quote('%'.$tableName.'\_').' || pg_attribute.attname || \'%\' AND pg_indexes.tablename='.$this->_quote($tableName).' ' + .'LEFT OUTER JOIN pg_constraint ON pg_constraint.conname=pg_indexes.indexname ' + .'WHERE ' + .'pg_class.relname='.$this->_quote($tableName).' ' + .'AND ' + .'pg_attribute.attnum>0 ' + ; + $result = $this->_queryAll( $sql, null, 'hash' ); + if( $result === false ) { + $this->error('データベーステーブル情報の取得に失敗しました。:'.pg_last_error($this->resource_id).':'.$sql); + return false; + } else { + $this->debug( '[EXECUTED SELECT] ' . $sql ); + $fieldHash = array(); + foreach( $result as $row ) { + $fieldName = $row['field_name']; + if( preg_match('/^[tT](|[rR][uU][eE])$/',trim($row['not_null'])) > 0 ) { + $row['not_null'] = true; + } else { + $row['not_null'] = false; + } + if( preg_match('/^[tT](|[rR][uU][eE])$/',trim($row['is_serial'])) > 0 ) { + $row['is_serial'] = true; + } else { + $row['is_serial'] = false; + } + if( preg_match('/^[tT](|[rR][uU][eE])$/',trim($row['has_default'])) > 0 ) { + $row['has_default'] = true; + } else { + $row['has_default'] = false; + } + $fieldHash[$fieldName] = $row; + } + return $fieldHash; + } + } + /** + * テーブル存在確認メソッド + */ + function _existsTable( $tableName ) { + $sql = 'SELECT COUNT(*) FROM pg_tables WHERE tablename='.$this->_quote($tableName); + $result = $this->_queryOne( $sql ); + if( false === $result || $result == 0 ) { + $this->error('テーブル存在確認に失敗しました。:'.pg_last_error($this->resource_id).':'.$sql); + return false; + } else { + $this->debug( '[EXECUTED SELECT] ' . $sql ); + return true; + } + } + /** + * データベース存在確認メソッド + */ + function _existsDatabase( $databaseName ) { + $sql = 'SELECT COUNT(*) FROM pg_database WHERE datname='.$this->_quote($databaseName); + $result = $this->_queryOne( $sql ); + if( false === $result || $result == 0 ) { + $this->error('データベース存在確認に失敗しました。:'.pg_last_error($this->resource_id).':'.$sql); + return false; + } else { + $this->debug( '[EXECUTED SELECT] ' . $sql ); + return true; + } + } + /** + * 指定データベースのエンコード設定を取得します。 + */ + function _selectDatabaseEncoding($databaseName) { + $sql = 'SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname='.$this->_quote($databaseName); + $result = $this->_queryOne( $sql ); + if( false === $result || strlen($result) == 0 ) { + $this->error('データベース文字コードの確認に失敗しました。:'.pg_last_error($this->resource_id).':'.$sql); + return false; + } else { + $this->debug( '[EXECUTED SELECT] ' . $sql ); + if( isset($GLOBALS['DEF_DATABASE2_CONNECTION_PG_ENCODINGS'][$result]) ) { + return $GLOBALS['DEF_DATABASE2_CONNECTION_PG_ENCODINGS'][$result]; + } + return $result; + } + } + /** + * 対象テーブルのバキューム処理を行います + * postgres固有 + */ + function _pgVacuumTable( $tableName ) { + $sql = 'VACUUM ANALYZE '. $tableName; + $result = $this->_query( $sql ); + if( $result !== false ) { + return true; + } else { + $this->error('データベース存在確認に失敗しました。:'.pg_last_error($this->resource_id).':'.$sql); + return false; + } + } +} +?> \ No newline at end of file Added: db/current/spider/lib/db/define.inc.php =================================================================== --- db/current/spider/lib/db/define.inc.php (rev 0) +++ db/current/spider/lib/db/define.inc.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,47 @@ +<?php +/** + * databaseパッケージ用設定定義ファイル + * + * @package database データベースパッケージ + * @version 2.0.0 + * @author Multimedia Digital Contents Systems.Co.,Ltd. <info****@md-sy*****> + * @since PHP 4.0 + */ + +/** デフォルト DBタイプ mysql / pgsql */ +if( !defined('DATABASE_TYPE') ) { + define ( 'DATABASE_TYPE', 'mysql' ); +} +/** デフォルト DB名 */ +if( !defined('DATABASE_NAME') ) { + define ( 'DATABASE_NAME', 'mdsm' ); +} +/** デフォルト DBユーザー */ +if( !defined('DATABASE_USER') ) { + define ( 'DATABASE_USER', 'mdsm' ); +} +/** デフォルト DBパスワード */ +if( !defined('DATABASE_PASS') ) { + define ( 'DATABASE_PASS', 'mdsm' ); +} +/** デフォルト データベース内部文字コード */ +if( !defined('DATABASE_CHARSET') ) { + define ( 'DATABASE_CHARSET', 'UTF-8' ); +} +/** デフォルト DBホスト */ +if( !defined('DATABASE_HOST') ) { + define ( 'DATABASE_HOST', 'localhost' ); +} +/** デフォルト DBポート */ +if( !defined('DATABASE_PORT') ) { + define ( 'DATABASE_PORT', '3306' ); +} +/** デフォルト データベース権限ユーザ */ +if( !defined('DATABASE_MASTER_USER') ) { + define ( 'DATABASE_MASTER_USER', 'root' ); +} +/** デフォルト データベース権限パスワード */ +if( !defined('DATABASE_MASTER_PASSWORD') ) { + define ( 'DATABASE_MASTER_PASSWORD', 'admin'); +} +?> \ No newline at end of file Added: db/current/spider/lib/example/Hello.class.php =================================================================== --- db/current/spider/lib/example/Hello.class.php (rev 0) +++ db/current/spider/lib/example/Hello.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,41 @@ +<?php +/* + * you make module extends ModuleBase like this. + * see 'lib/spider/ModuleBase.class.php'. + */ +require_once(dirname(dirname(__FILE__)) + .DIRECTORY_SEPARATOR.'spider' + .DIRECTORY_SEPARATOR.'ModuleBase.class.php'); +class example_Hello extends spider_ModuleBase { + /** + * Constractor + * + */ + function example_Hello() { + // if you need, you write unique process here. + } + /** + * execute method + * you need override this method for your application! + * @param object spider_HttpRequest + * @see lib/spider/HttpRequest.class.php + */ + function execute( & $request ) { + // set message example + $message = 'Hello Spider! This is Module Test!'; + $request->setAttribute('message', $message ); + // set array example + $message_array = array('you','can','make','web site'); + $request->setAttribute('message_array', $message_array ); + // set hash example + $message_hash = array( 'first_name' => 'Masanori', 'family_name' => 'Nakashima'); + $request->setAttribute('message_hash', $message_hash ); + // set 2D hash example + $person_hash = array( + 'Masanori Nakashima' => array( 'sex' => 'male', 'country'=>'Japan', 'prefecture' => 'Saitama'), + 'Takeshi Kato' => array( 'sex' => 'male', 'country'=>'Japan', 'prefecture' => 'Tokyo'), + ); + $request->setAttribute('person_hash', $person_hash ); + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/BuildInformation.class.php =================================================================== --- db/current/spider/lib/spider/BuildInformation.class.php (rev 0) +++ db/current/spider/lib/spider/BuildInformation.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,253 @@ +<?php +require_once(dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'util'.DIRECTORY_SEPARATOR.'CharUtility.class.php'); +/** + * ビルドファイルを作成する情報を保持するデータオブジェクトクラス + * + * @package spider spiderのコアパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class spider_BuildInformation { + /** 実行ファイルパス */ + var $execute_file_path; + /** リクエストページのURI */ + var $page_uri; + /** ユーザーエージェント分類 */ + var $agent_class = null; + /** 実行モジュール名配列 */ + var $module_exec_info_hash = array(); + /** ホットビルド機能:タイムスタンプ比較ファイル配列 */ + var $compare_time_file_array = array(); + /** ホットビルド機能:ファイル存在確認ファイル配列 */ + var $confirm_exists_file_array = array(); + /** 処理開始前実行コードハッシュ */ + var $preview_process_hash = array(); + /** 表示後実行コードハッシュ */ + var $postview_process_hash = array(); + /** 表示文字列に対する処理実行コードハッシュ */ + var $convert_view_process_hash = array(); + /** 今後の拡張:出力ハンドラ */ + var $output_handler = 'mb_output_handler'; + /** 今後の拡張:言語 */ + var $output_language = 'Japanese'; + /** 今後の拡張:出力文字セット */ + var $output_charset = 'UTF-8'; + /** 今後の拡張:インターナル文字セット */ + var $internal_charset = 'UTF-8'; + /** 今後の拡張:文字セット判断順序 */ + var $detect_order = 'UTF-8,EUC-JP,SJIS,SJIS-win,JIS,UTF-7'; + /** + * コンストラクタ + */ + function spider_BuildInformation() { + $this->execute_file_path = $_SERVER['SCRIPT_FILENAME']; + $this->getAgentClass(); + $this->_pickout_premodules(); + } + /** + * ユーザーエージェント分類を取得します + */ + function getAgentClass() { + if( !is_null($this->agent_class) ) { + return $this->agent_class; + } + $this->agent_class = 'default'; + foreach( $GLOBALS['SPIDER_USER_AGENT_CLASS_REGX_HASH'] as $regx_str => $agent_class ) { + if( preg_match( $regx_str, $_SERVER['HTTP_USER_AGENT'] ) > 0 ) { + $this->agent_class = $agent_class; + break; + } + } + return $this->agent_class; + } + /** + * 対象ページのエージェント別URIを取得します + */ + function getAgentPageUri( $directory_separator=DIRECTORY_SEPARATOR ) { + return $this->agent_class.$this->getPageUri($directory_separator); + } + /** + * 実行ファイルのページURIを取得します + */ + function getPageUri( $directory_separator=DIRECTORY_SEPARATOR ) { + if( is_null($this->page_uri) ) { + $base_uri = APPLICATION_BASE_URI; + if( !preg_match( '/\\/$/', $base_uri ) ) { + $base_uri = APPLICATION_BASE_URI.'/'; + } + $request_uri = $_SERVER['PHP_SELF']; + if( preg_match( '/\\?/', $request_uri ) ) { + list( $request_uri, $params ) = explode('?',$request_uri); + } + if( preg_match( '/\\/$/', $request_uri ) ) { + $request_uri .= 'index.php'; + } + $this->page_uri = str_replace( $base_uri, '/', $request_uri ); + } + $page_uri = $this->page_uri; + $page_uri = str_replace('/',$directory_separator,$page_uri); + return $page_uri; + } + /** + * 実行ビルドファイルパスを取得します + */ + function getAgentPageBuildFilePath() { + $virtual_root = APPLICATION_BASE_PATH; + if( preg_match('/^[a-zA-Z]\\:\\\/', APPLICATION_BASE_PATH, $regmatch_array ) ) { + // Windows対策ドライブをディレクトリとして変換 + $drive_name = substr($regmatch_array[0],0,1); + $virtual_root = preg_replace('/^[a-zA-Z]\\:\\\/' + ,$drive_name.DIRECTORY_SEPARATOR,$virtual_root ); + } else { + $virtual_root = substr($virtual_root,1); + } + // 2009-12-16 実行ファイル作成パスをspiderの上層ディレクトリ起点とする + if( !defined('SPIDER_USE_ABSOLUTE_BIN_PATH') || SPIDER_USE_ABSOLUTE_BIN_PATH === false ) { + $cutPath = dirname(DIR_PATH_SPIDER_DATA); + if( preg_match('/^[a-zA-Z]\\:\\\/', APPLICATION_BASE_PATH, $regmatch_array ) > 0 ) { + // Windows対策ドライブをディレクトリとして変換 + $driveName = substr($regmatch_array[0],0,1); + $cutPath = preg_replace('/^[a-zA-Z]\\:\\\/' + ,$driveName.DIRECTORY_SEPARATOR, $cutPath ); + } + $virtual_root = preg_replace('/^'.util_CharUtility::escapeRegxStr($cutPath).'/','',$virtual_root); + } + $bin_file_path = DIR_PATH_BIN + .DIRECTORY_SEPARATOR.$virtual_root + .DIRECTORY_SEPARATOR.str_replace('/','',str_replace(DIRECTORY_SEPARATOR,'',APPLICATION_BASE_URI)) + .DIRECTORY_SEPARATOR.$this->getAgentPageUri(); + $bin_file_path = str_replace(DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR,DIRECTORY_SEPARATOR,$bin_file_path); + if( !is_dir( dirname($bin_file_path) ) ) { + // 上位ディレクトリがないならディレクトリ階層を作成する + $dirname_array = explode(DIRECTORY_SEPARATOR, dirname($bin_file_path) ); + $dir_path = ''; + foreach( $dirname_array as $dir_name ) { + if( strlen($dir_path) > 0 ) { + $dir_path .= DIRECTORY_SEPARATOR.$dir_name; + } else { + if( strlen($dir_name) == 0) { + $dir_path = DIRECTORY_SEPARATOR; + } else { + $dir_path = $dir_name; + } + } + if( strlen($dir_path) > strlen(DIR_PATH_BIN) && !is_dir($dir_path) ) { + if( @mkdir( $dir_path, SPIDER_FOLDER_CREATE_PERMITTION ) ) { + @chmod( $dir_path, SPIDER_FOLDER_CREATE_PERMITTION ); + } else { + header('Content-Type: text/plain;charset=UTF-8'); + die('Core Erorr! Can\'t create build file directoreis! '.$dir_path); + } + } + } + } + return $bin_file_path; + } + /** + * プレモジュール取り出し + */ + function _pickout_premodules() { + // 上位階層から確認してpre_module.inc.phpがあるか確認してモジュール追加 + $target_dir = dirname( $this->execute_file_path ); + $target_dir = str_replace("/",DIRECTORY_SEPARATOR,$target_dir); + $target_dir = str_replace("\\",DIRECTORY_SEPARATOR,$target_dir); + $dir_name_array = explode(DIRECTORY_SEPARATOR,$target_dir ); + $dir_path = ''; + if( preg_match('/^[a-zA-Z]\\:\\\/',$target_dir) ) { + // Windowsなら頭にセパレータをつけないのでそのまま + } else { + // Unix系ならパスはディレクトリセパレータから開始 + $dir_path = DIRECTORY_SEPARATOR; + } + // php.iniのbase_dirで読み込み階層が制限されていた場合の対策 + $spiderBaseDir = dirname(DIR_PATH_SPIDER_DATA); + foreach( $dir_name_array as $dirname ) { + if( strlen($dirname) > 0 ) { + $dir_path .= $dirname.DIRECTORY_SEPARATOR; + // php.iniのbase_dirで読み込み階層が制限されていた場合の対策 + if( strlen($dir_path) >= strlen($spiderBaseDir) ) { + $pre_module_file = $dir_path."pre_module.inc.php"; + if ( file_exists( $pre_module_file ) ) { + $lines = file( $pre_module_file ); + foreach ( $lines as $line ) { + $line = trim( $line ); + $this->addExecModuleByString( $line ); + } + // ホットビルドタイムスタンプ比較ファイルに追加 + array_push( $this->compare_time_file_array, $pre_module_file ); + } + } + } + } + } + /** + * 文字列を指定して実行モジュールハッシュに追加します + */ + function addExecModuleByString( $string ) { + $string = trim( $string ); + if( strlen($string) > 0 ) { + $info_array = explode(' ', $string); + // ひとつめの要素は必ずモジュール名 + $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); + if( preg_match('/^[pP][oO][sS][tT]\\(/',$info) > 0 ) { + // 上書きPOSTパラメータ + $val = preg_replace('/^[pP][oO][sS][tT]\\(/','',$info); + $val = preg_replace('/\\)$/','',$val); + $info_hash['post'] = $val; + } else if( preg_match('/^[gG][eE][tT]\\(/',$info) > 0 ) { + // 上書きGETパラメータ + $val = preg_replace('/^[gG][eE][tT]\\(/','',$info); + $val = preg_replace('/\\)$/','',$val); + $info_hash['get'] = $val; + } else if( preg_match('/^[aA][tT][tT][rR][iI][bB][uU][tT][eE]\\_[pP][rR][eE][fF][iI][xX]\\(/',$info) > 0 ) { + // 上書きGETパラメータ + $val = preg_replace('/^[aA][tT][tT][rR][iI][bB][uU][tT][eE]\\_[pP][rR][eE][fF][iI][xX]\\(/','',$info); + $val = preg_replace('/\\)$/','',$val); + $info_hash['attribute_prefix'] = $val; + } else if( preg_match('/^[tT][rR][uU][eE]|[fF][aA][lL][sS][eE]|[fF][oO][rR][cC][eE]$/',$info) > 0 ) { + // 強制実行かどうか + if( preg_match('/^[tT][rR][uU][eE]|[fF][oO][rR][cC][eE]$/',$info) > 0 ) { + $info_hash['force'] = true; + } else { + $info_hash['force'] = false; + } + } + } + // パラメータが異なる場合にキーを変更してハッシュに登録する。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; + } + } + } + /** + * タイムスタンプ比較ファイルを追加します + */ + function addCompareFile( $file_path ) { + if( strlen( $file_path ) > 0 && file_exists( $file_path ) ) { + array_push( $this->compare_time_file_array, $file_path ); + } + return true; + } + /** + * ビルド前ファイル存在確認ファイルを追加します + */ + function addConfirmFile( $file_path ) { + if( strlen( $file_path ) > 0 && file_exists( $file_path ) ) { + array_push( $this->confirm_exists_file_array, $file_path ); + } + return true; + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/Builder.class.php =================================================================== --- db/current/spider/lib/spider/Builder.class.php (rev 0) +++ db/current/spider/lib/spider/Builder.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,380 @@ +<?php +$GLOBALS['DEF_SPIDER_CHARSET_REPLACE_ENCODINGS'] = array( + 'SJIS-win' => 'Shift_JIS', + 'SJIS' => 'Shift_JIS', + +); +/** + * 実行ファイルを作成します。 + * + * @package spider spiderのコアパッケージ + * @version 1.0.01 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class spider_Builder { + + /** 元の本文文字列 */ + var $org_body_strings; + /** 出力する本文文字列 */ + var $out_body_strings; + + /** + * コンストラクタ + */ + function spider_Builder() { + } + /** + * HTMLボディを生成する + */ + function convertBody( & $build_information_object ) { + $action_lines = file( $build_information_object->execute_file_path ); + $this->out_body_strings = implode( "", $action_lines ); + $this->org_body_strings = $this->out_body_strings; + + // 改行コード統一と連続改行の削除 + $this->out_body_strings = str_replace( "\r\n", "\n", $this->out_body_strings ); + $this->out_body_strings = str_replace( "\r", "\n", $this->out_body_strings ); + $this->out_body_strings = str_replace( "\n\n\n", "\n", $this->out_body_strings ); + $this->out_body_strings = str_replace( "\n\n", "\n", $this->out_body_strings ); + $this->out_body_strings = str_replace( "\n\n", "\n", $this->out_body_strings ); + + // cms.phpインクルード行を削除 + preg_match_all( '/include_once\\([^\\)]*?cms\\.php[^\\)]*?\\)\\;/' + , $this->out_body_strings + , $output_array + , PREG_PATTERN_ORDER ); + foreach ( $output_array as $output ) { + foreach ( $output as $target ) { + // 空行にならないよう前後が改行も削除 + $this->out_body_strings = str_replace( "\n".$target."\n", "", $this->out_body_strings ); + $this->out_body_strings = str_replace( $target, "", $this->out_body_strings ); + } + } + preg_match_all( '/require_once\\([^\\)]*?cms\\.php[^\\)]*?\\)\\;/' + , $this->out_body_strings + , $output_array + , PREG_PATTERN_ORDER ); + foreach ( $output_array as $output ) { + foreach ( $output as $target ) { + // 空行にならないよう前後が改行も削除 + $this->out_body_strings = str_replace( "\n".$target."\n", "", $this->out_body_strings ); + $this->out_body_strings = str_replace( $target, "", $this->out_body_strings ); + } + } + // spider.inc.phpインクルード行を削除 + preg_match_all( '/include_once\\([^\\)]*?spider\\.inc\\.php[^\\)]*?\\)\\;/' + , $this->out_body_strings + , $output_array + , PREG_PATTERN_ORDER ); + foreach ( $output_array as $output ) { + foreach ( $output as $target ) { + // 空行にならないよう前後が改行も削除 + $this->out_body_strings = str_replace( "\n".$target."\n", "", $this->out_body_strings ); + $this->out_body_strings = str_replace( $target, "", $this->out_body_strings ); + } + } + preg_match_all( '/require_once\\([^\\)]*?spider\\.inc\\.php[^\\)]*?\\)\\;/' + , $this->out_body_strings + , $output_array + , PREG_PATTERN_ORDER ); + foreach ( $output_array as $output ) { + foreach ( $output as $target ) { + // 空行にならないよう前後が改行も削除 + $this->out_body_strings = str_replace( "\n".$target."\n", "", $this->out_body_strings ); + $this->out_body_strings = str_replace( $target, "", $this->out_body_strings ); + } + } + + // 空PHP部分を削除 + $this->out_body_strings = preg_replace('/<\\?php[\\s]*\\?>\\n/','',$this->out_body_strings); + $this->out_body_strings = preg_replace('/<\\?php[\\s]*\\?>/','',$this->out_body_strings); + + // フォルダデフォルトファイルの適用 + $folder_default_path = null; + $folder_path = dirname($build_information_object->execute_file_path); + // 存在しなかった場合の存在確認比較ファイルパス + $confirm_default_path_array = array(); + while( strlen($folder_path) >= strlen(APPLICATION_BASE_PATH) ) { + $folder_default_path = $folder_path.DIRECTORY_SEPARATOR.'.default'; + if( file_exists( $folder_default_path ) ) { + break; + } else { + array_push( $confirm_default_path_array, $folder_default_path ); + $folder_default_path = null; + } + $folder_path = dirname($folder_path); + } + if( !is_null( $folder_default_path ) && file_exists($folder_default_path) ) { + $str = trim(file_get_contents($folder_default_path)); + $this->out_body_strings = $str.$this->out_body_strings; + // フォルダデフォルトファイルをタイムスタンプ比較ファイルに追加 + $build_information_object->addCompareFile( $folder_default_path ); + } else if( count( $confirm_default_path_array ) > 0 ) { + foreach( $confirm_default_path_array as $path ) { + $build_information_object->addConfirmFile( $path ); + } + } + + // 変換タグの読み込みと変換 + $tag_object_array = array(); + $dir_path_tags = dirname(__FILE__).DIRECTORY_SEPARATOR."tags".DIRECTORY_SEPARATOR; + if ( is_dir($dir_path_tags) ) { + if ( $dh = opendir( $dir_path_tags ) ) { + while ( ( $file_name = readdir($dh) ) !== false ) { + if( $file_name != "." && $file_name != ".." + && preg_match('/^[0-9a-zA-Z]+?\\.class\\.php$/',$file_name)) { + require_once( dirname(__FILE__).DIRECTORY_SEPARATOR + ."tags".DIRECTORY_SEPARATOR.$file_name ); + $tag_class_name = "spider_tags_".substr($file_name,0,strpos($file_name,".")); + $tag_class_obj = new $tag_class_name; + if( !isset($tag_object_array[$tag_class_obj->priority]) || !is_array($tag_object_array[$tag_class_obj->priority]) ) { + $tag_object_array[$tag_class_obj->priority] = array(); + } + array_push( $tag_object_array[$tag_class_obj->priority], $tag_class_obj ); + } + } + closedir($dh); + } else { + } + } else { + } + // 外部変換タグの読み込みと変換 + $external_tags_conf_file = dirname(__FILE__) + .DIRECTORY_SEPARATOR."tags".DIRECTORY_SEPARATOR."externals.conf"; + if( file_exists( $external_tags_conf_file ) ) { + $lines = file( $external_tags_conf_file ); + foreach( $lines as $line ) { + $line = trim($line); + $tag_class_name = $line; + $tag_class_file = DIR_PATH_LIB.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$line).'.class.php'; + if( file_exists($tag_class_file) ) { + require_once( $tag_class_file ); + $tag_class_obj = new $tag_class_name; + if( !is_array( $tag_object_array[$tag_class_obj->priority]) ) { + $tag_object_array[$tag_class_obj->priority] = array(); + } + array_push( $tag_object_array[$tag_class_obj->priority], $tag_class_obj ); + } + } + } + // 優先順にタグのコンバートメソッドを実行 + ksort($tag_object_array); + foreach( $tag_object_array as $key => $tag_array ) { + foreach($tag_array as $tag_obj ) { + $tag_obj->convert( $this->out_body_strings, $build_information_object ); + } + } + } + /** + * 実行ファイル実体を書き出す + * @param $bin_file_path 実行ファイルの出力パス + */ + function createBinFile( & $build_information_object ) { + + $bin_file_path = $build_information_object->getAgentPageBuildFilePath(); + + // 実行ファイルを解析 + $this->convertBody($build_information_object); + + // 表示前実行部分作成 + $string = "<?php\n"; + + // 処理開始前実行コードを記述 + foreach( $build_information_object->preview_process_hash as $code_array ) { + foreach( $code_array as $code ) { + $string .= $code."\n"; + } + } + + // モジュール実行のスクリプト追加 + 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'; + } + $attribute_prefix = ''; + if( isset($info_hash['attribute_prefix']) ) { + $attribute_prefix = $info_hash['attribute_prefix']; + $attribute_prefix = str_replace('"','\\"',$attribute_prefix); + } + $post_contents = ''; + if( isset($info_hash['post']) ) { + $post_contents = $info_hash['post']; + $post_contents = str_replace('"','\\"',$post_contents); + } + $get_contents = ''; + if( isset($info_hash['get']) ) { + $get_contents = $info_hash['get']; + $get_contents = str_replace('"','\\"',$get_contents); + } + $string .= '$controller->loadModule( "' . $module_name . '", '.$force.',"'.$attribute_prefix + .'","'.$get_contents.'", "'.$post_contents.'" );'."\n"; + $string .= 'if($_GET[\'spiderdebugcmd\'] == \'viewmoduletime\' ' + .'&& is_array($GLOBALS[\'SPIDER_DEBUG_COMMAND_PERMIT_ADDRESSES\']) ' + .'&& in_array($_SERVER[\'REMOTE_ADDR\'],$GLOBALS[\'SPIDER_DEBUG_COMMAND_PERMIT_ADDRESSES\']) ' + .') { ' + .'$request_object->debugExecTime(\''.$module_name.'\'); ' + .'}'."\n"; + } + + // モジュール実行結果による分岐処理を記述 + $string .= 'if ( $request_object->isError() ) {'."\n"; + $string .= '$is_error = true;'."\n"; + $string .= '$request_object->setAttribute("IS_ERROR", $is_error );'."\n"; + $string .= '$tmp_array = $request_object->errors;'."\n"; + $string .= '$request_object->setAttribute("errors", $tmp_array );'."\n"; + $string .= '} else {'."\n"; + $string .= '$is_error = false;'."\n"; + $string .= '$request_object->setAttribute("IS_ERROR", $is_error );'."\n"; + $string .= '}'."\n"; + + // リクエスト属性をグローバル変数に格納する + $string .= 'foreach( $request_object->attribute_array as $key => $value ) { '; + $string .= ' $GLOBALS[$key] = $value; '; + $string .= ' }'."\n"; + + // ファイルアウトプット機能の追加 + // リクエストオブジェクトに乗せられたヘッダ + $string .= 'if( count( $request_object->headers ) > 0 ) {'."\n"; + $string .= 'foreach( $request_object->headers as $hkey => $hval ) {'."\n"; + $string .= 'header("$hkey: $hval");'."\n"; + $string .= '}'."\n"; + $string .= '}'."\n"; + + // リダイレクトの場合 + $string .= 'if( !is_null( $request_object->redirect_url ) && strlen($request_object->redirect_url)> 0 ) {'."\n"; + $string .= 'header("Location: ".$request_object->redirect_url);'."\n"; + $string .= "die;\n"; + $string .= '}'; + // レスポンスファイルが指定されている場合 + $string .= 'else if( !is_null( $request_object->response_file_path ) && strlen( $request_object->response_file_path ) > 0 && file_exists( $request_object->response_file_path ) ){'."\n"; + $string .= 'readfile($request_object->response_file_path);'."\n"; + // レスポンスボディが指定されている場合 + $string .= '} else if( !is_null( $request_object->response_body ) && strlen( $request_object->response_body ) > 0 ) {'."\n"; + $string .= 'echo $request_object->response_body;'."\n"; + // レスポンスが何も指定されていないなら継続処理 + $string .= "} else { \n\n?>"; + + // テキスト出力があるなら出力 + $string .= $this->out_body_strings; + + // 出力を文字列に取得する + $string .= "<?php\n"; + $string .= 'mb_internal_encoding(\'UTF-8\');'."\n"; + $string .= 'mb_http_output(\'UTF-8\');'."\n"; + $string .= '$outstr = ob_get_clean();'."\n"; + $string .= '$outstr = trim($outstr);'."\n"; + + // 表示文字列に対する処理実行コードを記述 + foreach( $build_information_object->convert_view_process_hash as $code_array ) { + foreach( $code_array as $code ) { + $string .= $code."\n"; + } + } + + // 最終的にできた表示文字列をフラッシュする + $outputReplaceCode = $build_information_object->output_charset; + if( isset($GLOBALS['DEF_SPIDER_CHARSET_REPLACE_ENCODINGS'][$outputReplaceCode]) ) { + // 変換文字が定義されているなら変換文字を使う(SJIS等の場合Shift_JISにするなどの為) + $outputReplaceCode = $GLOBALS['DEF_SPIDER_CHARSET_REPLACE_ENCODINGS'][$outputReplaceCode]; + } + $string .= 'if(\'UTF-8\'!=\''.$build_information_object->output_charset.'\'){'."\n"; + $string .= '$needContentType = false;'."\n"; + $string .= '$sentContentType = false;'."\n"; + $string .= 'if( preg_match(\'/^4/\',phpversion()) > 0 || preg_match(\'/^3/\',phpversion()) > 0 ) {'."\n"; + $string .= 'if( headers_sent() ) {'."\n"; + $string .= '$sentContentType = true;'."\n"; + $string .= '}'."\n"; + $string .= '} else {'."\n"; + $string .= '$headers = headers_list();'."\n"; + $string .= 'foreach( $headers as $hk => $hv ) {'."\n"; + $string .= 'if(preg_match(\'/^[cC][oO][nN][tT][eE][nN][tT]\\\\-[tT][yY][pP][eE]/\',$hv) > 0 ) {'."\n"; + $string .= '$sentContentType = true;'."\n"; + $string .= 'if(preg_match(\'/[uU][tT][fF]\\\\-8/\',$hv) > 0 ) {'."\n"; + $string .= '$needContentType = true;'."\n"; + $string .= '}'."\n"; + $string .= '}'."\n"; + $string .= '}'."\n"; + $string .= '}'."\n"; + $string .= 'if(!$sentContentType || $needContentType ){ header(\'Content-Type: text/html;charset='.$outputReplaceCode.';\'); }'."\n"; + $string .= 'echo mb_convert_encoding($outstr,\''.$build_information_object->output_charset.'\',\'UTF-8\');'."\n"; + $string .= '} else {'."\n"; + $string .= 'echo $outstr;'."\n"; + $string .= '}'."\n"; + $string .= "}\n"; + + // 表示後実行コードを記述 + foreach( $build_information_object->postview_process_hash as $code_array ) { + foreach( $code_array as $code ) { + $string .= $code."\n"; + } + } + + // フラッシュ後にモジュール後処理の実行 + $string .= '$controller->post_process_all(); '; + $string .= "?>\n"; + + $fp = @fopen( $bin_file_path, "w" ); + if( $fp ) { + if (@flock($fp, LOCK_EX)) { + fwrite( $fp, $string ); + flock($fp, LOCK_UN); + @fclose( $fp ); + @chmod( $bin_file_path, SPIDER_FILE_CREATE_PERMITTION ); + } else { + @fclose( $fp ); + @chmod( $bin_file_path, SPIDER_FILE_CREATE_PERMITTION ); + die('Core Error: Can\'t create execute file!!'); + } + } else { + die('Core Error: Can\'t create execute file!!'); + } + + // ビルドタイムスタンプファイル作成 + $build_file_path = $bin_file_path.".build.php"; + $bin_file_path = str_replace('\\','\\\\',$bin_file_path ); + $string = "<?php\n"; + $string .= '$build=false;'."\n"; + $target_file_path = $build_information_object->execute_file_path; + $target_file_path = str_replace('\\','\\\\',$target_file_path ); + $string .= 'if( file_exists("'.$target_file_path.'") ){if( filemtime("'.$bin_file_path.'") < filemtime("'.$target_file_path.'") ) { $build=true; }}'."\n"; + // 比較ファイルとのタイムスタンプ比較 + foreach( $build_information_object->compare_time_file_array as $compare_file_path ) { + $compare_file_path = str_replace('\\','\\\\',$compare_file_path); + $compare_file_path = str_replace('"','\\"',$compare_file_path); + // ファイルが存在する場合、ビルドファイルより更新日が新しいなら再ビルド、ファイルがなくなっていても再ビルド + $string .= 'if( file_exists("'.$compare_file_path.'") ){if( filemtime("'.$bin_file_path.'") < filemtime("'.$compare_file_path.'") ) { $build=true; }} else { $build=true; }'."\n"; + } + // 存在確認ファイル確認 + foreach( $build_information_object->confirm_exists_file_array as $compare_file_path ) { + if( strlen($compare_file_path) > 0 ) { + $compare_file_path = str_replace('\\','\\\\',$compare_file_path); + $compare_file_path = str_replace('"','\\"',$compare_file_path); + // ファイルができていたら再ビルド + $string .= 'if( file_exists("'.$compare_file_path.'") ){ $build=true; }'."\n"; + } + } + + $string .= "?>\n"; + + $fp = @fopen( $build_file_path, "w" ); + if( $fp ) { + if (@flock($fp, LOCK_EX)) { + fwrite( $fp, $string ); + flock($fp, LOCK_UN); + @fclose( $fp ); + @chmod( $build_file_path, SPIDER_FILE_CREATE_PERMITTION ); + } else { + @fclose( $fp ); + @chmod( $build_file_path, SPIDER_FILE_CREATE_PERMITTION ); + die('Core Error: Can\'t create build file!!'); + } + } else { + die('Core Error: Can\'t create build file!!'); + } + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/Controller.class.php =================================================================== --- db/current/spider/lib/spider/Controller.class.php (rev 0) +++ db/current/spider/lib/spider/Controller.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,245 @@ +<?php +require_once( dirname(__FILE__).DIRECTORY_SEPARATOR.'HttpRequest.class.php' ); +/** + * モジュールの実行をコントロールするクラスです。 + * 各モジュールの実行は、本クラスによって行われます。 + * + * @package spider spiderのコアパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class spider_Controller { + + /** 実行モジュールのモジュール名+実行パラメータ文字列配列(実行した順) */ + var $executed_module_info_array = array(); + /** 実行モジュールのオブジェクトハッシュ */ + var $executed_module_object_array = array(); + + /** リクエストコンテナオブジェクト */ + var $request_object = null; + /** 出力オブジェクト */ + var $http_output_object = null; + + /** + * コンストラクタ + */ + function spider_Controller( & $request_object, & $http_output_obj ) { + $this->executed_module_info_array = array(); + $this->executed_module_object_array = array(); + $this->post_hash = $_POST; + $this->get_hash = $_GET; + $this->request_object = & $request_object; + $this->http_output_object = & $http_output_obj; + } + + /** + * 全体実行 + * @param $request_object + * @param $http_output_obj + */ + function execute( & $request_object, & $http_output_obj ) { + + if( is_null($request_object) ) { + $this->request_object = & $request_object; + } + if( is_null($http_output_obj) ) { + $this->http_output_object = & $http_output_obj; + } + + // グローバルエラーが存在したらエラーに追加 + if( isset($_SESSION) ) { + $global_errors = unserialize( $_SESSION['spider.global_errors'] ); + if( is_array( $global_errors ) ) { + $this->request_object->errors = $global_errors; + } + unset( $_SESSION['spider.global_errors'] ); + } + // リクエスト出力 + $this->http_output_object->output( $this, $this->request_object ); + } + /** + * モジュール実行 + * @param $module_name 実行するモジュール名 + */ + function loadModule( $module_name, $force=false, $attribute_prefix=null, $get_contents=null, $post_contents=null ) { + // forceがtrueでないばあい、requestにエラーがある場合は実行しない + if( $force || !$this->request_object->isError() ) { + // 実行済みかどうかを判断する文字列 + $execute_info_name = $module_name.' '.$attribute_prefix.' '.$get_contents.' '.$post_contents; + // モジュールクラスファイルの存在確認 + $path = str_replace( ".", DIRECTORY_SEPARATOR, $module_name ); + $path = DIR_PATH_LIB . DIRECTORY_SEPARATOR . $path; + if ( file_exists( $path . ".class.php" ) ) { + include_once( $path . ".class.php" ); + } else if ( file_exists( $path . ".inc.php" ) ) { + include_once( $path . ".inc.php" ); + } else if ( file_exists( $path . ".php" ) ) { + include_once( $path . ".php" ); + } else if ( file_exists( $path . ".php.inc" ) ) { + include_once( $path . ".php.inc" ); + } else if( file_exists( $path . ".inc" ) ){ + include_once( $path . ".inc" ); + } else { + header('Content-Type: text/plain;charset=UTF-8'); + die($GLOBALS['spider.messages']['spider.controller.moduleisnotfound'].'[' . $module_name . ']'); + } + // 実行モジュールクラス名の取り出し + $module_real_name = str_replace( ".", "_", $module_name ); + $module_obj = null; + if( isset($this->executed_module_object_array[$module_name]) ) { + $module_obj = $this->executed_module_object_array[$module_name]; + } + if( is_null( $module_obj ) ) { + // モジュールがスタックにない場合は新規作成して実行 + $module_obj = new $module_real_name; + $module_obj->controller_object = & $this; + $module_obj->http_output_object = & $this->http_output_object; + $module_obj->http_request_object = & $this->request_object; + // 要求モジュールが存在して未実行の場合は先に強制実行する + if( is_array( $module_obj->require_module_array ) ) { + foreach( $module_obj->require_module_array as $require_module_name ) { + $this->loadModule( $require_module_name, false, null, null, null ); + } + } + // プレフィックス指定があるなら実行前にrequestに設定 + if( !is_null( $attribute_prefix ) && strlen( $attribute_prefix ) > 0 ) { + $this->request_object->attribute_prefix = $attribute_prefix; + } + // post_contents.get_contentsが渡されているなら上書き + $org_post = null; + $org_get = null; + if( strlen($post_contents) > 0 ) { + $org_post = $_POST; + $post_hash = $this->content2Hash( $post_contents ); + $this->overwriteHash( $post_hash, $_POST ); + } + if( strlen($get_contents) > 0 ) { + $org_get = $_GET; + $get_hash = $this->content2Hash( $get_contents ); + $this->overwriteHash( $get_hash, $_GET ); + } + // 指定モジュールを実行する + $module_obj->execute( $this->request_object ); + $module_obj = $this->executed_module_object_array[$module_name] = $module_obj; + array_unshift( $this->executed_module_info_array, $execute_info_name ); + // post_contents.get_contentsが渡されているなら元に戻す + if( strlen($post_contents) > 0 ) { + $_POST = $org_post; + } + if( strlen($get_contents) > 0 ) { + $_GET = $org_get; + } + // プレフィックス指定を解除する + $this->request_object->attribute_prefix = null; + // 指定後処理モジュールがあるなら実行する + if( is_array( $module_obj->post_module_array ) ) { + foreach( $module_obj->post_module_array as $post_module_name ) { + $this->loadModule( $post_module_name, false, null, null, null ); + } + } + } else if( !in_array( $execute_info_name, $this->executed_module_info_array ) ) { + // モジュールスタックにオブジェクトがあっても実行済みモジュール情報にないなら実行 + // 要求モジュールが存在して未実行の場合は先に強制実行する + if( is_array( $module_obj->require_module_array ) ) { + foreach( $module_obj->require_module_array as $require_module_name ) { + $this->loadModule( $require_module_name, false, null, null, null ); + } + } + // プレフィックス指定があるなら実行前にrequestに設定 + if( !is_null( $attribute_prefix ) && strlen( $attribute_prefix ) > 0 ) { + $this->request_object->attribute_prefix = $attribute_prefix; + } + // post_contents.get_contentsが渡されているなら上書き + $org_post = null; + $org_get = null; + if( strlen($post_contents) > 0 ) { + $org_post = $_POST; + $post_hash = $this->content2Hash( $post_contents ); + $this->overwriteHash( $post_hash, $_POST ); + } + if( strlen($get_contents) > 0 ) { + $org_get = $_GET; + $get_hash = $this->content2Hash( $get_contents ); + $this->overwriteHash( $get_hash, $_GET ); + } + // 指定モジュールを実行する + $module_obj->execute( $this->request_object ); + $module_obj = $this->executed_module_object_array[$module_name] = $module_obj; + array_unshift( $this->executed_module_info_array, $execute_info_name ); + // post_contents.get_contentsが渡されているなら元に戻す + if( strlen($post_contents) > 0 ) { + $_POST = $org_post; + } + if( strlen($get_contents) > 0 ) { + $_GET = $org_get; + } + // プレフィックス指定を解除する + $this->request_object->attribute_prefix = null; + // 指定後処理モジュールがあるなら実行する + if( is_array( $module_obj->post_module_array ) ) { + foreach( $module_obj->post_module_array as $post_module_name ) { + $this->loadModule( $post_module_name, false, null, null, null ); + } + } + } else { + // 同条件で実行済みなら何もしない + return; + } + } + } + /** + * 現在までに実行したモジュールの後処理メソッドを降順で呼び出します。 + */ + function post_process_all() { + foreach ( $this->executed_module_info_array as $execute_info_name ) { + list( $module_name, $attribute_prefix, $get_contents, $post_contents ) + = explode(' ', $execute_info_name ); + $module_obj = $this->executed_module_object_array[$module_name]; + if ( method_exists ( $module_obj, 'post_process' ) ) { + $module_obj->post_process( $this->request_object ); + } + } + } + /** + * ハッシュのキーと値をsourceからdestinationへ上書きします + */ + function overwriteHash( & $source_hash, & $destination_hash ) { + foreach( $source_hash as $key => $val ) { + $destination_hash[$key] = $val; + } + } + /** + * コンテンツ文字列を分割してハッシュに格納して返す + */ + function content2Hash( $strings ) { + $reterun_hash = array(); + $strings = trim($strings); + if( strlen($strings) > 0 ) { + $param_array = explode('&',$strings); + foreach( $param_array as $var ) { + list( $key, $val ) = explode('=',$var); + $key = urldecode($key); + $val = urldecode($val); + if( preg_match('/\\[[^\\[\\]]+\\]$/',$key ) > 0 ) { + $name = preg_replace('/\\[[^\\[\\]]+\\]$/','',$key); + if( !is_array($reterun_hash[$name]) ) { + $reterun_hash[$name] = array(); + } + list( $name, $hash_key ) = explode('[',$key); + $hash_key = trim(preg_replace('/\\]$/','',$hash_key)); + if( strlen($hash_key) > 0 ) { + $reterun_hash[$name][$hash_key] = $val; + } else { + array_push( $reterun_hash[$name], $val ); + } + } else { + $reterun_hash[$key] = $val; + } + } + } + return $reterun_hash; + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/HttpOutput.class.php =================================================================== --- db/current/spider/lib/spider/HttpOutput.class.php (rev 0) +++ db/current/spider/lib/spider/HttpOutput.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,115 @@ +<?php +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'functions.inc.php' ); +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'BuildInformation.class.php' ); +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'Builder.class.php'); +require_once(dirname(dirname( __FILE__ )).DIRECTORY_SEPARATOR.'util'.DIRECTORY_SEPARATOR.'LockProcess.class.php' ); +/** + * HTTP出力を行うクラスです。 + * + * @package spider spiderのコアパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class spider_HttpOutput { + + /** + * コンストラクタ + * @param $template_foler_path テンプレートファイルのルートディレクトリ + */ + function spider_HttpOutput() { + } + /** + * リクエストの出力 + * @param $controller モジュールを実行するspider_Controllerオブジェクト + * @param $request_object spider_HttpRequestオブジェクト + */ + function output( $controller, & $request ) { + + // 互換性 + $request_object = & $request; + + // ビルド情報クラスの作成 + $build_information_object = new spider_BuildInformation(); + + // ユーザーエージェント分類をリクエストにセット + $request->setAttribute('spider.access_agent_class',$build_information_object->agent_class); + $request->agentClass = $build_information_object->agent_class; + + // ビルドファイルパスを取得 + $build_file_path = $build_information_object->getAgentPageBuildFilePath(); + $build_confirm_path = $build_file_path.'.build.php'; + + // 指定ファイルに対してロックオブジェクト作成 + $bin_lock_name = str_replace('/','_S_',str_replace(DIRECTORY_SEPARATOR,'_S_',$build_information_object->execute_file_path)); + $lock_obj = new util_LockProcess($bin_lock_name); + + // ファイルとテンプレートの更新を確認 + $build = false; + if( file_exists( $build_confirm_path ) ) { + // ビルド確認ファイルが存在するなら実行してビルド済みファイルが古くないか確認 + require_once( $build_confirm_path ); + if( $build ) { + // ビルドファイルが古いならビルドファイルを削除 + if( $lock_obj->lock() ) { + if( file_exists($build_file_path) ) { + @unlink( $build_file_path ); + } + if( file_exists($build_confirm_path) ) { + @unlink( $build_confirm_path ); + } + } else { + $lock_obj->release(); + $this->exitWithCoreError(); + } + } else if( $lock_obj->wait() ) { + require_once( $build_file_path ); + return; + } else { + $this->exitWithCoreError(); + } + } else if( file_exists( $build_file_path ) ) { + // ビルド確認ファイルが存在しないならビルドファイルも削除する + if( $lock_obj->lock() ) { + if( file_exists($build_file_path) ) { + @unlink( $build_file_path ); + } + } else { + $lock_obj->release(); + $this->exitWithCoreError(); + } + } else { + if( $lock_obj->lock() ) { + if( file_exists($build_file_path) ) { + @unlink( $build_file_path ); + } + if( file_exists($build_confirm_path) ) { + @unlink( $build_confirm_path ); + } + } else { + $lock_obj->release(); + $this->exitWithCoreError(); + } + } + + // 実行ファイル作成オブジェクト + $builder_object = new spider_Builder(); + + // 実行ファイル作成 + $builder_object->createBinFile( $build_information_object ); + $lock_obj->release(); + + // 実行ファイル実行 + require( $build_file_path ); + + return; + } + /** + * コアエラーが起こった場合にエラーメッセージを出力して終了します。 + */ + function exitWithCoreError() { + spider_exitWithCoreError($GLOBALS['spider.messages']['spider.httpoutput.busy']); + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/HttpRequest.class.php =================================================================== --- db/current/spider/lib/spider/HttpRequest.class.php (rev 0) +++ db/current/spider/lib/spider/HttpRequest.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,598 @@ +<?php +/** + * クライアントからの要求を提供するHTTPリクエスト、 + * クライアントへの応答を送信する際の処理を行うHTTPレスポンス + * それぞれで使用するデータを保持するクラスです。 + * + * @package spider spiderのコアパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +define( 'SPIDER_SESSION_SCOPE_GLOBAL', 'GLOBAL' ); +define( 'SPIDER_SESSION_SCOPE_AUTO', 'AUTO' ); +require_once(dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'util'.DIRECTORY_SEPARATOR.'CharUtility.class.php'); +class spider_HttpRequest { + /** Attributes */ + var $attribute_array = array(); + /** Errors */ + var $errors = array(); + /** Global Errors */ + var $global_errors = array(); + /** Response Headers */ + var $headers = array(); + /** Response Body */ + var $response_body = null; + /** Response File Path */ + var $response_file_path = null; + /** Redirect To URL */ + var $redirect_url = null; + /** Attribute Prefix */ + var $attribute_prefix = null; + /** Access User Agent Class */ + var $agentClass = null; + + var $startTime; + var $lastTime; + + /** + * コンストラクタ + */ + function spider_HttpRequest() { + $this->attribute_array = array(); + $this->errors = array(); + $this->startTime = time(); + $this->lastTime = time(); + } + /** + * 属性を設定します。 + * @param $key 属性名 + * @param $value 属性値 + */ + function setAttribute( $key, & $value ) { + $reg_key = $key; + $callstack = debug_backtrace(); + $caller_file = $callstack[0]['file']; + unset($callstack); + if( strpos($caller_file,DIR_PATH_LIB) !== false + && strpos($caller_file,DIR_PATH_LIB.DIRECTORY_SEPARATOR.'spider') === false ) { + // 呼び出し元がlib内のファイルの場合 + $lib_uri = str_replace(DIR_PATH_LIB,'',$caller_file); + $caller_class = preg_replace('/^_/','',str_replace('.class.php','',str_replace(DIRECTORY_SEPARATOR,'_',$lib_uri))); + $caller_prefix = str_replace('_','.',$caller_class); + $package_prefix = preg_replace('/\\.[^\\.]+$/','',$caller_prefix); + if( preg_match('/^'.util_CharUtility::escape_regx_str($caller_prefix).'/',$key) == 0 + && preg_match('/^'.util_CharUtility::escape_regx_str($package_prefix).'/',$key) == 0 + ) { + // パッケージ名もクラス名も属性名に含まれないならクラスプレフィックスつけて登録 + $reg_key = $caller_prefix.'.'.$reg_key; + } + } else { + // lib内でない場合、下位互換の為、$GLOBALSにも登録する + $reg_key = 'page.'.$key; + $GLOBALS[$reg_key] = $value; + $GLOBALS[$key] = $value; + } + if( !is_null( $this->attribute_prefix ) && strlen($this->attribute_prefix) > 0 ) { + $reg_key = $this->attribute_prefix.'.'.$reg_key; + } + $this->attribute_array[$reg_key] = $value; + $this->attribute_array[$key] = $value; + } + /** + * 指定キーの属性を取得します。 + * @param $key 属性名 + */ + function getAttribute( $key ) { + $ref = & $this->attribute_array[$key]; + return $ref; + } + /** + * 指定キーの性がセットされたか確認します + */ + function existAttribute( $key ) { + return array_key_exists( $key, $this->attribute_array ); + } + /** + * エラーメッセージを追加します。 + * @param $message エラーメッセージ + * @param $log_level ログ出力を同時に行う場合に指定します。falseを指定すると記録しません。デフォルトはfalseです。 + */ + function addError( $message, $log_level=false ) { + array_push( $this->errors, $message ); + if( false !== $log_level && is_numeric($log_level) ) { + $this->writeLog( $message, $log_level ); + } + } + /** + * エラーがあるか確認します。 + * @return true:エラーあり、false:それ以外 + */ + function isError() { + if( count( $this->errors ) > 0 ) { + return true; + } else { + return false; + } + } + /** + * グローバルエラーを追加します + */ + function addGlobalError( $message ) { + if( isset($_SESSION) ) { + if( isset($_SESSION['spider.global_errors']) ) { + $globalErrors = unserialize( $_SESSION['spider.global_errors'] ); + } + if( !is_array( $globalErrors ) ) { + $globalErrors = array(); + } + array_push($globalErrors,$message); + $_SESSION['spider.global_errors'] = serialize($globalErrors); + } + array_push( $this->global_errors, $message ); + } + /** + * レスポンスヘッダを設定します + */ + function setResponseHeader( $key, $value ) { + $this->headers[$key] = $value; + } + /** + * レスポンスボディを設定します + */ + function setResponseBody( $body ) { + $this->response_body = $body; + } + /** + * レスポンスボディをファイルパスで設定します。 + */ + function setResponseFile( $file_path ) { + $this->response_file_path = $file_path; + } + /** + * リダイレクト先を設定します + */ + function redirectTo($url) { + if( preg_match('/^\\//',$url) > 0 ) { + // リダイレクトURLがドキュメントルートからのパスで記載されている場合 + if( defined('APPLICATION_PROXY_REV_HOST') && strlen(APPLICATION_PROXY_REV_HOST) > 0 + && ( APPLICATION_PROXY_REV_HOST == $_SERVER['HTTP_X_FORWARDED_HOST'] + || APPLICATION_PROXY_REV_HOST == $_SERVER['HTTP_X_FORWARDED_SERVER'] ) ) { + // リバースプロキシホスト名が設置されていてそこからのアクセスの場合 + $url = preg_replace('/\\/$/','',APPLICATION_PROXY_REV_BASE_URI).$url; + $this->redirect_url = $url; + } else { + // リバースプロキシ経由でない場合 + $this->redirect_url = $url; + } + } else { + // 相対パスかプロトコルからの完全URLの場合 + $this->redirect_url = $url; + } + } + /** + * セッション変数を設定します + * @param $key + * @param $value + * @param $scopse GLOBALまたは有効フォルダURI + */ + function setSession( $key, $value, $scope=SPIDER_SESSION_SCOPE_AUTO ) { + $this->optimizeSession(); + if( $scope == SPIDER_SESSION_SCOPE_AUTO ) { + $scope = dirname($_SERVER['PHP_SELF']); + } + if( SPIDER_SESSION_SCOPE_GLOBAL == $scope ) { + $key = $this->_getGlobalSessionKey( $key ); + } else { + $key = $scope.'/'.$key; + } + $spiderSession = new spider_Session(); + if( isset($_SESSION) && isset($_SESSION['spider_session_object']) ) { + $spiderSession = unserialize($_SESSION['spider_session_object']); + } + $spiderSession->setValue($key,$value); + $_SESSION['spider_session_object'] = serialize($spiderSession); + } + /** + * セッション変数を取得します + * @param $key + */ + function getSession( $key ) { + $this->optimizeSession(); + $spiderSession = new spider_Session(); + if( isset($_SESSION) && isset($_SESSION['spider_session_object']) ) { + $spiderSession = unserialize($_SESSION['spider_session_object']); + } + $value = null; + $current_scope = dirname( $_SERVER['PHP_SELF'] ); + while( strlen($current_scope) > 1 ) { + $target_key = $current_scope.'/'.$key; + if( false !== $spiderSession->getValue($target_key) ) { + return $spiderSession->getValue($target_key); + } + $current_scope = dirname( $current_scope ); + } + $target_key = $this->_getGlobalSessionKey( $key ); + if( false !== $spiderSession->getValue($target_key) ) { + return $spiderSession->getValue($target_key); + } + return null; + } + /** + * セッション変数が登録されているか確認します + * @param $key + */ + function existsSession( $key ) { + $this->optimizeSession(); + $spiderSession = new spider_Session(); + if( isset($_SESSION) && isset($_SESSION['spider_session_object']) ) { + $spiderSession = unserialize($_SESSION['spider_session_object']); + } + $value = null; + $current_scope = dirname( $_SERVER['PHP_SELF'] ); + while( strlen($current_scope) > 1 ) { + $target_key = $current_scope.'/'.$key; + if( false !== $spiderSession->getValue($target_key) ) { + return true; + } + $current_scope = dirname( $current_scope ); + } + $target_key = $this->_getGlobalSessionKey( $key ); + if( false !== $spiderSession->getValue($target_key) ) { + return true; + } + return false; + } + /** + * セッション登録済みの変数を削除します + */ + function removeSession( $key, $scope=SPIDER_SESSION_SCOPE_AUTO ) { + $this->optimizeSession(); + $spiderSession = new spider_Session(); + if( isset($_SESSION) && isset($_SESSION['spider_session_object']) ) { + $spiderSession = unserialize($_SESSION['spider_session_object']); + } + if( $scope == SPIDER_SESSION_SCOPE_AUTO ) { + $scope = dirname($_SERVER['PHP_SELF']); + } + if( SPIDER_SESSION_SCOPE_GLOBAL == $scope ) { + $key = $this->_getGlobalSessionKey( $key ); + } else { + $key = $scope.'/'.$key; + } + $spiderSession->removeValue($key); + $_SESSION['spider_session_object'] = serialize($spiderSession); + } + /** + * セッション登録済み情報を最適化します + */ + function optimizeSession() { + if( isset( $_SESSION ) && is_array( $_SESSION ) ) { + $spiderSession = new spider_Session(); + if( isset($_SESSION) && isset($_SESSION['spider_session_object']) ) { + $spiderSession = unserialize($_SESSION['spider_session_object']); + } + $current_scope = dirname( $_SERVER['PHP_SELF'] ); + foreach( $_SESSION as $key => $value ) { + if( strlen($key) > 0 && preg_match('/^spider\\_GLOBAL\\./',$key) == 0 + && preg_match('/^'.util_CharUtility::escape_regx_str($current_scope).'/',$key) == 0 ) { + $spiderSession->removeValue($key); + } + } + $_SESSION['spider_session_object'] = serialize($spiderSession); + } + } + /** + * グローバルセッションキー + */ + function _getGlobalSessionKey( $key ) { + return 'spider_GLOBAL.'.$key; + } + /** + * ログを出力します + * @param $message ログメッセージ + */ + function writeLog( $message, $log_level=SPIDER_LOG_LEVEL_INFO, $logFileUri=null ) { + $system_log_level = SPIDER_LOG_LEVEL_INFO; + if( defined('SYSTEM_LOG_LEVEL') && is_numeric(SYSTEM_LOG_LEVEL) + && preg_match('/^[0-4]$/',SYSTEM_LOG_LEVEL) > 0 ) { + $system_log_level = SYSTEM_LOG_LEVEL; + } + // システム設定のログレベルより大きいレベルのログは出力しない + if( $log_level > $system_log_level ) { + return true; + } + + $message = str_replace( "\r\n", "\n", $message ); + $message = str_replace( "\r", "\n", $message ); + $message = str_replace( "\n", " ", $message ); + + $callstack = debug_backtrace(); + $caller_file = $callstack[0]['file']; + $caller_line = $callstack[0]['line']; + unset($callstack); + + $log_message = date('Y-m-d H:i:s') + . "\t".$message + . "\t"."[".$caller_file."] " + . "\t"."[".$caller_line."] " + . "\t" . $_SERVER['REMOTE_ADDR'] + . "\t" . $_SERVER['REMOTE_HOST'] + . "\t" . $_SERVER['HTTP_USER_AGENT']; + + $log_type = SPIDER_LOG_TYPE_FILE; + if( defined('SYSTEM_LOG_TYPE') && is_numeric(SYSTEM_LOG_TYPE) ) { + if( SPIDER_LOG_TYPE_SYSLOG == SYSTEM_LOG_TYPE ) { + $log_type = SPIDER_LOG_TYPE_SYSLOG; + } + } + if( SPIDER_LOG_TYPE_SYSLOG == $log_type ) { + // syslogdに出力する場合 + openlog('spiderLog', LOG_PID | LOG_NDELAY, LOG_SYSLOG); + $log_level = LOG_INFO; + switch ($log_level) { + case SPIDER_LOG_LEVEL_DEBUG: + $log_level = LOG_DEBUG; + break; + case SPIDER_LOG_LEVEL_INFO: + $log_level = LOG_INFO; + break; + case SPIDER_LOG_LEVEL_NOTICE: + $log_level = LOG_NOTICE; + break; + case SPIDER_LOG_LEVEL_WARNING: + $log_level = LOG_WARNING; + break; + case SPIDER_LOG_LEVEL_ERROR: + $log_level = LOG_ERR; + break; + case SPIDER_LOG_LEVEL_FATAL: + $log_level = LOG_CRIT; + break; + default: + break; + } + syslog($log_level, $log_message); + closelog(); + } else { + // ファイルに出力する + $logFilePath = null; + // ログファイル名の決定 + if( is_null($logFileUri) || strlen($logFileUri) == 0 ) { + // ファイルURIが指定されていない場合は自動生成 + $logFilePath = DIR_PATH_LOG.DIRECTORY_SEPARATOR.'spider'; + if( !file_exists( $logFilePath ) ) { + if( @mkdir( $logFilePath, SPIDER_FOLDER_CREATE_PERMITTION ) ) { + @chmod( $logFilePath, SPIDER_FOLDER_CREATE_PERMITTION ); + } + } + $logFilePath = $logFilePath.DIRECTORY_SEPARATOR.date('Y'); + if( !file_exists( $logFilePath ) ) { + if( @mkdir( $logFilePath, SPIDER_FOLDER_CREATE_PERMITTION ) ) { + @chmod( $logFilePath, SPIDER_FOLDER_CREATE_PERMITTION ); + } + } + $logFilePath = $logFilePath.DIRECTORY_SEPARATOR.date('m'); + if( !file_exists( $logFilePath ) ) { + if( @mkdir( $logFilePath, SPIDER_FOLDER_CREATE_PERMITTION ) ) { + @chmod( $logFilePath, SPIDER_FOLDER_CREATE_PERMITTION ); + } + } + $logFilePath = $logFilePath.DIRECTORY_SEPARATOR.'system_'.date('d').'.log'; + if( !file_exists( $logFilePath ) ) { + if(@touch( $logFilePath, SPIDER_FILE_CREATE_PERMITTION )){ + @chmod( $logFilePath, SPIDER_FILE_CREATE_PERMITTION ); + } + } + } else { + // ログファイルURIが指定されている場合は指定ログファイルへ出力 + $logFilePath = DIR_PATH_LOG; + $logFileUri = str_replace(DIRECTORY_SEPARATOR,'/',$logFileUri); + $dirNames = explode('/',$logFileUri); + $fileName = array_pop($dirNames); + foreach( $dirNames as $dirName ) { + if( strlen(trim($dirName)) > 0 ) { + $logFilePath .= DIRECTORY_SEPARATOR.$dirName; + if( !file_exists( $logFilePath ) ) { + if( @mkdir( $logFilePath, SPIDER_FOLDER_CREATE_PERMITTION ) ) { + @chmod( $logFilePath, SPIDER_FOLDER_CREATE_PERMITTION ); + } + } + } + } + $logFilePath .= DIRECTORY_SEPARATOR.$fileName; + if( !file_exists( $logFilePath ) ) { + if(@touch( $logFilePath, SPIDER_FILE_CREATE_PERMITTION )){ + @chmod( $logFilePath, SPIDER_FILE_CREATE_PERMITTION ); + } + } + } + // ログを出力 + error_log($log_message."\n" , 3, $logFilePath ); + } + return true; + } + /** + * Fatalレベルのログを出力します。 + * @param $message ログメッセージ + */ + function fatal($message, $logFileUri=null){ + $this->writeLog( $message, SPIDER_LOG_LEVEL_FATAL, $logFileUri ); + } + /** + * Errorレベルのログを出力します。 + * @param $message ログメッセージ + */ + function error($message, $logFileUri=null){ + $this->writeLog( $message, SPIDER_LOG_LEVEL_ERROR, $logFileUri ); + } + /** + * Warningレベルのログを出力します。 + * @param $message ログメッセージ + */ + function warn($message, $logFileUri=null){ + $this->writeLog( $message, SPIDER_LOG_LEVEL_WARNING, $logFileUri ); + } + /** + * Noticeレベルのログを出力します。 + * @param $message ログメッセージ + */ + function notice($message, $logFileUri=null){ + $this->writeLog( $message, SPIDER_LOG_LEVEL_NOTICE, $logFileUri ); + } + /** + * Infoレベルのログを出力します。 + * @param $message ログメッセージ + */ + function info($message, $logFileUri=null){ + $this->writeLog( $message, SPIDER_LOG_LEVEL_INFO, $logFileUri ); + } + /** + * Debugレベルのログを出力します。 + * @param $message ログメッセージ + */ + function debug($message, $logFileUri=null){ + $this->writeLog( $message, SPIDER_LOG_LEVEL_DEBUG, $logFileUri ); + } + /** + * システム設定された値でメール送信オブジェクトを作成して取得します。 + * @return mixed util_Mailクラスの実装オブジェクト・インスタンスを作成できなかった場合はfalse + */ + function getSystemMailer() { + if( defined('SYSTEM_MAIL_SEND_METHOD') ) { + require_once( dirname(dirname(__FILE__)) + . DIRECTORY_SEPARATOR . "util" + . DIRECTORY_SEPARATOR . "Mail.class.php" ); + // 送信オプション + $params = array(); + // 送信方法の決定 + $class_name = 'PHP'; + if( preg_match('/^[sS][mM][tT][pP]$/',SYSTEM_MAIL_SEND_METHOD) > 0 ) { + $class_name = 'SMTP'; + } else if( preg_match('/^[sS][eE][nN][dD][mM][aA][iI][lL]$/',SYSTEM_MAIL_SEND_METHOD) > 0 ) { + $class_name = 'SendMail'; + } + $params = $GLOBALS['SYSTEM_MAIL_SEND_METHOD_OPTIONS']; + // 送信オブジェクト作成 + $send_object = util_Mail::get_instance( $class_name, $params ); + if( $send_object === false ) { + return false; + } else { + return $send_object; + } + } else { + return false; + } + } + /** + * メールを送信します。 + * 宛先、配信元、返信先、戻り先のメールアドレスを指定しなかった場合、下記に定義された定数もしはグローバル配列を探して + * 定義済みの変数を元に送信を実行します。定義がなかった場合はfalseを返します。 + * + * 宛て先メールアドレス $GLOBALS['SYSTEM_MAIL_REPORT_TO_ADDRESSES'] 配列で定義してください。 + * 配信元メールアドレス SYSTEM_MAIL_FROM_ADDRESS 文字列で定義してください。 + * 配信先メールアドレス SYSTEM_MAIL_REPLY_ADDRESS 指定がない場合はSYSTEM_MAIL_FROM_ADDRESSを利用します。 + * 戻り先メールアドレス SYSTEM_MAIL_RETURN_ADDRESS 指定がない場合はSYSTEM_MAIL_FROM_ADDRESSを利用します。 + * + * @param $subject メール件名 + * @param $message メール本文 + * @param $mailto 宛て先メールアドレス + * @param $from 配信元メールアドレス指定 + * @param $reply 返信先メールアドレス指定 + * @param $return エラー戻り先メールアドレス指定 + * @return boolean + */ + function mailTo($subject,$message,$mailto=null,$from=null,$reply=null,$return=null) { + $mailto_addresses = array(); + if( isset($GLOBALS['SYSTEM_MAIL_REPORT_TO_ADDRESSES']) + && is_array($GLOBALS['SYSTEM_MAIL_REPORT_TO_ADDRESSES']) ) { + $mailto_addresses = $GLOBALS['SYSTEM_MAIL_REPORT_TO_ADDRESSES']; + } + $mailto = trim($mailto); + if(!is_null($mailto) && strlen($mailto) > 0 ) { + array_push($mailto_addresses, $mailto); + } + if(count($mailto_addresses)==0){ + $this->warn('HttpRequest->MailTo: derivery mail address is required!: '.$subject.':'.$message); + return false; + } + if(defined('SYSTEM_MAIL_SUBJECT_PREFIX')){ + $subject = SYSTEM_MAIL_SUBJECT_PREFIX.$subject; + } + if( is_null($from) || strlen($from) == 0 ) { + if(defined('SYSTEM_MAIL_FROM_ADDRESS') && strlen(SYSTEM_MAIL_FROM_ADDRESS)>0 ) { + if(defined('SYSTEM_MAIL_FROM_NAME') && strlen(SYSTEM_MAIL_FROM_NAME)>0 ) { + $from = SYSTEM_MAIL_FROM_NAME.' <'.SYSTEM_MAIL_FROM_ADDRESS.'>'; + } else { + $from = SYSTEM_MAIL_FROM_ADDRESS; + } + } else { + $this->warn('HttpRequest->MailTo: from address is required!: '.$subject.':'.$message); + return false; + } + } + if( is_null($reply) || strlen($reply) == 0 ) { + if(defined('SYSTEM_MAIL_REPLY_ADDRESS') && strlen(SYSTEM_MAIL_REPLY_ADDRESS)>0 ) { + $reply = SYSTEM_MAIL_REPLY_ADDRESS; + } else { + $reply = $from; + } + } + if( is_null($return) || strlen($return) == 0 ) { + if(defined('SYSTEM_MAIL_RETURN_ADDRESS') && strlen(SYSTEM_MAIL_RETURN_ADDRESS)>0 ) { + $return = SYSTEM_MAIL_RETURN_ADDRESS; + } else { + $return = $from; + } + } + + if( $send_object = $this->getSystemMailer() ) { + foreach( $mailto_addresses as $address ) { + $result = $send_object->send( $address, $subject, $message, $from, $reply, $return ); + if( $result ) { + $this->info( 'HttpRequest->MailTo: '.$address.':'.$subject.':'.$message ); + return true; + } else { + $this->warn('HttpRequest->MailTo: delivey error: '.$subject.':'.$message); + return false; + } + } + } else { + $this->warning( 'HttpRequest->MailTo: can\'t create mailer instance!: '.$mailto.':'.$subject.':'.$message ); + return false; + } + } + /** + * for debug echo time + */ + function debugExecTime($caption='') { + $time = time() - $this->lastTime; + echo $caption.'='.$time."<br />\n"; + $this->lastTime = time(); + } +} +/** + * spider_HttpRequestクラスオブジェクトを経由したセッション保存用の + * 情報コンテナクラス + */ +class spider_Session { + var $valueHash = array(); + function spider_Session(){ + $this->valueHash = array(); + } + function setValue($key,$value) { + $this->valueHash[$key] = $value; + } + function getValue($key) { + if( isset($this->valueHash[$key]) ) { + return $this->valueHash[$key]; + } else { + return false; + } + } + function removeValue($key) { + unset($this->valueHash[$key]); + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/ModuleBase.class.php =================================================================== --- db/current/spider/lib/spider/ModuleBase.class.php (rev 0) +++ db/current/spider/lib/spider/ModuleBase.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,139 @@ +<?php +/** + * すべてのモジュールのベースクラスです。 + * モジュールはすべて本クラスのサブクラスになります。 + * + * @package spider spiderのコアパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class spider_ModuleBase { + /** Controllerクラスオブジェクトへの参照 */ + var $controller_object; + /** HttpOutputクラスオブジェクトへの参照 */ + var $http_output_object; + /** HttpRequestクラスオブジェクトへの参照 */ + var $http_request_object; + /** 要求モジュール配列 */ + var $require_module_array = array(); + /** 後実行モジュール配列 */ + var $post_module_array = array(); + /** + * コンストラクタ + */ + function spider_ModuleBase() { + } + /** + * モジュールを実行します。 + * このメソッドをオーバーライドすることにより、モジュールが実行されます。 + * @param $request + */ + function execute( & $request ) { + } + /** + * モジュールの後処理を行います。 + * このメソッドをオーバーライドすることにより、モジュールの後処理として実行されます。 + * @param $request + */ + function post_process( & $request ) { + } + /** + * 本モジュールを実行するのに事前に実行する必要があるモジュール名の配列を取得します。 + */ + function get_require_module_array() { + return $this->require_module_array; + } + /** + * 本モジュールを実行した後に必ず実行する必要があるモジュール名配列を取得します。 + */ + function get_post_module_array() { + return $this->post_module_array; + } + /** + * メールレポートを送信します。 + * @param $subject + * @param $message + * @param $maito + * @deprecated v1.0.00 - 2009/04/17 正式リリース前の仕様です。HttpRequestクラスオブジェクトのmailToメソッドを利用してください。 + */ + function report_mailto($subject,$message,$mailto=null) { + if(is_object($this->http_request_object)){ + return $this->http_request_object->mailTo($subject,$message,$mailto); + } + return false; + } + /** + * システム設定された値でメール送信オブジェクトを作成して取得します。 + * @deprecated v1.0.00 - 2009/04/17 正式リリース前の仕様です。HttpRequestクラスオブジェクトのmailToメソッドを利用してください。 + */ + function get_system_mailer() { + if(is_object($this->http_request_object)){ + return $this->http_request_object->getSystemMailer(); + } + return false; + } + /** + * ログを出力します。 + * @param $message ログメッセージ + * @param $log_level 出力するログのレベル + * @deprecated v1.0.00 - 2009/04/17 正式リリース前の仕様です。HttpRequestクラスオブジェクトのwriteLogメソッドを利用してください。 + */ + function write_log( $message, $log_level=SPIDER_LOG_LEVEL_INFO ) { + if(is_object($this->http_request_object)){ + $this->http_request_object->writeLog($message,$log_level); + } + } + /** + * Fatalレベルのログを出力します。 + * @param $message ログメッセージ + * @deprecated v1.0.00 - 2009/04/17 正式リリース前の仕様です。HttpRequestクラスオブジェクトのfatalメソッドを利用してください。 + */ + function fatal($message){ + if(is_object($this->http_request_object)){ + $this->http_request_object->writeLog($message,SPIDER_LOG_LEVEL_FATAL); + } + } + /** + * Errorレベルのログを出力します。 + * @param $message ログメッセージ + * @deprecated v1.0.00 - 2009/04/17 正式リリース前の仕様です。HttpRequestクラスオブジェクトのerrorメソッドを利用してください。 + */ + function error($message){ + if(is_object($this->http_request_object)){ + $this->http_request_object->writeLog($message,SPIDER_LOG_LEVEL_ERROR); + } + } + /** + * Warningレベルのログを出力します。 + * @param $message ログメッセージ + * @deprecated v1.0.00 - 2009/04/17 正式リリース前の仕様です。HttpRequestクラスオブジェクトのwarnメソッドを利用してください。 + */ + function warn($message){ + if(is_object($this->http_request_object)){ + $this->http_request_object->writeLog($message,SPIDER_LOG_LEVEL_WARNING); + } + } + /** + * Infoレベルのログを出力します。 + * @param $message ログメッセージ + * @deprecated v1.0.00 - 2009/04/17 正式リリース前の仕様です。HttpRequestクラスオブジェクトのinfoメソッドを利用してください。 + */ + function info($message){ + if(is_object($this->http_request_object)){ + $this->http_request_object->writeLog($message,SPIDER_LOG_LEVEL_INFO); + } + } + /** + * Debugレベルのログを出力します。 + * @param $message ログメッセージ + * @deprecated v1.0.00 - 2009/04/17 正式リリース前の仕様です。HttpRequestクラスオブジェクトのdebugメソッドを利用してください。 + */ + function debug($message){ + if(is_object($this->http_request_object)){ + $this->http_request_object->writeLog($message,SPIDER_LOG_LEVEL_DEBUG); + } + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/functions.inc.php =================================================================== --- db/current/spider/lib/spider/functions.inc.php (rev 0) +++ db/current/spider/lib/spider/functions.inc.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,331 @@ +<?php +/* + * グローバル関数定義ファイル + * spiderで利用するグローバル関数を定義するファイルです + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +/** + * spiderに必要なディレクトリとファイルのパーミッションを確認します + * @return エラーメッセージ配列 + */ +function spider_is_avairable_permittion() { + $errors = array(); + if( !file_exists(DIR_PATH_LIB) ) { + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.libdirisnotfound'] ); + } + if( !file_exists(DIR_PATH_TEMPLATES) ) { + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.templatedirisnotfound'] ); + } + + if( !file_exists(DIR_PATH_WORK) ) { + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.workdirisnotfound'] ); + } else if( !is_writable(DIR_PATH_WORK) ){ + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.workdirisnotwritable'] ); + } else { + if( !file_exists(DIR_PATH_BIN) ) { + if( @mkdir(DIR_PATH_BIN,SPIDER_FOLDER_CREATE_PERMITTION) ) { + @chmod(DIR_PATH_BIN,SPIDER_FOLDER_CREATE_PERMITTION); + } else { + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.cantcreatebindir'] ); + } + } else if( !is_writable(DIR_PATH_BIN) ){ + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.bindirisnotwritable'] ); + } + if( !file_exists(DIR_PATH_LOCK) ) { + if( @mkdir( DIR_PATH_LOCK, SPIDER_FOLDER_CREATE_PERMITTION ) ) { + @chmod( DIR_PATH_LOCK, SPIDER_FOLDER_CREATE_PERMITTION ); + } else { + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.cantcreatelockdir'] ); + } + } else if( !is_writable(DIR_PATH_LOCK) ){ + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.lockdirisnotwritable'] ); + } + if( !file_exists(DIR_PATH_TMP) ) { + if( @mkdir( DIR_PATH_TMP, SPIDER_FOLDER_CREATE_PERMITTION ) ) { + @chmod( DIR_PATH_TMP, SPIDER_FOLDER_CREATE_PERMITTION ); + } else { + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.cantcreatetmpdir'] ); + } + } else if( !is_writable(DIR_PATH_TMP) ){ + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.tmpdirisnotwritable'] ); + } + if( !file_exists(DIR_PATH_CACHE) ) { + if( @mkdir( DIR_PATH_CACHE, SPIDER_FOLDER_CREATE_PERMITTION ) ) { + @chmod( DIR_PATH_CACHE, SPIDER_FOLDER_CREATE_PERMITTION ); + } else { + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.cantcreatecachedir'] ); + } + } else if( !is_writable(DIR_PATH_CACHE) ){ + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.cachedirisnotwritable'] ); + } + } + + if( !file_exists(DIR_PATH_DATA) ) { + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.datadirisnotfound'] ); + } else if( !is_writable(DIR_PATH_DATA) ){ + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.datadirisnotwritable'] ); + } else { + if( !file_exists(DIR_PATH_LOG) ) { + if( @mkdir( DIR_PATH_LOG, SPIDER_FOLDER_CREATE_PERMITTION ) ) { + @chmod( DIR_PATH_LOG, SPIDER_FOLDER_CREATE_PERMITTION ); + } else { + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.cantcreatelogdir'] ); + } + } else if( !is_writable(DIR_PATH_LOG) ){ + array_push( $errors, $GLOBALS['spider.messages']['spider.finctions.logdirisnotwritable'] ); + } + } + return $errors; +} +/** + * コアエラーが発生した場合に出力して処理を終了します。 + */ +function spider_exitWithCoreError($message) { + header('Content-type: text/plain;charset=UTF-8'); + die('Core Error: '.$message); +} +/** + * spiderにおけるセッションを開始します + * セッションIDの重複を避けるため、生成したIDのセッションが存在するかどうか + * 確認してからセッションIDを発行します + * 新規セッション発行時にロックをかけるため通常のPHPセッションスタートする場合よりも + * 多少のオーバーヘッドがあります。 + */ +function spider_session_start() { + // セッション名を確認 + $session_name = session_name(); + // 送信されたセッションIDを取得 + $session_id = trim($_COOKIE[$session_name]); + if( is_null($session_id) || strlen($session_id) == 0 ) { + $session_id = trim($_GET[$session_name]); + if( is_null($session_id) || strlen($session_id) == 0 ) { + $session_id = trim($_POST[$session_name]); + } + } + // セッションIDが送信されていないならセッション開始していない + // 独自にセッションIDを発行する + if( is_null($session_id) || strlen($session_id) == 0 ) { + if( spider_plock() ) { + $session_id = spider_create_session_id(); + $save_path = session_save_path().DIRECTORY_SEPARATOR.'sess_'.$session_id; + while( file_exists($save_path) ) { + $session_id = spider_create_session_id(); + $save_path = session_save_path().DIRECTORY_SEPARATOR.'sess_'.$session_id; + } + session_id($session_id); + session_start(); + $_SESSION['spider.session.initiated'] = serialize(true); + spider_prelease(); + } else { + return false; + } + } else { + session_start(); + if (!isset($_SESSION['spider.session.initiated'])) { + session_regenerate_id(true); + $_SESSION['spider.session.initiated'] = serialize(true); + } + } + return true; +} +/** + * マイクロタイムスタンプを元にランダム文字列のセッションIDを生成します。 + */ +function spider_create_session_id() { + $mictime = microtime(); + list( $msec, $sec ) = explode(' ', $mictime ); + $microtimestamp = $sec . str_replace('0.','',$msec ); + $unique_num = + spider_get_random_string(2) + .substr($microtimestamp,0,2) + .spider_get_random_string(2) + .substr($microtimestamp,2,2) + .spider_get_random_string(2) + .substr($microtimestamp,4,2) + .spider_get_random_string(2) + .substr($microtimestamp,6,2) + .spider_get_random_string(2) + .substr($microtimestamp,8,2) + .spider_get_random_string(2) + .substr($microtimestamp,10,2) + .spider_get_random_string(2) + .substr($microtimestamp,12,2) + .spider_get_random_string(2) + .substr($microtimestamp,14,2) + ; + return $unique_num; +} +/** + * ランダム文字列を作成します + */ +function spider_get_random_string( $length = 32 ) { + $str_array = array( + 'A','B','C','D','E','F','G','H','I','J', + 'K','L','M','N','O','P','Q','R','S','T', + 'U','V','W','X','Y','Z', + 'a','b','c','d','e','f','g','h','i','j', + 'k','l','m','n','o','p','q','r','s','t', + 'u','v','w','x','y','z', + '0','1','2','3','4','5','6','7','8','9', + 'A','B','C','D','E','F','G','H','I','J', + 'K','L','M','N','O','P','Q','R','S','T', + 'U','V','W','X','Y','Z', + 'a','b','c','d','e','f','g','h','i','j', + 'k','l','m','n','o','p','q','r','s','t', + 'u','v','w','x','y','z', + '0','1','2','3','4','5','6','7','8','9', + 'A','B','C','D','E','F','G','H','I','J', + 'K','L','M','N','O','P','Q','R','S','T', + 'U','V','W','X','Y','Z', + 'a','b','c','d','e','f','g','h','i','j', + 'k','l','m','n','o','p','q','r','s','t', + 'u','v','w','x','y','z', + '0','1','2','3','4','5','6','7','8','9', + 'A','B','C','D','E','F','G','H','I','J', + 'K','L','M','N','O','P','Q','R','S','T', + 'U','V','W','X','Y','Z', + 'a','b','c','d','e','f','g','h','i','j', + 'k','l','m','n','o','p','q','r','s','t', + 'u','v','w','x','y','z', + '0','1','2','3','4','5','6','7','8','9', + 'A','B','C','D','E','F','G','H','I','J', + 'K','L','M','N','O','P','Q','R','S','T', + 'U','V','W','X','Y','Z', + 'a','b','c','d','e','f','g','h','i','j', + 'k','l','m','n','o','p','q','r','s','t', + 'u','v','w','x','y','z', + '0','1','2','3','4','5','6','7','8','9', + 'A','B','C','D','E','F','G','H','I','J', + 'K','L','M','N','O','P','Q','R','S','T', + 'U','V','W','X','Y','Z', + 'a','b','c','d','e','f','g','h','i','j', + 'k','l','m','n','o','p','q','r','s','t', + 'u','v','w','x','y','z', + '0','1','2','3','4','5','6','7','8','9', + 'A','B','C','D','E','F','G','H','I','J', + 'K','L','M','N','O','P','Q','R','S','T', + 'U','V','W','X','Y','Z', + 'a','b','c','d','e','f','g','h','i','j', + 'k','l','m','n','o','p','q','r','s','t', + 'u','v','w','x','y','z', + '0','1','2','3','4','5','6','7','8','9', + ); + $keys = array_rand( $str_array, $length ); + $string = ''; + foreach( $keys as $key ) { + $string .= $str_array[$key]; + } + return $string; +} +/** + * フォルダ作成ベースの処理ロック + */ +function spider_plock(){ + // 現在ロックがかかっているか確認する + $lock_path = DIR_PATH_LOCK.DIRECTORY_SEPARATOR.'spider.orgsession.mainlock'; + if( spider_pwait() ) { + // ロックがかかっていないならロックディレクトリ作成 + mkdir( $lock_path, SPIDER_FOLDER_CREATE_PERMITTION ); + chmod( $lock_path, SPIDER_FOLDER_CREATE_PERMITTION ); + return true; + } else { + return false; + } +} + +/** + * 指定名のロックを解除します。 + */ +function spider_prelease(){ + $lock_path = DIR_PATH_LOCK.DIRECTORY_SEPARATOR.'spider.orgsession.mainlock'; + if( is_dir( $lock_path ) ){ + rmdir( $lock_path ); + } + return true; +} +/** + * ロックが解除されるまで待機します + */ +function spider_pwait() { + $lock_path = DIR_PATH_LOCK.DIRECTORY_SEPARATOR.'spider.orgsession.mainlock'; + $loop_count = 0; + while( true ) { + $loop_count++; + if( $loop_count > 300 ){ + return false; + } else if ( !is_dir( $lock_path ) ) { + return true; + } else if ( filemtime($lock_path) + 30 < time() ){ + spider_prelease(); + return true; + } else { + usleep(500); + continue; + } + } +} +/** + * 文字列長を比較して$aと$bが同じ場合は0を、$aが$bより長い場合は1を、$aが$bより短い場合は-1を返します。 + */ +function spiderCmp( $a, $b ) { + $alen = strlen($a); + $blen = strlen($b); + if( $alen == $blen ) { + return 0; + } else if( $alen > $blen ) { + return 1; + } else { + return -1; + } +} +/** + * 文字列長を比較して$aと$bが同じ場合は0を、$aが$bより長い場合は-1を、$aが$bより短い場合は1を返します。 + */ +function spiderCmpR( $a, $b ) { + $alen = strlen($a); + $blen = strlen($b); + if( $alen == $blen ) { + return 0; + } else if( $alen > $blen ) { + return -1; + } else { + return 1; + } +} +/** + * CSVデータラインを配列にして返します + */ +function convert_csv_columns( $strings ) { + $strings = str_replace("\r\n","\n",$strings); + $strings = str_replace("\r","\n",$strings); + $columns = explode(',',$strings); + $regist_columns = array(); + $column_value = ''; + // カラム値を""と,の関係維持して正確に分割する + foreach( $columns as $val ) { + if( strlen($column_value) > 0 ) { + $column_value .= ','.$val; + } else { + $column_value .= $val; + } + $quote_count = substr_count( $column_value, '"' ); + if( $quote_count % 2 != 0 ) { + // クォータ数が偶数でない場合はカラムデータが完結していないので次の行へ + } else { + // 完結している場合はカラムとして処理 + if( preg_match('/^"/',$column_value) > 0 && preg_match( '/"$/', $column_value ) > 0 ) { + $column_value = preg_replace('/^"/','',$column_value ); + $column_value = preg_replace('/"$/','',$column_value ); + $column_value = preg_replace('/""/','"',$column_value ); + } + $column_value = mb_convert_kana($column_value,'KVas'); + array_push( $regist_columns, $column_value ); + $column_value = ''; + } + } + return $regist_columns; +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/module/AutoEncode.class.php =================================================================== --- db/current/spider/lib/spider/module/AutoEncode.class.php (rev 0) +++ db/current/spider/lib/spider/module/AutoEncode.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,52 @@ +<?php +require_once( dirname(dirname(__FILE__)) + .DIRECTORY_SEPARATOR."ModuleBase.class.php"); +/** + * spider:POSTおよびGETで入力されたパラメータの文字コードを全てUTF-8に変換する + * アクションモジュールクラス + * + * @package spider spider/moduleパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class spider_module_AutoEncode extends spider_ModuleBase { + function spider_module_AutoEncode() { + } + function execute( & $request ) { + $vars = $_POST; + $strings = print_r($vars,true); + $vars = $_GET; + $strings .= print_r($vars,true); + $vars = null; + $inputCharset = mb_detect_encoding($strings,'auto'); + if( $inputCharset != 'UTF-8' ) { + // POSTパラメータ + $this->encodeHash( $_POST,'UTF-8', $inputCharset ); + // GETパラメータ + $this->encodeHash( $_GET,'UTF-8', $inputCharset ); + } + $request->setAttribute( 'postparams', $_POST ); + $request->setAttribute( 'getparams', $_GET ); + } + /** + * 多次元配列を指定文字セットにエンコードします + */ + function encodeHash( & $hash,$toChar='UTF-8', $fromChar ) { + if( is_array($hash) ) { + foreach( $hash as $key => $val ) { + $encKey = mb_convert_encoding( $key, $toChar, $fromChar ); + if( is_array($val) ) { + $this->encodeHash( $hash[$key],$toChar,$fromChar ); + $hash[$encKey] = $hash[$key]; + } else { + $val = mb_convert_encoding( $val, $toChar, $fromChar ); + $hash[$key] = $val; + $hash[$encKey] = $val; + } + } + } + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/module/AutoFormat.class.php =================================================================== --- db/current/spider/lib/spider/module/AutoFormat.class.php (rev 0) +++ db/current/spider/lib/spider/module/AutoFormat.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,44 @@ +<?php +require_once( dirname(dirname(__FILE__)) + .DIRECTORY_SEPARATOR."ModuleBase.class.php"); +/** + * spider:POSTおよびGETで入力されたパラメータの文字列を以下のとおり書式変換する + * 1)「半角カタカナ」を「全角カタカナ」に変換します。 + * 2)濁点付きの文字を一文字に変換します。 + * 3)「全角」英数字を「半角」に変換します。 + * 4)「全角」スペースを「半角」に変換します。 + * アクションモジュールクラス + * + * @package spider spider/moduleパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 5.2 + */ +class spider_module_AutoFormat extends spider_ModuleBase { + function spider_module_AutoFormat() { + } + function execute( & $request ) { + // POSTパラメータ + $this->convertKana( $_POST,'KVas','UTF-8' ); + // GETパラメータ + $this->convertKana( $_GET,'KVas','UTF-8' ); + $request->setAttribute( 'postparams', $_POST ); + $request->setAttribute( 'getparams', $_GET ); + } + /** + * 多次元配列の値をフォーマットにエンコードします + */ + function convertKana( & $hash, $format='KVas', $toChar='UTF-8') { + if( is_array($hash) ) { + foreach( $hash as $key => $val ) { + if( is_array($val) ) { + $this->convertKana( $hash[$key] ); + } else { + $hash[$key] = mb_convert_kana($val,$format,$toChar); + } + } + } + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/module/NoCache.class.php =================================================================== --- db/current/spider/lib/spider/module/NoCache.class.php (rev 0) +++ db/current/spider/lib/spider/module/NoCache.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,26 @@ +<?php +require_once( dirname(dirname(__FILE__)) + .DIRECTORY_SEPARATOR."ModuleBase.class.php"); +/** + * spider:No CacheをHTTPレスポンスヘッダに出力するアクションモジュールクラス + * + * @package spider spider/moduleパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class spider_module_NoCache extends spider_ModuleBase { + + function spider_module_NoCache(){ + } + + function execute( & $request ) { + $request->setResponseHeader( 'Expires', 'Mon, 26 Jul 1997 05:00:00 GMT' ); + $request->setResponseHeader( 'Cache-Control', 'no-store, no-cache, must-revalidate' ); + $request->setResponseHeader( 'Cache-Control', 'pre-check=0, post-check=0, max-age=0' ); + $request->setResponseHeader( 'Pragma', 'no-cache' ); + $request->setResponseHeader( 'Expires', '0' ); + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/tags/Charset.class.php =================================================================== --- db/current/spider/lib/spider/tags/Charset.class.php (rev 0) +++ db/current/spider/lib/spider/tags/Charset.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,167 @@ +<?php +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'TagBase.class.php'); +/** + * HTML用変換タグ:charsetタグクラス + * + * {charset:[文字コード指定文字列]}で指定された文字コードでページを出力するよう変更します。 + * + * [文字コード指定文字列]にはPHPのmbstringによる文字コード指定方法を用いてください。 + * 例)Windows向けShift_JISの場合→SJIS-win + * + * また出力時にHTMLタグ内の以下のメタタグ内の文字セットの書き換えも試みます。 + * <meta http-equiv="Content-type" content="text/html; charset=UTF-8"> + * + * 記述例) + * {charset:SJIS-win} + * + * ※本タグはテンプレート・ウィジェット・ページ全てあわせて1つのみ指定できます。 + * 複数のタグが記述されている場合、出力文字列の一番最後に記述されているcharset指定が有効になります。 + * + * @package spider spiderのコアパッケージ + * @subpackage tags spiderのテンプレートタグ変換クラスパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class spider_tags_Charset extends spider_tags_TagBase { + + /** + * コンストラクタ + */ + function spider_tags_Charset() { + $this->priority = 30; + } + /** + * コンバートメソッド + */ + function convert( &$result_strings, &$build_information ){ + // charsetタグ内文字列 + $charsetStrings = ''; + if ( preg_match_all( '/\\{charset\\:[^\\}]*?\\}/' + , $result_strings + , $output_array + , PREG_PATTERN_ORDER ) > 0 ) { + // charsetタグが明示的に指定されている場合、最後に書かれたものを適用 + foreach ( $output_array as $output ) { + foreach ( $output as $target ) { + $charsetStrings = preg_replace( '/\\{charset\\:/','', $target ); + $charsetStrings = preg_replace( '/\\}/','', $charsetStrings ); + // 空行にならないよう前後が改行も削除 + $result_strings = str_replace( "\n".$target."\n", "", $result_strings ); + $result_strings = str_replace( $target, "", $result_strings ); + $charsetStrings = trim($charsetStrings); + } + } + } else { + // charsetタグがない場合はユーザーエージェント指定の文字コードがあるなら適用 + if( isset($GLOBALS['SPIDER_USER_AGENT_CLASS_OUTPUT_CHARSET']) + && isset($GLOBALS['SPIDER_USER_AGENT_CLASS_OUTPUT_CHARSET'][$build_information->agent_class]) + && strlen($GLOBALS['SPIDER_USER_AGENT_CLASS_OUTPUT_CHARSET'][$build_information->agent_class]) > 0 ) { + // 対象ユーザーエージェント分類の文字コードが指定されているなら適用 + $charsetStrings = $GLOBALS['SPIDER_USER_AGENT_CLASS_OUTPUT_CHARSET'][$build_information->agent_class]; + } else { + // 定義がないなら常にUTF-8で出力する + $charsetStrings = 'UTF-8'; + } + } + + $charsetArray = explode( ' ', $charsetStrings ); + // 最初の項は必ず文字コード + $outputCharset = trim(array_shift($charsetArray)); + $convert_kana = ''; + $internal_charset = 'UTF-8'; + $output_handler = 'mb_output_handler'; + $detect_order = 'UTF-8,EUC-JP,SJIS,SJIS-win,JIS,UTF-7'; + $language = 'japanese'; + // 残りの項の解析 + foreach( $charsetArray as $str ) { + if( strlen(trim($str)) > 0 ) { + list( $key, $val ) = explode('=',trim($str)); + $key = trim($key); + $val = trim($val); + if( strlen($val) == 0 ) { + // 単一項目ならconvert_kanaと判断する(下位互換) + $convert_kana = $key; + } else if( 'internal_charset' == $key ){ + $internal_charset = $val; + } else if( 'output_handler' == $key ) { + $output_handler = $val; + } else if( 'convert_kana' == $key ) { + $convert_kana = $val; + } else if( 'detect_order' == $key ) { + $detect_order = $val; + } else if( 'language' == $key ) { + $language = $val; + } + } + } + // 互換の為buil_informationにも設定 + $build_information->output_charset = $outputCharset; + $build_information->convert_kana = $convert_kana; + $build_information->output_handler = $output_handler; + $build_information->internal_charset = $internal_charset; + $build_information->detect_order = $detect_order; + $build_information->output_language = $language; + + // 出力HTML内の文字コード指定変換 + $htmlReplaceCode = $outputCharset; + if( isset($GLOBALS['DEF_SPIDER_CHARSET_REPLACE_ENCODINGS'][$outputCharset]) ) { + // 変換文字が定義されているなら変換文字を使う(SJIS等の場合Shift_JISにするなどの為) + $htmlReplaceCode = $GLOBALS['DEF_SPIDER_CHARSET_REPLACE_ENCODINGS'][$outputCharset]; + } + // メタタグのcharsetを変更 + $result_strings = preg_replace( + '/(<[mM][eE][tT][aA][^>]*\\s[cC][oO][nN][tT][eE][nN][tT]\\=[\'"][^\'"]*[cC][hH][aA][rR][sS][eE][tT]\\=)([^\'"\\;]+)([^\'"]*[\'"][^>]*>)/', + '$1'.$htmlReplaceCode.'$3', + $result_strings + ); + // XML宣言もあれば変更 + $result_strings = preg_replace( + '/(<\\?xml[^>]*\\s[eE][nN][cC][oO][dD][iI][nN][gG]\\=[\'"])([^\'"]*)([^\'"]*[\'"][^>]*>)/', + '$1'.$htmlReplaceCode.'$3', + $result_strings + ); + + // 前処理の文字コードフラッシュコードを追加 + $process_code = "ob_start('".$output_handler."');\n"; + $process_code .= "ob_implicit_flush( false );\n"; + $process_code .= "mb_language('".$language."');\n"; + $process_code .= "mb_detect_order('".$detect_order."');\n"; + $process_code .= "mb_internal_encoding('".$internal_charset."');\n"; + // 2009-07-01 DoCoMo XHTML対応 暫定 PHPheaderでセットしたContent-Typeの文字セットでob_get_cleanの取得文字コードを勝手に操作する為UTF-8で指定... + if( preg_match('/\\<\\!DOCTYPE\\shtml\\sPUBLIC\\s\\"\\-\\/\\/i\\-mode group/',$result_strings) > 0 ) { + $process_code .= 'if(preg_match(\'/^DoCoMo/\',$_SERVER[\'HTTP_USER_AGENT\']) > 0 ) {'."\n"; + $process_code .= '$request->setResponseHeader(\'Content-Type\',\'application/xhtml+xml;charset='.$htmlReplaceCode.'\');'."\n"; + $process_code .= '}'."\n"; + } + + if( !isset($build_information->preview_process_hash) + || !is_array($build_information->preview_process_hash) ){ + $build_information->preview_process_hash = array(); + } + if( !isset($build_information->preview_process_hash[$this->priority]) + || !is_array($build_information->preview_process_hash[$this->priority]) ){ + $build_information->preview_process_hash[$this->priority] = array(); + } + array_push( $build_information->preview_process_hash[$this->priority], $process_code ); + + // 表示文字列に対する処理実行コードを記述 + if( !isset($build_information->convert_view_process_hash) + || !is_array($build_information->convert_view_process_hash) ){ + $build_information->convert_view_process_hash = array(); + } + if( !isset($build_information->convert_view_process_hash[$this->priority]) + || !is_array($build_information->convert_view_process_hash[$this->priority]) ){ + $build_information->convert_view_process_hash[$this->priority] = array(); + } + if( strlen( trim( $convert_kana ) ) > 0 ) { + $process_code = '$outstr = mb_convert_kana( $outstr, "' . $convert_kana . '" );'."\n"; + array_push( $build_information->convert_view_process_hash[$this->priority], $process_code ); + } else if ( 'docomo' == $build_information->agent_class || 'docomo2' == $build_information->agent_class || 'softbank' == $build_information->agent_class || 'au' == $build_information->agent_class ) { + $process_code = '$outstr = mb_convert_kana( $outstr, "kna" );'."\n"; + array_push( $build_information->convert_view_process_hash[$this->priority], $process_code ); + } + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/tags/DynamicPage.class.php =================================================================== --- db/current/spider/lib/spider/tags/DynamicPage.class.php (rev 0) +++ db/current/spider/lib/spider/tags/DynamicPage.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,137 @@ +<?php +/** + * HTML用変換タグの動的ページタグクラス + * + * {dynamic-page}タグをブラウザに応じて準備された動的ページフォルダ内のファイルに記述された + * 文字列に変更します。 + * + * ブラウザごとの振り分けフォルダの定義はDATA/define.inc.phpの記述に準じます。 + * ターゲットブラウザのフォルダが見つからない場合は、defaultフォルダ内を検索します。 + * + * 定数 DIR_NAME_PAGESが定義されていない場合は変換を実行しません。 + * + * 通常、DIR_NAME_PAGESは公開ドキュメントルート内の + * spider.inc.phpファイルのファイル行頭部分で定義しています。 + * デフォルトでは[pages]となっています。 + * + * define('DIR_NAME_PAGES', 'pages'); + * + * 一つのspiderのDATAフォルダで複数のドキュメントルートを公開したい場合は、 + * ドキュメントルートごとのspider.inc.phpにてDIR_NAME_PAGESをpages以外に + * 変更し、DATAフォルダ内に指定した名前のフォルダを作成してください。 + * + * 例) + * define('DIR_NAME_PAGES', 'pages2'); + * DATA/pages2フォルダを作成 + * + * @package spider spiderのコアパッケージ + * @subpackage tags spiderのテンプレートタグ変換クラスパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'TagBase.class.php'); +class spider_tags_DynamicPage extends spider_tags_TagBase { + + var $request_uri = null; + + /** + * コンストラクタ + */ + function spider_tags_DynamicPage() { + $this->priority = 1; + } + /** + * コンバートメソッド + */ + function convert( &$result_strings, &$build_information ){ + + // ユーザーエージェントタイプ確認 + $agent_class = $build_information->agent_class; + + // ダイナミックページの内容 + $dynamic_page_contents = ''; + if( defined('DIR_NAME_PAGES') && defined('DIR_PATH_PAGES') ) { + // 動的ページファイルパスの確定 + $page_file_path = $this->getRealPageFilePath( $build_information ); + if( false !== $page_file_path ) { + // ファイル内容を取得 + $dynamic_page_contents = file_get_contents($page_file_path); + } else { + // ファイルが取得できなかった場合 + $dynamic_page_contents = 'ご利用のブラウザではこのページを閲覧できません。' + .'['.$build_information->agent_class.']'; + } + } else { + $dynamic_page_contents = 'ダイナミックページタグを利用するドキュメントルートとして指定されていません。'; + } + + // ダイナミックタグ変換 + preg_match_all( '/\\{dynamic\\-page\\}/' + , $result_strings + , $output_array + , PREG_PATTERN_ORDER ); + foreach ( $output_array as $output ) { + foreach ( $output as $target ) { + $result_strings = preg_replace( '/\\{dynamic\\-page\\}/' + ,$dynamic_page_contents, $result_strings ); + } + } + } + /** + * ユーザーエージェント分類にあったテンプレートファイルのパスを取得する + */ + function getRealPageFilePath( &$build_information ) { + // ターゲットユーザーエージェントページファイルを確認 + $page_file_path = $this->getAgentFile( $build_information ); + if( file_exists( $page_file_path ) ) { + $build_information->addCompareFile( $page_file_path ); + return $page_file_path; + } else { + // ターゲットファイルが存在しない場合、生成されていれば再ビルド + $build_information->addConfirmFile( $page_file_path ); + } + // 代替ページファイルの確認 + $alt_agent = null; + if( isset($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH']) + && isset($GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'][$build_information->agent_class]) ) { + $alt_agent = $GLOBALS['SPIDER_USER_AGENT_CLASS_ALT_HASH'][$build_information->agent_class]; + } + if( !is_null($alt_agent) && strlen($alt_agent) > 0 ) { + // 代替ユーザーエージェントが指定されているなら + $page_file_path = $this->getAgentFile( $build_information, $alt_agent ); + if( file_exists( $page_file_path ) ) { + // 代替ファイルがあるならタイムスタンプ比較を追加してリターン + $build_information->addCompareFile( $page_file_path ); + return $page_file_path; + } else { + // 代替ファイルもない場合、出来ていたら再ビルド + $build_information->addConfirmFile( $page_file_path ); + } + } + // デフォルトファイルを確認 + $page_file_path = $this->getAgentFile( $build_information, 'default' ); + if( file_exists( $page_file_path ) ) { + // デフォルトファイルがあるならタイムスタンプ比較を追加してリターン + $build_information->addCompareFile( $page_file_path ); + return $page_file_path; + } else { + // デフォルトファイルもない場合、出来ていたら再ビルド + $build_information->addConfirmFile( $page_file_path ); + } + return false; + } + /** + * ユーザーエージェント分類ごとのファイルパスを取得します(存在確認なし) + */ + function getAgentFile( & $build_information, $agent_class=null ) { + if( is_null($agent_class) || strlen($agent_class) == 0 ) { + $agent_class = $build_information->agent_class; + } + $page_file_path = DIR_PATH_PAGES + .DIRECTORY_SEPARATOR.$agent_class.$build_information->getPageUri(); + return $page_file_path; + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/tags/Foreach.class.php =================================================================== --- db/current/spider/lib/spider/tags/Foreach.class.php (rev 0) +++ db/current/spider/lib/spider/tags/Foreach.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,202 @@ +<?php +/** + * HTML用変換タグ:foreachタグクラス + * + * $requestの属性に登録された配列値に対してforeach処理をするタグの変換クラスです。 + * 開始タグのオプションとして以下の値をとることができます。 + * + * + キーを伴うループを実現したい場合: foreach( .. as key => value )形式 + * 1番目:配列の属性名 + * 2番目:配列のキー + * 3番目:配列の値 + * + * + キーを伴なわないループを実現したい場合: foreach( .. as value )形式 + * 1番目:配列の属性名 + * 2番目:配列の値 + * + * このタグはループ箇所の最後を必ず{/foreach}タグで閉じる必要があります。 + * + * 記述例) + * {foreach:attribute_name key value} + * {write:value}<br /> + * {/foreach} + * + * @package spider spiderのコアパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR."TagBase.class.php"); +class spider_tags_Foreach extends spider_tags_TagBase { + + /** + * コンストラクタ + */ + function spider_tags_Foreach() { + $this->tag_name = 'foreach'; + } + /** + * コンバートメソッド + */ + function convert( &$result_strings, &$build_information ){ + 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.'; '; + 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.'; '; + } + $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); + } + } + 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; + } + } + } + // ループ最後のポジションから最後の要素を切り出し + $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 Added: db/current/spider/lib/spider/tags/If.class.php =================================================================== --- db/current/spider/lib/spider/tags/If.class.php (rev 0) +++ db/current/spider/lib/spider/tags/If.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,327 @@ +<?php +/** + * HTML用変換タグ: ifタグクラス + * + * requestに登録された属性値に対して、phpコードで値を取り出すことなくページ内でのif分岐利用を + * 可能にするifタグ機能を実現する変換タグです。 + * ifタグは必ず条件分岐終了地点を分岐終了タグ{/if}で閉じる必要があります。 + * また、現状、{else}タグを記述することによってif(..){...}else{..}文を実現することができます。 + * (現在のバージョンではelse ifは実現できません。) + * + * 記述例) + * {if:value='a'} + * 値はaです + * {else} + * 値はaではありません + * {/if} + * + * また、{if:条件文}の条件文は、and/orで区切って複数の条件を指定することができます。 + * 条件文の中で、アプリケーションが判別可能な関数を記述することも可能です。 + * + * 記述例) + * {if:strlen(value)>0 and value='c'} + * 値はcで文字が入っています + * {else} + * 文字が入っていないかcではありません + * {/if} + * + * @package spider spiderのコアパッケージ + * @version 1.1.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR."TagBase.class.php"); +class spider_tags_If extends spider_tags_TagBase { + + /** + * コンストラクタ + */ + function spider_tags_If() { + } + /** + * コンバートメソッド + */ + function convert( &$result_strings, &$build_information ){ + // ifの変換 + $vars_tags_aray = array(); + preg_match_all( '/\\{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( '/\\{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 ) { + // 下位互換の文字列変更 + $strings = $this->oldCondition2NewCondition( $strings ); + // ネイティブコードに変換 + $attribute_name_array = array(); + return $this->tagCode2NativeCode( $strings, $attribute_name_array ); + } + /** + * if条件文の式を解析する + * 定義済み文字列: and / or / = / != / > / < / + / - / * // is null /is not null/in + */ + function parseCondition( $strings, $prefix=1 ) { + + // 内部で利用されている変数を全て取り出す + $var_name_array = array(); + $and_array = explode( ' and ', $strings ); + foreach( $and_array as $condition_and ) { + $or_array = explode( ' or ', $condition_and ); + foreach( $or_array as $condition_or ) { + $divider = ''; + if( preg_match('/\\<=/', $condition_or ) > 0 ) { + $divider = '<='; + } else if( preg_match('/\\</', $condition_or ) > 0 ) { + $divider = '<'; + } else if( preg_match('/\\>=/', $condition_or ) > 0 ) { + $divider = '>='; + } else if( preg_match('/\\>/', $condition_or ) > 0 ) { + $divider = '>'; + } else if( preg_match('/\\!=/', $condition_or ) > 0 ) { + $divider = '!='; + } else if( preg_match('/\\=/', $condition_or ) > 0 ) { + $divider = '='; + } else if( preg_match('/ is not null/', $condition_or ) > 0 ) { + $divider = ' is not null'; + } else if( preg_match('/ is null/', $condition_or ) > 0 ) { + $divider = ' is null'; + } else if( preg_match('/ in /', $condition_or ) > 0 ) { + $divider = ' in '; + } else { + $divider = ''; + } + if( $divider == ' in ' ) { + list( $pre, $post ) = explode( $divider, $condition_or ); + $str = 'in_array('.$pre.','.$post.')'; + $strings = str_replace( $condition_or, $str, $strings ); + } + if( $divider == ' is null' ) { + list( $pre ) = explode( $divider, $condition_or ); + $str = 'is_null('.$pre.') || ( is_string('.$pre.') && strlen('.$pre.') == 0 ) '; + $strings = str_replace( $condition_or, $str, $strings ); + } + if( $divider == ' is not null' ) { + list( $pre ) = explode( $divider, $condition_or ); + $str = '!is_null('.$pre.')'; + $strings = str_replace( $condition_or, $str, $strings ); + } + // =/ !=で前または後が空文字列だった場合の対策 + if( $divider == '=' ) { + list( $pre, $post ) = explode( $divider, $condition_or ); + if( strlen(trim($pre)) == 0 ) { + $pre = "''"; + } + if( strlen(trim($post)) == 0 ) { + $post = "''"; + } + $str = trim($pre)." == ".trim($post); + $strings = str_replace( $condition_or, $str, $strings ); + } + if( $divider == '!=' ) { + list( $pre, $post ) = explode( $divider, $condition_or ); + if( strlen(trim($pre)) == 0 ) { + $pre = "''"; + } + if( strlen(trim($post)) == 0 ) { + $post = "''"; + } + $str = trim($pre)." != ".trim($post); + $strings = str_replace( $condition_or, $str, $strings ); + } + + if( strlen($divider) > 0 ) { + // 比較演算子で区切れるなら計算式の項を前から順に取り出す + $element_array = explode($divider,$condition_or); + foreach( $element_array as $element ) { + $pos=0; + for( $i=0; $i<strlen($element); $i++ ) { + $char = substr($element,$i,1); + if( '+' == $char || '-' == $char + || '*' == $char || '/' == $char || '%' == $char + || '(' == $char || ')' == $char || ',' == $char || '!' == $char ) { + // 演算子が登場したらひとつ前までを文字列切り出し + $str = substr( $element, $pos, $i-$pos ); + $pos = $i+1; + if( '(' != $char && strlen( trim($str) ) > 0 ) { + // 関数名でなければ追加 + $var_name_array[trim($str)] = ''; + } + } + } + // ループ最後のポジションから最後の要素を切り出し + $str = substr( $element, $pos, $i-$pos ); + if( strlen( trim($str) ) > 0 ) { + $var_name_array[trim($str)] = ''; + } + } + } else { + // 比較演算子で区切れないなら単一要素 + $pos=0; + for( $i=0; $i<strlen($condition_or); $i++ ) { + $char = substr($condition_or,$i,1); + if( '+' == $char || '-' == $char + || '*' == $char || '/' == $char || '%' == $char + || '(' == $char || ')' == $char || ',' == $char || '!' == $char ) { + // 演算子が登場したらひとつ前までを文字列切り出し + $str = substr( $condition_or, $pos, $i-$pos ); + $pos = $i+1; + if( '(' != $char && strlen( trim($str) ) > 0 ) { + // 関数名でなければ追加 + $var_name_array[trim($str)] = ''; + } + } + } + // ループ最後のポジションから最後の要素を切り出し + $str = substr( $condition_or, $pos, $i-$pos ); + if( strlen( trim($str) ) > 0 ) { + $var_name_array[trim($str)] = ''; + } + } + } + } + // 変数一時格納配列 + $temporary_valiable_getter_array = array(); + + // 変数の変換を確認 + $vcounter = 0; + foreach( $var_name_array as $key => $value ) { + if( strlen($key) > 0 ) { + if( is_numeric( $key ) ) { + // 変数が数字なら変換対象としない + $var_name_array[$key] = $key; + } else if( 'true' == $key || 'false' == $key ) { + // trueとfalseはそのまま利用する + $var_name_array[$key] = $key; + } else { + // 変数が文字列の場合 + $tmp_name = '$____' . sprintf('%03d',$prefix) . sprintf('%03d',$vcounter); + $var_name_array[$key] = $tmp_name; + if( preg_match('/^\\\'(.)*\\\'$/',$key) > 0 ) { + $str = $tmp_name. '='.$key.';'."\n"; + array_push( $temporary_valiable_getter_array, $str ); + } else { + $vname = $key; + $vparam = ''; + if( strpos($key,'::') !== false ) { + list( $vname, $vparam ) = explode('::',$key); + } + // 一時編集取得文字列作成 + $str = $tmp_name. '=$request_object->getAttribute(\''.$vname.'\');'."\n"; + $str .= 'if( !$request_object->existAttribute("'.$vname.'") ){'."\n"; + $str .= "\t".$tmp_name. '=\''.$vname.'\';'."\n"; + $str .= '} else if(\'array\'==gettype('.$tmp_name.')) {'."\n"; + if( is_numeric($vparam) ) { + $str .= "\t".$tmp_name. '='.$tmp_name.'['.$vparam.'];'."\n"; + } else if( strlen(trim($vparam)) > 0 ){ + $str .= "\t".$tmp_name. '='.$tmp_name.'[\''.$vparam.'\'];'."\n"; + } + $str .= '} else if(\'object\'==gettype('.$tmp_name.')) {'."\n"; + if( is_numeric($vparam) ) { + // オブジェクトの場合、数値は許可できません。(変数名、メソッド名は数値から始められない) + $str .= "\t".'$request_object->addError(\'オブジェクトの添え字には数字を指定できません。\');'."\n"; + } else if( strlen(trim($vparam)) > 0 ){ + $str .= "\t".$tmp_name. '='.$tmp_name.'->'.$vparam.';'."\n"; + } + $str .= '}'."\n"; + array_push( $temporary_valiable_getter_array, $str ); + } + $vcounter++; + } + } + } + // 変数配列を文字列の長い順にソート + $order_array = array(); + foreach( $var_name_array as $key => $value ) { + if( !isset($order_array[strlen($key)]) || !is_array( $order_array[strlen($key)] ) ) { + $order_array[strlen($key)] = array(); + } + array_push($order_array[strlen($key)],$key); + } + krsort($order_array); + $new_var_name_array = array(); + foreach( $order_array as $item_array ) { + foreach( $item_array as $name ) { + $new_var_name_array[$name] = $var_name_array[$name]; + } + } + + // 渡された文字列の置換 + foreach( $new_var_name_array as $key => $value ) { + $strings = str_replace( $key, $value, $strings ); + } + // and or の置換 + $strings = str_replace( 'and', '&&', $strings ); + $strings = str_replace( 'or', '||', $strings ); + $strings = 'if( ' . $strings .' ) {'; + // 変数取り出し文字列を冒頭に追加 + $strings = implode("\n",$temporary_valiable_getter_array).$strings; + $strings = '<?php ' . $strings .' ?>'; + + return $strings; + } + /** + * 記述の下位互換の為、条件式文字列を変換するメソッド + */ + function oldCondition2NewCondition( $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); + return $strings; + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/tags/Module.class.php =================================================================== --- db/current/spider/lib/spider/tags/Module.class.php (rev 0) +++ db/current/spider/lib/spider/tags/Module.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,61 @@ +<?php +/** + * HTML用変換タグ:モジュールタグ + * + * {module:[パッケージ名].[モジュール名]}によってテンプレート、ウィジェット、ページファイル内から + * プログラムモジュールを呼び出す処理を追加するタグです。 + * + * テンプレート、ウィジェット、ページ内のどこで記述されても、 + * モジュール実行はページ表示前に行われます。 + * + * モジュールタグは追加パラメータとして以下のパラメータをとることができます。 + * + * post([URLエンコードしたPOST文字列]) + * モジュール実行時に、POST値があるなしに関わらず強制的にPOSTに代入してモジュールを + * 実行することができます。 + * POST値変更は呼び出しモジュールに対する一時的なものであり、 + * 他のモジュールを実行される場合には元のPOST値に復元されます。 + * + * get([URLエンコードしたGET文字列]) + * モジュール実行時に、GET値があるなしに関わらず強制的にPOSTに代入してモジュールを + * 実行することができます。 + * GET値変更は呼び出しモジュールに対する一時的なものであり、 + * 他のモジュールを実行される場合には元のGET値に復元されます。 + * + * attribute_prefix([英数字のプレフィックス]) + * 実行モジュールで登録する属性名は通常[パッケージ名].[モジュール名].が付加されますが + * 本オプションパラメータにて[プレフィックス].[パッケージ名].[モジュール名].として + * 属性名を変更することができます。 + * 同じモジュールを複数の条件で呼び出して結果を表示する場合にpost()やget()と組み合わせ + * ることで有効な利用ができます。 + * + * @package spider spiderのコアパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR."TagBase.class.php"); +class spider_tags_Module extends spider_tags_TagBase { + + /** + * コンストラクタ + */ + function spider_tags_Module() { + $this->priority = 10; + $this->tag_name = 'module'; + } + /** + * 個々のタグ文字列の変換後文字列を取得します + */ + 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 Added: db/current/spider/lib/spider/tags/OutputHtml.class.php =================================================================== --- db/current/spider/lib/spider/tags/OutputHtml.class.php (rev 0) +++ db/current/spider/lib/spider/tags/OutputHtml.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,110 @@ +<?php +/** + * 変換タグ HTMLファイル出力を指定する + * + * {output-html}とテンプレート、ウィジェット、ページ内のどこかに記述することで + * 実行されたURIのファイルと同じフォルダに同名で.htmlファイルを出力します。 + * + * 本タグ利用時には、ドキュメントルートフォルダ以下のフォルダ全てがWebサーバ実行ユーザにより + * 書込み可能な状態である必要があります。 + * + * 有効なオプション) + * lifetime=[ライフタイムを秒で指定] + * + * 記述例) + * {output-html:lifetime=300} + * 前回のHTML出力から300秒を過ぎていた場合新たにHTMLファイルを出力しなおす + * + * @package spider spiderのコアパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR."TagBase.class.php"); +class spider_tags_OutputHtml extends spider_tags_TagBase { + + /** + * コンストラクタ + */ + function spider_tags_OutputHtml() { + $this->priority = 999; + } + /** + * コンバートメソッド + */ + function convert( &$result_strings, &$build_information ){ + // charsetタグ内文字列 + $output_option = ''; + $is_exists = false; + if ( preg_match_all( '/\\{output\\-html[^\\}]*?\\}/' + , $result_strings + , $output_array + , PREG_PATTERN_ORDER ) > 0 ) { + foreach ( $output_array as $output ) { + foreach ( $output as $target ) { + $output_option = preg_replace( '/\\{output\\-html/','', $target ); + $output_option = trim(preg_replace( '/\\}/','', $output_option )); + if( strlen($output_option) == 0 || preg_match('/^\\:/',$output_option) > 0 ) { + // 文字がないか:から始まる場合はオプション指定なので変換実行 + $result_strings = str_replace( $target, "", $result_strings ); + $output_option = trim($output_option); + $output_option = preg_match('/^\\:/','',$output_option); + $is_exists = true; + } else { + // :以外の文字が続く場合は違うタグなので処理しない + } + } + } + } + + // 存在するならHTML出力行を追加 + if( $is_exists ) { + // オプションの整理 + $option_values = explode(' ',$output_option); + $option_hash = array(); + foreach( $option_values as $option_value ) { + $name = $option_value; + $value = $option_value; + if( preg_match('/\\=/',$option_value) > 0 ) { + list( $name, $value ) = explode('=',$option_value); + $name = trim($name); + $value = trim($value); + } + $option_hash[$name] = $value; + } + // HTMLファイルのライフタイム(sec) + $lifetime = 3600; + if( isset($option_hash['lifetime']) + && preg_match('/^[0-9]{1-10}$/', $option_hash['lifetime'] ) > 0 ) { + $lifetime = $option_hash['lifetime']; + } + + // コード追加 + $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"; + $process_code .= 'if (@flock($fp, LOCK_EX)) {'."\n"; + $process_code .= 'fwrite($fp,$outstr);'."\n"; + $process_code .= 'flock($fp, LOCK_UN);'."\n"; + $process_code .= '}'."\n"; + $process_code .= '@fclose( $fp );'."\n"; + $process_code .= '@chmod( "'.$html_path.'", '.SPIDER_FILE_CREATE_PERMITTION.' );'."\n"; + $process_code .= '}'."\n"; + $process_code .= '}'."\n"; + if( !isset($build_information->convert_view_process_hash) + || !is_array($build_information->convert_view_process_hash) ){ + $build_information->convert_view_process_hash = array(); + } + if( !isset($build_information->convert_view_process_hash[$this->priority]) + || !is_array($build_information->convert_view_process_hash[$this->priority]) ){ + $build_information->convert_view_process_hash[$this->priority] = array(); + } + array_push( $build_information->convert_view_process_hash[$this->priority], $process_code ); + } + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/tags/PageTitle.class.php =================================================================== --- db/current/spider/lib/spider/tags/PageTitle.class.php (rev 0) +++ db/current/spider/lib/spider/tags/PageTitle.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,57 @@ +<?php +/** + * HTML用変換タグ:ページタイトルタグ + * + * {page-title:[ページタイトル文言]}で、モジュール実行に優先して + * ページタイトルをpage_titleという属性名でrequestに登録します。 + * + * @package spider spiderのコアパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR."TagBase.class.php"); +class spider_tags_PageTitle extends spider_tags_TagBase { + + /** + * コンストラクタ + */ + function spider_tags_PageTitle() { + $this->priority = 60; + } + /** + * コンバートメソッド + */ + function convert( &$result_strings, &$build_information ){ + $page_title = ''; + // ページ名指定行を取得 + if( preg_match_all( '/\\{page\\-title\\:[^\\}]*?\\}/' + , $result_strings + , $output_array + , PREG_PATTERN_ORDER ) > 0 ) { + foreach ( $output_array as $output ) { + foreach ( $output as $target ) { + $page_title = preg_replace( '/\\{page\\-title\\:/','', $target ); + $page_title = preg_replace( '/\\}/','', $page_title ); + $result_strings = str_replace( "\n".$target."\n", "", $result_strings ); + $result_strings = str_replace( $target, "", $result_strings ); + $page_title = trim($page_title); + } + } + } + // 前処理追加:ページタイトルを属性にセット + $process_code = '$page_title="'.str_replace("'","\\'",$page_title).'";'."\n"; + $process_code .= '$request_object->setAttribute("page_title",$page_title );'."\n"; + if( !isset($build_information->preview_process_hash) + || !is_array($build_information->preview_process_hash) ){ + $build_information->preview_process_hash = array(); + } + if( !isset($build_information->preview_process_hash[$this->priority]) + || !is_array($build_information->preview_process_hash[$this->priority]) ){ + $build_information->preview_process_hash[$this->priority] = array(); + } + array_push( $build_information->preview_process_hash[$this->priority], $process_code ); + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/tags/RewriteDocumentRoot.class.php =================================================================== --- db/current/spider/lib/spider/tags/RewriteDocumentRoot.class.php (rev 0) +++ db/current/spider/lib/spider/tags/RewriteDocumentRoot.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,124 @@ +<?php +/** + * HTML用変換タグ:ドキュメントルート自動変換タグ + * + * {rewrite-document-root:[true/false]} + * + * trueが指定された場合 + * 最終的に出力するHTML文字列内のhref="",src=""内のURIが/から始まっていた場合、 + * 自動的にアプリケーション設置ルートを前に付加するタグです。 + * + * デフォルトはtrueです。 + * + * @package spider spiderのコアパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR."TagBase.class.php"); +class spider_tags_RewriteDocumentRoot extends spider_tags_TagBase { + + /** + * コンストラクタ + */ + function spider_tags_RewriteDocumentRoot() { + $this->priority = 0; + } + /** + * コンバートメソッド + */ + function convert( &$result_strings, &$build_information ){ + + if( preg_match('/\\{rewrite\\-document\\-root\\:[fF][aA][lL][sS][eE]\\}/', $result_strings ) > 0 + || preg_match('/\\{rewrite\\-document\\-root\\:[nN][oO]\\}/', $result_strings ) > 0 ) { + // falseかnoが指定されているなら書き換えない + $result_strings = preg_replace( '/\\{rewrite\\-document\\-root\\:[fF][aA][lL][sS][eE]\\}/' + , "", $result_strings ); + } else { + // 明示的に否定していないなら暗黙的に書き換える + $result_strings = preg_replace( '/\\{rewrite\\-document\\-root\\:[^\\}]*?\\}/' + , "", $result_strings ); + $replace_uri = APPLICATION_BASE_URI; + if( preg_match('/\\/$/', APPLICATION_BASE_URI) > 0 ) { + $replace_uri = preg_replace('/\\/$/','',$replace_uri); + } + // src書き換え + $process_code = 'if( preg_match_all( \'/[sS][rR][cC]\\\\=([\\\'"])(\\/([^\\\'"\\/][^\\\'"]*|))([\\\'"])/\''; + $process_code .= ', $outstr'; + $process_code .= ', $output_array'; + $process_code .= ', PREG_PATTERN_ORDER ) > 0 ) { '; + $process_code .= 'foreach ( $output_array as $output ) { '; + $process_code .= 'foreach ( $output as $target ) { '; + $process_code .= 'if( preg_match(\'/\'.str_replace("/","\\/",\''.$replace_uri.'\').\'/\', $target ) == 0 ) { '."\n"; + $process_code .= '$repstr = preg_replace(\'/[sS][rR][cC]\\\\=([\\\'"])(\\/[^\\\'"]*)([\\\'"])/\',\'src=${1}'.$replace_uri.'${2}${3}\',$target); '."\n"; + $process_code .= '$outstr = str_replace( $target, $repstr, $outstr );'."\n"; + $process_code .= ' }'."\n"; + $process_code .= '}}}'; + + // href書き換え + $process_code .= 'if( preg_match_all( \'/[hH][rR][eE][fF]\\\\=([\\\'"])(\\/([^\\\'"\\/][^\\\'"]*|))([\\\'"])/\''; + $process_code .= ', $outstr'; + $process_code .= ', $output_array'; + $process_code .= ', PREG_PATTERN_ORDER ) > 0 ) { '; + $process_code .= 'foreach ( $output_array as $output ) { '; + $process_code .= 'foreach ( $output as $target ) { '; + $process_code .= 'if( preg_match(\'/\'.str_replace("/","\\/",\''.$replace_uri.'\').\'/\', $target ) == 0 ) { '."\n"; + $process_code .= '$repstr = preg_replace(\'/[hH][rR][eE][fF]\\\\=([\\\'"])(\\/[^\\\'"]*)([\\\'"])/\',\'href=${1}'.$replace_uri.'${2}${3}\',$target); '."\n"; + $process_code .= '$outstr = str_replace( $target, $repstr, $outstr );'."\n"; + $process_code .= ' }'."\n"; + $process_code .= '}}}'; + + // action書き換え + $process_code .= 'if( preg_match_all( \'/[aA][cC][tT][iI][oO][nN]\\\\=([\\\'"])(\\/([^\\\'"\\/]|)[^\\\'"]*)([\\\'"])/\''; + $process_code .= ', $outstr'; + $process_code .= ', $output_array'; + $process_code .= ', PREG_PATTERN_ORDER ) > 0 ) { '; + $process_code .= 'foreach ( $output_array as $output ) { '; + $process_code .= 'foreach ( $output as $target ) { '; + $process_code .= 'if( preg_match(\'/\'.str_replace("/","\\/",\''.$replace_uri.'\').\'/\', $target ) == 0 ) { '."\n"; + $process_code .= '$repstr = preg_replace(\'/[aA][cC][tT][iI][oO][nN]\\\\=([\\\'"])(\\/[^\\\'"]*)([\\\'"])/\',\'action=${1}'.$replace_uri.'${2}${3}\',$target); '."\n"; + $process_code .= '$outstr = str_replace( $target, $repstr, $outstr );'."\n"; + $process_code .= ' }'."\n"; + $process_code .= '}}}'; + + // window.open()書き換え + $process_code .= 'if( preg_match_all( \'/window\\\\.open\\\\(([\\\'"])(\\/[^\\\'"]*)([\\\'"])/\''; + $process_code .= ', $outstr'; + $process_code .= ', $output_array'; + $process_code .= ', PREG_PATTERN_ORDER ) > 0 ) { '; + $process_code .= 'foreach ( $output_array as $output ) { '; + $process_code .= 'foreach ( $output as $target ) { '; + $process_code .= 'if( preg_match(\'/\'.str_replace("/","\\/",\''.$replace_uri.'\').\'/\', $target ) == 0 ) { '."\n"; + $process_code .= '$repstr = preg_replace(\'/window\\\\.open\\\\(([\\\'"])(\\/[^\\\'"]*)([\\\'"])/\',\'window.open(${1}'.$replace_uri.'${2}${3}\',$target); '."\n"; + $process_code .= '$outstr = str_replace( $target, $repstr, $outstr );'."\n"; + $process_code .= ' }'."\n"; + $process_code .= '}}}'; + + // url()書き換え + $process_code .= 'if( preg_match_all( \'/url\\\\(([\\\'"])(\\/[^\\\'"]*)([\\\'"])/\''; + $process_code .= ', $outstr'; + $process_code .= ', $output_array'; + $process_code .= ', PREG_PATTERN_ORDER ) > 0 ) { '; + $process_code .= 'foreach ( $output_array as $output ) { '; + $process_code .= 'foreach ( $output as $target ) { '; + $process_code .= 'if( preg_match(\'/\'.str_replace("/","\\/",\''.$replace_uri.'\').\'/\', $target ) == 0 ) { '."\n"; + $process_code .= '$repstr = preg_replace(\'/url\\\\(([\\\'"])(\\/[^\\\'"]*)([\\\'"])/\',\'url(${1}'.$replace_uri.'${2}${3}\',$target); '."\n"; + $process_code .= '$outstr = str_replace( $target, $repstr, $outstr );'."\n"; + $process_code .= ' }'."\n"; + $process_code .= '}}}'; + + if( !isset($build_information->convert_view_process_hash) + || !is_array($build_information->convert_view_process_hash) ){ + $build_information->convert_view_process_hash = array(); + } + if( !isset($build_information->convert_view_process_hash[$this->priority]) + || !is_array($build_information->convert_view_process_hash[$this->priority]) ){ + $build_information->convert_view_process_hash[$this->priority] = array(); + } + array_push( $build_information->convert_view_process_hash[$this->priority], $process_code ); + } + + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/tags/SetAttribute.class.php =================================================================== --- db/current/spider/lib/spider/tags/SetAttribute.class.php (rev 0) +++ db/current/spider/lib/spider/tags/SetAttribute.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,446 @@ +<?php +/** + * HTML用変換タグ:setAttributeを実行するクラス + * + * {set:[新たに登録する属性名] [属性名]->[メンバ名]} + * {set:[新たに登録する属性名] [属性名][配列添え字]} + * + * と指定することでオブジェクトや配列の中の値を属性として新たに設定することができます。 + * + * @package spider spiderのコアパッケージ + * @version 1.0.01 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR."TagBase.class.php"); +class spider_tags_SetAttribute extends spider_tags_TagBase { + + /** + * コンストラクタ + */ + function spider_tags_SetAttribute() { + } + /** + * コンバートメソッド + */ + function convert( &$result_strings, &$build_information ){ + // set の変換 + $tagStringsHash = array(); + preg_match_all( '/\\{set\\:[^\\}]*?}/' + , $result_strings + , $tagStringsHash + , PREG_PATTERN_ORDER ); + $valiable_counter = 0; + foreach ( $tagStringsHash as $tagStringsArray ) { + foreach ( $tagStringsArray as $tagStrings ) { + $optionStrings = preg_replace( '/\\{set\\:/','', $tagStrings ); + $optionStrings = preg_replace( '/\\}$/','', $optionStrings ); + $optionStrings = trim( $optionStrings ); + if( strlen($optionStrings) > 0 ) { + // オプションがあるなら分解 + $optionArray = $this->splitOptionBySpace( $optionStrings ); + if( count($optionArray) < 2 ) { + // オプション数が足りない場合 + $result_strings = str_replace( $tagStrings, '[set tag requre 2 parameters! '.$tagStrings.']', $result_strings ); + } else if( count($optionArray) == 2 ) { + // オプション数が2つの場合 + // 新規登録属性名 + $attributeName = trim(array_shift($optionArray)); + // 属性値 + $attibuteValue = trim(array_shift($optionArray)); + if( preg_match('/\\:\\:/',$attibuteValue) > 0 ) { + // コロン連続を含むなら下位互換 + $repCode = $this->cnvOldCode( $attributeName, $attibuteValue ); + $result_strings = str_replace( $tagStrings, $repCode, $result_strings ); + } else if( preg_match('/\\-\\>[a-zA-Z_][0-9a-zA-Z_]*$/',$attibuteValue) > 0 ) { + // ''で囲まれないメンバ変数が記述されていたら下位互換 + $repCode = $this->cnvOldCode( $attributeName, $attibuteValue ); + $result_strings = str_replace( $tagStrings, $repCode, $result_strings ); + } else { + // 含まないならPHPコード化 + $attributeNameArray = array(); + $attributeValue = $this->tagCode2NativeCode( $attibuteValue, $attributeNameArray ); + // 下位互換の為setAttributeも行う + $repCode = '<?php ' + .' $GLOBALS[\''.$attributeName.'\'] = '.$attributeValue.'; ' + .'$request->setAttribute(\''.$attributeName.'\',$GLOBALS[\''.$attributeName.'\']); ?>'; + $result_strings = str_replace( $tagStrings, $repCode, $result_strings ); + } + } else { + // オプション数が3つ以上複数ある場合 + // 新規登録属性名 + $attributeName = array_shift($optionArray); + // 属性値はPHPコード化する + $attributeValue = ''; + foreach( $optionArray as $option ) { + $attributeNameArray = array(); + $attributeValue .= ' '.$this->tagCode2NativeCode( $option, $attributeNameArray ); + } + // 下位互換の為setAttributeも行う + $repCode = '<?php ' + .' $GLOBALS[\''.$attributeName.'\'] = '.$attributeValue.'; ' + .'$request->setAttribute(\''.$attributeName.'\',$GLOBALS[\''.$attributeName.'\']); ?>'; + $result_strings = str_replace( $tagStrings, $repCode, $result_strings ); + } + } else { + // オプションパラメーターがないならエラー表示に切り替え + $result_strings = str_replace( $tagStrings, '[set tag requre 2 parameters! '.$tagStrings.']', $result_strings ); + } + $valiable_counter++; + } + } + // presetタグの機能追加 + if( preg_match_all( '/\\{preset\\:[^\\}]*?\\}/' + , $result_strings + , $output_array + , PREG_PATTERN_ORDER ) > 0 ) { + foreach ( $output_array as $output ) { + foreach ( $output as $target ) { + $option_strings = preg_replace( '/\\{preset\\:/','', $target ); + $option_strings = preg_replace( '/\\}/','', $option_strings ); + $option_strings = trim($option_strings); + if( strpos($option_strings,' ') !== false ) { + // 空白が存在するなら分割して復元 + $option_array = $this->splitOptionBySpace( $option_strings ); + if( count($option_array) >= 2 ) { + // パラメータが2つ以上ならモジュール実行前コードを追加 + $this->createPresetCode( $build_information, $option_array ); + // タグ行の削除 + $result_strings = str_replace( "\n".$target."\n", "", $result_strings ); + $result_strings = str_replace( $target, "", $result_strings ); + } else { + // 空白が存在しないなら使い方が違うのでエラーメッセージを表示する + $result_strings = str_replace( $target, "[preset tag requre 2 parameters! ".$target."]", $result_strings ); + } + } else { + // 空白が存在しないなら使い方が違うのでエラーメッセージを表示する + $result_strings = str_replace( $target, "[preset tag requre 2 parameters! ".$target."]", $result_strings ); + } + } + } + } + } + /** + * 旧setタグの変換ロジックで変換した個別変換文字列を取得します。 + */ + function cnvOldCode( $var_name, $var_value ) { + $var_name = trim( $var_name ); + if( ( preg_match('/^"/',$var_name) > 0 && preg_match('/"$/',$var_name) > 0 ) + || ( preg_match('/^\'/',$var_name) > 0 && preg_match('/\'$/',$var_name) > 0 ) + ) { + $var_name = substr($var_name,1,strlen($var_name)-2); + } + $rep_string = "<?php "; + if( preg_match('/^\\".+?\\"$/',$var_value) || preg_match('/^\\\'.+?\\\'$/',$var_value) ) { + // 値がクォーテーションで囲まれている場合は中の値をそのまま登録する + $rep_string .= '$tmp='.$var_value.'; '; + $rep_string .= '$request_object->setAttribute( "' . $var_name . '",$tmp ); '; + $rep_string .= '$GLOBALS["' . $var_name . '"] =$tmp; '; + } else { + // 値がクォーテーションで囲まれていない場合は、スコープから変数を探して登録 + if( preg_match('/\\:\\:/',$var_value) > 0 ) { + // コロン二つがつく場合はオブジェクトかハッシュの属性自動判別 + list( $obj_name, $at_name ) = explode('::',$var_value); + $rep_string .= '$tmp=$request_object->getAttribute( "' . $obj_name . '" ); '; + $rep_string .= '$type=gettype($tmp); '; + if ( strlen(trim($at_name)) > 0 ) { + $rep_string .= 'if(\'array\'==$type) { '; + $rep_string .= '$tmp=$tmp[\''.$at_name.'\'];'; + $rep_string .= ' } '; + $rep_string .= 'if(\'object\'==$type) { $tmp=$tmp->'.$at_name.'; } '; + } + } else if( preg_match('/\\->/',$var_value) > 0 ) { + // オブジェクト指定子の場合はオブジェクトのメソッドまたはメンバ値である + list( $obj_name, $member_strings ) = explode('->',$var_value); + $rep_string .= '$tmp=$request_object->getAttribute( "' . $obj_name . '" ); '; + $rep_string .= '$type=gettype($tmp); '; + $member_strings = trim($member_strings); + if( strlen($member_strings) > 0 ) { + if( preg_match('/\\(/',$member_strings) > 0 && preg_match('/\\)$/',$member_strings) > 0 ) { + // 開始括弧があり、閉じ括弧で終了しているならメソッドの引数部分を確認 + list( $method_name, $method_param_strings ) = explode('(',$member_strings ); + list( $method_param_strings ) = explode(')',$method_param_strings ); + $method_param_strings = trim( $method_param_strings ); + $method_param_tmp_array = explode(',',$method_param_strings); + $method_param_array = array(); + foreach( $method_param_tmp_array as $param ) { + $param = trim( $param ); + if( strlen( $param ) > 0 ) { + if( ( preg_match('/^"/',$param) > 0 && preg_match('/"$/',$param) > 0 ) + || ( preg_match('/^\'/',$param) > 0 && preg_match('/\'$/',$param) > 0 ) + ) { + // シングルクォートかダブルクォートで囲まれているなら固定文字列 + array_push( $method_param_array, $param ); + } else if( is_numeric($param) ){ + // 数値ならそのまま登録 + array_push( $method_param_array, $param ); + } else { + // 文字列でないなら属性から取得 + $strmp = '$request_object->getAttribute( "' . $param . '" ); '; + array_push( $method_param_array, $strmp ); + } + } + } + $rep_string .= 'if(\'object\'==$type) { $tmp=$tmp->'.$method_name.'('.implode(',',$method_param_array).'); } '; + } else { + // 開始括弧も閉じ括弧もないならメンバ変数として処理 + $rep_string .= 'if(\'object\'==$type) { $tmp=$tmp->'.$member_strings.'; } '; + } + } + } else if( preg_match('/\\[/',$var_value) > 0 && preg_match('/\\[/',$var_value) > 0 ) { + // 開始大括弧と閉じ大括弧があるなら配列・ハッシュと判断する + list( $hash_name, $hash_key_strings ) = explode('[',$var_value ); + $rep_string .= '$tmp=$request_object->getAttribute( "' . $hash_name . '" ); '; + $rep_string .= '$type=gettype($tmp); '; + list( $hash_key_strings ) = explode(']',$hash_key_strings ); + $hash_key_strings = trim( $hash_key_strings ); + if( ( preg_match('/^"/',$hash_key_strings) > 0 && preg_match('/"$/',$hash_key_strings) > 0 ) + || ( preg_match('/^\'/',$hash_key_strings) > 0 && preg_match('/\'$/',$hash_key_strings) > 0 ) + ) { + // キー文字列がクォートされているなら文字列としてそのまま利用 + $rep_string .= 'if(\'array\'==$type) { $tmp=$tmp['.$hash_key_strings.']; } '; + } else if( is_numeric($hash_key_strings) ) { + // キー文字列が数値ならそのまま利用 + $rep_string .= 'if(\'array\'==$type) { $tmp=$tmp['.$hash_key_strings.']; } '; + } else { + // キー文字列が数字でなくクォートされていないなら属性から取得 + if( preg_match('/\\:\\:/',$hash_key_strings) > 0 ) { + // コロン二つがつく場合はオブジェクトかハッシュの属性自動判別 + list( $key_object_name, $key_at_name ) = explode('::',$hash_key_strings); + $rep_string .= '$tmp_key=$request_object->getAttribute( "' . $key_object_name . '" ); '; + $rep_string .= '$type_key=gettype($tmp_key); '; + if ( strlen(trim($key_at_name)) > 0 ) { + $rep_string .= 'if(\'array\'==$type_key) { $tmp_key=$tmp_key[\''.$key_at_name.'\']; } '; + $rep_string .= 'if(\'object\'==$type_key) { $tmp_key=$tmp_key->'.$key_at_name.'; } '; + $rep_string .= 'if(\'array\'==$type) { $tmp=$tmp[$tmp_key]; } '; + } + } else { + // とりあえず配列キーではメソッド呼び出しはできない仕様。その他の場合はそのままgetAttribute + $hash_key_strings = '$request_object->getAttribute("'.$hash_key_strings.'")'; + $rep_string .= 'if(\'array\'==$type) { $tmp=$tmp['.$hash_key_strings.']; } '; + } + } + } else { + // 単体文字列なら属性から取得 + $rep_string .= '$tmp = $request_object->getAttribute( "' . $var_value . '" ); '; + } + $rep_string .= '$request_object->setAttribute( "' . $var_name . '", $tmp ); '; + $rep_string .= '$GLOBALS["' . $var_name . '"] =$tmp; '; + } + $rep_string .= " ?>"; + return $rep_string; + } +/* + function convert( &$result_strings, &$build_information ){ + $vars_tags_aray = array(); + preg_match_all( '/\\{set\\:[^\\}]*?}/' + , $result_strings + , $vars_tags_aray + , PREG_PATTERN_ORDER ); + foreach ( $vars_tags_aray as $vars_tags ) { + foreach ( $vars_tags as $vars_tag ) { + $var_name = preg_replace( '/\\{set\\:/','', $vars_tag ); + $var_name = preg_replace( '/\\}$/','', $var_name ); + $var_name = trim( $var_name ); + list( $var_name, $var_value) = explode( ' ', $var_name ); + $var_name = trim( $var_name ); + $var_value = trim( $var_value ); + if( strlen(trim($var_name)) > 0 && strlen(trim($var_value)) > 0 ) { + // 名前と値を両方指定されている場合のみ変換 + // 登録属性名 + $var_name = trim( $var_name ); + if( ( preg_match('/^"/',$var_name) > 0 && preg_match('/"$/',$var_name) > 0 ) + || ( preg_match('/^\'/',$var_name) > 0 && preg_match('/\'$/',$var_name) > 0 ) + ) { + $var_name = substr($var_name,1,strlen($var_name)-2); + } + $rep_string = "<?php "; + if( preg_match('/^\\".+?\\"$/',$var_value) || preg_match('/^\\\'.+?\\\'$/',$var_value) ) { + // 値がクォーテーションで囲まれている場合は中の値をそのまま登録する + $rep_string .= '$tmp='.$var_value.'; '; + $rep_string .= '$request_object->setAttribute( "' . $var_name . '",$tmp ); '; + $rep_string .= '$GLOBALS["' . $var_name . '"] =$tmp; '; + } else { + // 値がクォーテーションで囲まれていない場合は、スコープから変数を探して登録 + if( preg_match('/\\:\\:/',$var_value) > 0 ) { + // コロン二つがつく場合はオブジェクトかハッシュの属性自動判別 + list( $obj_name, $at_name ) = explode('::',$var_value); + $rep_string .= '$tmp=$request_object->getAttribute( "' . $obj_name . '" ); '; + $rep_string .= '$type=gettype($tmp); '; + if ( strlen(trim($at_name)) > 0 ) { + $rep_string .= 'if(\'array\'==$type) { '; + $rep_string .= '$tmp=$tmp[\''.$at_name.'\'];'; + $rep_string .= ' } '; + $rep_string .= 'if(\'object\'==$type) { $tmp=$tmp->'.$at_name.'; } '; + } + } else if( preg_match('/\\->/',$var_value) > 0 ) { + // オブジェクト指定子の場合はオブジェクトのメソッドまたはメンバ値である + list( $obj_name, $member_strings ) = explode('->',$var_value); + $rep_string .= '$tmp=$request_object->getAttribute( "' . $obj_name . '" ); '; + $rep_string .= '$type=gettype($tmp); '; + $member_strings = trim($member_strings); + if( strlen($member_strings) > 0 ) { + if( preg_match('/\\(/',$member_strings) > 0 && preg_match('/\\)$/',$member_strings) > 0 ) { + // 開始括弧があり、閉じ括弧で終了しているならメソッドの引数部分を確認 + list( $method_name, $method_param_strings ) = explode('(',$member_strings ); + list( $method_param_strings ) = explode(')',$method_param_strings ); + $method_param_strings = trim( $method_param_strings ); + $method_param_tmp_array = explode(',',$method_param_strings); + $method_param_array = array(); + foreach( $method_param_tmp_array as $param ) { + $param = trim( $param ); + if( strlen( $param ) > 0 ) { + if( ( preg_match('/^"/',$param) > 0 && preg_match('/"$/',$param) > 0 ) + || ( preg_match('/^\'/',$param) > 0 && preg_match('/\'$/',$param) > 0 ) + ) { + // シングルクォートかダブルクォートで囲まれているなら固定文字列 + array_push( $method_param_array, $param ); + } else if( is_numeric($param) ){ + // 数値ならそのまま登録 + array_push( $method_param_array, $param ); + } else { + // 文字列でないなら属性から取得 + $strmp = '$request_object->getAttribute( "' . $param . '" ); '; + array_push( $method_param_array, $strmp ); + } + } + } + $rep_string .= 'if(\'object\'==$type) { $tmp=$tmp->'.$method_name.'('.implode(',',$method_param_array).'); } '; + } else { + // 開始括弧も閉じ括弧もないならメンバ変数として処理 + $rep_string .= 'if(\'object\'==$type) { $tmp=$tmp->'.$member_strings.'; } '; + } + } + } else if( preg_match('/\\[/',$var_value) > 0 && preg_match('/\\[/',$var_value) > 0 ) { + // 開始大括弧と閉じ大括弧があるなら配列・ハッシュと判断する + list( $hash_name, $hash_key_strings ) = explode('[',$var_value ); + $rep_string .= '$tmp=$request_object->getAttribute( "' . $hash_name . '" ); '; + $rep_string .= '$type=gettype($tmp); '; + list( $hash_key_strings ) = explode(']',$hash_key_strings ); + $hash_key_strings = trim( $hash_key_strings ); + if( ( preg_match('/^"/',$hash_key_strings) > 0 && preg_match('/"$/',$hash_key_strings) > 0 ) + || ( preg_match('/^\'/',$hash_key_strings) > 0 && preg_match('/\'$/',$hash_key_strings) > 0 ) + ) { + // キー文字列がクォートされているなら文字列としてそのまま利用 + $rep_string .= 'if(\'array\'==$type) { $tmp=$tmp['.$hash_key_strings.']; } '; + } else if( is_numeric($hash_key_strings) ) { + // キー文字列が数値ならそのまま利用 + $rep_string .= 'if(\'array\'==$type) { $tmp=$tmp['.$hash_key_strings.']; } '; + } else { + // キー文字列が数字でなくクォートされていないなら属性から取得 + if( preg_match('/\\:\\:/',$hash_key_strings) > 0 ) { + // コロン二つがつく場合はオブジェクトかハッシュの属性自動判別 + list( $key_object_name, $key_at_name ) = explode('::',$hash_key_strings); + $rep_string .= '$tmp_key=$request_object->getAttribute( "' . $key_object_name . '" ); '; + $rep_string .= '$type_key=gettype($tmp_key); '; + if ( strlen(trim($key_at_name)) > 0 ) { + $rep_string .= 'if(\'array\'==$type_key) { $tmp_key=$tmp_key[\''.$key_at_name.'\']; } '; + $rep_string .= 'if(\'object\'==$type_key) { $tmp_key=$tmp_key->'.$key_at_name.'; } '; + $rep_string .= 'if(\'array\'==$type) { $tmp=$tmp[$tmp_key]; } '; + } + } else { + // とりあえず配列キーではメソッド呼び出しはできない仕様。その他の場合はそのままgetAttribute + $hash_key_strings = '$request_object->getAttribute("'.$hash_key_strings.'")'; + $rep_string .= 'if(\'array\'==$type) { $tmp=$tmp['.$hash_key_strings.']; } '; + } + } + } else { + // 単体文字列なら属性から取得 + $rep_string .= '$tmp = $request_object->getAttribute( "' . $var_value . '" ); '; + } + $rep_string .= '$request_object->setAttribute( "' . $var_name . '", $tmp ); '; + $rep_string .= '$GLOBALS["' . $var_name . '"] =$tmp; '; + } + $rep_string .= " ?>"; + $result_strings = str_replace( $vars_tag, $rep_string, $result_strings ); + } else { + // 名前か値どちらかがカラ文字の場合は変換しない + } + } + } + + // presetタグの機能追加 + if( preg_match_all( '/\\{preset\\:[^\\}]*?\\}/' + , $result_strings + , $output_array + , PREG_PATTERN_ORDER ) > 0 ) { + foreach ( $output_array as $output ) { + foreach ( $output as $target ) { + $option_strings = preg_replace( '/\\{preset\\:/','', $target ); + $option_strings = preg_replace( '/\\}/','', $option_strings ); + $option_strings = trim($option_strings); + if( strpos($option_strings,' ') !== false ) { + // 空白が存在するなら分割して復元 + $option_array = $this->splitOptionBySpace( $option_strings ); + if( count($option_array) >= 2 ) { + // パラメータが2つ以上ならモジュール実行前コードを追加 + $this->createPresetCode( $build_information, $option_array ); + // タグ行の削除 + $result_strings = str_replace( "\n".$target."\n", "", $result_strings ); + $result_strings = str_replace( $target, "", $result_strings ); + } else { + // 空白が存在しないなら使い方が違うのでエラーメッセージを表示する + $result_strings = str_replace( $target, "[preset tag requre 2 parameters! ".$target."]", $result_strings ); + } + } else { + // 空白が存在しないなら使い方が違うのでエラーメッセージを表示する + $result_strings = str_replace( $target, "[preset tag requre 2 parameters! ".$target."]", $result_strings ); + } + } + } + } + } +*/ + /** + * presetタグのパラメータを受け取って実行前コードを作成します + */ + function createPresetCode( &$build_information, $param_array ) { + $process_code = ''; + if( count( $param_array ) >= 2 ) { + $name = array_shift( $param_array ); + if( preg_match('/^\\\'[^\\\']+\\\'$/',$name) > 0 ) { + $name = preg_replace('/^\\\'/','',$name); + $name = preg_replace('/\\\'$/','',$name); + } + if( preg_match('/^\\"[^\\\']+\\"$/',$name) > 0 ) { + $name = preg_replace('/^\\"/','',$name); + $name = preg_replace('/\\"$/','',$name); + } + $value = array_shift( $param_array ); + if( preg_match('/^\\\'[^\\\']+\\\'$/',$value) > 0 ) { + $value = preg_replace('/^\\\'/','',$value); + $value = preg_replace('/\\\'$/','',$value); + } + if( preg_match('/^\\"[^\\\']+\\"$/',$value) > 0 ) { + $value = preg_replace('/^\\"/','',$value); + $value = preg_replace('/\\"$/','',$value); + } + $var_name = str_replace('.','_',$name); + $process_code .= '$'.$var_name.' = $request_object->getAttribute("'.$name.'");'."\n"; + $process_code .= 'if( is_array($'.$var_name.') ) { '."\n"; + $process_code .= 'array_push( $'.$var_name.', "'.$value.'" );'."\n"; + $process_code .= '$request_object->setAttribute("'.$name.'",$'.$var_name.' );'."\n"; + $process_code .= '} else if( is_null($'.$var_name.') || strlen($'.$var_name.') == 0 ) { '."\n"; + $process_code .= '$'.$var_name.' = "'.$value.'";'."\n"; + $process_code .= '$request_object->setAttribute("'.$name.'",$'.$var_name.' );'."\n"; + $process_code .= '} else {'."\n"; + // objectの場合の検討..現状オブジェクトが登録済みの場合は上書きしない(あり得ないので) + $process_code .= '}'."\n"; + // ビルド情報に実行コードを追加 + if( !isset($build_information->preview_process_hash) + || !is_array($build_information->preview_process_hash) ){ + $build_information->preview_process_hash = array(); + } + if( !isset($build_information->preview_process_hash[$this->priority]) + || !is_array($build_information->preview_process_hash[$this->priority]) ){ + $build_information->preview_process_hash[$this->priority] = array(); + } + array_push( $build_information->preview_process_hash[$this->priority], $process_code ); + return true; + } else { + return false; + } + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/tags/SetRequestParam.class.php =================================================================== --- db/current/spider/lib/spider/tags/SetRequestParam.class.php (rev 0) +++ db/current/spider/lib/spider/tags/SetRequestParam.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,63 @@ +<?php +/** + * HTML用変換タグ:リクエストパラメータを属性に自動的に設定するタグ + * + * {set-request-param:[true/false]} + * + * HTTPリクエストと同時にPOST及びGETで渡されたパラメータの値を + * get.[getのキー], post.[postキー]の名前でrequest属性に登録します。 + * + * デフォルトはtrueです。 + * + * @package spider spiderのコアパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR."TagBase.class.php"); +class spider_tags_SetRequestParam extends spider_tags_TagBase { + + /** + * コンストラクタ + */ + function spider_tags_SetRequestParam() { + $this->priority = 0; + } + /** + * コンバートメソッド + */ + function convert( &$result_strings, &$build_information ){ + + if( preg_match('/\\{set\\-request\\-param\\:[fF][aA][lL][sS][eE]\\}/', $result_strings ) > 0 + || preg_match('/\\{set\\-request\\-param\\:[nN][oO]\\}/', $result_strings ) > 0 ) { + // falseかnoが指定されているなら登録しない + $result_strings = preg_replace( '/\\{set\\-request\\-param\\:[fF][aA][lL][sS][eE]\\}/' + , "", $result_strings ); + $result_strings = preg_replace( '/\\{set\\-request\\-param\\:[fF][aA][lL][sS][eE]\\}/' + , "", $result_strings ); + } else { + // 明示的に否定していないなら暗黙的にcookie及びpost,getの値をリクエストに登録 + $process_code = 'foreach($_POST as $key=>$value){'."\n"; + $process_code .= '$request_object->setAttribute(\'post.\'.$key,$value);'."\n"; + $process_code .= '}'."\n"; + $process_code .= 'foreach($_GET as $key=>$value){'."\n"; + $process_code .= '$request_object->setAttribute(\'get.\'.$key,$value);'."\n"; + $process_code .= '}'."\n"; + $process_code .= 'foreach($_COOKIE as $key=>$value){'."\n"; + $process_code .= '$request_object->setAttribute(\'cookie.\'.$key,$value);'."\n"; + $process_code .= '}'."\n"; + if( !isset($build_information->preview_process_hash) + || !is_array($build_information->preview_process_hash) ){ + $build_information->preview_process_hash = array(); + } + if( !isset($build_information->preview_process_hash[$this->priority]) + || !is_array($build_information->preview_process_hash[$this->priority]) ){ + $build_information->preview_process_hash[$this->priority] = array(); + } + array_push( $build_information->preview_process_hash[$this->priority], $process_code ); + } + + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/tags/TagBase.class.php =================================================================== --- db/current/spider/lib/spider/tags/TagBase.class.php (rev 0) +++ db/current/spider/lib/spider/tags/TagBase.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,226 @@ +<?php +/** + * HTML用変換タグの基礎クラス + * + * @package spider spiderのコアパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +require_once(dirname(dirname(dirname(__FILE__))) + .DIRECTORY_SEPARATOR.'util' + .DIRECTORY_SEPARATOR.'CharUtility.class.php'); +class spider_tags_TagBase { + /** 変換実行優先度 */ + var $priority = 50; + /** タグ文字列名称 */ + var $tag_name = ''; + /** + * コンストラクタ + */ + function spider_tags_TagBase() { + $this->priority = 50; + $this->tag_name = ''; + } + /** + * コンバートメソッド + */ + 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; + } + $tag_regx = util_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 + , PREG_PATTERN_ORDER ) > 0 ) { + foreach ( $tag_strings_array as $target_tag_array ) { + foreach ( $target_tag_array as $target_tag ) { + $options_string = preg_replace( '/'.$tag_regx.'/','', $target_tag ); + $options_string = preg_replace( '/\\}$/','', $options_string ); + if( strlen(trim($options_string)) == 0 ) { + // タグが終了しているようならオプション無で処理 + $option_array = 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); + $param_array = $this->splitOptionBySpace( $options_string ); + $option_array = array(); + foreach( $param_array as $param ) { + $param = trim($param); + if( strlen( $param ) > 0 ) { + array_push( $option_array, $param ); + } + } + $converted_strings = $this->getConvertedStrings( $result_strings, $build_information, $option_array, $valiable_counter ); + // 空行にならないよう前後が改行も削除 + if( strlen($converted_strings) == 0 ) { + $result_strings = str_replace( "\n".$target_tag."\n", $converted_strings, $result_strings ); + } + $result_strings = str_replace( $target_tag, $converted_strings, $result_strings ); + } else { + // 終了でも:でもないなら違うタグなので処理しない + } + $valiable_counter++; + } + } + } + return; + } + /** + * 個々のタグ文字列の変換後文字列を取得します + * 必要に応じて拡張したタグクラスで実装してください。 + */ + function getConvertedStrings( &$result_strings, &$build_information, $option_array=array(), $valiable_counter=0 ) { + return ''; + } + // + // タグ解析全般で利用するユーティリティメソッド + // + /** + * オプション文字列をオプション配列にします。 + */ + function splitOptionBySpace( $string ) { + // 最終的なオプション文字列配列 + $option_array = array(); + $string = trim($string); + if( strpos($string,' ') !== false ) { + // 2文字以上連続のスペースは1文字に統一 + while( preg_match('/\\s\\s/',$string) > 0 ) { + $string = str_replace( ' ',' ', $string ); + } + // 分割 + $column_array = explode(' ', $string); + // クォートを維持してオプション文字列配列にいれる + $data = ''; + foreach( $column_array as $column ) { + $data .= $column; + if( preg_match('/^\\\'/',$data) > 0 && substr_count( $data, "'" ) % 2 == 1 ) { + // 'から始まって'の数が偶数個なら次のカラムとつなげる + $data .= ' '; + continue; + } else if( preg_match('/^\\\"/',$data) > 0 && substr_count( $data, '"' ) % 2 == 1 ) { + // "から始まって"の数が偶数個なら次のカラムとつなげる + $data .= ' '; + continue; + } else { + // そうでない場合はカラムがデータとして完結しているので配列に追加 + array_push( $option_array, $data ); + // 次のデータに備えてデータを空文字で新しく設定 + $data = ''; + } + } + } else { + array_push( $option_array, $string ); + } + return $option_array; + } + /** + * タグコードをPHPコードに変換します + */ + function tagCode2NativeCode( $strings, & $attribute_name_array ) { + // 演算時の正規表現 + $signiture_regx = '\\+\\-\\/\\*\\%\\=\\<\\>\\&\\|\\(\\)\\!\\,\\[\\]'; + // 変換後文字列 + $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 if( preg_match('/^(true|false)$/',$element_data ) > 0 ) { + // true/falseならそのまま追加 + $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.'\']'; + if( is_array($attribute_name_array) ) { + array_push( $attribute_name_array, $element_data ); + } + } else { + // それ以外は$GLOBALSへ変換 + $converted_strings .= '$GLOBALS[\''.$element_data.'\']'; + if( is_array($attribute_name_array) ) { + array_push( $attribute_name_array, $element_data ); + } + } + } + } else { + // 演算子はそのまま追加 + $converted_strings .= $element_data; + } + $prev_data = $element_data; + $element_data = ''; + } + } + + return $converted_strings; + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/tags/Template.class.php =================================================================== (Binary files differ) Property changes on: db/current/spider/lib/spider/tags/Template.class.php ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: db/current/spider/lib/spider/tags/UseSession.class.php =================================================================== --- db/current/spider/lib/spider/tags/UseSession.class.php (rev 0) +++ db/current/spider/lib/spider/tags/UseSession.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,67 @@ +<?php +/** + * HTML用変換タグ:use-sessionタグクラス + * + * {use-session:[true/false]} + * 対象ページでPHPのセッション機能を利用するか否かを設定するタグです。 + * falseの場合sessionがスタートされません。 + * デフォルトはtrueです。 + * + * @package spider spiderのコアパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR."TagBase.class.php"); +class spider_tags_UseSession extends spider_tags_TagBase { + + /** + * コンストラクタ + */ + function spider_tags_UseSession() { + $this->priority = 0; + } + /** + * コンバートメソッド + */ + function convert( &$result_strings, &$build_information ){ + if( preg_match('/\\{use\\-session\\:[fF][aA][lL][sS][eE]\\}/', $result_strings ) > 0 + || preg_match('/\\{use\\-session\\:[nN][oO]\\}/', $result_strings ) > 0 ) { + // falseかnoが指定されているならセッションは開始しない + $result_strings = preg_replace( '/\\{use\\-session\\:[fF][aA][lL][sS][eE]\\}/' + , "", $result_strings ); + } else { + // 明示的にセッション開始を否定していないなら暗黙的にセッションを開始する + $result_strings = preg_replace( '/\\{use\\-session\\:[^\\}]*?\\}/' + , "", $result_strings ); + $process_code = "if( defined('SPIDER_USE_SPIDER_SESSION_ID') && SPIDER_USE_SPIDER_SESSION_ID ) {\n" + . "if( !spider_session_start() ) {\n" + . "header( 'Content-type: text/plain;charset=UTF-8' );\n" + . "die( '".$GLOBALS['spider.messages']['spider.tags.usesession.cantstart']."' );\n}\n" + . "}else{\n" + . "session_start();\n}" + . "\n" + . '$GLOBALS[\'request_object\']->setAttribute( \'spider.session_name\', session_name(), SPIDER_SESSION_SCOPE_GLOBAL );'. "\n" + . '$GLOBALS[\'request_object\']->setAttribute( \'spider.session_id\', session_id(), SPIDER_SESSION_SCOPE_GLOBAL );'. "\n" + . 'if( isset($_SESSION) ) {'."\n" + . '$globalErrors = unserialize( $_SESSION[\'spider.global_errors\'] );'."\n" + . 'if( is_array( $globalErrors ) ) {' + . '$GLOBALS[\'request_object\']->errors = $globalErrors;'."\n" + . '}'."\n" + . 'unset( $_SESSION[\'spider.global_errors\'] );'."\n" + . '}'."\n" + ; + if( !isset($build_information->preview_process_hash) + || !is_array($build_information->preview_process_hash) ){ + $build_information->preview_process_hash = array(); + } + if( !isset($build_information->preview_process_hash[$this->priority]) + || !is_array($build_information->preview_process_hash[$this->priority]) ){ + $build_information->preview_process_hash[$this->priority] = array(); + } + array_push( $build_information->preview_process_hash[$this->priority], $process_code ); + } + } +} +?> \ No newline at end of file Added: db/current/spider/lib/spider/tags/Widget.class.php =================================================================== (Binary files differ) Property changes on: db/current/spider/lib/spider/tags/Widget.class.php ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: db/current/spider/lib/spider/tags/Write.class.php =================================================================== --- db/current/spider/lib/spider/tags/Write.class.php (rev 0) +++ db/current/spider/lib/spider/tags/Write.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,324 @@ +<?php +/** + * HTML用変換タグ:writeタグクラス + * + * {write:[出力したいrequest属性名 etc]} + * + * request属性に登録された値をページ内に出力するタグです。 + * 通常の状態では値をhtmlspecialchars関数にてHTMLエスケープした状態で出力します。 + * + * またwriteタグ内では + * + * ・引数ひとつのグローバル関数で属性を処理して出力できます。 + * 例) + * {write:number_format(example.Hello.message)} + * + * ・値が数値の場合演算結果を出力できます。演算子と属性名の間に空白は入れないでください。 + * 例) + * {write:count+1} + * {write:example.counta+example.countb} + * + * ・配列、オブジェクトはprint_r()します + * + * ・以下のオプションを出力文字の後に空白区切りで指定できます。 + * ルールが相反するものでなければ複数同時に指定可能です。 + * noescape + * htmlspecialchars関数によるHTMLエスケープを行わずにHTMLタグもそのまま出力します。 + * nl2br + * 改行文字を<br />[改行文字]に変換して出力します。 + * nl2null + * 改行文字を削除して出力します。 + * escape-nl + * 改行文字\nをそのまま\n表記で出力します。(JavaScript利用時などに有効です) + * escape-sq + * 'シングルクォートを\'にエスケープして出力します。(JavaScript利用時などに有効です) + * escape-dq + * "ダブルクォートを\"にエスケープして出力します。(JavaScript利用時などに有効です) + * urlencode + * 値をURLエンコードして出力します。 + * + * @package spider spiderのコアパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +require_once(dirname(__FILE__).DIRECTORY_SEPARATOR."TagBase.class.php"); +class spider_tags_Write extends spider_tags_TagBase { + + /** + * コンストラクタ + */ + function spider_tags_Write() { + } + /** + * コンバートメソッド + */ + function convert( &$result_strings, &$build_information ){ + // 変数タグ + $vars_tags_aray = array(); + preg_match_all( '/\\{write\\:[^\\}]*?}/' + , $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( '/\\{write\\:/','', $vars_tag ); + $var_name = preg_replace( '/\\}$/','', $var_name ); + $var_name = trim( $var_name ); + // 下位互換の為::を含むなら旧ロジック + $repstr = ''; + if( preg_match('/\\:\\:/',$var_name) > 0 ) { + $repstr = $this->parseString( $var_name, $valiable_counter ); + } else { + $repstr = $this->tagOption2code( $var_name ); + } + $result_strings = str_replace( $vars_tag, $repstr, $result_strings ); + $valiable_counter++; + } + } + } + /** + * + */ + function tagOption2code( $strings ) { + // 最初に文字列化コード + $ret_strings = 'print_r( '.$strings.', true )'; + // 出力オプション指定文字の処理 + if( strpos( $ret_strings, 'nl2null' ) !== false ) { + $ret_strings = 'str_replace("\\n","",str_replace("\\r","",str_replace("\\r\\n","",'.$ret_strings.')))'; + $ret_strings = str_replace('nl2null','',$ret_strings); + } + if( strpos( $ret_strings, 'escape-nl' ) !== false ) { + $ret_strings = 'str_replace("\\n","\\\n",str_replace("\\r","\\n",str_replace("\\r\\n","\\n",'.$ret_strings.')))'; + $ret_strings = str_replace('escape-nl','',$ret_strings); + } + if( strpos( $ret_strings, 'escape-sq' ) !== false ) { + $ret_strings = 'str_replace("\'","\\\'",'.$ret_strings.')'; + $ret_strings = str_replace('escape-sq','',$ret_strings); + } + if( strpos( $ret_strings, 'escape-dq' ) !== false ) { + $ret_strings = 'str_replace(\'"\',\'\\"\','.$ret_strings.')'; + $ret_strings = str_replace('escape-dq','',$ret_strings); + } + if( strpos( $ret_strings, 'noescape' ) !== false ) { + $ret_strings = str_replace('noescape','',$ret_strings); + } else { + $ret_strings = 'htmlspecialchars('.$ret_strings.')'; + } + if( strpos( $ret_strings, 'nl2br' ) !== false ) { + $ret_strings = str_replace('nl2br','',$ret_strings); + $ret_strings = 'nl2br('.$ret_strings.')'; + } + if( strpos( $ret_strings, 'urlencode' ) !== false ) { + $ret_strings = str_replace('urlencode','',$ret_strings); + $ret_strings = 'urlencode('.$ret_strings.')'; + } + // ネイティブコード化 + $attribute_name_array = array(); + $ret_strings = $this->tagCode2NativeCode( $ret_strings, $attribute_name_array ); + $attribute_exist_confirm_array = array(); + foreach( $attribute_name_array as $attribute_name ) { + array_push( $attribute_exist_confirm_array, 'isset($GLOBALS[\''.$attribute_name.'\'])'); + } + // 最後にecho + $result_string = '<?php if( '; + $result_string .= implode(' && ', $attribute_exist_confirm_array ); + $result_string .= ' ) {'; + $result_string .= 'echo '.$ret_strings.';'; + $result_string .= '} ?>'; + return $result_string; + } + /** + * 文字列解析 + * 旧バージョン互換::を利用できる + */ + function parseString( $strings, $prefix=1 ) { + + // 出力オプションの確認 + $is_noescape = false; + $is_nl2br = false; + $is_nl2null = false; + $is_escape_nl = false; + $is_escape_sq = false; + $is_escape_dq = false; + $is_urlencode = false; + if( strpos( $strings, 'noescape' ) !== false ) { + $is_noescape = true; + $strings = str_replace('noescape','',$strings); + } + if( strpos( $strings, 'ln2br' ) !== false || strpos( $strings, 'nl2br' ) !== false ) { + $is_nl2br = true; + $strings = str_replace('ln2br','',$strings); + $strings = str_replace('nl2br','',$strings); + } + if( strpos( $strings, 'nl2null' ) !== false ) { + $is_nl2null = true; + $strings = str_replace('nl2null','',$strings); + } + if( strpos( $strings, 'escape-nl' ) !== false ) { + $is_escape_nl = true; + $strings = str_replace('escape-nl','',$strings); + } + if( strpos( $strings, 'escape-sq' ) !== false ) { + $is_escape_sq = true; + $strings = str_replace('escape-sq','',$strings); + } + if( strpos( $strings, 'escape-dq' ) !== false ) { + $is_escape_dq = true; + $strings = str_replace('escape-dq','',$strings); + } + if( strpos( $strings, 'urlencode' ) !== false ) { + $is_urlencode = true; + $strings = str_replace('urlencode','',$strings); + } + + // 内部で利用されている変数を全て取り出す + $var_name_array = array(); + // 単一要素式 + $pos=0; + for( $i=0; $i<strlen($strings); $i++ ) { + $char = substr($strings,$i,1); + if( '+' == $char || '-' == $char + || '*' == $char || '/' == $char + || '(' == $char || ')' == $char + || '[' == $char || ']' == $char + || ',' == $char ) { + // 演算子が登場したらひとつ前までを文字列切り出し + $str = substr( $strings, $pos, $i-$pos ); + $pos = $i+1; + if( '(' != $char && strlen( trim($str) ) > 0 ) { + // 関数名でなければ追加 + $var_name_array[trim($str)] = ''; + } else if( '(' == $char && strlen( trim($str) ) > 0 ) { + // 関数名の場合 + if( preg_match('/\\:\\:/',$str) > 0 ) { + // オブジェクトメソッドの場合はオブジェクト名のみ追加 + list( $obj_name, $method_name ) = explode('::',$str); + $var_name_array[trim($obj_name)] = ''; + } + } + } + } + // ループ最後のポジションから最後の要素を切り出し + $str = substr( $strings, $pos, $i-$pos ); + if( strlen( trim($str) ) > 0 ) { + $var_name_array[trim($str)] = ''; + } + + // 変数一時格納配列 + $temporary_valiable_getter_array = array(); + + // 変数の変換を確認 + $vcounter = 0; + foreach( $var_name_array as $key => $value ) { + if( strlen($key) > 0 ) { + 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); + $var_name_array[$key] = $tmp_name; + if( preg_match('/^\\\'(.)*\\\'$/',$key) > 0 ) { + // シングルクォートされているなら固定文字列 + $str = $tmp_name. '='.$key.';'."\n"; + array_push( $temporary_valiable_getter_array, $str ); + } else { + list( $vname, $vparam ) = explode('::',$key); + // 一時編集取得文字列作成 + $str = $tmp_name. '=$request_object->getAttribute(\''.$vname.'\');'."\n"; + $str .= 'if( is_null('.$tmp_name.') ){'."\n"; + $str .= "\t".$tmp_name. '=\''.$vname.'\';'."\n"; + $str .= '} else if(\'array\'==gettype('.$tmp_name.')) {'."\n"; + if( is_numeric($vparam) ) { + $str .= "\t".$tmp_name. '='.$tmp_name.'['.$vparam.'];'."\n"; + } else if( strlen(trim($vparam)) > 0 ){ + $str .= "\t".$tmp_name. '='.$tmp_name.'[\''.$vparam.'\'];'."\n"; + } + $str .= '} else if(\'object\'==gettype('.$tmp_name.')) {'."\n"; + if( is_numeric($vparam) ) { + // オブジェクトの場合、数値は許可できません。(変数名、メソッド名は数値から始められない) + $str .= "\t".'$request_object->addError(\'' + .$GLOBALS['spider.messages']['spider.tags.write.objectcanthasnumericmember'].'\');'."\n"; + } else if( strlen(trim($vparam)) > 0 ){ + $str .= "\t".$tmp_name. '='.$tmp_name.'->'.$vparam.';'."\n"; + } + $str .= '}'."\n"; + array_push( $temporary_valiable_getter_array, $str ); + } + $vcounter++; + } + } + } + // 変数配列を文字列の長い順にソート + $order_array = array(); + foreach( $var_name_array as $key => $value ) { + if( !isset($order_array[strlen($key)]) || !is_array( $order_array[strlen($key)] ) ) { + $order_array[strlen($key)] = array(); + } + array_push($order_array[strlen($key)],$key); + } + krsort($order_array); + $new_var_name_array = array(); + foreach( $order_array as $item_array ) { + foreach( $item_array as $name ) { + $new_var_name_array[$name] = $var_name_array[$name]; + } + } + + // 渡された文字列の置換 + foreach( $new_var_name_array as $key => $value ) { + $strings = str_replace( $key, $value, $strings ); + $strings = str_replace( $value.'::', $value.'->', $strings ); + } + + // 変数取り出し文字列を冒頭に追加 + $retstring = '<?php ' . implode("",$temporary_valiable_getter_array); + $retstring .= ' if(is_object('.$strings.')||is_array('.$strings.')){ '; + $retstring .= 'echo '; + if( $is_urlencode ) { $retstring .= 'urlencode('; } + if( $is_nl2br ) { $retstring .= 'nl2br('; } + if( !$is_noescape ) { $retstring .= 'htmlspecialchars('; } + if( $is_escape_sq ) { $retstring .= 'str_replace("\'","\\\'",'; } + if( $is_escape_dq ) { $retstring .= 'str_replace(\'"\',\'\\"\','; } + if( $is_escape_nl ) { $retstring .= 'str_replace("\\n","\\\n",str_replace("\\r","\\n",str_replace("\\r\\n","\\n",'; } + if( $is_nl2null ) { $retstring .= 'str_replace("\\n","",str_replace("\\r","",str_replace("\\r\\n","",'; } + $retstring .= 'print_r( '.$strings.', true )'; + if( $is_nl2null ) { $retstring .= ')'; } + if( $is_escape_nl ) { $retstring .= ')'; } + if( $is_escape_dq ) { $retstring .= ')'; } + if( $is_escape_sq ) { $retstring .= ')'; } + if( !$is_noescape ) { $retstring .= ')'; } + if( $is_nl2br ) { $retstring .= ')'; } + if( $is_urlencode ) { $retstring .= ')'; } + $retstring .= ';'; + $retstring .= ' }else{ '; + $retstring .= 'echo '; + if( $is_urlencode ) { $retstring .= 'urlencode('; } + if( $is_nl2br ) { $retstring .= 'nl2br('; } + if( !$is_noescape ) { $retstring .= 'htmlspecialchars('; } + if( $is_escape_sq ) { $retstring .= 'str_replace("\'","\\\'",'; } + if( $is_escape_dq ) { $retstring .= 'str_replace(\'"\',\'\\"\','; } + if( $is_escape_nl ) { $retstring .= 'str_replace("\\n","\\\n",str_replace("\\r","\\n",str_replace("\\r\\n","\\n",'; } + if( $is_nl2null ) { $retstring .= 'str_replace("\\n","",str_replace("\\r","",str_replace("\\r\\n","",'; } + $retstring .= $strings; + if( $is_nl2null ) { $retstring .= ')'; } + if( $is_escape_nl ) { $retstring .= ')'; } + if( $is_escape_dq ) { $retstring .= ')'; } + if( $is_escape_sq ) { $retstring .= ')'; } + if( !$is_noescape ) { $retstring .= ')'; } + if( $is_nl2br ) { $retstring .= ')'; } + if( $is_urlencode ) { $retstring .= ')'; } + $retstring .= ';'; + $retstring .= ' } ?>'; + + return $retstring; + + } +} +?> \ No newline at end of file Added: db/current/spider/lib/util/CharUtility.class.php =================================================================== --- db/current/spider/lib/util/CharUtility.class.php (rev 0) +++ db/current/spider/lib/util/CharUtility.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,283 @@ +<?php +/** + * 文字列用ユーティリティクラス + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class util_CharUtility { + function util_CharUtility() { + } + /** + * 渡された文字列を指定されたキーでMD5暗号化して返します。 + */ + function md5_encrypt($plain_text, $password, $iv_len = 16) { + $plain_text .= "\x13"; + $n = strlen($plain_text); + if ($n % 16) $plain_text .= str_repeat("\0", 16 - ($n % 16)); + $i = 0; + $enc_text = util_CharUtility::get_rnd_iv($iv_len); + $iv = substr($password ^ $enc_text, 0, 512); + while ($i < $n) { + $block = substr($plain_text, $i, 16) ^ pack('H*', md5($iv)); + $enc_text .= $block; + $iv = substr($block . $iv, 0, 512) ^ $password; + $i += 16; + } + return base64_encode($enc_text); + } + /** + * 渡された文字列を渡されたキーで複合化して返します。 + */ + function md5_decrypt($enc_text, $password, $iv_len = 16) { + $enc_text = base64_decode($enc_text); + $n = strlen($enc_text); + $i = $iv_len; + $plain_text = ''; + $iv = substr($password ^ substr($enc_text, 0, $iv_len), 0, 512); + while ($i < $n) { + $block = substr($enc_text, $i, 16); + $plain_text .= $block ^ pack('H*', md5($iv)); + $iv = substr($block . $iv, 0, 512) ^ $password; + $i += 16; + } + return preg_replace('/\\x13\\x00*$/', '', $plain_text); + } + /** + * + */ + function get_rnd_iv($iv_len) { + $iv = ''; + while ($iv_len-- > 0) { + $iv .= chr(mt_rand() & 0xff); + } + return $iv; + } + /** + * 指定桁数のランダム文字列を生成して返します。 + */ + function get_rundom_key( $length=16 ) { + $char_array = array( + '0','1','2','3','4','5','6','7','8','9' + ,'a','b','c','d','e','f','g','h','i','j' + ,'k','l','m','n','o','p','q','r','s','t' + ,'u','v','w','x','y','z' + ,'A','B','C','D','E','F','G','H','I','J' + ,'K','L','M','N','O','P','Q','R','S','T' + ,'U','V','W','X','Y','Z' + ,'-' + ); + $rand_keys = array_rand($char_array, $length); + $ret_str = ''; + foreach ( $rand_keys as $key ) { + $ret_str .= $char_array[$key]; + } + return $ret_str; + } + /** + * 指定桁数のランダム文字列を生成して返します。 + * 見た目が紛らわしい0,o,O,lなどの文字列は利用しません。 + */ + function get_rundom_password( $length=8 ) { + $char_array = array( + '1','2','3','4','5','6','7','8','9' + ,'a','b','c','d','e','f','g','h','i','j' + ,'k','m','n','p','q','r','s','t' + ,'u','v','w','x','y','z' + ,'A','B','C','D','E','F','G','H','J' + ,'K','M','N','P','Q','R','S','T' + ,'U','V','W','X','Y','Z' + ,'-' + ); + $rand_keys = array_rand($char_array, $length); + $ret_str = ''; + foreach ( $rand_keys as $key ) { + $ret_str .= $char_array[$key]; + } + return $ret_str; + } + /** + * 指定桁数のランダム文字列を生成して返します。 + * 見た目が紛らわしい0,o,O,lなどの文字列は利用しません。 + */ + function get_rundom_large_char( $length=8 ) { + $char_array = array( + '1','2','3','4','5','6','7','8','9' + ,'A','B','C','D','E','F','G','H','J' + ,'K','M','N','P','Q','R','S','T' + ,'U','V','W','X','Y','Z' + ); + $rand_keys = array_rand($char_array, $length); + $ret_str = ''; + foreach ( $rand_keys as $key ) { + $ret_str .= $char_array[$key]; + } + return $ret_str; + } + /** + * 指定長のランダムアルファベットを生成して返します + */ + function createRundomAlphabet( $length, $type=0 ) { + $start = 65; + $end = 90; + if( 1==$type ) { + $start = 97; + $end = 122; + } + return util_CharUtility::createRundomAscii( $length, $start, $end ); + } + /** + * 指定範囲のASCII文字列からランダム文字列を生成します + */ + function createRundomAscii( $length=8, $start=33, $end=126 ) { + $string = ''; + for( $i=0; $i<$length; $i++ ) { + $num = rand( $start, $end ); + $string .= pack('C*',$num); + } + return $string; + } + /** + * 文字列を数字部分とアルファベット部分ごとの要素に分けて配列で戻します。 + */ + function explodeAN( $string, $alphSep=0 ) { + $elm = ''; + $elmArray = array(); + $prevChar = ''; + for( $pos=0; $pos<strlen($string); $pos++ ) { + $char = substr($string,$pos,1); + if( strlen($prevChar) > 0 ) { + if( preg_match('/[0-9]/',$prevChar) >0 ) { + if( preg_match('/[0-9]/',$char) >0 ) { + $elm .= $char; + } else { + array_push( $elmArray, $elm ); + $elm = $char; + } + } else { + if( preg_match('/[0-9]/',$char) >0 ) { + array_push( $elmArray, $elm ); + $elm = $char; + } else { + if( $alphSep == 0 ) { + $elm .= $char; + } else { + if( strlen($elm) >= $alphSep ) { + array_push( $elmArray, $elm ); + $elm = $char; + } else { + $elm .= $char; + } + } + } + } + } else { + $elm .= $char; + } + $prevChar = $char; + } + if( strlen($elm) > 0 ) { + array_push( $elmArray, $elm ); + } + // 数字部分はint範囲内に収める為最後に文字の長さをチェック + $returnArray = array(); + foreach( $elmArray as $elm ) { + if( preg_match('/^[0-9]+$/',$elm) > 0 ) { + // 数字の場合文字数を確認 + if( strlen($elm) > 8 ) { + // 8文字以上ならあふれる恐れが高いので8文字ずつに分割 + for( $i=0; $i<strlen($elm);$i=$i+8 ) { + $numStr = trim(substr($elm,$i,8)); + array_push($returnArray,$numStr); + } + } else { + // 8文字以内ならそのまま利用 + array_push($returnArray,$elm); + } + } else { + array_push($returnArray,$elm); + } + } +// return $elmArray; + return $returnArray; + } + /** + * CSVデータラインを配列にして返します + */ + function csv2Array( $strings ) { + $strings = str_replace("\r\n","\n",$strings); + $strings = str_replace("\r","\n",$strings); + $columns = explode(',',$strings); + $regist_columns = array(); + $column_value = ''; + // カラム値を""と,の関係維持して正確に分割する + foreach( $columns as $val ) { + if( strlen($column_value) > 0 ) { + $column_value .= ','.$val; + } else { + $column_value .= $val; + } + $quote_count = substr_count( $column_value, '"' ); + if( $quote_count % 2 != 0 ) { + // クォータ数が偶数でない場合はカラムデータが完結していないので次の行へ + } else { + // 完結している場合はカラムとして処理 + if( preg_match('/^"/',$column_value) > 0 && preg_match( '/"$/', $column_value ) > 0 ) { + $column_value = preg_replace('/^"/','',$column_value ); + $column_value = preg_replace('/"$/','',$column_value ); + $column_value = preg_replace('/""/','"',$column_value ); + } + $column_value = mb_convert_kana($column_value,'KVas'); + array_push( $regist_columns, $column_value ); + $column_value = ''; + } + } + return $regist_columns; + } + /** + * CSVデータラインを指定定義のハッシュにして返します + */ + function csv2Hash( $orderDefinitionHash, $strings ) { + $dataArray = util_CharUtility::csv2Array( $strings ); + $returnHash = array(); + if( isset($orderDefinitionHash[0]) ) { + // キー0番目が格納されているならキーが順序の処理 + foreach( $orderDefinitionHash as $num => $keyName ) { + $returnHash[$keyName] = trim($dataArray[$num]); + } + } else { + // キーが数値でないなら値が順序の処理 + foreach( $orderDefinitionHash as $keyName => $order ) { + $returnHash[$keyName] = trim($dataArray[$order-1]); + } + } + return $returnHash; + } + /** + * 正規表現で利用する為の文字パターン用にエスケープします。 + */ + function escape_regx_str($str){ + return util_CharUtility::escapeRegxStr($str); + } + function escapeRegxStr($str){ + $str = str_replace('\\', '\\\\', $str); + $str = str_replace('*', '\\*', $str); + $str = str_replace('+', '\\+', $str); + $str = str_replace('.', '\\.', $str); + $str = str_replace('?', '\\?', $str); + $str = str_replace('(', '\\(', $str); + $str = str_replace(')', '\\)', $str); + $str = str_replace('{', '\\{', $str); + $str = str_replace('}', '\\}', $str); + $str = str_replace('[', '\\[', $str); + $str = str_replace(']', '\\]', $str); + $str = str_replace('^', '\\^', $str); + $str = str_replace('$', '\\$', $str); + $str = str_replace('|', '\\|', $str); + $str = str_replace('/', '\\/', $str); + $str = str_replace('_', '\\_', $str); + return $str; + } +} +?> \ No newline at end of file Added: db/current/spider/lib/util/Date.class.php =================================================================== --- db/current/spider/lib/util/Date.class.php (rev 0) +++ db/current/spider/lib/util/Date.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,70 @@ +<?php +class util_Date { + /** + * 指定年月の日数を取得します + * @param $year 年 + * @param $month 月 + * @return 月の日数,年月の指定が正しくない場合はfalse + */ + function getMonthMaxDay( $year, $month ) { + if( !is_numeric( $year ) || preg_match('/^[0-9]{1,4}$/',$year) == 0 ) { + return false; + } else if( !is_numeric( $month ) || preg_match('/^((|0)[1-9]|1[0-2])$/',$month) == 0 ) { + return false; + } + if ( ( $month == 4 || $month == 6 || $month == 9 || $month == 11 ) ) { + return 30; + } else if( 2 != $month ) { + return 31; + } else { + if ( ( $year % 400 ) == 0 ) { + return 29; + } else if ( ( $year % 100 ) == 0 ) { + return 28; + } else if ( ( $year % 4 ) == 0 ) { + return 29; + } else { + return 28; + } + } + } + /** + * 指定年月の日付ををキー、値を曜日とするハッシュを取得します + * @param $year 年 + * @param $month 月 + * @param $isHash 日付以下をハッシュにするかのフラグ + * @return array 指定年月の日付ををキー、値を曜日とするハッシュ + */ + function getMonthCalendarHash( $year, $month, $isHash=false, $is2d=false ) { + if( $maxDays = util_Date::getMonthMaxDay( $year, $month ) ) { + $calendarHash = array(); + for ( $day=1; $day<=$maxDays; $day++ ) { + $wday = jddayofweek( cal_to_jd( CAL_GREGORIAN, $month, $day, $year ), 0 ); + $vday = $day; + if( $is2d ) { + $vday = sprintf('%02d',$day); + } + if( $isHash ) { + $calendarHash[$vday] = array('wday'=>$wday); + } else { + $calendarHash[$vday] = $wday; + } + } + return $calendarHash; + } else { + return false; + } + } + /** + * 指定年月の1日から末日とその曜日の配列の生成 + */ + function getDayArray ( $year, $month ) { + $maxDays = util_Date::getMonthMaxDay( $year, $month ); + for ( $i=1; $i<=$maxDays; $i++ ) { + $week_day = jddayofweek( cal_to_jd( CAL_GREGORIAN, $month, $i, $year ), 0 ); + $day_array[$i] = $week_day; + } + return $day_array; + } +} +?> \ No newline at end of file Added: db/current/spider/lib/util/File.class.php =================================================================== --- db/current/spider/lib/util/File.class.php (rev 0) +++ db/current/spider/lib/util/File.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,81 @@ +<?php +/** + * ファイルシステムに関するユーティリティ関数群を提供する静的メソッドクラス + */ +class util_File { + /** + * 指定フォルダ以下のフォルダとファイルを指定フォルダ化にコピーします + * @param $resource_dir コピー元フォルダパス + * @param $destination_dir コピー先フォルダパス + */ + function copyDirFiles( $resource_dir, $destination_dir, $force=false ) { + if( is_dir( $resource_dir ) && is_dir($destination_dir) ) { + if ($dh = opendir($resource_dir)) { + while (($file_name = readdir($dh)) !== false) { + if( preg_match('/^\\./',$file_name) == 0 ) { + $file_absolute_path = $resource_dir.DIRECTORY_SEPARATOR.$file_name; + $file_type = filetype($file_absolute_path); + $destination_path = $destination_dir.DIRECTORY_SEPARATOR.$file_name; + if( preg_match('/^[dD][iI][rR]/', filetype($file_absolute_path) ) ) { + // フォルダの場合なければ作成する + if( !file_exists($destination_path) ) { + if( @mkdir( $destination_path, SPIDER_FOLDER_CREATE_PERMITTION ) ) { + @chmod( $destination_path, SPIDER_FOLDER_CREATE_PERMITTION ); + } else { + return false; + } + } + // 再帰呼び出し + if( !util_File::copyDirFiles( $file_absolute_path, $destination_path ) ) { + return false; + } + } else if( preg_match('/^[fF][iI][lL][eE]/', filetype($file_absolute_path) ) ) { + // 対象がファイルの場合なければコピー + if( $force || !file_exists($destination_path) ) { + if( @copy( $file_absolute_path, $destination_path ) ) { + @chmod( $destination_path, SPIDER_FOLDER_CREATE_PERMITTION ); + } else { + return false; + } + } + } + } + } + @closedir( $dh ); + } + } else { + return false; + } + return true; + } + /** + * spiderアプリケーション内の絶対ファイルパスをアプリケーションURIに変換します + */ + function path2suri( $absolutePath ) { + $basePath = str_replace(DIRECTORY_SEPARATOR,'/',APPLICATION_BASE_PATH); + $absolutePath = str_replace(DIRECTORY_SEPARATOR,'/',$absolutePath); + if( strlen($absolutePath) >= strlen($basePath) ) { + $retUri = str_replace($basePath,'',$absolutePath); + if( preg_match('/\\/$/',$retUri) > 0 ) { $retUri = preg_replace('/\\/$/','',$retUri); } + if( preg_match('/^\\//',$retUri) == 0 ) { $retUri = '/'.$retUri; } + return $retUri; + } + return false; + } + /** + * spiderアプリケーション内のURIからファイル絶対パスに変換します + */ + function suri2path( $uri ) { + $absolutePath = str_replace(DIRECTORY_SEPARATOR,'/',APPLICATION_BASE_PATH); + if( preg_match('/\\/$/',$absolutePath) > 0 ) { + $absolutePath = preg_replace('/\\/$/','',$absolutePath); + } + if( '/' == $uri ) { + } else { + $absolutePath .= $uri; + } + $absolutePath = str_replace('/',DIRECTORY_SEPARATOR,$absolutePath); + return $absolutePath; + } +} +?> \ No newline at end of file Added: db/current/spider/lib/util/GetHTTPResponse.class.php =================================================================== --- db/current/spider/lib/util/GetHTTPResponse.class.php (rev 0) +++ db/current/spider/lib/util/GetHTTPResponse.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,207 @@ +<?php +/** + * ユーティリティ:HTTPリクエストを送信してレスポンスを取得するユーティリティオブジェクト + * + * @package util ユーティリティパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class util_GetHTTPResponse { + var $protocol = ""; + var $status_code = ""; + var $status_string = ""; + var $response_headers = array(); + var $response_body = null; + function util_GetHTTPResponse(){ + } + function get($url,$header_params=array()){ + list( $pr, $blank, $domain ) = explode('/',$url ); + $uri = substr($url,strpos($url,$domain)); + $uri = str_replace($domain,"",$uri); + if( strlen($uri) == 0 ) { + $uri = '/'; + } + if( preg_match('/^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}/',gethostbyname($domain)) == 0 ) { + return false; + } + return $this->get_response($domain,$uri,$header_params); + } + function get_response($host,$uri,$header_params=array()){ + $request = "GET {$uri} HTTP/1.1\r\n" + ."Accept: */*\r\n" + ."Host: {$host}\r\n" + ; + foreach( $header_params as $key => $value ) { + if( strlen(trim($key)) > 0 && strlen(trim($value)) > 0 ) { + $request .= $key . ": " . $value . "\r\n"; + } + } + $request .= "Connection: close\r\n\r\n"; + if( $fp = @fsockopen( gethostbyname($host), 80, $rv->en, $rv->es, 20 ) ){ + if( socket_set_timeout( $fp, 30 ) ) { + fwrite( $fp, $request ); + $response = ''; + while (!feof($fp)) { + $response .= fgets($fp, 128); + } + // responseの解析 + $header_string = ''; + $response_body = null; + + // レスポンスヘッダ文字列を取得 + $header_string = substr( $response, 0, strpos($response,"\r\n\r\n")); + $headerpear_array = explode("\r\n",$header_string); + // レスポンスステータスを確認 + $status_str = array_shift($headerpear_array); + list($this->protocol,$this->status_code,$this->status_string) + = explode(" ",$status_str); + // その他のヘッダを取得 + foreach($headerpear_array as $line){ + if( strlen($line) > 0 ) { + $headers = explode(":",$line); + if( count($headers) > 0 ) { + $key = array_shift($headers); + $val = implode(':',$headers); + $this->response_headers[trim($key)] = trim($val); + } + } + } + // レスポンスボディの取得 + if( $this->response_headers['Transfer-Encoding'] == 'chunked' ) { + $header_hex_string = bin2hex($header_string."\r\n\r\n"); + $separator_hex_string = bin2hex("\r\n"); + $body_start_pos = strlen($header_hex_string); + $body_hex_string = bin2hex($response); + $body_hex_string = substr($body_hex_string,$body_start_pos); + $body_chunk_array = explode($separator_hex_string,$body_hex_string); + // 0,2,4,..偶数はチャンクサイズなので削除してつなげ直す + $i = 0; + $body_hex_string = ''; + foreach( $body_chunk_array as $val ) { + if( $i%2 != 0 ) { $body_hex_string .= $val; } + $i++; + } + $this->response_body = pack("H*",$body_hex_string); + } else { + $lines = explode("\r\n\r\n",$response); + $header_string = array_shift($lines); + $response_body = implode("\r\n\r\n",$lines); + $this->response_body = $response_body; + $headerpear_array = explode("\r\n",$header_string); + $status_str = array_shift($headerpear_array); + list($this->protocol,$this->status_code,$this->status_string) + = explode(" ",$status_str); + } + return true; + } + return false; + } else { + return false; + } + } + function post($url,$header_params=array(),$requestBody){ + list( $pr, $blank, $domain ) = explode('/',$url ); + $uri = substr($url,strpos($url,$domain)); + $uri = str_replace($domain,"",$uri); + if( strlen($uri) == 0 ) { + $uri = '/'; + } + if( preg_match('/^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}/',gethostbyname($domain)) == 0 ) { + return false; + } + return $this->post_response($domain,$uri,$header_params,$requestBody); + } + function post_response($host,$uri,$header_params=array(),$requestBody){ + $request = "POST {$uri} HTTP/1.1\r\n" + ."Accept: */*\r\n" + ."Host: {$host}\r\n" + ; + foreach( $header_params as $key => $value ) { + if( strlen(trim($key)) > 0 && strlen(trim($value)) > 0 ) { + $request .= $key . ": " . $value . "\r\n"; + } + } + $request .= "Connection: close\r\n\r\n"; + $request .= "Content-Type: application/x-www-form-urlencoded;charset=UTF-8\r\n"; + $request .= "Content-Length: ".strlen($requestBody)."\r\n\r\n"; + $request .= $requestBody; + if( $fp = @fsockopen( $host, 80, $rv->en, $rv->es, 20 ) ){ + if( socket_set_timeout( $fp, 30 ) ) { + fwrite( $fp, $request ); + $response = ''; + while (!feof($fp)) { + $response .= fgets($fp, 128); + } + // responseの解析 + $header_string = ''; + $response_body = null; + + // レスポンスヘッダ文字列を取得 + $header_string = substr( $response, 0, strpos($response,"\r\n\r\n")); + $headerpear_array = explode("\r\n",$header_string); + // レスポンスステータスを確認 + $status_str = array_shift($headerpear_array); + list($this->protocol,$this->status_code,$this->status_string) + = explode(" ",$status_str); + // その他のヘッダを取得 + foreach($headerpear_array as $line){ + if( strlen($line) > 0 ) { + $headers = explode(":",$line); + if( count($headers) > 0 ) { + $key = array_shift($headers); + $val = implode(':',$headers); + $this->response_headers[trim($key)] = trim($val); + } + } + } + // レスポンスボディの取得 + if( $this->response_headers['Transfer-Encoding'] == 'chunked' ) { + $header_hex_string = bin2hex($header_string."\r\n\r\n"); + $separator_hex_string = bin2hex("\r\n"); + $body_start_pos = strlen($header_hex_string); + $body_hex_string = bin2hex($response); + $body_hex_string = substr($body_hex_string,$body_start_pos); + $body_chunk_array = explode($separator_hex_string,$body_hex_string); + // 0,2,4,..偶数はチャンクサイズなので削除してつなげ直す + $i = 0; + $body_hex_string = ''; + foreach( $body_chunk_array as $val ) { + if( $i%2 != 0 ) { $body_hex_string .= $val; } + $i++; + } + $this->response_body = pack("H*",$body_hex_string); + } else { + $lines = explode("\r\n\r\n",$response); + $header_string = array_shift($lines); + $response_body = implode("\r\n\r\n",$lines); + $this->response_body = $response_body; + $headerpear_array = explode("\r\n",$header_string); + $status_str = array_shift($headerpear_array); + list($this->protocol,$this->status_code,$this->status_string) + = explode(" ",$status_str); + } + return true; + } + return false; + } else { + return false; + } + } +} +//$obj = new util_GetHTTPResponse(); +//if( $obj->get('http://www.md-systems.net/') ){ +//// foreach( $obj->response_headers as $key => $value ) { +//// header($key.': '.$value); +//// } +//// print $obj->response_body; +//// +// header('Content-type: text/plain;charset=UTF-8'); +//print_r($obj); +//} else { +// header('Content-type: text/plain;charset=UTF-8'); +// echo "通信に失敗"; +//} +// +?> \ No newline at end of file Added: db/current/spider/lib/util/LockProcess.class.php =================================================================== --- db/current/spider/lib/util/LockProcess.class.php (rev 0) +++ db/current/spider/lib/util/LockProcess.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,83 @@ +<?php +define( "UTIL_LOCK_PROCESS_MAX_LOOP", 30 ); +/** + * ユーティリティ:プロセスロックを行うユーティリティオブジェクト + * + * @package util ユーティリティパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class util_LockProcess { + + var $lock_name = 'common'; + var $lock_file_name; + + /** + * コンストラクタ + */ + function util_LockProcess($lock_name=null,$lock_dir_path=null){ + if( !is_null( $lock_name ) && strlen(trim($lock_name))) { + $this->lock_name = $lock_name; + $this->lock_name + = str_replace( DIRECTORY_SEPARATOR, '_S_', $this->lock_name ); + if( preg_match( '/\\:/', $this->lock_name ) ) { + $this->lock_name = str_replace( ':', '_C_', $this->lock_name ); + } + } + if( is_null( $lock_dir_path ) ) { + $lock_dir_path = DIR_PATH_LOCK; + } + $this->lock_file_name = $lock_dir_path + .DIRECTORY_SEPARATOR.".".$this->lock_name; + } + + /** + * ロックを確認、開始します。 + * @return 成功したらtrue / ロックに失敗したらfalse + */ + function lock(){ + // 現在ロックがかかっているか確認する + if( $this->wait() ) { + // ロックがかかっていないならロックディレクトリ作成 + mkdir( $this->lock_file_name, SPIDER_FOLDER_CREATE_PERMITTION ); + chmod( $this->lock_file_name, SPIDER_FOLDER_CREATE_PERMITTION ); + return true; + } else { + return false; + } + } + + /** + * 指定名のロックを解除します。 + */ + function release(){ + if( is_dir( $this->lock_file_name ) ){ + rmdir( $this->lock_file_name ); + } + return true; + } + /** + * ロックが解除されるまで待機します + */ + function wait() { + $loop_count = 0; + while( true ) { + $loop_count++; + if( $loop_count > UTIL_LOCK_PROCESS_MAX_LOOP ){ + return false; + } else if ( !is_dir( $this->lock_file_name ) ) { + return true; + } else if ( filemtime($this->lock_file_name) + 30 < time() ){ + $this->release(); + return true; + } else { + usleep(500); + continue; + } + } + } +} + +?> \ No newline at end of file Added: db/current/spider/lib/util/Mail.class.php =================================================================== --- db/current/spider/lib/util/Mail.class.php (rev 0) +++ db/current/spider/lib/util/Mail.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,1135 @@ +<?php +/** + * メール送信基底クラス + * @package util ユーティリティパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class util_Mail { + + /** 送信設定オプション */ + var $options = array(); + /** 初期化済みフラグ */ + var $is_init = false; + + // 送信項目 + /** subject */ + var $subject; + /** text body */ + var $text_body; + /** html body */ + var $html_body; + /** attachement */ + var $attachements = array(); + /** html inline images */ + var $inline_images = array(); + + /** To */ + var $to; + /** From */ + var $from; + /** Cc */ + var $cc = array(); + /** Bcc */ + var $bcc = array(); + /** reply to */ + var $reply_to; + /** return path */ + var $return_path; + + // option + var $boundary; + var $x_mailer = 'MDS.Co.,Ltd./Web Mailer v1.0.0/www.md-systems.net'; + var $charset_header = 'ISO-2022-JP'; + var $charset_body = 'ISO-2022-JP'; + var $charset_filename = 'Shift_JIS'; + var $replace_words = array(); + + /** + * コンストラクタ + */ + function util_Mail() { + } + /** + * 送信メソッドクラス定義に合わせたインスタンスを生成します。 + * $class_name: SendMail / SMTP /PHP + * $options: 送信オプション + */ + function get_instance( $class_name='SendMail', $options=array() ) { + $send_class_path = dirname(__FILE__) + .DIRECTORY_SEPARATOR.'mail' + .DIRECTORY_SEPARATOR.$class_name.'.class.php'; + if( !file_exists( $send_class_path ) ) { + return false; + } else { + require_once($send_class_path); + $send_class_name = 'util_mail_' . $class_name; + $send_object = new $send_class_name; + if( count($send_object->validate_options( $options )) == 0 ) { + $send_object->init( $options ); + return $send_object; + } else { + return false; + } + } + } + /** + * 送信設定オプションの妥当性検査を行いエラーメッセージの配列を返します。 + * エラーがない場合は要素0の配列を返します。 + */ + function validate_options( & $options ) { + return array(); + } + /** + * 指定された送信設定オプションで送信オブジェクトを初期化します。 + */ + function init( $options = array() ) { + $this->options = $options; + $this->is_init = true; + } + /** + * 件名を設定します。 + * @param $subject string + */ + function setSubject( $subject ) { + $this->subject = $subject; + } + /** + * テキスト本文を設定します。 + * @param $body string + */ + function setTextBody( $body ) { + $this->text_body = $body; + } + /** + * HTML本文を設定します。 + * @param $body string + */ + function setHtmlBody( $body ) { + $this->html_body = $body; + } + /** + * テンプレートから件名と本文を設定します。 + * @param $file_path テンプレートファイルパス + */ + function setTemplateFile( $file_path, $toEncoding=null, $fromEncoding='auto', $convertKana=null ) { + if( file_exists( $file_path ) ) { + if( $lines = @file( $file_path ) ) { + $this->subject = array_shift( $lines ); + $this->subject = str_replace("\r\n","",$this->subject); + $this->subject = str_replace("\r","",$this->subject); + $this->subject = str_replace("\n","",$this->subject); + $this->text_body = implode("",$lines); + $this->text_body = str_replace("\r\n","\n",$this->text_body); + $this->text_body = str_replace("\r","\n",$this->text_body); + if( !is_null($toEncoding) && $toEncoding != $fromEncoding ) { + if( !is_null($fromEncoding) ) { + $this->subject = mb_convert_encoding($this->subject,$toEncoding,$fromEncoding); + $this->text_body = mb_convert_encoding($this->text_body,$toEncoding,$fromEncoding); + } else { + $this->subject = mb_convert_encoding($this->subject,$toEncoding); + $this->text_body = mb_convert_encoding($this->text_body,$toEncoding); + } + } + if( !is_null($convertKana) ) { + $this->subject = mb_convert_kana($this->subject,$convertKana,$toEncoding); + $this->text_body = mb_convert_kana($this->text_body,$convertKana,$toEncoding); + } + } else { + return false; + } + } else { + return false; + } + return true; + } + /** + * Fromアドレスを設定します。 + * メールアドレス RFC 2822を満たしていればアドレスに名前を付加することもできます。 + * 例) MDS <info****@md-sy*****> + * @param $address string + */ + function setFrom( $address ) { + $this->from = $address; + } + function setReplyTo( $address ) { + $this->reply_to = $address; + } + function setReturnPath( $address ) { + $this->return_path = $address; + } + /** + * Ccアドレスを配列で設定します。 + * メールアドレス RFC 2822を満たしていればアドレスに名前を付加することもできます。 + * 例) MDS <info****@md-sy*****> + * @param $address_array string + */ + function setCc( $address_array ) { + if( is_array( $address_array ) ) { + $this->cc = $address_array; + } else if( strlen(trim($address_array)) > 0 ) { + $this->cc = array(); + array_push( $this->cc, $address_array ); + } + } + /** + * Ccアドレスを追加します。 + * メールアドレス RFC 2822を満たしていればアドレスに名前を付加することもできます。 + * 例) MDS <info****@md-sy*****> + * @param $address string + */ + function addCc( $address ) { + if( !is_array( $this->cc) ) { + $this->cc = array(); + } + array_push( $this->cc, $address ); + } + /** + * Bccアドレスを配列で設定します。 + * メールアドレス RFC 2822を満たしていればアドレスに名前を付加することもできます。 + * 例) MDS <info****@md-sy*****> + * @param $address_array string + */ + function setBcc( $address_array ) { + if( is_array( $address_array ) ) { + $this->bcc = $address_array; + } else if( strlen(trim($address_array)) > 0 ) { + $this->bcc = array(); + array_push( $this->bcc, $address_array ); + } + } + /** + * Bccアドレスを追加します。 + * メールアドレス RFC 2822を満たしていればアドレスに名前を付加することもできます。 + * 例) MDS <info****@md-sy*****> + * @param $address string + */ + function addBcc( $address ) { + if( !is_array( $this->bcc) ) { + $this->bcc = array(); + } + array_push( $this->bcc, $address ); + } + /** + * 添付ファイルを追加します。 + * @param $address string + */ + function addAttachement( $file_path, $name=null, $type="application/octet-stream" ) { + if( !is_array( $this->attachements ) ) { + $this->attachements = array(); + } + if( is_null( $name ) || strlen(trim($name)) == 0 ) { + $name = basename( $file_path ); + } + $file_info = array( + 'name' => $name, + 'path' => $file_path, + 'type' => $type + ); + array_push( $this->attachements, $file_info ); + } + /** + * 添付ファイルを追加します。 + * @param $address string + */ + function addInlineImage( $content_id, $file_path, $name=null, $type="application/octet-stream" ) { + if( !is_array( $this->inline_images ) ) { + $this->inline_images = array(); + } + if( is_null( $name ) || strlen(trim($name)) == 0 ) { + $name = basename( $file_path ); + } + $file_info = array( + 'name' => $name, + 'path' => $file_path, + 'type' => $type + ); + $this->inline_images[$content_id] = $file_info; + } + + /** + * メールを送信します + */ + function send( $to, $subject=null, $body=null, $from=null, $reply_to=null, $return_path=null, $cc=null, $bcc=null, $add_header_crlf=false, $convert_encoding=true ) { + $this->to = $to; + if( !is_null($subject) && strlen(trim($subject)) > 0 ) { + $this->subject = $subject; + } + if( !is_null($body) && strlen(trim($body)) > 0 ) { + $this->text_body = $body; + } + if( !is_null($from) && strlen(trim($from)) > 0 ) { + $this->from = $from; + } + if( !is_null($reply_to) && strlen(trim($reply_to)) > 0 ) { + $this->reply_to = $reply_to; + } + if( !is_null($return_path) && strlen(trim($return_path)) > 0 ) { + $this->return_path = $return_path; + } + if( is_array( $cc ) ) { + $this->setCc( $cc ); + } else if( strlen(trim($cc)) > 0 ) { + $this->addCc( $cc ); + } + if( is_array( $bcc ) ) { + $this->setBcc( $bcc ); + } else if( strlen(trim($bcc)) > 0 ) { + $this->addBcc( $bcc ); + } + return $this->send_execute( $add_header_crlf, $convert_encoding ); + } + /** + * 送信処理を行う抽象メソッド + */ + function send_execute( $add_header_crlf=false, $convert_encoding=true ) { + return false; + } + /** + * メールヘッダ用にエンコードした件名を取得します + */ + function get_encoded_subject( $add_header_crlf=false, $convert_encoding=true ) { + // 置換文字列の処理を行う + $subject = $this->subject; + foreach( $this->replace_words as $key => $val ) { + if( !$convert_encoding && $this->getHeaderEncoding() != 'UTF-8' ) { + // エンコーディングの必要がない場合、ヘッダエンコードに置換ワードを合わせる + $key = mb_convert_encoding($key, $this->getHeaderEncoding(),'auto'); + $val = mb_convert_encoding($val, $this->getHeaderEncoding(),'auto'); + } + $subject = str_replace( "{".$key."}", $val, $subject ); + } + if( $add_header_crlf ) { + if( $convert_encoding ) { + return mb_encode_mimeheader($subject,$this->getHeaderEncoding()); + } else { + return mb_encode_mimeheader($subject); + } + } else { + if( $convert_encoding && mb_detect_encoding($subject) != 'ascii' ) { + $subject = mb_convert_encoding($subject,$this->getHeaderEncoding(),'auto'); + } + $subject = base64_encode( $subject ); + return '=?'.$this->getHeaderCharset().'?B?'.$subject.'?='; + } + } + /** + * 設定されたメールヘッダーをヘッダー文字列として取得します。 + */ + function _get_header_part_strings( $include_to=false, $include_subject=false, $include_bcc=false, $add_header_crlf=false, $convert_encoding=true ) { + $header_hash = $this->_get_header_hash( $include_to, $include_subject, $include_bcc, $add_header_crlf, $convert_encoding ); + $header_strings = ''; + foreach( $header_hash as $key => $value ) { + $header_strings .= $key . ': ' . $value . "\r\n"; + } + return $header_strings . "\r\n"; + } + /** + * 設定されたメールヘッダーをエンコード済みのハッシュで取得します。 + */ + function _get_header_hash( $include_to=false, $include_subject=false, $include_bcc=false, $add_header_crlf=false, $convert_encoding=true ) { + $return_hash = array(); + $return_hash['MIME-Version'] = '1.0'; + $return_hash['Content-Transfer-Encoding'] = '7bit'; + $return_hash['X-Mailer'] = $this->x_mailer; + + if( strlen(trim($this->reply_to)) == 0 ) { + $this->reply_to = $this->from; + } + if( strlen(trim($this->return_path)) == 0 ) { + $this->return_path = $this->getFromAddress(); + } + + // メールアドレス RFC 2822を満たすことを前提としてユーザ名をエンコードする + if( $include_to ) { + $return_hash['To'] = $this->convertHeaderAddress( $this->to ); + } + $return_hash['From'] = $this->convertHeaderAddress( $this->from ); + $return_hash['Reply-To'] = $this->convertHeaderAddress( $this->reply_to ); + $return_hash['Return-Path'] = $this->convertHeaderAddress( $this->return_path ); + $new_cc_array = array(); + foreach( $this->cc as $address ) { + if( strlen(trim($address)) > 0 ) { + // RFC 2822を満たすことを前提としてユーザ名をエンコードする + array_push( $new_cc_array, $this->convertHeaderAddress( $address ) ); + } + } + if( count($new_cc_array) > 0 ) { + $return_hash['Cc'] = implode(", ", $new_cc_array ); + } + if( $include_bcc ) { + $new_bcc_array = array(); + foreach( $this->bcc as $address ) { + if( strlen(trim($address)) > 0 ) { + // RFC 2822を満たすことを前提としてユーザ名をエンコードする + array_push( $new_bcc_array, $this->convertHeaderAddress( $address ) ); + } + } + if( count($new_bcc_array) > 0 ) { + $return_hash['Bcc'] = implode(", ", $new_bcc_array ); + } + } + // 件名の処理 + if( $include_subject ) { + $return_hash['Subject'] = $this->get_encoded_subject( $add_header_crlf, $convert_encoding ); + } + // 現在の日時を追加 + $return_hash['Date'] = date('r'); + + // 添付ファイルの確認 + if( !is_array( $this->attachements) ){ $this->attachements = array(); } + if( !is_array( $this->inline_images) ){ $this->inline_images = array(); } + if( $this->isMobile() ) { + $this->boundary = substr(uniqid("b"),0,10); + if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) > 0 ) { + // HTMLメールで添付ファイルとインライン画像両方がある場合 + $return_hash['Content-Type'] = 'multipart/Related; boundary="'.$this->boundary.'"'; + } else if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) == 0 ) { + // HTMLメールで添付ファイルのみある場合 + $return_hash['Content-Type'] = 'multipart/Mixed; boundary="'.$this->boundary.'"'; + } else if( strlen($this->html_body) > 0 && count($this->attachements) == 0 && count($this->inline_images) > 0 ) { + // HTMLメールでインライン画像のみある場合 + $return_hash['Content-Type'] = 'multipart/Related; boundary="'.$this->boundary.'"'; + } else if( strlen($this->html_body) > 0 ) { + // HTMLメールで添付もインライン画像もない場合 + $return_hash['Content-Type'] = 'multipart/Mixed; boundary="'.$this->boundary.'"'; + } else if( count($this->attachements) > 0 ) { + // プレーンテキストで添付ファイルがある場合 + $return_hash['Content-Type'] = 'Multipart/Mixed; boundary="'.$this->boundary.'"'; + } else { + // プレーンテキストのみの場合 + $return_hash['Content-Type'] = 'text/plain; charset='.$this->getBodyCharset(); + } + } else { + $this->boundary = "bnd" . uniqid("b"); + if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) > 0 ) { + // HTMLメールで添付ファイルとインライン画像両方がある場合 + $return_hash['Content-Type'] = 'Multipart/Mixed; boundary="'.$this->boundary.'"'; + } else if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) == 0 ) { + // HTMLメールで添付ファイルのみある場合 + $return_hash['Content-Type'] = 'Multipart/Mixed; boundary="'.$this->boundary.'"'; + } else if( strlen($this->html_body) > 0 && count($this->attachements) == 0 && count($this->inline_images) > 0 ) { + // HTMLメールでインライン画像のみある場合 + $return_hash['Content-Type'] = 'Multipart/Related; boundary="'.$this->boundary.'"; type="Multipart/Alternative"'; + } else if( strlen($this->html_body) > 0 ) { + // HTMLメールで添付もインライン画像もない場合 + $return_hash['Content-Type'] = 'Multipart/Alternative; boundary="'.$this->boundary.'"'; + } else if( count($this->attachements) > 0 ) { + // プレーンテキストで添付ファイルがある場合 + $return_hash['Content-Type'] = 'Multipart/Mixed; boundary="'.$this->boundary.'"'; + } else { + // プレーンテキストのみの場合 + $return_hash['Content-Type'] = 'text/plain; charset='.$this->getBodyCharset(); + } + } + + return $return_hash; + } + /** + * Toのアドレス部分のみを抜き出したメールアドレスのみを取得します。 + */ + function getToAddress() { + $to = $this->to; + if( preg_match('/\\s/',$to) > 0 ) { + $params = explode(' ', $to ); + $to = array_pop($params); + } + $to = trim($to); + $to = preg_replace('/^</','',$to); + $to = preg_replace('/>$/','',$to); + return $to; + } + /** + * Fromのアドレス部分のみを抜き出したメールアドレスのみを取得します。 + */ + function getFromAddress() { + $from = $this->from; + if( preg_match('/\\s/',$from) > 0 ) { + $params = explode(' ', $from ); + $from = array_pop($params); + } + $from = trim($from); + $from = preg_replace('/^</','',$from); + $from = preg_replace('/>$/','',$from); + return $from; + } + /** + * Ccのアドレス部分のみを抜き出したメールアドレスのみの配列を取得します。 + */ + function getCcAddresses() { + $addresses = array(); + if( is_array($this->cc) ) { + foreach( $this->cc as $address ) { + if( strlen(trim($address)) > 0 ) { + if( preg_match('/\\s/',$address) > 0 ) { + $params = explode(' ', $address ); + $address = array_pop($params); + } + $address = trim($address); + $address = preg_replace('/^</','',$address); + $address = preg_replace('/>$/','',$address); + if( strlen(trim($address)) > 0 ) { + array_push( $addresses, $address ); + } + } + } + } + return $addresses; + } + /** + * Bccのアドレス部分のみを抜き出したメールアドレスのみの配列を取得します。 + */ + function getBccAddresses() { + $addresses = array(); + if( is_array($this->bcc) ) { + foreach( $this->bcc as $address ) { + if( strlen(trim($address)) > 0 ) { + if( preg_match('/\\s/',$address) > 0 ) { + $params = explode(' ', $address ); + $address = array_pop($params); + } + $address = trim($address); + $address = preg_replace('/^</','',$address); + $address = preg_replace('/>$/','',$address); + if( strlen(trim($address)) > 0 ) { + array_push( $addresses, $address ); + } + } + } + } + return $addresses; + } + /** + * + */ + function convertHeaderAddress( $address, $convert_encoding = true ) { + // to RFC 2822を満たすことを前提としてユーザ名をエンコードする + $name = ''; + if( preg_match('/\\s/',$address) > 0 ) { + $params = explode(' ', $address ); + $address = array_pop( $params ); + $name = implode( ' ', $params ); + if( $convert_encoding && mb_detect_encoding($address) != 'ascii' ) { + $name = mb_convert_encoding($name,$this->getHeaderEncoding(),'auto'); + } + $name = base64_encode( $name ); + $name = '=?'.$this->getHeaderCharset().'?B?'.$name.'?='; + $address = $name.' '.$address; + } + return $address; + } + /** + * メールのボディパート文字列を取得します。 + */ + function _get_body_part_strings( $convert_encoding=true ) { + // text_bodyのみ置換文字列の処理を行う + $text_body = $this->text_body; + $text_body = str_replace("\r\n","\n",$text_body); + $text_body = str_replace("\r","\n",$text_body); + $text_body = str_replace("\n","\r\n",$text_body); + $html_body = $this->html_body; + $html_body = str_replace("\r\n","\n",$html_body); + $html_body = str_replace("\r","\n",$html_body); + $html_body = str_replace("\n","\r\n",$html_body); + foreach( $this->replace_words as $key => $val ) { + if( !$convert_encoding && $this->getBodyEncoding() != 'UTF-8' ) { + // エンコーディングの必要がない場合、ヘッダエンコードに置換ワードを合わせる + $key = mb_convert_encoding($key, $this->getBodyEncoding(),'auto'); + $val = mb_convert_encoding($val, $this->getBodyEncoding(),'auto'); + } + $text_body = str_replace( "{".$key."}", $val, $text_body ); + $html_body = str_replace( "{".$key."}", $val, $html_body ); + } + if( !is_array( $this->attachements) ){ $this->attachements = array(); } + if( !is_array( $this->inline_images) ){ $this->inline_images = array(); } + + if( $convert_encoding ) { + $text_body = mb_convert_encoding($text_body,$this->getBodyEncoding(),'auto'); + $html_body = mb_convert_encoding($html_body,$this->getBodyEncoding(),'auto'); + } + + // リターンするbody文字列を作成する + $return_body = ''; + if( $this->isMobile() ) { + // 添付とデコメールのパターン判断 + if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) > 0 ) { + // HTMLメールで添付ファイルとインライン画像両方がある場合 + // multipart/alternativeパート + $return_body = '--' . $this->boundary . "\r\n"; + $alternative_boundary = "" . substr(uniqid("b"),0,8); + $return_body .= 'Content-Type: Multipart/Alternative; boundary="'.$alternative_boundary.'"' ."\r\n\r\n"; + // textパート + $return_body .= '--' . $alternative_boundary . "\r\n"; + $return_body .= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n"; +// $return_body .= 'Content-Transfer-Encoding: 7bit'."\r\n\r\n"; +// $return_body .= $text_body; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($text_body); + $return_body .= "\r\n\r\n"; + // htmlパート + $return_body .= '--' . $alternative_boundary . "\r\n"; + $return_body .= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"' ."\r\n"; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($html_body); + $return_body .= "\r\n\r\n"; + // multipart/alternativeパート終了 + $return_body .= '--' . $alternative_boundary . '--'."\r\n\r\n"; + // インラインファイル添付 + foreach( $this->inline_images as $content_id => $file_info ) { + $file_path = $file_info['path']; + $file_type = $file_info['type']; + $file_name = $file_info['name']; + $contents = file_get_contents( $file_path ); + $attach = chunk_split(base64_encode($contents)); + $file_name = mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto'); + $file_name = base64_encode($file_name); + $file_name = '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?='; + $return_body .= '--' . $this->boundary . "\r\n"; + $return_body .= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n"; + $return_body .= 'Content-Transfer-Encoding: base64'."\r\n"; + $return_body .= 'Content-Id: <'.$content_id.'>'."\r\n\r\n"; + $return_body .= $attach . "\r\n"; + $return_body .= "\r\n\r\n"; + } + // ファイルパート + foreach( $this->attachements as $file_info ) { + $file_path = $file_info['path']; + $file_type = $file_info['type']; + $file_name = $file_info['name']; + $contents = file_get_contents( $file_path ); + $attach = chunk_split(base64_encode($contents)); + $file_name = mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto'); + $file_name = base64_encode($file_name); + $file_name = '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?='; + $return_body .= '--' . $this->boundary . "\r\n"; + $return_body .= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n"; + $return_body .= 'Content-Transfer-Encoding: base64'."\r\n"; + $return_body .= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n"; + $return_body .= "\r\n"; + $return_body .= $attach . "\r\n"; + $return_body .= "\r\n\r\n"; + } + // マルチパート終了 + $return_body .= '--' . $this->boundary . '--'."\r\n"; + } else if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) == 0 ) { + // HTMLメールで添付ファイルのみある場合 + // multipart/alternativeパート + $return_body = '--' . $this->boundary . "\r\n"; + $alternative_boundary = "" . substr(uniqid("b"),0,8); + $return_body .= 'Content-Type: Multipart/Alternative; boundary="'.$alternative_boundary.'"' ."\r\n\r\n"; + // textパート + $return_body .= '--' . $alternative_boundary . "\r\n"; + $return_body .= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n"; +// $return_body .= 'Content-Transfer-Encoding: 7bit'."\r\n\r\n"; +// $return_body .= $text_body; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($text_body); + $return_body .= "\r\n\r\n"; + // htmlパート + $return_body .= '--' . $alternative_boundary . "\r\n"; + $return_body .= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"' ."\r\n"; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($html_body); + $return_body .= "\r\n\r\n"; + // multipart/alternativeパート終了 + $return_body .= '--' . $alternative_boundary . '--'."\r\n\r\n"; + // ファイルパート + foreach( $this->attachements as $file_info ) { + $file_path = $file_info['path']; + $file_type = $file_info['type']; + $file_name = $file_info['name']; + $contents = file_get_contents( $file_path ); + $attach = chunk_split(base64_encode($contents)); + $file_name = mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto'); + $file_name = base64_encode($file_name); + $file_name = '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?='; + $return_body .= '--' . $this->boundary . "\r\n"; + $return_body .= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n"; + $return_body .= 'Content-Transfer-Encoding: base64'."\r\n"; + $return_body .= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n"; + $return_body .= "\r\n"; + $return_body .= $attach . "\r\n"; + $return_body .= "\r\n\r\n"; + } + // マルチパート終了 + $return_body .= '--' . $this->boundary . '--'."\r\n"; + } else if( strlen($this->html_body) > 0 && count($this->attachements) == 0 && count($this->inline_images) > 0 ) { + // HTMLメールでインライン画像のみある場合 + // multipart/alternativeパート + $return_body = '--' . $this->boundary . "\r\n"; + $alternative_boundary = "" . substr(uniqid("b"),0,8); + $return_body .= 'Content-Type: Multipart/Alternative; boundary="'.$alternative_boundary.'"' ."\r\n\r\n"; + // textパート + $return_body .= '--' . $alternative_boundary . "\r\n"; + $return_body .= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n"; +// $return_body .= 'Content-Transfer-Encoding: 7bit'."\r\n\r\n"; +// $return_body .= $text_body; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($text_body); + $return_body .= "\r\n\r\n"; + // htmlパート + $return_body .= '--' . $alternative_boundary . "\r\n"; + $return_body .= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"' ."\r\n"; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($html_body); + $return_body .= "\r\n\r\n"; + // multipart/alternativeパート終了 + $return_body .= '--' . $alternative_boundary . '--'."\r\n\r\n"; + // インラインファイル添付 + $num = 1; + foreach( $this->inline_images as $content_id => $file_info ) { + $file_path = $file_info['path']; + $file_type = $file_info['type']; + $file_name = $file_info['name']; + $contents = file_get_contents( $file_path ); + $attach = chunk_split(base64_encode($contents)); + $file_name = mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto'); + $file_name = base64_encode($file_name); + $file_name = '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?='; + $return_body .= '--' . $this->boundary . "\r\n"; + $return_body .= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n"; + $return_body .= 'Content-Transfer-Encoding: base64'."\r\n"; + $return_body .= 'Content-Id: <'.$content_id.'>'."\r\n\r\n"; + $return_body .= $attach . "\r\n"; + $return_body .= "\r\n\r\n"; + $num++; + } + // マルチパート終了 + $return_body .= '--' . $this->boundary . '--'."\r\n"; + } else if( strlen($this->html_body) > 0 ) { + // HTMLメールで添付もインライン画像もない場合 + // multipart/alternativeパート + $return_body = '--' . $this->boundary . "\r\n"; + $alternative_boundary = "" . substr(uniqid("b"),0,8); + $return_body .= 'Content-Type: Multipart/Alternative; boundary="'.$alternative_boundary.'"' ."\r\n\r\n"; + // textパート + $return_body .= '--' . $alternative_boundary . "\r\n"; + $return_body .= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n"; +// $return_body .= 'Content-Transfer-Encoding: 7bit'."\r\n\r\n"; +// $return_body .= $text_body; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($text_body); + $return_body .= "\r\n\r\n"; + // htmlパート + $return_body .= '--' . $alternative_boundary . "\r\n"; + $return_body .= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"' ."\r\n"; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($html_body); + $return_body .= "\r\n\r\n"; + // multipart/alternativeパート終了 + $return_body .= '--' . $alternative_boundary . '--'."\r\n\r\n"; + // マルチパート終了 + $return_body .= '--' . $this->boundary . '--'."\r\n"; + } else if( count($this->attachements) > 0 ) { + // プレーンテキストで添付ファイルがある場合 + // textパート + $return_body = '--' . $this->boundary . "\r\n\r\n"; + $return_body .= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n\r\n"; + $return_body .= $text_body; + $return_body .= "\r\n\r\n"; + // ファイルパート + foreach( $this->attachements as $file_info ) { + $file_path = $file_info['path']; + $file_type = $file_info['type']; + $file_name = $file_info['name']; + $contents = file_get_contents( $file_path ); + $attach = chunk_split(base64_encode($contents)); + $file_name = mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto'); + $file_name = base64_encode($file_name); + $file_name = '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?='; + + $return_body .= '--' . $this->boundary . "\r\n"; + $return_body .= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n"; + $return_body .= 'Content-Transfer-Encoding: base64'."\r\n"; + $return_body .= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n"; + $return_body .= "\r\n"; + $return_body .= $attach . "\r\n"; + $return_body .= "\r\n\r\n"; + } + // マルチパート終了 + $return_body .= '--' . $this->boundary . '--'."\r\n"; + } else { + // プレーンテキストで添付ファイルもない bodyの改行コードはLFに統一する + $return_body = str_replace("\r\n","\n",$text_body); + $return_body = str_replace("\r","\n",$return_body); + } + } else { + // 添付とHTMLのパターン判断 + if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) > 0 ) { + // HTMLメールで添付ファイルとインライン画像両方がある場合 + // multipart/relatedパート + $return_body .= '--' . $this->boundary . "\r\n"; + $related_boundary = "*-bndd" . uniqid("b"); + $return_body .= 'Content-Type: Multipart/Related; type="multipart/alternative"; boundary="'.$related_boundary.'"' ."\r\n\r\n"; + // multipart/alternativeパート + $return_body .= '--' . $related_boundary . "\r\n"; + $alternative_boundary = "*-bndd" . uniqid("b"); + $return_body .= 'Content-Type: Multipart/Alternative; boundary="'.$alternative_boundary.'"' ."\r\n\r\n"; + // textパート + $return_body .= '--' . $alternative_boundary . "\r\n"; + $return_body .= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"'."\r\n"; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($text_body); + $return_body .= "\r\n\r\n"; + // htmlパート + $return_body .= '--' . $alternative_boundary . "\r\n"; + $return_body .= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"'."\r\n"; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($html_body); + $return_body .= "\r\n\r\n"; + // multipart/alternativeパート終了 + $return_body .= '--' . $alternative_boundary . '--'."\r\n\r\n"; + // インラインファイル添付 + foreach( $this->inline_images as $content_id => $file_info ) { + $file_path = $file_info['path']; + $file_type = $file_info['type']; + $file_name = $file_info['name']; + $contents = file_get_contents( $file_path ); + $attach = chunk_split(base64_encode($contents)); + $file_name = mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto'); + $file_name = base64_encode($file_name); + $file_name = '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?='; + $return_body .= '--' . $related_boundary . "\r\n"; + $return_body .= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n"; + $return_body .= 'Content-Transfer-Encoding: base64'."\r\n"; + $return_body .= 'Content-Id: <'.$content_id.'>'."\r\n"; + $return_body .= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n\r\n"; + $return_body .= $attach . "\r\n"; + $return_body .= "\r\n\r\n"; + } + // multipart/relatedパート終了 + $return_body .= '--' . $related_boundary . '--'."\r\n\r\n"; + // ファイルパート + foreach( $this->attachements as $file_info ) { + $file_path = $file_info['path']; + $file_type = $file_info['type']; + $file_name = $file_info['name']; + $contents = file_get_contents( $file_path ); + $attach = chunk_split(base64_encode($contents)); + $file_name = mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto'); + $file_name = base64_encode($file_name); + $file_name = '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?='; + $return_body .= '--' . $this->boundary . "\r\n"; + $return_body .= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n"; + $return_body .= 'Content-Transfer-Encoding: base64'."\r\n"; + $return_body .= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n"; + $return_body .= "\r\n"; + $return_body .= $attach . "\r\n"; + $return_body .= "\r\n\r\n"; + } + // マルチパート終了 + $return_body .= '--' . $this->boundary . '--'."\r\n\r\n"; + } else if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) == 0 ) { + // HTMLメールで添付ファイルのみある場合 + // multipart/alternativeパート + $return_body = '--' . $this->boundary . "\r\n"; + $alternative_boundary = "*-bndd" . uniqid("b"); + $return_body .= 'Content-Type: Multipart/Alternative; boundary="'.$alternative_boundary.'"' ."\r\n\r\n"; + // textパート + $return_body .= '--' . $alternative_boundary . "\r\n"; + $return_body .= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n"; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($text_body); + $return_body .= "\r\n\r\n"; + // htmlパート + $return_body .= '--' . $alternative_boundary . "\r\n"; + $return_body .= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"' ."\r\n"; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($html_body); + $return_body .= "\r\n\r\n"; + // multipart/alternativeパート終了 + $return_body .= '--' . $alternative_boundary . '--'."\r\n\r\n"; + // ファイルパート + foreach( $this->attachements as $file_info ) { + $file_path = $file_info['path']; + $file_type = $file_info['type']; + $file_name = $file_info['name']; + $contents = file_get_contents( $file_path ); + $attach = chunk_split(base64_encode($contents)); + $file_name = mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto'); + $file_name = base64_encode($file_name); + $file_name = '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?='; + $return_body .= '--' . $this->boundary . "\r\n"; + $return_body .= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n"; + $return_body .= 'Content-Transfer-Encoding: base64'."\r\n"; + $return_body .= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n"; + $return_body .= "\r\n"; + $return_body .= $attach . "\r\n"; + $return_body .= "\r\n\r\n"; + } + // マルチパート終了 + $return_body .= '--' . $this->boundary . '--'."\r\n"; + } else if( strlen($this->html_body) > 0 && count($this->attachements) == 0 && count($this->inline_images) > 0 ) { + // HTMLメールでインライン画像のみある場合 + // multipart/alternativeパート + $return_body = '--' . $this->boundary . "\r\n"; + $alternative_boundary = "*-bndd" . uniqid("b"); + $return_body .= 'Content-Type: Multipart/Alternative; boundary="'.$alternative_boundary.'"' ."\r\n\r\n"; + // textパート + $return_body .= '--' . $alternative_boundary . "\r\n"; + $return_body .= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n"; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($text_body); + $return_body .= "\r\n\r\n"; + // htmlパート + $return_body .= '--' . $alternative_boundary . "\r\n"; + $return_body .= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"' ."\r\n"; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($html_body); + $return_body .= "\r\n\r\n"; + // multipart/alternativeパート終了 + $return_body .= '--' . $alternative_boundary . '--'."\r\n\r\n"; + // インラインファイル添付 + foreach( $this->inline_images as $content_id => $file_info ) { + $file_path = $file_info['path']; + $file_type = $file_info['type']; + $file_name = $file_info['name']; + $contents = file_get_contents( $file_path ); + $attach = chunk_split(base64_encode($contents)); + $file_name = mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto'); + $file_name = base64_encode($file_name); + $file_name = '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?='; + $return_body .= '--' . $this->boundary . "\r\n"; + $return_body .= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n"; + $return_body .= 'Content-Transfer-Encoding: base64'."\r\n"; + $return_body .= 'Content-Id: <'.$content_id.'>'."\r\n"; + $return_body .= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n\r\n"; + $return_body .= $attach . "\r\n"; + $return_body .= "\r\n\r\n"; + } + // マルチパート終了 + $return_body .= '--' . $this->boundary . '--'."\r\n"; + } else if( strlen($this->html_body) > 0 ) { + // HTMLメールで添付もインライン画像もない場合 + // textパート + $return_body .= '--' . $this->boundary . "\r\n"; + $return_body .= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n"; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($text_body); + $return_body .= $text_body; + $return_body .= "\r\n\r\n"; + // htmlパート + $return_body .= '--' . $this->boundary . "\r\n"; + $return_body .= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"' ."\r\n"; + $return_body .= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n"; + $return_body .= $this->quoted_printable_encoding($html_body); + $return_body .= "\r\n\r\n"; + // マルチパート終了 + $return_body .= '--' . $this->boundary . '--'."\r\n"; + } else if( count($this->attachements) > 0 ) { + // プレーンテキストで添付ファイルがある場合 + // textパート + $return_body = '--' . $this->boundary . "\r\n"; + $return_body .= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n\r\n"; + $return_body .= $text_body; + $return_body .= "\r\n\r\n"; + // ファイルパート + foreach( $this->attachements as $file_info ) { + $file_path = $file_info['path']; + $file_type = $file_info['type']; + $file_name = $file_info['name']; + $contents = file_get_contents( $file_path ); + $attach = chunk_split(base64_encode($contents)); + $file_name = mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto'); + $file_name = base64_encode($file_name); + $file_name = '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?='; + + $return_body .= '--' . $this->boundary . "\r\n"; + $return_body .= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n"; + $return_body .= 'Content-Transfer-Encoding: base64'."\r\n"; + $return_body .= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n"; + $return_body .= "\r\n"; + $return_body .= $attach . "\r\n"; + $return_body .= "\r\n\r\n"; + } + // マルチパート終了 + $return_body .= '--' . $this->boundary . '--'."\r\n"; + } else { + // プレーンテキストで添付ファイルもない bodyの改行コードはLFに統一する + $return_body = str_replace("\r\n","\n",$text_body); + $return_body = str_replace("\r","\n",$return_body); + } + } + + return trim($return_body); + } + /** + * 本文と件名の特定置き換えワードを設定します。 + */ + function addReplaceWord( $name, $value ) { + $this->replace_words[$name] = $value; + } + /** + * 本文と件名の特定置き換えワードをハッシュで設定します。 + */ + function addReplaceWordByHash( $prefix_name, $hash ) { + foreach( $hash as $key=>$val ) { + if( gettype( $val ) != 'object' + && gettype( $val ) != 'array' + && gettype( $val ) != 'resource' + ) { + $this->addReplaceWord( $prefix_name."::".$key, $val ); + } + } + } + /** + * 本文と件名の特定置き換えワードをオブジェクトで設定します。 + */ + function addReplaceWordByObject( $prefix_name, $object ) { + $vars = get_object_vars( $object ); + foreach( $vars as $key=>$val ) { + if( gettype( $val ) != 'object' + && gettype( $val ) != 'array' + && gettype( $val ) != 'resource' + ) { + $this->addReplaceWord( $prefix_name."::".$key, $val ); + } + } + } + /** + * メールヘッダの文字コードを指定します。 + */ + function setHeaderCharset( $charset ) { + $this->charset_header = $charset; + } + /** + * 設定されているメールヘッダ文字コードを取得します + */ + function getHeaderCharset() { + return $this->charset_header; + } + /** + * 設定されているメールヘッダ文字コードで利用するPHPコード変換ルールを取得します + */ + function getHeaderEncoding() { + $key = strtoupper($this->charset_header); + if( isset( $GLOBALS['UTIL_MAIL_CHARSET_CODE_MAP'][$key]) ) { + return $GLOBALS['UTIL_MAIL_CHARSET_CODE_MAP'][$key]; + } else { + return $this->charset_header; + } + } + /** + * テキストボディの文字コードを指定します。 + */ + function setBodyCharset( $charset ) { + $this->charset_body = $charset; + } + /** + * 設定されているテキストボディ文字コードを取得します + */ + function getBodyCharset() { + return $this->charset_body; + } + /** + * 設定されているテキストボディ文字コードで利用するPHPコード変換ルールを取得します + */ + function getBodyEncoding() { + $key = strtoupper($this->charset_body); + if( isset( $GLOBALS['UTIL_MAIL_CHARSET_CODE_MAP'][$key]) ) { + return $GLOBALS['UTIL_MAIL_CHARSET_CODE_MAP'][$key]; + } else { + return $this->charset_body; + } + } + /** + * 添付ファイル名の文字コードを指定します。 + */ + function setFileNameCharset( $charset ) { + $this->charset_filename = $charset; + } + /** + * 設定されている添付ファイル名文字コードを取得します + */ + function getFileNameCharset() { + return $this->charset_filename; + } + /** + * 設定されている添付ファイル名文字コードで利用するPHPコード変換ルールを取得します + */ + function getFileNameEncoding() { + $key = strtoupper($this->charset_filename); + if( isset( $GLOBALS['UTIL_MAIL_CHARSET_CODE_MAP'][$key]) ) { + return $GLOBALS['UTIL_MAIL_CHARSET_CODE_MAP'][$key]; + } else { + return $this->charset_filename; + } + } + /** + * 文字列をquoted printableエンコードして返します。 + * @param string $str エンコード前文字列 + * @return string エンコード後文字列 + */ + function quoted_printable_encoding($str){ + if( !defined('CRLF') ) { + define('CRLF', "\r\n"); + } + $str = trim($str); + $str = str_replace("\r\n","\n",$str); + $lines = preg_split("/\r?\n/", $str); + $retStrings = ''; + foreach ( $lines as $line ) { + $lineDec = ''; + for( $i=0; $i < strlen($line); $i++ ) { + $char = substr( $line, $i, 1 ); + $ascii = ord( $char ); + if ( $ascii < 32 || $ascii == 61 || $ascii > 126 ) { + $char = '='.strtoupper( dechex( $ascii ) ); + } + if ( ( strlen ( $lineDec ) + strlen ( $char ) ) >= 76 ) { + $retStrings .= $lineDec.'='.CRLF; + $lineDec = ''; + } + $lineDec .= $char; + } + if( strlen(trim($lineDec)) > 0 ) { + $retStrings .= $lineDec.CRLF; + } else { + $retStrings .= '=0A=0D='.CRLF; + } + } + return trim($retStrings); + } + /** + * 携帯電話メール宛か確認します + */ + function isMobile() { + foreach( $GLOBALS['MOBILE_MAIL_DOMAIN_ARRAY'] as $fqdn ) { + $fqdn_regx = str_replace('.','\\.',$fqdn ); + if( preg_match('/\\@'.$fqdn_regx.'$/',$this->to) > 0 ) { + return true; + } + } + } + /** + * 件名の特定置き換えワードを設定した文字列を返す。 + */ + function getReplacedTextSubject( $convert_encoding=true ) { + $subject = $this->subject; + foreach( $this->replace_words as $key => $val ) { + $subject = str_replace( "{".$key."}", $val, $subject ); + } + return $subject; + } + /** + * 本文の特定置き換えワードを設定した文字列を返す。 + */ + function getReplacedTextBody( $convert_encoding=true ) { + $text_body = $this->text_body; + foreach( $this->replace_words as $key => $val ) { + $text_body = str_replace( "{".$key."}", $val, $text_body ); + } + return $text_body; + } +} +// 本クラスで利用するグローバル変数定義 +/** 文字コード変換ルール */ +$GLOBALS['UTIL_MAIL_CHARSET_CODE_MAP'] = array( + 'JIS' => 'ISO-2022-JP', + 'SHIFT_JIS' => 'SJIS-win', + 'Shift_JIS' => 'SJIS-win', + 'SHIFT-JIS' => 'SJIS-win', +); +?> \ No newline at end of file Added: db/current/spider/lib/util/MobileTerminal.class.php =================================================================== --- db/current/spider/lib/util/MobileTerminal.class.php (rev 0) +++ db/current/spider/lib/util/MobileTerminal.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,91 @@ +<?php +/** + * ユーティリティ:ユーザーエージェントから携帯端末種別を解析・保持するユーティリティオブジェクト + * + * @package util ユーティリティパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class MobileTerminal { + var $agent; + var $terminal_name; + var $terminal_id; + var $carrier; + var $html_flag; + var $sim_id; + + function MobileTerminal($agent) { + $this->agent = $agent; + $this->html_flag = "h"; + if ( ereg( "^DoCoMo", $agent ) ) { + $this->carrier = "d"; + $this->perseSubscririberIdFromDoCoMo(); + } else if ( ereg( "^J\\-PHONE", $agent ) ) { + $this->carrier = "v"; + $this->perseSubscririberIdFromVodafone(); + } else if ( ereg( "^Vodafone", $agent ) ) { + $this->carrier = "v"; + $this->perseSubscririberIdFromVodafone(); + } else if ( ereg( "^SoftBank", $agent ) ) { + $this->carrier = "s"; + $this->perseSubscririberIdFromVodafone(); + } else if ( ereg( "^KDDI\\-", $agent ) ) { + $this->carrier = "a"; + $this->terminal_id = $_SERVER['HTTP_X_UP_SUBNO']; + $this->html_flag = "x"; + list( $this->terminal_name, $etc ) = explode( ' ', $agent ); + } else if ( ereg( "^^UP\\.Browser\\/[0-9\\.]+\\-", $agent ) ) { + $this->carrier = "a"; + $this->terminal_id = $_SERVER['HTTP_X_UP_SUBNO']; + $this->html_flag = "d"; + list( $this->terminal_name, $etc ) = explode( ' ', $agent ); + list( $pre, $this->terminal_name ) = explode( '-', $this->terminal_name ); + } else { + return false; + } + } + + function perseSubscririberIdFromDoCoMo() { + if ( ereg( "DoCoMo\\/1.0", $this->agent ) ) { + $this->terminal_name = $this->agent; + $str = substr( $this->agent, strpos( $this->agent, "/ser" ) ); + $this->terminal_id = str_replace( "/ser", "", $str ); + } else { + $this->terminal_name = substr( $this->agent, 0, strpos( $this->agent, "(" ) ); + $str = substr( $this->agent, strpos( $this->agent, "(" ) ); + $str = substr( $this->agent, 0, strpos( $this->agent, ")" ) ); + $val_array = explode( ";", $str ); + foreach ( $val_array as $val ) { + if ( ereg( "ser", $val ) ) { + // ser + $this->terminal_id = str_replace( "ser", "", $val ); + } else if ( ereg( "icc", $val ) ) { + // icc + $this->sim_id = str_replace( "icc", "", $val ); + } + } + } + } + function perseSubscririberIdFromVodafone() { + $val_array = explode( "/", $this->agent ); + $tid_str = ""; + foreach ( $val_array as $val ) { + if ( ereg( "^SN", $val ) ) { + $tid_str = $val; + list( $sn, $browser ) = explode( " ", $tid_str ); + $this->terminal_id = str_replace( "SN", "", $sn ); + break; + } + if(strlen($this->terminal_name)>0){ + $this->terminal_name .= "/"; + } + $this->terminal_name .= $val; + } + } + function getMessage() { + return $this->message; + } +} +?> \ No newline at end of file Added: db/current/spider/lib/util/ValidateFunctions.class.php =================================================================== --- db/current/spider/lib/util/ValidateFunctions.class.php (rev 0) +++ db/current/spider/lib/util/ValidateFunctions.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,216 @@ +<?php +/** + * 妥当性検査用の静的メソッドを保持するライブラリクラス + * @package util ユーティリティパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class ValidateFunctions { + function ValidateFunctions() { + } + /** + * 渡された年、月、日がカレンダーで有効な日付であるか検査します。 + * 有効であればtrue、無効であればfalseを返します。 + * @param $year 西暦年 + * @param $month 月 + * @param $day 日 + * @return boolean 有効であればtrue、無効であればfalse + */ + function isAvailableDate( $year, $month, $day ) { + if( strlen( trim( $year ) ) == 0 + || strlen( trim( $month ) ) == 0 + || strlen( trim( $day ) ) == 0 ) { + return false; + } else if ( !preg_match("/^[0-9]+$/", $year ) + || !preg_match("/^[0-9]+$/", $month ) + || !preg_match("/^[0-9]+$/", $day ) ){ + return false; + } else if ( ( $year < 1900 || $year > 2037 ) + || ( $month < 1 || $month > 12 ) + || ( $day < 1 || $day > 31 ) ) { + return false; + } else if ( $month == 2 && $day == 29 ) { + // 閏年の確認 + if ( ( $year % 400 ) == 0 ) { + return true; + } else if ( ( $year % 100 ) == 0 ) { + return false; + } else if ( ( $year % 4 ) == 0 ) { + return true; + } else { + return false; + } + } else if ( $month == 2 && $day > 29 ) { + return false; + } else if ( ( $month == 4 || $month == 6 || $month == 9 || $month == 11 ) + && $day == 31 ) { + return false; + } else { + return true; + } + } + /** + * 渡された年月日フォーマットがカレンダーで有効な日付であるか検査します。 + * 有効であればtrue、無効であればfalseを返します。 + * @param $date_strings 日付フォーマット文字列 + * @return boolean 有効であればtrue、無効であればfalse + */ + function isAvailableDateFormat( $date_string ) { + $elements = explode('-',$date_string); + if( count($elements) == 3 ) { + $year = array_shift($elements); + $month = array_shift($elements); + $day = array_shift($elements); + return ValidateFunctions::isAvailableDate( $year, $month, $day ); + } else { + return false; + } + } + /** + * 渡された時分秒が有効な時間であるか検査します。 + * 有効であればtrue、無効であればfalseを返します。 + * @param $hour 時 + * @param $min 分 + * @param $sec 秒 + * @return boolean 有効であればtrue、無効であればfalse + */ + function isAvailableTime( $hour, $min, $sec, $permit_decimal_sec=false ) { + if( preg_match('/^[0-9]{1,2}$/',$hour) == 0 ) { + return false; + } else if( $hour < 0 || $hour > 23 ) { + return false; + } + if( preg_match('/^[0-9]{1,2}$/',$min) == 0 ) { + return false; + } else if( $min < 0 || $min > 59 ) { + return false; + } + if( !is_null($sec) && strlen($sec) > 0 ) { + if( $permit_decimal_sec ) { + if( preg_match('/^[0-9]{1,2}(|\\.[0-9]+)$/',$sec) == 0 ) { + return false; + } else if( $sec < 0 || $sec >= 60 ) { + return false; + } + } else { + if( preg_match('/^[0-9]{1,2}$/',$sec) == 0 ) { + return false; + } else if( $sec < 0 || $sec >= 60 ) { + return false; + } + } + } + return true; + } + /** + * 渡された時分秒フォーマットが有効な時間であるか検査します。 + * 有効であればtrue、無効であればfalseを返します。 + * @param $time_string 日付フォーマット文字列 + * @return boolean 有効であればtrue、無効であればfalse + */ + function isAvailableTimeFormat( $time_string ) { + $elements = explode(':',$time_string); + if( count($elements) == 2 || count($elements) == 3 ) { + $hour = array_shift($elements); + $min = array_shift($elements); + $sec = array_shift($elements); + return ValidateFunctions::isAvailableTime( $hour, $min, $sec ); + } else { + return false; + } + } + /** + * 渡された文字列が日時フォーマットとして有効化検査します + * 有効であればtrue、無効であればfalseを返します。 + * @param $datetime_string 日時フォーマット文字列 + * @return boolean 有効であればtrue、無効であればfalse + */ + function isAvailableDatetimeFormat( $datetime_string ) { + $elements = explode(' ',$datetime_string); + if( count($elements) == 2 ) { + $date_string = array_shift($elements); + $time_string = array_shift($elements); + if( ValidateFunctions::isAvailableDateFormat($date_string) ) { + return ValidateFunctions::isAvailableTimeFormat($time_string); + } else { + return false; + } + } else { + return false; + } + } + /** + * 電話番号の書式チェックを行います + */ + function validateTelephoneNumber( &$request, $telephone_area_code, $telephone_city_code, $telephone_code, $item_name ) { + $telephone_len = strlen( $telephone_area_code ) + + strlen( $telephone_city_code ) + + strlen( $telephone_code ); + if ( $telephone_len == 0 ) { + $telephone_area_code = ""; + $telephone_city_code = ""; + $telephone_code = ""; + $telephone_number = ""; + } else if ( $telephone_len > 0 ) { + if ( strlen( $telephone_area_code) == 0 + || strlen( $telephone_city_code) == 0 + || strlen( $telephone_code) == 0 ) { + $request->addError($item_name.'は市外局番・市内局番・局番を全て半角数字で入力してください。'); + } else if( $telephone_len > 14 ) { + $request->addError($item_name.'の数字は合計14文字以下で入力してください。'); + } else { + $telephone_number = $telephone_area_code + . "-" . $telephone_city_code + . "-" . $telephone_code; + + if( !preg_match('/^[0-9]{1,5}$/',$telephone_area_code) ) { + $request->addError($item_name.'(市外局番)は半角数字のみで入力してください。'); + } + if( !preg_match('/^[0-9]{1,5}$/',$telephone_city_code) ) { + $request->addError($item_name.'(市内局番)は半角数字のみで入力してください。'); + } + if( !preg_match('/^[0-9]{1,5}$/',$telephone_code) ) { + $request->addError($item_name.'(局番)は半角数字のみで入力してください。'); + } + if( !$request->isError() ) { + $telephone_number = $telephone_area_code . "-" . $telephone_city_code . "-" . $telephone_code; + } + } + } + return $telephone_number; + } + /** + * 郵便番号の書式チェックを行います + */ + function validateZipCode( &$request, $zip_area_code, $zip_city_code, $item_name ) { + $zip_len = strlen( $zip_area_code ) + + strlen( $zip_city_code ) + ; + if ( $zip_len == 0 ) { + $zip_area_code = ""; + $zip_city_code = ""; + $zip_code = ""; + } elseif ( $zip_len > 0 ) { + if ( strlen( $zip_area_code) == 0 + || strlen( $zip_city_code) == 0 ) { + $request->addError($item_name.'は全て半角数字で入力してください。'); + } else { + $zip_code = $zip_area_code . "-" . $zip_city_code + ; + if( !preg_match('/^[0-9]{3}$/',$zip_area_code) ) { + $request->addError($item_name.'(上3桁)は半角数字のみで入力してください。'); + } + if( !preg_match('/^[0-9]{4}$/',$zip_city_code) ) { + $request->addError($item_name.'(下4桁)は半角数字のみで入力してください。'); + } + if( !$request->isError() ) { + $zip_code = $zip_area_code . "-" . $zip_city_code; + } + } + } + return $zip_code; + } +} +?> \ No newline at end of file Added: db/current/spider/lib/util/XMLNode.class.php =================================================================== --- db/current/spider/lib/util/XMLNode.class.php (rev 0) +++ db/current/spider/lib/util/XMLNode.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,114 @@ +<?php +/** + * XMLノードをオブジェクト構造として保持するクラス + * @package util ユーティリティパッケージ + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class util_XMLNode { + var $elementName; + var $attributes = array(); + var $parentNode; + var $childNodes = array(); + var $contents = ''; + function util_XMLNode() { + } + function parseXML( $strings ) { + $this->childNodes = array(); + // 最初のタグ終了までを解析 + $element_str = ''; + $need_end_tag = true; + $in_element_attribute = false; + $after_strings = ''; + $is_end_thisnode = false; + $inner_strings = ''; + for( $i = 0; $i < strlen($strings); $i++ ) { + $char = substr($strings,$i,1); + if( strlen(trim($this->elementName)) == 0 ) { + // ルートノード名が取得できていない場合 + if( '<' == $char ) { + $in_element_attribute = true; + } else if( '>' == $char ){ + $in_element_attribute = false; + // 要素名の決定処理 + $attributes = explode("\s",$element_str); + $this->elementName = array_shift($attributes); + // 属性の取得 + foreach( $attributes as $attribute ) { + if( strlen( trim($attribute) ) > 1 ) { + list( $key, $value ) = explode('=',$attribute); + $value = preg_replace('/^\\"/','',$value); + $value = preg_replace('/\\"$/','',$value); + $this->attributes[$key] = $value; + } + } + // 最後が/で終わっているなら終了タグを必要としない + if( $attributes[count($attributes)-1] == '/' ) { + $need_end_tag = false; + } + $element_str = ''; + } else if( $in_element_attribute ) { + $element_str .= $char; + } else { + // 最初のルートノードが取得できるまで文字列は無視するので何もしない + } + } else if(!$need_end_tag) { + // 終了タグを必要としないなら残りの文字は全て同列要素文字列 + $after_strings .= $char; + } else if($is_end_thisnode) { + // 終了タグ後なら残りの文字は全て同列要素文字列 + $after_strings .= $char; + } else { + // タグ内容に関わらず終了タグが来ていないなら内包文字として追加 + $inner_strings .= $char; + // 終了タグを必要とするなら終了タグを検索 + if( '<' == $char ) { + $in_element_attribute = true; + } else if( '>' == $char ){ + $in_element_attribute = false; + // タグ要素名の解析 + $attributes = explode("\s",$element_str); + $element_name = array_shift($attributes); + if( '/'.$this->elementName == $element_name ) { + // 本ノードの終了タグなら + $is_end_thisnode = true; + } + $element_str = ''; + } else if( $in_element_attribute ) { + $element_str .= $char; + } + } + } + // 閉じタグがあるなら消去しておく + if( $need_end_tag && $is_end_thisnode ) { + $inner_strings = str_replace('</'.$this->elementName.'>','',$inner_strings); + } + + if( $need_end_tag && !$is_end_thisnode ) { + // 閉じタグが必要にも関わらず終了タグが見つからなかった場合はエラー + return false; + } + if( preg_match('/<(.)+>/',$inner_strings) > 0 ) { + // 内部文字列はカラ文字列になるまで処理を繰り返す + while( strlen(trim($inner_strings)) > 0 ) { + $child_node = new util_XMLNode(); + $inner_strings = $child_node->parseXML( $inner_strings ); + if( $inner_strings === false ) { + // 子ノードで閉じタグ不正が発覚した場合はエラー + return false; + } else { + // 子ノード作成OK + $child_node->parentNode = & $this; + array_push( $this->childNodes, $child_node); + } + } + } else { + $this->contents = $inner_strings; + } + // 同列の残り文字列は親に処理を戻す + return trim($after_strings); + } +} +?> \ No newline at end of file Added: db/current/spider/lib/util/mail/Mime.class.php =================================================================== --- db/current/spider/lib/util/mail/Mime.class.php (rev 0) +++ db/current/spider/lib/util/mail/Mime.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,102 @@ +<?php +/** + * メールの文字列をヘッダとボディに分割して保持するオブジェクトクラス + */ +class util_mail_Mime { + /** メールヘッダーハッシュ */ + var $headers = array(); + /** ボディ要素配列 */ + var $bodys = array(); + /** From */ + var $from; + /** From Name */ + var $fromName; + /** To */ + var $to; + /** To Name */ + var $toName; + /** + * コンストラクタ + */ + function util_mail_Mime( $mailData = null ) { + if( strlen($mailData) > 0 ) { + $this->decode( $mailData ); + } + } + /** + * メールデータ文字列を受け取ってデコードします + */ + function decode( $mailData ) { + $elements = explode("\r\n\r\n",$mailData); + // メールヘッダの取り出し + $headerStrings = array_shift($elements); + $headerStrings = str_replace("\r\n","\n",$headerStrings); + $headerStrings = str_replace("\r","\n",$headerStrings); + $headerLines = explode("\n",$headerStrings); + $this->headers = array(); + $before_name = null; + foreach( $headerLines as $line ) { + $line = trim($line); + $cols = explode(':',$line); + $name = ''; + if( count($cols) > 1 ) { + $name = trim(array_shift($cols)); + $val = trim(implode(':',$cols)); + $this->headers[$name] = $val; + } else if( count($cols) == 1 && strlen(trim($before_name)) > 0 ){ + $val = trim(array_shift($cols)); + $this->headers[$before_name] .= "\n".$val; + } + if( strlen($name) > 0 ) { + $before_name = $name; + } + } + // 残りはボディパーツ + $this->bodys = $elements; + // 主要ヘッダのみ切り分け + // 受取アドレスを取得 + $this->to = null; + if( isset($this->headers['To']) ) { + $this->to = $this->headers['To']; + } + if( strlen($this->to) == 0 ) { + if( isset($this->headers['to']) ) { + $this->to = $this->headers['to']; + } + if( strlen($this->to) == 0 ) { + if( isset($this->headers['TO']) ) { + $this->to = $this->headers['TO']; + } + } + } + if( strlen($this->to) > 0 && false !== strpos($this->to,'<') ) { + $this->to = trim($this->to); + list( $this->toName, $this->to ) = explode('<',$this->to); + $this->to = preg_replace('/>$/','',$this->to); + $this->toName = trim($this->toName); + } + + // 送信元アドレス取得 + $this->from = null; + if( isset($this->headers['From'] ) ) { + $this->from = $this->headers['From']; + } + if( strlen($this->from) == 0 ) { + if( isset($this->headers['from']) ){ + $this->from = $this->headers['from']; + } + if( strlen($this->from) == 0 ) { + if( isset($this->headers['FROM']) ){ + $this->from = $this->headers['FROM']; + } + } + } + if( strlen($this->from) > 0 && false !== strpos($this->from,'<') ) { + $this->from = trim($this->from); + list( $this->fromName, $this->from ) = explode('<',$this->from); + $this->from = preg_replace('/>$/','',$this->from); + $this->fromName = trim($this->fromName); + } + } +} +?> \ No newline at end of file Added: db/current/spider/lib/util/mail/PHP.class.php =================================================================== --- db/current/spider/lib/util/mail/PHP.class.php (rev 0) +++ db/current/spider/lib/util/mail/PHP.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,37 @@ +<?php +require_once( dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'Mail.class.php'); +/** + * メール送信ユーティリティ拡張クラス:PHPのmail関数による送信の実装クラス + * + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class util_mail_PHP extends util_Mail { + function util_mail_PHP() { + } + /** + * メールを送信します + */ + function send_execute( $add_header_crlf=false, $convert_encoding = true ) { + + // 本文文字列を取得する + $header_strings = $this->_get_header_part_strings(false,false,true,$add_header_crlf,$convert_encoding); + $body_strings = $this->_get_body_part_strings($convert_encoding); + // 件名を別途エンコードする + $subject = $this->get_encoded_subject( $add_header_crlf, $convert_encoding ); + return @mail($this->convertHeaderAddress( $this->to ) + , $subject, $body_strings, $header_strings); + } + /** + * 送信設定オプションの妥当性検査を行いエラーメッセージの配列を返します。 + * エラーがない場合は要素0の配列を返します。 + */ + function validate_options( & $options ) { + $error_messages = array(); + // TODO: オプションはないのでmail関数利用可能かチェックする + return $error_messages; + } +} +?> \ No newline at end of file Added: db/current/spider/lib/util/mail/SMTP.class.php =================================================================== --- db/current/spider/lib/util/mail/SMTP.class.php (rev 0) +++ db/current/spider/lib/util/mail/SMTP.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,242 @@ +<?php +require_once( dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'Mail.class.php'); +/** + * メール送信ユーティリティ拡張クラス:SMTP接続による送信の実装クラス + * + * ※ 本クラスはPEAR/Mailパッケージを利用します。 + * + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class util_mail_SMTP extends util_Mail { + function util_mail_SMTP() { + } + /** + * メールを送信します + */ + function send_execute( $add_header_crlf=false, $convert_encoding=true ) { + + $header_hash = $this->_get_header_hash(true,true,false,$add_header_crlf,$convert_encoding); + $body_strings = $this->_get_body_part_strings($convert_encoding); + + // 最初にそのままPEARを要求してみる + $is_exist_pear_mail = false; + if( @require_once ( 'PEAR.php' ) ) { + // pearが存在するならMailパッケージの確認 + if( @require_once ( 'Mail.php' ) ) { + // pear mailパッケージインストール済み + $is_exist_pear_mail = true; + } + } + if( !$is_exist_pear_mail ) { + // デフォルトのインクルードパスに存在しないなら設定された追加パスを確認 + $separator = ":"; + if( PHP_OS == "WINNT" ){ + $separator = ";"; + } + $includePath = get_include_path(); + $includePath .= $separator . $this->options['pear_path'] . $separator; + set_include_path( $includePath ); + if( @require_once ( 'PEAR.php' ) ) { + if( @require_once ( 'Mail.php' ) ) { + } else { + return false; + } + } else { + return false; + } + } + $mailSendObj = null; + if( preg_match('/^[fF](|[aA][lL][sS][eE])$/',$this->options['smtp_auth']) > 0 + || strlen($this->options['smtp_auth']) == 0 ) { + $this->options['smtp_auth'] = false; + } + if( preg_match('/^[pP][oO][pP][bB][eE][fF][oO][rR][eE]$/',$this->options['smtp_auth']) > 0 ) { + if( $this->connectPopBeforeSmtp() ) { + $params = array( + "host" => $this->options['smtp_host'], + "port" => $this->options['smtp_port'], + "localhost" => $_SERVER['HOST_NAME'] + ); + $mailSendObj = & Mail::factory( 'smtp', $params ); + } else { + return false; + } + } else { + $params = array( + "host" => $this->options['smtp_host'], + "port" => $this->options['smtp_port'], + "auth" => $this->options['smtp_auth'], + "username" => $this->options['smtp_auth_user'], + "password" => $this->options['smtp_auth_pass'], + "localhost" => $_SERVER['HOST_NAME'] + ); + $mailSendObj = & Mail::factory( 'smtp', $params ); + } + + // 送信を実行する + $result = $mailSendObj->send( $this->getToAddress(), $header_hash, $body_strings ); + if ( PEAR::isError( $result ) ) { + return false; + } else { + // Ccにメール送信する + $cc_array = $this->getCcAddresses(); + foreach( $cc_array as $address ) { + $mailSendObj->send( $address, $header_hash, $body_strings ); + } + // Bccにメール送信する + $bcc_array = $this->getBccAddresses(); + foreach( $bcc_array as $address ) { + $mailSendObj->send( $address, $header_hash, $body_strings ); + } + return true; + } + } + /** + * 送信設定オプションの妥当性検査を行いエラーメッセージの配列を返します。 + * エラーがない場合は要素0の配列を返します。 + */ + function validate_options( & $options ) { + $error_messages = array(); + if( !is_array($options) ) { + array_push($error_messages,'送信オプションを入力してください。'); + } else { + if( !isset($options['pear_path']) && isset($options[0]) ) { + $options['pear_path'] = trim(stripslashes($options[0])); + unset( $options[0] ); + } + if( !isset($options['smtp_host']) && isset($options[1]) ) { + $options['smtp_host'] = trim(stripslashes($options[1])); + unset( $options[1] ); + } + if( !isset($options['smtp_port']) && isset($options[2]) ) { + $options['smtp_port'] = trim(stripslashes($options[2])); + unset( $options[2] ); + } + if( !isset($options['smtp_auth']) && isset($options[3]) ) { + $options['smtp_auth'] = trim(stripslashes($options[3])); + unset( $options[3] ); + } + if( !isset($options['smtp_auth_user']) && isset($options[4]) ) { + $options['smtp_auth_user'] = trim(stripslashes($options[4])); + unset( $options[4] ); + } + if( !isset($options['smtp_auth_pass']) && isset($options[5]) ) { + $options['smtp_auth_pass'] = trim(stripslashes($options[5])); + unset( $options[5] ); + } + } + + $pear_path = trim($options['pear_path']); + $smtp_host = trim($options['smtp_host']); + $smtp_port = trim($options['smtp_port']); + + // pear mailの存在確認 + $is_exist_pear_mail = false; + if( @require_once ( 'PEAR.php' ) ) { + if( @require_once ( 'Mail.php' ) ) { + $is_exist_pear_mail = true; + } + } + if( !$is_exist_pear_mail ) { + // デフォルトにないならオプションを確認 + if( strlen($pear_path) == 0 ) { + array_push($error_messages,'PEARライブラリのパスを入力してください。'); + } else if( !file_exists($pear_path) ) { + array_push($error_messages,'指定されたPEARライブラリのパスが存在しません。'); + } else { + $separator = ":"; + if( PHP_OS == "WINNT" ){ + $separator = ";"; + } + $includePath = get_include_path(); + $includePath .= $separator . $this->options['pear_path'] . $separator; + set_include_path( $includePath ); + if( @require_once ( 'PEAR.php' ) ) { + if( @require_once ( 'Mail.php' ) ) { + } else { + array_push($error_messages,'PEAR Mailパッケージがインストールされていません。'); + } + } else { + array_push($error_messages,'指定されたパスにPEARライブラリはインストールされていません。'); + } + } + } + if( strlen($smtp_host) == 0 ) { + array_push($error_messages,'SMTPサーバホスト名を入力してください。'); + } + if( strlen($smtp_port) == 0 ) { + array_push($error_messages,'SMTPサーバポート番号を入力してください。'); + } else if( preg_match('/^[0-9]+$/',$smtp_port) == 0 ) { + array_push($error_messages,'SMTPサーバポート番号は半角数字のみで入力してください。'); + } + $smtp_auth = trim($options['smtp_auth']); + $smtp_auth_user = trim($options['smtp_auth_user']); + $smtp_auth_pass = trim($options['smtp_auth_pass']); + + if( preg_match('/^[fF](|[aA][lL][sS][eE])$/',$smtp_auth) > 0 + || strlen($smtp_auth) == 0 ) { + $smtp_auth = false; + } + if( $smtp_auth === false ) { + // 認証なし + } else if( preg_match('/^[pP][oO][pP][bB][eE][fF][oO][rR][eE]$/',$smtp_auth) > 0 ) { + // pop before smtp + if( strlen(trim($options['pop_host'])) == 0 ) { + array_push($error_messages,'認証用POPサーバホスト名を入力してください。'); + } + if( strlen(trim($options['pop_port'])) == 0 ) { + array_push($error_messages,'認証用POPサーバポート番号を入力してください。'); + } + if( strlen($smtp_auth_user) == 0 ) { + array_push($error_messages,'認証ユーザ名を入力してください。'); + } + if( strlen($smtp_auth_pass) == 0 ) { + array_push($error_messages,'認証パスワードを入力してください。'); + } + } else { + if( strlen($smtp_auth_user) == 0 ) { + array_push($error_messages,'SMTP認証ユーザ名を入力してください。'); + } + if( strlen($smtp_auth_pass) == 0 ) { + array_push($error_messages,'SMTP認証パスワードを入力してください。'); + } + } + return $error_messages; + } + /** + * pop before smtpのためpopサーバーに接続して切断します + */ + function connectPopBeforeSmtp() { + $socket = fsockopen($this->options['pop_host'], $this->options['pop_port'], $errorNumber, $errorMessage, 10); + if( $socket !== false ) { + $buffer = fgets($socket, 512); + if (substr($buffer, 0, 3) != '+OK') { + fputs($socket, "QUIT \r\n"); + fclose($socket); + } else { + fputs($socket, "USER ".$this->options['smtp_auth_user']."\r\n "); + $buffer = fgets($socket, 512); + if (substr($buffer, 0, 3) != '+OK') { + fputs($socket, "QUIT \r\n"); + fclose($socket); + } else { + fputs($socket, "PASS ".$this->options['smtp_auth_pass']."\r\n"); + $buffer = fgets($socket, 512); + if (substr($buffer, 0, 3) != '+OK') { + fputs($socket, "QUIT \r\n"); + fclose($socket); + } else { + fputs($socket, "QUIT \r\n"); + fclose($socket); + return true; + } + } + } + } + return false; + } +} +?> \ No newline at end of file Added: db/current/spider/lib/util/mail/SendMail.class.php =================================================================== --- db/current/spider/lib/util/mail/SendMail.class.php (rev 0) +++ db/current/spider/lib/util/mail/SendMail.class.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,98 @@ +<?php +require_once( dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'Mail.class.php'); +/** + * メール送信ユーティリティ拡張クラス:sendmailコマンドによる送信の実装クラス + * @version 1.0.0 + * @copyright Copyright © 2008, Multimedia Digital Contents Systems.Co.,Ltd.<info****@md-sy*****> http://www.md-systems.net/ + * @author Multimedia Digital Contents Systems.Co.,Ltd. m.nakashima <m_nakas****@md-sy*****> + * @since PHP 4.3 + */ +class util_mail_SendMail extends util_Mail { + var $sendmail_path = '/usr/sbin/sendmail -f'; + function util_mail_SendMail() { + } + /** + * 設定された内容で実際にメールを送信処理します + */ + function send_execute( $add_header_crlf=false, $convert_encoding=true ) { + + // 本文文字列を取得する + $header_strings = $this->_get_header_part_strings(true,true,false,$add_header_crlf,$convert_encoding); + $body_strings = $this->_get_body_part_strings($convert_encoding); + $sendwrite_strings = trim($header_strings)."\r\n".trim($body_strings); + $sendwrite_strings = str_replace("\r\n","\n",$sendwrite_strings); + + // メールアドレス部分のみ抜き出す + $to = $this->getToAddress(); + $from = $this->getFromAddress(); + $return_path = $this->return_path; + if( strlen(trim($return_path)) == 0 ) { + $return_path = $from; + } + + if( $this->sendmailTo( $from, $to, $sendwrite_strings, $return_path ) ) { + // 送信成功したら + // Ccにメール送信する + $cc_array = $this->getCcAddresses(); + foreach( $cc_array as $address ) { + $this->sendmailTo( $from, $address, $sendwrite_strings, $return_path ); + } + // Bccにメール送信する + $bcc_array = $this->getBccAddresses(); + foreach( $bcc_array as $address ) { + $this->sendmailTo( $from, $address, $sendwrite_strings, $return_path ); + } + return true; + } else { + return false; + } + } + /** + * sendmail コマンドへ書き出します + */ + function sendmailTo( $from, $to, $strings, $envelope_from=null ) { + if( is_null( $envelope_from ) ) { + $envelope_from = $from; + } + $sendmail_path = trim($this->options['sendmail_path']); + // コマンド文字列 + $command = $sendmail_path.' -f'.$envelope_from.' '. $to; + // sendmailへパイプオープン + $mp = popen($command, "w"); + if( $mp ) { + fputs($mp, $strings); + pclose($mp); + return true; + } else { + return false; + } + } + /** + * 送信設定オプションの妥当性検査を行いエラーメッセージの配列を返します。 + * エラーがない場合は要素0の配列を返します。 + */ + function validate_options( & $options ) { + $error_messages = array(); + if( !is_array($options) ) { + array_push($error_messages,'送信オプションを入力してください。'); + } else { + if( !isset($options['sendmail_path']) && isset($options[0]) ) { + $options['sendmail_path'] = trim(stripslashes($options[0])); + unset( $options[0] ); + } + } + // sendmail_pathが必須 + $sendmail_path = trim($options['sendmail_path']); + if( strlen(trim($sendmail_path)) == 0 ) { + array_push($error_messages, 'sendmailのパスを設定してください。' ); + } else { + $command_elements = explode(' ',$sendmail_path); + $command_file_path = array_shift( $command_elements ); + if( !file_exists( $command_file_path ) ) { + array_push($error_messages, '指定されたパスにsendmailコマンドが存在しません。' ); + } + } + return $error_messages; + } +} +?> \ No newline at end of file Added: db/current/spider/messages.inc.php =================================================================== --- db/current/spider/messages.inc.php (rev 0) +++ db/current/spider/messages.inc.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,29 @@ +<?php +/* + * framework-spider: メッセージリソース設定ファイル + */ +$GLOBALS['spider.messages'] = array( + // core + 'spider.controller.moduleisnotfound' => 'Core Error: 存在しないモジュール呼び出しです。', + 'spider.httpoutput.busy' => 'Core Error: 現在アクセスが非常に混雑しています。しばらくたってからもう一度アクセスしてください。', + 'spider.finctions.libdirisnotfound' => 'Core Error : ライブラリディレクトリがありません。', + 'spider.finctions.templatedirisnotfound' => 'Core Error : テンプレートディレクトリがありません。', + 'spider.finctions.workdirisnotfound' => 'Core Error : ワークディレクトリがありません。', + 'spider.finctions.workdirisnotwritable' => 'Core Error : ワークディレクトリが書き込み不能になっています。', + 'spider.finctions.cantcreatebindir' => 'Core Error : ビルドファイル保存ディレクトリを作成できません。', + 'spider.finctions.bindirisnotwritable' => 'Core Error : ビルドファイル保存ディレクトリが書き込み不能になっています。', + 'spider.finctions.cantcreatelockdir' => 'Core Error : プロセスロックディレクトリを作成できません。', + 'spider.finctions.lockdirisnotwritable' => 'Core Error : プロセスロックディレクトリが書き込み不能になっています。', + 'spider.finctions.cantcreatetmpdir' => 'Core Error : 一時ディレクトリを作成できません。', + 'spider.finctions.tmpdirisnotwritable' => 'Core Error : 一時ディレクトリが書き込み不能になっています。', + 'spider.finctions.cantcreatecachedir' => 'Core Error : キャッシュディレクトリを作成できません。', + 'spider.finctions.cachedirisnotwritable' => 'Core Error : キャッシュディレクトリが書き込み不能になっています。', + 'spider.finctions.datadirisnotfound' => 'Core Error : データディレクトリがありません。', + 'spider.finctions.datadirisnotwritable' => 'Core Error : データディレクトリが書き込み不能になっています。', + 'spider.finctions.cantcreatelogdir' => 'Core Error : ログディレクトリを作成できません。', + 'spider.finctions.logdirisnotwritable' => 'Core Error : ログディレクトリが書き込み不能になっています。', + // tags + 'spider.tags.usesession.cantstart' => 'Core Error : アプリケーションセッションを開始できませんでした。', + 'spider.tags.write.objectcanthasnumericmember' => 'Core Error : オブジェクトの添え字には数字を指定できません。', +); +?> \ No newline at end of file Added: db/current/spider/pages/default/index.php =================================================================== --- db/current/spider/pages/default/index.php (rev 0) +++ db/current/spider/pages/default/index.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,91 @@ + + <h1>This is framework spider example page!</h1> + + <div class="example-block"> + <h2>Widget example => </h2> + <table style="margin:0 auto;width:80%;background-color:#FFFFFF;"> + <tbody> + <tr> + <th>Dynamic Widget</th> + <th>Static Widget</th> + </tr> + <tr> + <td> + {widget:example.tpl dynamic} + </td> + <td> + {widget:example.tpl} + </td> + </tr> + </tbody> + </table> + </div> + + <div class="example-block"> + <h2>write scolar example => </h2> + <p style="color:#0000FF;"> + {write:example.Hello.message} + </p> + + </div> + + <div class="example-block"> + <h2>use array example => </h2> + <p>you can use 'foreach' tag like this!</p> + <ol> + {foreach:example.Hello.message_array message} + <li style="color:#0000FF;">{write:message}</li> + {/foreach} + </ol> + <p>and you can use 'write' tag like this!</p> + <p style="color:#0000FF;"> + 0 = {write:example.Hello.message_array[0]}<br /> + 3 = {write:example.Hello.message_array[3]} + </p> + + </div> + + <div class="example-block"> + <h2>use hash example => </h2> + <p>you can use 'foreach' tag like this!</p> + <ul> + {foreach:example.Hello.message_hash key value} + <li style="color:#0000FF;">{write:key} = {write:value}</li> + {/foreach} + </ul> + <p>and you can use 'write' tag like this!</p> + <p style="color:#0000FF;"> + first name = {write:example.Hello.message_hash['first_name']}<br /> + family name = {write:example.Hello.message_hash['family_name']} + </p> + + </div> + + <div class="example-block"> + <h2>use 2D hash example => </h2> + <p>you can use 'foreach' tag like this!</p> + <table style="margin:0 auto;width:80%;background-color:#FFFFFF;"> + <tbody> + <tr> + <th>Name</th> + <th>Information</th> + </tr> + {foreach:example.Hello.person_hash person_name person_information} + <tr> + <td>{write:person_name}</td> + <td> + {foreach:person_information key value} + {if:key='sex'} + oh! > {write:key}={write:value}<br /> + {else-if:key='prefecture'} + yeah! > {write:key}={write:value}<br /> + {/if} + {/foreach} + </td> + </tr> + {/foreach} + </tbody> + </table> + </div> + + \ No newline at end of file Added: db/current/spider/spider_command.inc.php =================================================================== --- db/current/spider/spider_command.inc.php (rev 0) +++ db/current/spider/spider_command.inc.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,85 @@ +<?php +/* + * framework-spider: コマンドプログラム用共通読み込みファイル + */ +// Framework Version +define( 'SPIDER_VERSION', '1.0.01' ); +define ( 'DIR_PATH_SPIDER_DATA', dirname(__FILE__) ); + +/* 設定ファイルの読み込み */ +require_once( dirname(__FILE__).DIRECTORY_SEPARATOR.'define.inc.php' ); +require_once( dirname(__FILE__).DIRECTORY_SEPARATOR.'messages.inc.php' ); +if ( file_exists( dirname( __FILE__ ).DIRECTORY_SEPARATOR.'unique_setting.inc.php' ) ) { + include_once( dirname( __FILE__ ).DIRECTORY_SEPARATOR.'unique_setting.inc.php' ); +} +// システムメール定義ファイルの読み込み +if( defined('FILE_PATH_SYSTEM_DEFINITION') && file_exists( FILE_PATH_SYSTEM_DEFINITION ) ){ + require_once( FILE_PATH_SYSTEM_DEFINITION ); +} + +/* グローバル関数ファイル */ +require_once( DIR_PATH_LIB + .DIRECTORY_SEPARATOR.'spider' + .DIRECTORY_SEPARATOR.'functions.inc.php' ); + +/* パーミッションの確認 */ +$errors = spider_is_avairable_permittion(); +if( count( $errors ) > 0 ) { + header( 'Content-Type: text/plain;charset=UTF-8'); + echo "Core Error!!\n"; + foreach( $errors as $error ) { + echo $error."\n"; + } + die; +} + +// 出力クラス +require_once( DIR_PATH_LIB + .DIRECTORY_SEPARATOR.'spider' + .DIRECTORY_SEPARATOR.'HttpOutput.class.php' ); +$GLOBALS['output'] = new spider_HttpOutput(); +// リクエストクラス +require_once( DIR_PATH_LIB + .DIRECTORY_SEPARATOR.'spider' + .DIRECTORY_SEPARATOR.'HttpRequest.class.php' ); +$GLOBALS['request'] = new spider_HttpRequest(); +/* コントローラークラス */ +require_once( DIR_PATH_LIB + .DIRECTORY_SEPARATOR.'spider' + .DIRECTORY_SEPARATOR.'Controller.class.php' ); +$GLOBALS['controller'] = new spider_Controller( $GLOBALS['request'], $GLOBALS['output'] ); + + +// 出力文字コードの確認 +mb_language('japanese'); +mb_internal_encoding('UTF-8'); +ob_start('mb_output_handler'); +if( preg_match('/[wW][iI][nN]/',$_ENV['OS'] ) > 0 ) { + mb_http_output('SJIS-win'); +} else if( preg_match('/[eE][uU][cC][jJ][pP]/', $_ENV['LANG'] ) > 0 ) { + mb_http_output('EUC_JP'); +} else if( preg_match('/[uU][tT][fF]\\-8/', $_ENV['LANG'] ) > 0 ) { + mb_http_output('UTF-8'); +} +// phpのインストール種別を確認 +$is_cli = false; +if( preg_match('/[cC][lL][iI]/',php_sapi_name()) > 0 ) { + $is_cli = true; +} else if( preg_match('/[hH][aA][nN][dD][lL][eE][rR]/',php_sapi_name()) > 0 ) { + header('Content-Type: text/plain; charset=UTF-8;'); + echo "Core Error!!\n"; + echo "this process called by php spi version.\n"; + echo "please call on commandline.\n"; + exit(0); +} else { + echo "Core Error!!\n"; + echo "this process called by php unknown version.\n"; + echo "please call on commandline.\n"; + exit(0); +} + +ob_implicit_flush( true ); +if ( file_exists( dirname( __FILE__ ).DIRECTORY_SEPARATOR.'unique_setting.inc.php' ) ) { + include_once( dirname( __FILE__ ).DIRECTORY_SEPARATOR.'unique_setting.inc.php' ); +} +?> \ No newline at end of file Added: db/current/spider/spider_main.inc.php =================================================================== --- db/current/spider/spider_main.inc.php (rev 0) +++ db/current/spider/spider_main.inc.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,110 @@ +<?php +/* + * framework-spider: Webページ利用用共通メイン実行ファイル + */ +// Framework Version +define( 'SPIDER_VERSION', '1.0.01' ); + +/* 設定ファイルの読み込み */ +require_once( dirname(__FILE__).DIRECTORY_SEPARATOR.'define.inc.php' ); +require_once( dirname(__FILE__).DIRECTORY_SEPARATOR.'messages.inc.php' ); +if ( file_exists( dirname( __FILE__ ).DIRECTORY_SEPARATOR.'unique_setting.inc.php' ) ) { + include_once( dirname( __FILE__ ).DIRECTORY_SEPARATOR.'unique_setting.inc.php' ); +} +// システムメール定義ファイルの読み込み +if( defined('FILE_PATH_SYSTEM_DEFINITION') && file_exists( FILE_PATH_SYSTEM_DEFINITION ) ){ + require_once( FILE_PATH_SYSTEM_DEFINITION ); +} + +// アクションファイルパスの取得 +$action_file_path = $_SERVER['SCRIPT_FILENAME']; +if ( str_replace( '\\', '/', __FILE__ ) + == str_replace( '\\', '/', $action_file_path ) ) { + // 本ファイル直接呼出しなら実行中止 + header( 'Content-type: text/plain;charset=UTF-8' ); + die( 'Core Error : コントロールファイルです。' ); +} + +/* リクエストコンテナオブジェクト */ +require_once( DIR_PATH_LIB + .DIRECTORY_SEPARATOR.'spider' + .DIRECTORY_SEPARATOR.'HttpRequest.class.php' ); +$GLOBALS['request'] = new spider_HttpRequest(); +$GLOBALS['request_object'] = & $GLOBALS['request']; + +/* 出力クラス */ +require_once( DIR_PATH_LIB + .DIRECTORY_SEPARATOR.'spider' + .DIRECTORY_SEPARATOR.'HttpOutput.class.php' ); +$GLOBALS['output_object'] = new spider_HttpOutput(); + +/* コントローラークラス */ +require_once( DIR_PATH_LIB + .DIRECTORY_SEPARATOR.'spider' + .DIRECTORY_SEPARATOR.'Controller.class.php' ); + +/* グローバル関数ファイル */ +require_once( DIR_PATH_LIB + .DIRECTORY_SEPARATOR.'spider' + .DIRECTORY_SEPARATOR.'functions.inc.php' ); + +/* パーミッションの確認 */ +$errors = spider_is_avairable_permittion(); +if( count( $errors ) > 0 ) { + header( 'Content-Type: text/plain;charset=UTF-8'); + echo "Core Error!!\n"; + foreach( $errors as $error ) { + echo $error."\n"; + } + die; +} + +// POSTとGETとCOOKIEの値をオブジェクトに設定する +$GLOBALS['request_object']->setAttribute( 'postparams', $_POST ); +foreach( $_POST as $key => $value ) { + $GLOBALS['request_object']->setAttribute( 'post.'.$key, $value ); +} +$GLOBALS['request_object']->setAttribute( 'getparams', $_GET ); +foreach( $_GET as $key => $value ) { + $GLOBALS['request_object']->setAttribute( 'get.'.$key, $value ); +} +foreach( $_COOKIE as $key => $value ) { + $GLOBALS['request_object']->setAttribute( 'cookie.'.$key, $value ); +} +// session_idが正しく取れないのでUseSessionタグ内に移動 +//// sessionのnameとidをリクエストに登録する +//$GLOBALS['request_object']->setAttribute( 'spider.session_name', session_name(), SPIDER_SESSION_SCOPE_GLOBAL ); +//$GLOBALS['request_object']->setAttribute( 'spider.session_id', session_id(), SPIDER_SESSION_SCOPE_GLOBAL ); + +// spiderの固定値をリクエスト属性に設定する +$base_url = APPLICATION_BASE_URL; +$GLOBALS['request_object']->setAttribute( 'spider.base_url', $base_url, SPIDER_SESSION_SCOPE_GLOBAL ); +$nomal_url = APPLICATION_NML_URL; +$GLOBALS['request_object']->setAttribute( 'spider.nomal_url', $nomal_url, SPIDER_SESSION_SCOPE_GLOBAL ); +$ssl_url = APPLICATION_SSL_URL; +$GLOBALS['request_object']->setAttribute( 'spider.ssl_url', $ssl_url, SPIDER_SESSION_SCOPE_GLOBAL ); +$base_uri = APPLICATION_BASE_URI; +$GLOBALS['request_object']->setAttribute( 'spider.base_uri', $base_uri, SPIDER_SESSION_SCOPE_GLOBAL ); +$base_path = APPLICATION_BASE_PATH; +$GLOBALS['request_object']->setAttribute( 'spider.base_path', $base_path, SPIDER_SESSION_SCOPE_GLOBAL ); +$access_uri = preg_replace('/^'.str_replace('.','\\.',str_replace('/','\\/',$base_uri)).'/','/',$_SERVER['REQUEST_URI']); +$GLOBALS['request_object']->setAttribute( 'spider.access_uri', $access_uri, SPIDER_SESSION_SCOPE_GLOBAL ); + +// コントローラー +$GLOBALS['controller'] = new spider_Controller( $GLOBALS['request_object'], $GLOBALS['output_object'] ); +// 前処理スクリプトの指定があるなら読み込む +if( is_array($GLOBALS['SPIDER_PREVIOUS_SCRIPT_FILE_PATH_ARRAY']) + && count($GLOBALS['SPIDER_PREVIOUS_SCRIPT_FILE_PATH_ARRAY']) > 0 ) { + foreach( $GLOBALS['SPIDER_PREVIOUS_SCRIPT_FILE_PATH_ARRAY'] as $script_path ) { + $script_path = trim( $script_path ); + if( strlen($script_path) > 0 && file_exists( $script_path) ) { + include_once( $script_path ); + } + } +} +// メイン処理実行 +$GLOBALS['controller']->execute( $GLOBALS['request_object'], $GLOBALS['output_object'] ); + +die; + +?> \ No newline at end of file Added: db/current/spider/templates/default/public_default.tpl =================================================================== --- db/current/spider/templates/default/public_default.tpl (rev 0) +++ db/current/spider/templates/default/public_default.tpl 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="ja" xml:lang="ja"> +<head> + <meta http-equiv="Content-type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Script-Type" content="text/javascript" /> + <meta http-equiv="Content-Style-Type" content="text/css" /> + <meta content="ja" name="content-language" /> + <meta content="2008.09.01" name="build" /> + <meta content="M.Nakashima" name="author" /> + <meta name="description" content="Welcome spider framework!" /> + <meta name="keywords" content="Welcome spider framework!" /> + <title>{write:page_title}</title> + <style type="text/css"> + * { font-family:monospace; } + table { border-style:solid; border-width:1px; border-color:#000080; border-collapse:collapse; } + th,td { border-style:solid; border-width:1px; border-color:#000080; text-align:center; padding:5px; } + th { color:#FFFFFF; background-color:#0000D0; } + #header { width:100%; background-color:#6060D0; color:#F0F0F0; } + #contents { width:100%; text-align:left; padding:5px; } + #footer { width:100%; background-color:#6060D0; color:#F0F0F0; } + #contents h1 { font-size:20px; color:#008080; text-align:center; } + #contents h2 { font-size:18px; color:#FFFFFF; background-color:#008080; margin:0px 0px 5px 0px; padding:3px; } + #contents h3 { font-size:16px; color:#FFFFFF; background-color:#008080; margin:0px 0px 5px 0px; padding:3px; } + div.example-block { background-color:#DDFFFF; border-style:solid; border-width:1px; border-color:#008080; margin: 5px auto 5px auto; padding: 5px; } + </style> +</head> +<body style="margin:0 auto;text-align:center;"> + <div id="header">Welcome Spider framework! This is sample template!</div> + <div id="contents"> + {page-contents} + </div> + <div id="footer">Welcome Spider framework! This is sample template!</div> +</body> +</html> \ No newline at end of file Added: db/current/spider/unique_setting.inc.php =================================================================== --- db/current/spider/unique_setting.inc.php (rev 0) +++ db/current/spider/unique_setting.inc.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,26 @@ +<?php +/* + * framework-spider: アプリケーション固有のグローバル変数の定義用ファイル + */ +/** + * spiderデバッグ用コマンドを許可するIPアドレス + * spiderdebugcmd= viewmoduletime/ 他検討 + */ +$GLOBALS['SPIDER_DEBUG_COMMAND_PERMIT_ADDRESSES'] = array( + '127.0.0.1', +); +/* + * 前処理スクリプトファイルパス配列 + * + * ビルドファイルを作成する前に処理したいプログラムを記述したスクリプトファイルを用意して + * 実行させることができます。このスクリプト読み込み実行はコマンドラインからの実行でない + * 限りビルドファイルのあるなしに関わらず事前に必ず実行されます。 + * スクリプトファイルの中で標準出力を行ってはいけません。 + * ページ表示というイベントに対するフックスクリプトのようなイメージで利用してください。 + */ +$GLOBALS['SPIDER_PREVIOUS_SCRIPT_FILE_PATH_ARRAY'] = array(); + +// PHP内部文字セット(基本的に変更しないこと) +define ( 'CHARSET_INTERNAL', 'UTF-8' ); + +?> \ No newline at end of file Added: db/current/spider/widgets/default/example.tpl =================================================================== --- db/current/spider/widgets/default/example.tpl (rev 0) +++ db/current/spider/widgets/default/example.tpl 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,4 @@ +<div style="width:150px;height:150px;border-style:solid;border-width:1px;text-align:center;"> + Example<br /> + Widget! +</div> \ No newline at end of file Added: db/current/spider/widgets/default/example.tpl.index.php =================================================================== --- db/current/spider/widgets/default/example.tpl.index.php (rev 0) +++ db/current/spider/widgets/default/example.tpl.index.php 2010-04-20 16:08:15 UTC (rev 97) @@ -0,0 +1,5 @@ +<div style="width:150px;height:150px;border-style:solid;border-width:1px;text-align:center;"> + index.php<br /> + Dynamic<br /> + Widget! +</div> \ No newline at end of file