*** features
+- Ethna_Controller::getCLI()(CLI¤Ç¼Â¹ÔÃ椫¤É¤¦¤«¤òÊÖ¤¹¥á¥½¥Ã¥É)¤òÄɲÃ
+- ethna_error_handler¤¬php.ini¤ÎÀßÄê¤Ë±þ¤¸¤ÆPHP¥í¥°¤â½ÐÎϤ¹¤ë¤è¤¦¤ËÊѹ¹
+- Smarty¥×¥é¥°¥¤¥ó(truncate_i18n)¤òÄɲÃ
- Ethna_AppObject/Ethna_AppManager¤Ë¥¥ã¥Ã¥·¥åµ¡¹½¤òÄɲÃ(experimental)
- ¥á¡¼¥ë¥Æ¥ó¥×¥ì¡¼¥È¥¨¥ó¥¸¥ó¤Î¥Õ¥Ã¥¯¥á¥½¥Ã¥É¤òÄɲÃ
- MIME¥¨¥ó¥³¡¼¥ÉÍѥ桼¥Æ¥£¥ê¥Æ¥£¥á¥½¥Ã¥É¤òÄɲÃ
*** bug fixes
+- ethna_error_handler¤Îtypo¤ò½¤Àµ
+- Ethna_Session¥¯¥é¥¹¤Ç¥í¥°¤¬Àµ¤·¤¯½ÐÎϤµ¤ì¤Ê¤¤ÌäÂê¤ò½¤Àµ
+
** [2005/01/14] 0.1.4
*** features
// ¥Ð¥Ã¥¯¥¢¥Ã¥×/¥¥ã¥Ã¥·¥å¹¹¿·
$this->prop_backup = $this->prop;
- unset($GLOBALS['_ETHNA_APP_OBJECT_CACHE'][strtolower(get_class($this))]);
- unset($GLOBALS['_ETHNA_APP_MANAGER_OL_CACHE'][strtolower(get_class($this))]);
- unset($GLOBALS['_ETHNA_APP_MANAGER_OPL_CACHE'][strtolower(get_class($this))]);
- unset($GLOBALS['_ETHNA_APP_MANAGER_OP_CACHE'][strtolower(get_class($this))]);
+ $this->_clearPropCache();
return 0;
}
// ¥×¥í¥Ñ¥Æ¥£/¥Ð¥Ã¥¯¥¢¥Ã¥×/¥¥ã¥Ã¥·¥å¥¯¥ê¥¢
$this->id = $this->prop = $this->prop_backup = null;
- unset($GLOBALS['_ETHNA_APP_OBJECT_CACHE'][strtolower(get_class($this))]);
- unset($GLOBALS['_ETHNA_APP_MANAGER_OL_CACHE'][strtolower(get_class($this))]);
- unset($GLOBALS['_ETHNA_APP_MANAGER_OPL_CACHE'][strtolower(get_class($this))]);
- unset($GLOBALS['_ETHNA_APP_MANAGER_OP_CACHE'][strtolower(get_class($this))]);
+ $this->_clearPropCache();
return 0;
}
function _getSQL_Select($key_type, $key)
{
$key_type = to_array($key_type);
- $key = to_array($key);
+ if (is_null($key)) {
+ // add()Á°
+ $key = array();
+ for ($i = 0; $i < count($key_type); $i++) {
+ $key[$i] = null;
+ }
+ } else {
+ $key = to_array($key);
+ }
// SQL¥¨¥¹¥±¡¼¥×
Ethna_AppSQL::escapeSQL($key);
}
return false;
}
+
+ /**
+ * ¥¥ã¥Ã¥·¥å¥Ç¡¼¥¿¤òºï½ü¤¹¤ë
+ *
+ * @access private
+ */
+ function _clearPropCache()
+ {
+ $class_name = strtolower(get_class($this));
+ foreach (array('_ETHNA_APP_OBJECT_CACHE', '_ETHNA_APP_MANAGER_OL_CACHE', '_ETHNA_APP_MANAGER_OPL_CACHE', '_ETHNA_APP_MANAGER_OP_CACHE') as $key) {
+ if (array_key_exists($key, $GLOBALS) && array_key_exists($class_name, $GLOBALS[$key])) {
+ unset($GLOBALS[$key][$class_name]);
+ }
+ }
+ }
}
// }}}
?>
/** @var object Ethna_Logger ¥í¥°¥ª¥Ö¥¸¥§¥¯¥È */
var $logger = null;
+ /** @var bool CLI¥¢¥¯¥·¥ç¥ó¼Â¹ÔÃæ¥Õ¥é¥° */
+ var $cli = false;
+
/**#@-*/
}
/**
+ * CLI¼Â¹ÔÃæ¥Õ¥é¥°¤ò¼èÆÀ¤¹¤ë
+ *
+ * @access public
+ * @return bool CLI¼Â¹ÔÃæ¥Õ¥é¥°
+ */
+ function getCLI()
+ {
+ return $this->cli;
+ }
+
+ /**
+ * CLI¼Â¹ÔÃæ¥Õ¥é¥°¤òÀßÄꤹ¤ë
+ *
+ * @access public
+ * @param bool CLI¼Â¹ÔÃæ¥Õ¥é¥°
+ */
+ function setCLI($cli)
+ {
+ $this->cli = $cli;
+ }
+
+ /**
* ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Î¥¨¥ó¥È¥ê¥Ý¥¤¥ó¥È
*
* @access public
function main_CLI($class_name, $action_name)
{
$c =& new $class_name;
+ $c->setCLI(true);
$c->action[$action_name] = array();
$c->trigger('www', $action_name);
}
$action_obj =& $this->_getAction($fallback_action_name);
}
if ($action_obj == null) {
- return Ethna::raiseError(E_APP_UNDEFINED_ACTION, "undefined action [%s]", $action_name);
+ return Ethna::raiseError("undefined action [%s]", E_APP_UNDEFINED_ACTION, $action_name);
} else {
$action_name = $fallback_action_name;
}
// ¥í¥°½ÐÎÏ
list ($log_level, $dummy) = $this->logger->errorLevelToLogLevel($error->getLevel());
$message = $error->getMessage();
- $this->logger->log($log_level, sprintf("[APP(%d)] %s", $error->getCode(), $message));
+ $this->logger->log($log_level, sprintf("%s [ERROR CODE(%d)]", $message, $error->getCode()));
}
/**
$smarty->register_modifier('filter', 'smarty_modifier_filter');
$smarty->register_modifier('unique', 'smarty_modifier_unique');
$smarty->register_modifier('wordwrap_i18n', 'smarty_modifier_wordwrap_i18n');
+ $smarty->register_modifier('truncate_i18n', 'smarty_modifier_truncate_i18n');
$smarty->register_modifier('i18n', 'smarty_modifier_i18n');
$smarty->register_modifier('checkbox', 'smarty_modifier_checkbox');
$smarty->register_modifier('select', 'smarty_modifier_select');
*/
function log($level, $message)
{
- $prefix = strftime('%Y/%m/%d %H:%M:%S ') . $this->ident;
+ $c =& Ethna_Controller::getInstance();
+
+ $prefix = $this->ident;
if ($this->option & LOG_PID) {
$prefix .= sprintf('[%d]', getmypid());
}
- $prefix .= sprintf('(%s): ', $this->_getLogLevelName($level));
- if ($this->option & LOG_FUNCTION) {
- $function = $this->_getFunctionName();
- if ($function) {
- $prefix .= sprintf('%s: ', $function);
+ $prefix .= sprintf($c->getCLI() ? '(%s): ' : '(<b>%s</b>): ',
+ $this->_getLogLevelName($level)
+ );
+ if ($this->option & (LOG_FUNCTION | LOG_POS)) {
+ $tmp = "";
+ $bt = $this->_getBacktrace();
+ if ($bt && ($this->option & LOG_FUNCTION) && $bt['function']) {
+ $tmp .= $bt['function'];
+ }
+ if ($bt && ($this->option & LOG_POS) && $bt['pos']) {
+ $tmp .= $tmp ? sprintf('(%s)', $bt['pos']) : $bt['pos'];
+ }
+ if ($tmp) {
+ $prefix .= $tmp . ": ";
}
}
- printf($prefix . $message . "\n");
+
+ printf($prefix . $message . "%s\n", $c->getCLI() ? "" : "<br />");
return $prefix . $message;
}
}
/**
- * ¥í¥°½ÐÎϸµ¤Î´Ø¿ô¤ò¼èÆÀ¤¹¤ë
+ * ¥í¥°½ÐÎϲսê¤Î¾ðÊó(´Ø¿ô̾/¥Õ¥¡¥¤¥ë̾Åù)¤ò¼èÆÀ¤¹¤ë
*
* @access private
- * @return string ¥í¥°½ÐÎϸµ¥¯¥é¥¹/¥á¥½¥Ã¥É̾("class.method")
+ * @return array ¥í¥°½ÐÎϲսê¤Î¾ðÊó
*/
- function _getFunctionName()
+ function _getBacktrace()
{
$skip_method_list = array(
- array('ethna', 'raise*'),
+ array('ethna', 'raise.*'),
+ array(null, 'raiseerror'),
+ array(null, 'handleerror'),
array('ethna_logger', null),
- array('ethna_logwriter_*', null),
+ array('ethna_logwriter*', null),
array('ethna_error', null),
array('ethna_apperror', null),
array('ethna_actionerror', null),
foreach ($skip_method_list as $method) {
$class = $function = true;
if ($method[0] != null) {
- if (preg_match('/\*$/', $method[0])) {
- $n = strncasecmp($bt[$i]['class'], $method[0], strlen($method[0])-1);
- } else {
- $n = strcasecmp($bt[$i]['class'], $method[0]);
- }
- $class = $n == 0 ? true : false;
+ $class = preg_match("/$method[0]/i", $bt[$i]['class']);
}
if ($method[1] != null) {
- if (preg_match('/\*$/', $method[1])) {
- $n = strncasecmp($bt[$i]['function'], $method[1], strlen($method[1])-1);
- } else {
- $n = strcasecmp($bt[$i]['function'], $method[1]);
- }
- $function = $n == 0 ? true : false;
+ $function = preg_match("/$method[1]/i", $bt[$i]['function']);
}
if ($class && $function) {
$skip = true;
}
}
- return sprintf("%s.%s", isset($bt[$i]['class']) ? $bt[$i]['class'] : 'global', $bt[$i]['function']);
+ $c =& Ethna_Controller::getInstance();
+ $basedir = $c->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));
}
}
// }}}
$prefix .= sprintf('[%d]', getmypid());
}
$prefix .= sprintf('(%s): ', $this->_getLogLevelName($level));
- if ($this->option & LOG_FUNCTION) {
- $function = $this->_getFunctionName();
- if ($function) {
- $prefix .= sprintf('%s: ', $function);
+ if ($this->option & (LOG_FUNCTION | LOG_POS)) {
+ $tmp = "";
+ $bt = $this->_getBacktrace();
+ if ($bt && ($this->option & LOG_FUNCTION) && $bt['function']) {
+ $tmp .= $bt['function'];
+ }
+ if ($bt && ($this->option & LOG_POS) && $bt['pos']) {
+ $tmp .= $tmp ? sprintf('(%s)', $bt['pos']) : $bt['pos'];
+ }
+ if ($tmp) {
+ $prefix .= $tmp . ": ";
}
}
fwrite($this->fp, $prefix . $message . "\n");
function log($level, $message)
{
$prefix = sprintf('%s: ', $this->_getLogLevelName($level));
- if ($this->option & LOG_FUNCTION) {
- $function = $this->_getFunctionName();
- if ($function) {
- $prefix .= sprintf('%s: ', $function);
+ if ($this->option & (LOG_FUNCTION | LOG_POS)) {
+ $tmp = "";
+ $bt = $this->_getBacktrace();
+ if ($bt && ($this->option & LOG_FUNCTION) && $bt['function']) {
+ $tmp .= $bt['function'];
+ }
+ if ($bt && ($this->option & LOG_POS) && $bt['pos']) {
+ $tmp .= $tmp ? sprintf('(%s)', $bt['pos']) : $bt['pos'];
+ }
+ if ($tmp) {
+ $prefix .= $tmp . ": ";
}
}
syslog($level, $prefix . $message);
define('LOG_FILE', 1 << 16);
/**
+ * ³ÈÄ¥¥í¥°¥×¥í¥Ñ¥Æ¥£: ɸ½à½ÐÎÏ
+ */
+define('LOG_ECHO', 1 << 17);
+
+/**
* ³ÈÄ¥¥í¥°¥×¥í¥Ñ¥Æ¥£: ´Ø¿ô̾ɽ¼¨
*/
-define('LOG_FUNCTION', 1 << 17);
+define('LOG_FUNCTION', 1 << 18);
+
+/**
+ * ³ÈÄ¥¥í¥°¥×¥í¥Ñ¥Æ¥£: ¥Õ¥¡¥¤¥ë̾+¹ÔÈÖ¹æɽ¼¨
+ */
+define('LOG_POS', 1 << 19);
// {{{ ethna_error_handler
*/
function ethna_error_handler($errno, $errstr, $errfile, $errline)
{
- $c =& Ethna_Controller::getInstance();
-
- list($level, $name) = Ethna_Logger::errorLevelToLogLevel($errno);
if ($errno == E_STRICT) {
// E_STRICT¤Ïɽ¼¨¤·¤Ê¤¤
return E_STRICT;
}
+ list($level, $name) = Ethna_Logger::errorLevelToLogLevel($errno);
+ switch ($errno) {
+ case E_ERROR:
+ case E_CORE_ERROR:
+ case E_COMPILE_ERROR:
+ case E_USER_ERROR:
+ $php_errno = 'Fatal error'; break;
+ case E_WARNING:
+ case E_CORE_WARNING:
+ case E_COMPILE_WARNING:
+ case E_USER_WARNING:
+ $php_errno = 'Warning'; break;
+ case E_PARSE:
+ $php_errno = 'Parse error'; break;
+ case E_NOTICE:
+ case E_USER_NOTICE:
+ $php_errno = 'Notice'; break;
+ default:
+ $php_errno = 'Unknown error'; break;
+ }
+
+ $php_errstr = sprintf('PHP %s: %s in %s on line %d', $php_errno, $errstr, $errfile, $errline);
+ if (ini_get('log_errors') && (error_reporting() & $errno)) {
+ $locale = setlocale(LC_TIME, 0);
+ setlocale(LC_TIME, 'C');
+ error_log($php_errstr, 0);
+ setlocale(LC_TIME, $locale);
+ }
+
+ $c =& Ethna_Controller::getInstance();
$logger =& $c->getLogger();
- $logger->log($level, sprintf("[PHP] %s: %s in %s on line %d", $code, $errstr, $errfile, $errline));
+ $logger->log($level, sprintf("[PHP] %s: %s in %s on line %d", $name, $errstr, $errfile, $errline));
+
+ $facility = $logger->getLogFacility();
+ if (($facility != LOG_ECHO && is_null($facility) == false) && ini_get('display_errors') && (error_reporting() & $errno)) {
+ if ($c->getCLI()) {
+ $format = "%s: %s in %s on line %d\n";
+ } else {
+ $format = "<b>%s</b>: %s in <b>%s</b> on line <b>%d</b><br />\n";
+ }
+ printf($format, $php_errno, $errstr, $errfile, $errline);
+ }
}
// }}}
'user' => array('name' => 'LOG_USER'),
'uucp' => array('name' => 'LOG_UUCP'),
'file' => array('name' => 'LOG_FILE'),
+ 'echo' => array('name' => 'LOG_ECHO'),
);
/** @var array ¥í¥°¥ì¥Ù¥ë°ìÍ÷ */
var $log_option_list = array(
'pid' => array('name' => 'PIDɽ¼¨', 'value' => LOG_PID),
'function' => array('name' => '´Ø¿ô̾ɽ¼¨', 'value' => LOG_FUNCTION),
+ 'pos' => array('name' => '¥Õ¥¡¥¤¥ë̾ɽ¼¨', 'value' => LOG_POS),
);
/** @var array ¥í¥°¥ì¥Ù¥ë¥Æ¡¼¥Ö¥ë */
/** @var int ¥í¥°¥ì¥Ù¥ë */
var $level;
+ /** @var int ¥í¥°¥Õ¥¡¥·¥ê¥Æ¥£ */
+ var $facility;
+
/** @var int ¥¢¥é¡¼¥È¥ì¥Ù¥ë */
var $alert_level;
// ̤ÀßÄê¤Ê¤éLOG_WARNING
$this->level = LOG_WARNING;
}
- $facility = $this->_parseLogFacility($config->get('log_facility'));
- $file = sprintf('%s/%s.log', $controller->getDirectory('log'), strtolower($controller->getAppid()));
+ $this->facility = $this->_parseLogFacility($config->get('log_facility'));
$option = $this->_parseLogOption($config->get('log_option'));
$this->alert_level = $this->_parseLogLevel($config->get('log_alert_level'));
$this->alert_mailaddress = preg_split('/\s*,\s*/', $config->get('log_alert_mailaddress'));
$this->message_filter_do = $config->get('log_filter_do');
$this->message_filter_ignore = $config->get('log_filter_ignore');
- if ($facility == LOG_FILE) {
- $writer_class = "Ethna_LogWriter_File";
- } else if (is_null($facility)) {
- $writer_class = "Ethna_LogWriter";
- } else {
- $writer_class = "Ethna_LogWriter_Syslog";
- }
- $this->writer =& new $writer_class($controller->getAppId(), $facility, $file, $option);
+ // LogWriter¥¯¥é¥¹¤ÎÀ¸À®
+ $file = $this->_getLogFile();
+ $this->writer =& $this->_getLogWriter($file, $option);
set_error_handler("ethna_error_handler");
}
/**
+ * ¥í¥°¥Õ¥¡¥·¥ê¥Æ¥£¤ò¼èÆÀ¤¹¤ë
+ *
+ * @access public
+ * @return int ¥í¥°¥Õ¥¡¥·¥ê¥Æ¥£
+ */
+ function getLogFacility()
+ {
+ return $this->facility;
+ }
+
+ /**
* PHP¥¨¥é¡¼¥ì¥Ù¥ë¤ò¥í¥°¥ì¥Ù¥ë¤ËÊÑ´¹¤¹¤ë
*
* @access public
}
/**
+ * ¥í¥°¥Õ¥¡¥¤¥ë¤Î½ñ¤½Ð¤·Àè¤ò¼èÆÀ¤¹¤ë(¥í¥°¥Õ¥¡¥·¥ê¥Æ¥£¤Ë
+ * LOG_FILE¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç¤Î¤ß͸ú)
+ *
+ * ¥í¥°¥Õ¥¡¥¤¥ë¤Î½ñ¤½Ð¤·Àè¤òÊѹ¹¤·¤¿¤¤¾ì¹ç¤Ï¤³¤Î¥á¥½¥Ã¥É¤ò
+ * ¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Þ¤¹
+ *
+ * @access protected
+ * @return string ¥í¥°¥Õ¥¡¥¤¥ë¤Î½ñ¤½Ð¤·Àè
+ */
+ function _getLogFile()
+ {
+ return sprintf('%s/%s.log',
+ $this->controller->getDirectory('log'),
+ strtolower($this->controller->getAppid())
+ );
+ }
+
+ /**
+ * LogWriter¥ª¥Ö¥¸¥§¥¯¥È¤ò¼èÆÀ¤¹¤ë
+ *
+ * ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¸ÇͤÎLogWriter¤òÍøÍѤ·¤¿¤¤¾ì¹ç¤Ï¤³¤Î¥á¥½¥Ã¥É¤ò
+ * ¥ª¡¼¥Ð¡¼¥é¥¤¥É¤·¤Þ¤¹
+ *
+ * @access protected
+ * @param string $file ¥í¥°¥Õ¥¡¥¤¥ë
+ * @param array $option ¥í¥°¥ª¥×¥·¥ç¥ó
+ * @return object LogWriter LogWriter¥ª¥Ö¥¸¥§¥¯¥È
+ */
+ function &_getLogWriter($file, $option)
+ {
+ if ($this->facility == LOG_FILE) {
+ $writer_class = "Ethna_LogWriter_File";
+ } else if ($this->facility == LOG_ECHO || is_null($this->facility)) {
+ $writer_class = "Ethna_LogWriter";
+ } else {
+ $writer_class = "Ethna_LogWriter_Syslog";
+ }
+ return new $writer_class($this->controller->getAppId(), $this->facility, $file, $option);
+ }
+
+ /**
* ¥í¥°¥ª¥×¥·¥ç¥ó(ÀßÄê¥Õ¥¡¥¤¥ëÃÍ)¤ò²òÀϤ¹¤ë
*
* @access private
$option |= LOG_PID;
} else if ($elt == 'function') {
$option |= LOG_FUNCTION;
+ } else if ($elt == 'pos') {
+ $option |= LOG_POS;
}
}
if (($src & 0xffff0000) == ($dst & 0xffff0000)) {
return true;
} else {
- $this->logger(LOG_NOTICE, "session IP validation failed [%s] - [%s]", $src_ip, $dst_ip);
+ $this->logger->log(LOG_NOTICE, "session IP validation failed [%s] - [%s]", $src_ip, $dst_ip);
return false;
}
}
}
/**
+ * smarty modifier:ʸ»úÎóÀÚ¤êµÍ¤á½èÍý(i18nÂбþ)
+ *
+ * sample:
+ * <code>
+ * {"ÆüËܸì¤Ç¤¹"|truncate_i18n:5:"..."}
+ * </code>
+ * <code>
+ * ÆüËÜ...
+ * </code>
+ *
+ * @param int $len ºÇÂçʸ»úÉý
+ * @param string $postfix ËöÈø¤ËÉղ乤ëʸ»úÎó
+ */
+function smarty_modifier_truncate_i18n($string, $len = 80, $postfix = "...")
+{
+ return mb_strimwidth($string, 0, $len, $postfix, 'EUC-JP');
+}
+
+/**
* smarty modifier:i18n¥Õ¥£¥ë¥¿
*
* sample:
// include_path¤ÎÀßÄê(¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥Ç¥£¥ì¥¯¥È¥ê¤òÄɲÃ)
$app = BASE . "/app";
$lib = BASE . "/lib";
-ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . implode(PATH_SEPARATOR, array"$app, $lib));
+ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . implode(PATH_SEPARATOR, array($app, $lib)));
/** ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¥é¥¤¥Ö¥é¥ê¤Î¥¤¥ó¥¯¥ë¡¼¥É */
*/
$config = array(
'debug' => false,
+ 'log_facility' => 'echo',
+ 'log_level' => 'warning',
+ 'log_option' => 'pid,function,pos',
+ 'log_alert_level' => 'crit',
+ 'log_alert_mailaddress' => '',
+ 'log_filter_do' => '',
+ 'log_filter_ignore' => 'Undefined index.*%%.*tpl',
);
?>