/** * smarty function:フォーム表示名生成 * * @param string $name フォーム項目名 */ function smarty_function_form_name($params, &$smarty) { // name if (isset($params['name'])) { $name = $params['name']; unset($params['name']); } else { return null; } // view object $view = Ethna_Container::getInstance()->getView(); if ($view === null) { return null; } // action $action = null; if (isset($params['action'])) { $action = $params['action']; unset($params['action']); } else { for ($i = count($smarty->_tag_stack); $i >= 0; --$i) { if ($smarty->_tag_stack[$i][0] === 'form') { if (isset($smarty->_tag_stack[$i][1]['ethna_action'])) { $action = $smarty->_tag_stack[$i][1]['ethna_action']; } break; } } } if ($action !== null) { $view->addActionFormHelper($action); } return $view->getFormName($name, $action, $params); }
/** * Cachemaanger プラグインのインスタンスを取得する * * @param string $type キャッシュタイプ('localfile', 'memcache'...) * @return object Ethna_Plugin_CacheMaanger Cachemanager プラグインのインスタンス * @access public */ public static function getInstance($type) { $container = Ethna_Container::getInstance(); $plugin = $container->getPlugin(); $cache_manager = $plugin->getPlugin('Cachemanager', ucfirst($type)); return $cache_manager; }
/** * Ethna_I18Nクラスのコンストラクタ * * @access public * @param string $locale_dir プロジェクトのロケールディレクトリ * @param string $appid アプリケーションID */ public function __construct($locale_dir, $appid) { $this->locale_dir = $locale_dir; $this->appid = $appid; $container = Ethna_Container::getInstance(); $this->logger = $container->getLogger(); $this->messages = false; // not initialized yet. }
/** * smarty block:フォームタグ出力プラグイン */ function smarty_block_form($params, $content, &$smarty, &$repeat) { if ($repeat) { // {form}: ブロック内部に進む前の処理 // default if (isset($params['default']) === false) { // 指定なしのときは $form を使う $af = Ethna_Container::getInstance()->getActionForm(); // c.f. http://smarty.php.net/manual/en/plugins.block.functions.php $smarty->_tag_stack[count($smarty->_tag_stack) - 1][1]['default'] = $af->getArray(false); } // 動的フォームヘルパを呼ぶ if (isset($params['ethna_action'])) { $ethna_action = $params['ethna_action']; $view = Ethna_Container::getInstance()->getView(); $view->addActionFormHelper($ethna_action, true); } // ここで返す値は出力されない return ''; } else { // {/form}: ブロック全体を出力 $view = Ethna_Container::getInstance()->getView(); if ($view === null) { return null; } // ethna_action if (isset($params['ethna_action'])) { $ethna_action = $params['ethna_action']; unset($params['ethna_action']); $view->addActionFormHelper($ethna_action); $hidden = getActionRequest($ethna_action, 'hidden'); $content = $hidden . $content; //デバグ用に、送信先のアクション名を表示する //超絶便利。これのおかげて開発効率だいぶあがった。 if (Ethna_Container::getInstance()->getConfig()->get('showFormActionName')) { echo "[" . $ethna_action . "]"; } } // enctype の略称対応 if (isset($params['enctype'])) { if ($params['enctype'] == 'file' || $params['enctype'] == 'multipart') { $params['enctype'] = 'multipart/form-data'; } else { if ($params['enctype'] == 'url') { $params['enctype'] = 'application/x-www-form-urlencoded'; } } } // defaultはもう不要 if (isset($params['default'])) { unset($params['default']); } // $contentを囲む<form>ブロック全体を出力 return $view->getFormBlock($content, $params); } }
/** * smarty function:フォームのsubmitボタン生成 * * @param string $submit フォーム項目名 */ function smarty_function_form_submit($params, &$smarty) { $view = Ethna_Container::getInstance()->getView(); if ($view === null) { return null; } //ここでi18n変換をかます $params['value'] = _et($params['value']); return $view->getFormSubmit($params); }
/** * smarty modifier:フォーム値出力フィルタ * * フォーム名を変数で指定してフォーム値を取得したい場合に使用する * * sample: * <code> * $this->af->set('foo', 'bar'); * $smarty->assign('key', 'foo'); * {$key|form_value} * </code> * <code> * bar * </code> * * @param string $string フォーム項目名 * @return string フォーム値 */ function smarty_modifier_form_value($string) { $af = Ethna_Container::getInstance()->getActionForm(); $elts = explode(".", $string); $r = $af->get($elts[0]); for ($i = 1; $i < count($elts); $i++) { $r = $r[$elts[$i]]; } return htmlspecialchars($r, ENT_QUOTES, mb_internal_encoding()); }
/** * smarty function:フォームタグ生成 * * @param string $name フォーム項目名 */ function smarty_function_form_input($params, &$smarty) { // name if (isset($params['name'])) { $name = $params['name']; unset($params['name']); } else { return null; } // view object $view = Ethna_Container::getInstance()->getView(); if ($view === null) { return null; } // 現在の{form_input}を囲むform blockがあればパラメータを取得しておく $block_params = null; for ($i = count($smarty->_tag_stack); $i >= 0; --$i) { if ($smarty->_tag_stack[$i][0] === 'form') { $block_params = $smarty->_tag_stack[$i][1]; break; } } // action $action = null; if (isset($params['action'])) { $action = $params['action']; unset($params['action']); } else { if (isset($block_params['ethna_action'])) { $action = $block_params['ethna_action']; } } if ($action !== null) { $view->addActionFormHelper($action, true); } // default if (isset($params['default'])) { // {form_input default=...}が指定されていればそのまま } else { if (isset($block_params['default'])) { // 外側の {form default=...} ブロック if (isset($block_params['default'][$name])) { $params['default'] = $block_params['default'][$name]; } } } // 現在のアクションで受け取ったフォーム値 $af = Ethna_Container::getInstance()->getActionForm(); $val = $af->get($name); if ($val !== null) { $params['default'] = $val; } return $view->getFormInput($name, $action, $params); }
/** * smarty function:指定されたフォーム項目に対応するエラーメッセージを出力する * * sample: * <code> * <input type="text" name="foo">{message name="foo"} * </code> * <code> * <input type="text" name="foo">fooを入力してください * </code> * * @param string $name フォーム項目名 */ function smarty_function_message($params, &$smarty) { if (isset($params['name']) === false) { return ''; } $action_error = Ethna_Container::getInstance()->getActionError(); $message = $action_error->getMessage($params['name']); if ($message === null) { return ''; } $id = isset($params['id']) ? $params['id'] : str_replace("_", "-", "ethna-error-" . $params['name']); $class = isset($params['class']) ? $params['class'] : "ethna-error"; return sprintf('<span class="%s" id="%s">%s</span>', $class, $id, htmlspecialchars($message, null, mb_internal_encoding())); }
/** * smarty function: 正当なポストであることを保証するIDを出力する * * sample: * <code> * {csrfid} * </code> * <code> * <input type="hidden" name="csrfid" value="a0f24f75e...e48864d3e"> * </code> * * @param string $type 表示タイプ("get" or "post"−デフォルト="post") * @see isRequestValid */ function smarty_function_csrfid($params, &$smarty) { $container = Ethna_Container::getInstance(); $name = $container->getConfig()->get('csrf'); if (is_null($name)) { $name = 'Session'; } $plugin = $container->getPlugin(); $csrf = $plugin->getPlugin('Csrf', $name); $csrfid = $csrf->get(); $token_name = $csrf->getTokenName(); if (isset($params['type']) && $params['type'] == 'get') { return sprintf("%s=%s", $token_name, $csrfid); } else { return sprintf("<input type=\"hidden\" name=\"%s\" value=\"%s\" />\n", $token_name, $csrfid); } }
/** * メールを送信する * * @access protected * @param string $message ログメッセージ */ function _alert($message) { restore_error_handler(); $appid = Ethna_Container::getInstance()->getAppId(); $header = "Mime-Version: 1.0\n"; $header .= "Content-Type: text/plain; charset=ISO-2022-JP\n"; $header .= "X-Alert: " . $appid; $subject = sprintf("[%s] alert (%s%s)\n", $appid, substr($message, 0, 12), strlen($message) > 12 ? "..." : ""); $message = sprintf("--- [log message] ---\n%s\n\n", $message); if (function_exists("debug_backtrace")) { $bt = debug_backtrace(); $message .= sprintf("--- [backtrace] ---\n%s\n", Ethna_Util::FormatBacktrace($bt)); } foreach ($this->mailaddress as $address) { mail($address, $subject, mb_convert_encoding($message, "ISO-2022-JP"), $header); } set_error_handler("ethna_error_handler"); }
/** * Ethna_UrlHandlerクラスのインスタンスを取得する * * $name がクラス名 ('_'を含む) の場合はそのクラスを、 * そうでないときはプラグイン名とみなしてインスタンスを返す * * @access public */ public static function getInstance($name = null) { static $instance = array(); if ($name === null) { $name = __CLASS__; } if (isset($instance[$name])) { return $instance[$name]; } if (strpos($name, '_') !== false) { $instance[$name] = new $name(); } else { // get instance with plugin $plugin = Ethna_Container::getInstance()->getPlugin(); $instance[$name] = $plugin->getPlugin('Urlhandler', $name); } return $instance[$name]; }
/** * Ethna_Errorクラスのコンストラクタ * $userinfo は第5引数に設定すること。 * * @access public * @param string $message エラーメッセージ * @param int $code エラーコード * @param int $mode エラーモード(Ethna_Errorはコールバックを * 常に使用するので実質無視される) * @param array $options エラーモード依存のオプション * @param array $userinfo エラー追加情報($options より後の全ての引数) * @see http://pear.php.net/manual/ja/core.pear.pear-error.pear-error.php */ public function __construct($message = null, $code = null, $mode = null, $options = null) { $container = Ethna_Container::getInstance(); if ($container !== null) { $this->i18n = $container->getI18N(); } // $options 以降の引数 -> $userinfo if (func_num_args() > 4) { $userinfo = array_slice(func_get_args(), 4); if (count($userinfo) == 1) { if (is_array($userinfo[0])) { $this->userinfo = $userinfo[0]; } else { if (is_null($userinfo[0])) { $this->userinfo = array(); } } } else { $this->userinfo = $userinfo[0]; } } else { $this->userinfo = array(); } // メッセージ補正処理 ($message) if (is_null($message)) { // $codeからメッセージを取得する $message = $this->getErrorMessage($code); if (is_null($message)) { $message = 'unknown error'; } } $this->message = $message; // その他メンバ変数設定 $this->code = $code; $this->mode = $mode; $this->options = $options; $this->level = $this->options === NULL ? E_USER_NOTICE : $options; // Ethnaフレームワークのエラーハンドラ(callback) Ethna::handleError($this); }
/** * smarty function:url生成 */ function smarty_function_url($params, &$smarty) { $action = $path = $path_key = null; $query = $params; foreach (array('action', 'anchor', 'scheme') as $key) { if (isset($params[$key])) { ${$key} = $params[$key]; } else { ${$key} = null; } unset($query[$key]); } $container = Ethna_Container::getInstance(); $url_handler = $container->getUrlHandler(); list($path, $path_key) = $url_handler->actionToRequest($action, $query); if ($path != "") { if (is_array($path_key)) { foreach ($path_key as $key) { unset($query[$key]); } } } else { $query = $url_handler->buildActionParameter($query, $action); } $query = $url_handler->buildQueryParameter($query); $url = sprintf('%s%s', $container->getUrl(), $path); if (preg_match('|^(\\w+)://(.*)$|', $url, $match)) { if ($scheme) { $match[1] = $scheme; } $match[2] = preg_replace('|/+|', '/', $match[2]); $url = $match[1] . '://' . $match[2]; } $url .= $query ? "?{$query}" : ""; $url .= $anchor ? "#{$anchor}" : ""; return $url; }
/** * ログ出力箇所の情報(関数名/ファイル名等)を取得する * * @access private * @return array ログ出力箇所の情報 */ function _getBacktrace() { $skip_method_list = array(array('ethna', 'raise'), array(null, 'raiseerror'), array(null, 'handleerror'), array('ethna_logger', null), array('ethna_plugin_logwriter', null), array('ethna_error', null), array('ethna_apperror', null), array('ethna_actionerror', null), array(null, 'ethna_error_handler'), array(null, 'trigger_error')); if ($this->have_backtrace == false) { return null; } $bt = debug_backtrace(); $i = 0; while ($i < count($bt)) { if (isset($bt[$i]['class']) == false) { $bt[$i]['class'] = null; } if (isset($bt[$i]['file']) == false) { $bt[$i]['file'] = null; } if (isset($bt[$i]['line']) == false) { $bt[$i]['line'] = null; } $skip = false; // メソッドスキップ処理 foreach ($skip_method_list as $method) { $class = $function = true; if ($method[0] != null) { $class = preg_match("/^{$method['0']}/i", $bt[$i]['class']); } if ($method[1] != null) { $function = preg_match("/^{$method['1']}/i", $bt[$i]['function']); } if ($class && $function) { $skip = true; break; } } if ($skip) { $i++; } else { break; } } $basedir = Ethna_Container::getInstance()->getBasedir(); $function = sprintf("%s.%s", isset($bt[$i]['class']) ? $bt[$i]['class'] : 'global', $bt[$i]['function']); $file = $bt[$i]['file']; if (strncmp($file, $basedir, strlen($basedir)) == 0) { $file = substr($file, strlen($basedir)); } if (strncmp($file, ETHNA_BASE, strlen(ETHNA_BASE)) == 0) { $file = preg_replace('#^/+#', '', substr($file, strlen(ETHNA_BASE))); } $line = $bt[$i]['line']; return array('function' => $function, 'pos' => sprintf('%s:%s', $file, $line)); }
/** * チェックメソッド(基底クラス) * * @access public * @param string $name フォーム項目名 * @return array チェック対象のフォーム値(エラーが無い場合はnull) */ public function check($name) { if (is_null($this->get($name)) || $this->get($name) === "") { return null; } //ここは意味不明 $c = Ethna_Container::getInstance(); $this->container = $c; return to_array($this->get($name)); }
/** * Ethna 本体付属のプラグインのソースを include する * * @access public * @param string $type プラグインの種類 * @param string $name プラグインの名前 * @static */ public static function import($type, $name = null) { $plugin = Ethna_Container::getInstance()->getPlugin(); $plugin->includePlugin($type, $name); }
/** * ログファイルの書き出し先を取得する(ログファシリティに * LOG_FILEが指定されている場合のみ有効) * * ログファイルの書き出し先を変更したい場合はこのメソッドを * オーバーライドします * * @access protected * @return string ログファイルの書き出し先 */ function _getLogFile() { $container = Ethna_Container::getInstance(); if (array_key_exists("dir", $this->option)) { $dir = $this->option['dir']; } else { $dir = $container->getDirectory('log'); } return sprintf('%s/%s', $dir, $this->getFileName()); }
/** * テンポラリディレクトリのファイルを削除する * * @access public * @param string $prefix ファイルのプレフィクス * @param int $timeout 削除対象閾値(秒−60*60*1なら1時間) */ public static function purgeTmp($prefix, $timeout) { $container = Ethna_Container::getInstance(); $dh = opendir($container->getDirectory('tmp')); if ($dh) { while (($file = readdir($dh)) !== false) { if ($file == '.' || $file == '..') { continue; } else { if (is_dir($container->getDirectory('tmp') . '/' . $file)) { continue; } else { if (strncmp($file, $prefix, strlen($prefix)) == 0) { $f = $container->getDirectory('tmp') . "/" . $file; $st = stat($f); if ($st[9] + $timeout < time()) { unlink($f); } } } } } closedir($dh); } }
/** * グローバルユーティリティ関数: 指定されたフォーム項目にエラーがあるかどうかを返す * * @param string $name フォーム項目名 * @return bool true:エラー有り false:エラー無し */ function is_error($name = null) { $container = Ethna_Container::getInstance(); $action_error = $container->getActionError(); if ($name !== null) { return $action_error->isError($name); } else { return $action_error->count() > 0; } }
/** * helperアクションフォームオブジェクトを設定する * * @param string $action アクション名 * @param boolean $dynamic_helper 動的フォームヘルパを呼ぶか否か * @access public */ public function addActionFormHelper($action, $dynamic_helper = false) { // // 既に追加されている場合は処理をしない // if (isset($this->helper_action_form[$action]) && is_object($this->helper_action_form[$action])) { return; } // 現在のアクションと等しければ、対応する // アクションフォームを設定 $container = Ethna_Container::getInstance(); if ($action === $container->getCurrentActionName()) { $this->helper_action_form[$action] = $this->af; } else { // アクションが異なる場合 $form_name = $container->getActionFormName($action); if ($form_name === null) { $this->logger->log(LOG_WARNING, 'action form for the action [%s] not found.', $action); return; } $this->helper_action_form[$action] = new $form_name($container); } // 動的フォームを設定するためのヘルパメソッドを呼ぶ if ($dynamic_helper) { $af = $this->helper_action_form[$action]; $af->setFormDef_ViewHelper(); } }
/** * smarty modifier:i18nフィルタ * * sample: * <code> * {"you have %d apples"|i18n:$n} * </code> * <code> * あなたはリンゴを3つ持っています。 * </code> * * @param string $string i18n処理対象の文字列 * @param mixed $val 任意のパラメータ * @return string ロケールに対応したメッセージ */ function smarty_modifier_i18n($string, $arg1 = null) { $i18n = Ethna_Container::getInstance()->getI18N(); $msg = $i18n->get($string); return sprintf($msg, $arg1); }