/** * コンストラクタ * @param string{} $def 接続情報 [type,host,name,port,user,password,sock,encode,timezone] */ public function __construct(array $def = []) { if (empty($def)) { /** * @param string{} $connection デフォルトの接続情報 [type,host,name,port,user,password,sock,encode,timezone] */ $def = \ebi\Conf::gets('connection'); } $type = isset($def['type']) ? $def['type'] : null; $host = isset($def['host']) ? $def['host'] : null; $dbname = isset($def['name']) ? $def['name'] : null; $port = isset($def['port']) ? $def['port'] : null; $user = isset($def['user']) ? $def['user'] : null; $password = isset($def['password']) ? $def['password'] : null; $sock = isset($def['sock']) ? $def['sock'] : null; $encode = isset($def['encode']) ? $def['encode'] : null; $timezone = isset($def['timezone']) ? $def['timezone'] : null; if (empty($type)) { $type = \ebi\SqliteConnector::type(); } if (empty($encode)) { $encode = 'utf8'; } try { $type = \ebi\Util::get_class_name($type); } catch (\InvalidArgumentException $e) { throw new \ebi\exception\ConnectionException('could not find connector `' . $type . '`'); } $r = new \ReflectionClass($type); $this->dbname = $dbname; $this->connector = $r->newInstanceArgs([$encode, $timezone]); if (!$this->connector instanceof \ebi\DbConnector) { throw new \ebi\exception\ConnectionException('must be an instance of \\ebi\\DbConnector'); } if (self::$autocommit === null) { /** * @param boolean $autocommit オートコミットを行うかの真偽値 */ self::$autocommit = \ebi\Conf::get('autocommit', false); } $this->connection = $this->connector->connect($this->dbname, $host, $port, $user, $password, $sock, self::$autocommit); if (empty($this->connection)) { throw new \ebi\exception\ConnectionException('connection fail ' . $this->dbname); } if (self::$autocommit !== true) { $this->connection->beginTransaction(); } }
/** * アプリケーションを実行する * @param mixed{} $map */ public static function app($map = []) { if (empty($map)) { $map = ['patterns' => ['' => ['action' => 'ebi.Dt', 'mode' => 'local']]]; } else { if (is_string($map)) { $map = ['patterns' => ['' => ['action' => $map]]]; } else { if (is_array($map) && !isset($map['patterns'])) { $map = ['patterns' => $map]; } } } if (!isset($map['patterns']) || !is_array($map['patterns'])) { throw new \ebi\exception\InvalidArgumentException('patterns not found'); } $entry_file = null; foreach (debug_backtrace(false) as $d) { if ($d['file'] !== __FILE__) { $entry_file = basename($d['file']); break; } } /** * @param string $val アプリケーションURL、末尾が * = 実行エントリ, ** = エントリファイル名(*.php) */ $app_url = \ebi\Conf::get('app_url'); if (is_array($app_url)) { if (isset($app_url[$entry_file])) { $app_url = $app_url[$entry_file]; } else { if (isset($app_url['*'])) { $app_url = $app_url['*']; } else { $app_url = null; } } } self::$app_url = $app_url; /** * @param string $val メディアファイルのベースURL * http://localhost:8000/resources/media */ self::$media_url = \ebi\Conf::get('media_url'); if (empty(self::$app_url)) { $host = \ebi\Request::host(); self::$app_url = (empty($host) ? 'http://localhost:8000/' : $host . '/') . $entry_file; } else { if (substr(self::$app_url, -1) == '*') { self::$app_url = substr(self::$app_url, 0, -1); self::$app_url = substr(self::$app_url, -1) == '*' ? substr(self::$app_url, 0, -1) . $entry_file : self::$app_url . substr($entry_file, 0, -4); } } self::$app_url = \ebi\Util::path_slash(str_replace('https://', 'http://', self::$app_url), null, true); if (empty(self::$media_url)) { $media_path = preg_replace('/\\/[^\\/]+\\.php[\\/]$/', '/', self::$app_url); self::$media_url = $media_path . 'resources/media/'; } self::$media_url = \ebi\Util::path_slash(self::$media_url, null, true); /** * @param string $val テンプレートファイルのディレクトリ */ self::$template_path = \ebi\Util::path_slash(\ebi\Conf::get('template_path', \ebi\Conf::resource_path('templates')), null, true); $automap_idx = 1; $selfmap = ['patterns' => self::expand_patterns('', $map['patterns'], [], $automap_idx)]; unset($map['patterns']); $selfmap = array_merge($selfmap, $map); self::$workgroup = array_key_exists('workgroup', $selfmap) ? $selfmap['workgroup'] : basename($entry_file, '.php'); /** * @param boolean $val HTTPSを有効にするか,falseの場合、mapのsecureフラグもすべてfalseとなる */ $conf_secure = \ebi\Conf::get('secure'); $map_secure = array_key_exists('secure', $selfmap) && $selfmap['secure'] === true; $is_secure_pattern_func = function ($pattern) use($conf_secure, $map_secure) { if ($conf_secure === false) { return false; } if (array_key_exists('secure', $pattern)) { return $pattern['secure'] === true; } return $map_secure == true; }; $https = str_replace('http://', 'https://', self::$app_url); $url_format_func = function ($url, $pattern) use($https, $is_secure_pattern_func) { $num = 0; $format = \ebi\Util::path_absolute($is_secure_pattern_func($pattern) ? $https : self::$app_url, empty($url) ? '' : substr(preg_replace_callback("/([^\\\\])(\\(.*?[^\\\\]\\))/", function ($n) { return $n[1] . '%s'; }, ' ' . $url, -1, $num), 1)); return [str_replace(['\\\\', '\\.', '_ESC_'], ['_ESC_', '.', '\\'], $format), $num]; }; foreach ($selfmap['patterns'] as $k => $v) { list($selfmap['patterns'][$k]['format'], $selfmap['patterns'][$k]['num']) = $url_format_func($k, $v); } krsort($selfmap['patterns']); if (self::$is_get_map) { self::$is_get_map = false; self::$map = $selfmap; return; } $pathinfo = preg_replace("/(.*?)\\?.*/", "\\1", isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : ''); if (preg_match('/^\\/' . preg_quote(self::$package_media_url, '/') . '\\/(\\d+)\\/(.+)$/', $pathinfo, $m)) { foreach ($selfmap['patterns'] as $p) { if (isset($p['@']) && isset($p['idx']) && (int) $p['idx'] === (int) $m[1] && is_file($file = $p['@'] . '/resources/media/' . $m[2])) { \ebi\HttpFile::attach($file); } } \ebi\HttpHeader::send_status(404); return self::terminate(); } foreach ($selfmap['patterns'] as $k => $pattern) { if (preg_match('/^' . (empty($k) ? '' : '\\/') . str_replace(['\\/', '/', '@#S'], ['@#S', '\\/', '\\/'], $k) . '[\\/]{0,1}$/', $pathinfo, $param_arr)) { if ($is_secure_pattern_func($pattern)) { if (substr(\ebi\Request::current_url(), 0, 5) === 'http:' && (!isset($_SERVER['HTTP_X_FORWARDED_HOST']) || isset($_SERVER['HTTP_X_FORWARDED_PORT']) && $_SERVER['HTTP_X_FORWARDED_PORT'] != 443 || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] != 'https')) { header('Location: ' . preg_replace('/^.+(:\\/\\/.+)$/', 'https\\1', \ebi\Request::current_url())); exit; } self::$media_url = str_replace('http://', 'https://', self::$media_url); } self::$template = new \ebi\Template(); try { $funcs = $class = $method = $template = $ins = null; $exception = null; $has_flow_plugin = false; $result_vars = $plugins = []; $accept_debug = \ebi\Conf::get('accept_debug', false) && strpos(strtolower((new \ebi\Env())->get('HTTP_ACCEPT')), 'application/debug') !== false; array_shift($param_arr); if (array_key_exists('action', $pattern)) { if (is_string($pattern['action'])) { list($class, $method) = explode('::', $pattern['action']); } else { if (is_callable($pattern['action'])) { $funcs = $pattern['action']; } else { throw new \ebi\exception\InvalidArgumentException($pattern['name'] . ' action invalid'); } } } foreach ($selfmap['patterns'] as $m) { self::$url_pattern[$m['name']][$m['num']] = $m['format']; if (array_key_exists('@', $pattern) && array_key_exists('@', $m) && $pattern['idx'] == $m['idx']) { list(, $mm) = explode('::', $m['action']); self::$selected_class_pattern[$mm][$m['num']] = ['format' => $m['format'], 'name' => $m['name']]; } } if (array_key_exists('vars', $selfmap) && is_array($selfmap['vars'])) { $result_vars = $selfmap['vars']; } if (array_key_exists('vars', $pattern) && is_array($pattern['vars'])) { $result_vars = array_merge($result_vars, $pattern['vars']); } if (array_key_exists('redirect', $pattern)) { self::map_redirect($pattern['redirect'], $result_vars, $pattern); } foreach (array_merge(array_key_exists('plugins', $selfmap) ? is_array($selfmap['plugins']) ? $selfmap['plugins'] : [$selfmap['plugins']] : [], array_key_exists('plugins', $pattern) ? is_array($pattern['plugins']) ? $pattern['plugins'] : [$pattern['plugins']] : []) as $m) { $o = \ebi\Util::strtoinstance($m); self::set_class_plugin($o); $plugins[] = $o; } if (!isset($funcs) && isset($class)) { $ins = \ebi\Util::strtoinstance($class); $traits = \ebi\Util::get_class_traits(get_class($ins)); if ($has_flow_plugin = in_array('ebi\\FlowPlugin', $traits)) { foreach ($ins->get_flow_plugins() as $m) { $o = \ebi\Util::strtoinstance($m); $plugins[] = $o; self::set_class_plugin($o); } $ins->set_pattern($pattern); } if (in_array('ebi\\Plugin', $traits)) { foreach ($plugins as $o) { $ins->set_object_plugin($o); } } $funcs = [$ins, $method]; } foreach ($plugins as $o) { self::$template->set_object_plugin($o); } if (self::has_class_plugin('before_flow_action')) { /** * 前処理 */ self::call_class_plugin_funcs('before_flow_action'); } if ($has_flow_plugin) { $ins->before(); $before_redirect = $ins->get_before_redirect(); if (isset($before_redirect)) { self::map_redirect($before_redirect, $result_vars, $pattern); } } if (isset($funcs)) { try { $action_result_vars = call_user_func_array($funcs, $param_arr); if (is_array($action_result_vars)) { $result_vars = array_merge($result_vars, $action_result_vars); } } catch (\Exception $exception) { } } if ($has_flow_plugin) { $ins->after(); $template_block = $ins->get_template_block(); if (!empty($template_block)) { self::$template->put_block(\ebi\Util::path_absolute(self::$template_path, $ins->get_template_block())); } $template = $ins->get_template(); if (!empty($template)) { $pattern['template'] = $template; } $result_vars = array_merge($result_vars, $ins->get_after_vars()); $after_redirect = $ins->get_after_redirect(); if (isset($after_redirect) && !array_key_exists('after', $pattern) && !array_key_exists('cond_after', $pattern)) { $pattern['after'] = $after_redirect; } } if (self::has_class_plugin('after_flow_action')) { /** * 後処理 */ self::call_class_plugin_funcs('after_flow_action'); } if (isset($exception)) { throw $exception; } \ebi\Exceptions::throw_over(); if (!$accept_debug) { if (isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] == 'POST') { if (array_key_exists('post_cond_after', $pattern) && is_array($pattern['post_cond_after'])) { foreach ($pattern['post_cond_after'] as $cak => $cav) { if (isset($result_vars[$cak])) { self::map_redirect($cav, $result_vars, $pattern); } } } if (array_key_exists('post_after', $pattern)) { self::map_redirect($pattern['post_after'], $result_vars, $pattern); } } if (array_key_exists('cond_after', $pattern) && is_array($pattern['cond_after'])) { foreach ($pattern['cond_after'] as $cak => $cav) { if (isset($result_vars[$cak])) { self::map_redirect($cav, $result_vars, $pattern); } } } if (array_key_exists('after', $pattern)) { self::map_redirect($pattern['after'], $result_vars, $pattern); } if (array_key_exists('template', $pattern)) { if (array_key_exists('template_super', $pattern)) { self::$template->template_super(\ebi\Util::path_absolute(self::$template_path, $pattern['template_super'])); } return self::template($result_vars, $pattern, $ins, \ebi\Util::path_absolute(self::$template_path, $pattern['template'])); } else { if (isset($template)) { return self::template($result_vars, $pattern, $ins, \ebi\Util::path_absolute(self::$template_path, $template)); } else { if (array_key_exists('@', $pattern) && is_file($t = \ebi\Util::path_absolute(self::$template_path, $pattern['name']) . '.html')) { return self::template($result_vars, $pattern, $ins, $t); } else { if (array_key_exists('@', $pattern) && is_file($t = $pattern['@'] . '/resources/templates/' . preg_replace('/^.+::/', '', $pattern['action'] . '.html'))) { $app_url = $is_secure_pattern_func($pattern) ? str_replace('http://', 'https://', self::$app_url) : self::$app_url; return self::template($result_vars, $pattern, $ins, $t, $app_url . self::$package_media_url . '/' . $pattern['idx']); } else { if (array_key_exists('find_template', $selfmap) && $selfmap['find_template'] === true && is_file($t = \ebi\Util::path_absolute(self::$template_path, $pattern['name'] . '.html'))) { return self::template($result_vars, $pattern, $ins, $t); } else { if (self::has_class_plugin('flow_output')) { /** * 結果を出力する * @param mixed{} $result_vars actionで返却された変数 */ self::call_class_plugin_funcs('flow_output', $result_vars); return self::terminate(); } } } } } } } \ebi\HttpHeader::send('Content-Type', 'application/json'); print \ebi\Json::encode(['result' => \ebi\Util::to_primitive($result_vars)]); return self::terminate(); } catch (\Exception $e) { \ebi\FlowInvalid::set($e); \ebi\Dao::rollback_all(); /** * @param string[] $val ログに記録しない例外クラス名 */ if (!in_array(get_class($e), \ebi\Conf::gets('ignore_exceptions'))) { \ebi\Log::warning($e); } if (isset($pattern['error_status'])) { \ebi\HttpHeader::send_status($pattern['error_status']); } else { if (isset($selfmap['error_status'])) { \ebi\HttpHeader::send_status($selfmap['error_status']); } } if (isset($pattern['vars']) && !empty($pattern['vars']) && is_array($pattern['vars'])) { $result_vars = array_merge($result_vars, $pattern['vars']); } if (!$accept_debug) { if (isset($pattern['@']) && is_file($t = $pattern['@'] . '/resources/templates/error.html')) { $app_url = $is_secure_pattern_func($pattern) ? str_replace('http://', 'https://', self::$app_url) : self::$app_url; return self::template($result_vars, $pattern, $ins, $t, $app_url . self::$package_media_url . '/' . $pattern['idx']); } else { if (array_key_exists('error_redirect', $pattern)) { return self::map_redirect($pattern['error_redirect'], [], $pattern); } else { if (array_key_exists('error_template', $pattern)) { return self::template($result_vars, $pattern, $ins, \ebi\Util::path_absolute(self::$template_path, $pattern['error_template'])); } else { if (array_key_exists('error_redirect', $selfmap)) { return self::map_redirect($selfmap['error_redirect'], [], $pattern); } else { if (array_key_exists('error_template', $selfmap)) { return self::template($result_vars, $pattern, $ins, \ebi\Util::path_absolute(self::$template_path, $selfmap['error_template'])); } else { if (self::has_class_plugin('flow_exception')) { /** * 例外発生時の処理・出力 * @param \Exception $e 発生した例外 */ self::call_class_plugin_funcs('flow_exception', $e); return self::terminate(); } else { if (self::has_class_plugin('flow_output')) { self::call_class_plugin_funcs('flow_output', ['error' => ['message' => $e->getMessage()]]); return self::terminate(); } } } } } } } } /** * @param boolean $val Error Json出力時にException traceも出力するフラグ */ $trace = \ebi\Conf::get('exception_trace', false); $message = []; foreach (\ebi\FlowInvalid::get() as $g => $e) { $em = ['message' => $e->getMessage(), 'type' => basename(str_replace("\\", '/', get_class($e)))]; if ($trace) { $em['trace'] = $e->getTraceAsString(); } if (!empty($g)) { $em['group'] = $g; } $message[] = $em; } \ebi\HttpHeader::send('Content-Type', 'application/json'); print json_encode(['error' => $message]); return self::terminate(); } } } if (array_key_exists('nomatch_redirect', $selfmap) && strpos($selfmap['nomatch_redirect'], '://') === false) { foreach ($selfmap['patterns'] as $m) { if ($selfmap['nomatch_redirect'] == $m['name']) { self::$url_pattern[$m['name']][$m['num']] = $m['format']; break; } } self::map_redirect($selfmap['nomatch_redirect'], [], []); } \ebi\HttpHeader::send_status(404); return self::terminate(); }
public function __construct() { call_user_func_array('parent::__construct', func_get_args()); if (func_num_args() == 1) { foreach (func_get_arg(0) as $n => $v) { switch ($n) { case '_has_hierarchy_': case '_class_id_': case '_hierarchy_': $this->{$n} = $v; break; default: } } } $p = get_class($this); if (!isset($this->_class_id_)) { $this->_class_id_ = $p; } if (isset(self::$_dao_[$this->_class_id_])) { foreach (self::$_dao_[$this->_class_id_]->_has_dao_ as $name => $dao) { $this->{$name}($dao); } return; } $annotation = \ebi\Annotation::get_class($p, ['readonly', 'table']); $anon = [null, isset($annotation['table']['name']) ? $annotation['table']['name'] : null, $annotation['readonly'] !== null]; if (empty(self::$_connection_settings_)) { /** * DBの接続情報 * * `````````````````````````````````````````````````````````` * [ * 'ebi.SessionDao'=>[ // ebi.SessionDaoモデルの接続情報となります * 'type'=>'ebi.MysqlConnector', * 'name'=>'ebitest' * ], * '*'=>[ // *を指定した場合は他のパターンにマッチしたなかったもの全てがこの接続になります * 'type'=>'ebi.MysqlConnector', * 'name'=>'ebitest' * ], * ] * `````````````````````````````````````````````````````````` * * @param string{} $connection 接続情報配列 */ self::$_connection_settings_ = \ebi\Conf::gets('connection'); if (empty(self::$_connection_settings_)) { self::$_connection_settings_ = ['*' => ['host' => getcwd()]]; } } // find connection settings $findns = explode('\\', $p); while (!array_key_exists(implode('.', $findns), self::$_connection_settings_) && !empty($findns)) { array_pop($findns); } if (empty($findns) && !isset(self::$_connection_settings_['*'])) { throw new \ebi\exception\ConnectionException('could not find the connection settings `' . $p . '`'); } $anon[0] = empty($findns) ? '*' : implode('.', $findns); if (empty($anon[1])) { $table_class = $p; $parent_class = get_parent_class($p); $ref = new \ReflectionClass($parent_class); while (true) { $ref = new \ReflectionClass($parent_class); if (__CLASS__ == $parent_class || $ref->isAbstract()) { break; } $table_class = $parent_class; $parent_class = get_parent_class($parent_class); } $table_class = preg_replace("/^.*\\\\(.+)\$/", "\\1", $table_class); $anon[1] = strtolower($table_class[0]); for ($i = 1; $i < strlen($table_class); $i++) { $anon[1] .= ctype_lower($table_class[$i]) ? $table_class[$i] : '_' . strtolower($table_class[$i]); } } $db_settings = self::get_db_settings($anon[0], $p); $prefix = isset($db_settings['prefix']) ? $db_settings['prefix'] : ''; $upper = isset($db_settings['upper']) && $db_settings['upper'] === true; $lower = isset($db_settings['lower']) && $db_settings['lower'] === true; self::$_con_[get_called_class()] = self::$_connections_[$anon[0]]->connector(); $set_table_name = function ($name, $class) use($prefix, $upper, $lower) { $name = $prefix . $name; if ($upper) { $name = strtoupper($name); } else { if ($lower) { $name = strtolower($name); } } return $name; }; self::$_co_anon_[$p] = $anon; self::$_co_anon_[$p][1] = $set_table_name(self::$_co_anon_[$p][1], $p); $has_hierarchy = isset($this->_hierarchy_) ? $this->_hierarchy_ - 1 : $this->_has_hierarchy_; $root_table_alias = 't' . self::$_cnt_++; $_self_columns_ = $_where_columns_ = $_conds_ = $_join_conds_ = $_alias_ = $_has_many_conds_ = $_has_dao_ = []; $prop = $last_cond_column = []; $ref = new \ReflectionClass($this); foreach ($ref->getProperties(\ReflectionProperty::IS_PUBLIC | \ReflectionProperty::IS_PROTECTED) as $prop) { if ($prop->getName()[0] != '_' && $this->prop_anon($prop->getName(), 'extra') !== true) { $props[] = $prop->getName(); } } while (!empty($props)) { $name = array_shift($props); $anon_cond = $this->prop_anon($name, 'cond'); $column_type = $this->prop_anon($name, 'type'); if (empty($column_type)) { if ($name == 'id') { $this->prop_anon($name, 'type', 'serial', true); } else { if ($name == 'created_at' || $name == 'create_date' || $name == 'created') { $this->prop_anon($name, 'type', 'timestamp', true); $this->prop_anon($name, 'auto_now_add', true, true); } else { if ($name == 'updated_at' || $name == 'update_date' || $name == 'modified') { $this->prop_anon($name, 'type', 'timestamp', true); $this->prop_anon($name, 'auto_now', true, true); } else { if ($name == 'code') { $this->prop_anon($name, 'type', 'string', true); $this->prop_anon($name, 'auto_code_add', true, true); } } } } $column_type = $this->prop_anon($name, 'type', 'string'); } if ($this->prop_anon($name, 'type') == 'serial') { $this->prop_anon($name, 'primary', true, true); } $column = new \ebi\Column(); $column->name($name); $column->column($this->prop_anon($name, 'column', $name)); $column->column_alias('c' . self::$_cnt_++); if ($anon_cond === null) { if (ctype_upper($column_type[0]) && class_exists($column_type) && is_subclass_of($column_type, __CLASS__)) { throw new \ebi\exception\InvalidQueryException('undef ' . $name . ' annotation `cond`'); } $column->table($this->table()); $column->table_alias($root_table_alias); $column->primary($this->prop_anon($name, 'primary', false) || $column_type === 'serial'); $column->auto($column_type === 'serial'); $_alias_[$column->column_alias()] = $name; $_self_columns_[$name] = $column; } else { if (false !== strpos($anon_cond, '(')) { $is_has = class_exists($column_type) && is_subclass_of($column_type, __CLASS__); $is_has_many = $is_has && $this->prop_anon($name, 'attr') === 'a'; if ((!$is_has || $has_hierarchy > 0) && preg_match("/^(.+)\\((.*)\\)(.*)\$/", $anon_cond, $match)) { list(, $self_var, $conds_string, $has_var) = $match; $conds = []; $ref_table = $ref_table_alias = null; if (!empty($conds_string)) { foreach (explode(',', $conds_string) as $cond) { $tcc = explode('.', $cond, 3); switch (sizeof($tcc)) { case 1: $conds[] = \ebi\Column::cond_instance($tcc[0], 'c' . self::$_cnt_++, $this->table(), $root_table_alias); break; case 2: list($t, $c1) = $tcc; $ref_table = $set_table_name($t, $p); $ref_table_alias = 't' . self::$_cnt_++; $conds[] = \ebi\Column::cond_instance($c1, 'c' . self::$_cnt_++, $ref_table, $ref_table_alias); break; case 3: list($t, $c1, $c2) = $tcc; $ref_table = $set_table_name($t, $p); $ref_table_alias = 't' . self::$_cnt_++; $conds[] = \ebi\Column::cond_instance($c1, 'c' . self::$_cnt_++, $ref_table, $ref_table_alias); $conds[] = \ebi\Column::cond_instance($c2, 'c' . self::$_cnt_++, $ref_table, $ref_table_alias); break; default: throw new \ebi\exception\InvalidAnnotationException('annotation error : `' . $name . '`'); } } } if ($is_has_many) { if (empty($has_var)) { throw new \ebi\exception\InvalidAnnotationException('annotation error : `' . $name . '`'); } $dao = new $column_type(['_class_id_' => $p . '___' . self::$_cnt_++]); $_has_many_conds_[$name] = [$dao, $has_var, $self_var]; } else { if ($is_has) { if (empty($has_var)) { throw new \ebi\exception\InvalidAnnotationException('annotation error : `' . $name . '`'); } $dao = new $column_type(['_class_id_' => $p . '___' . self::$_cnt_++, '_hierarchy_' => $has_hierarchy]); $this->{$name}($dao); $_has_many_conds_[$name] = [$dao, $has_var, $self_var]; } else { if ($self_var[0] == '@') { $cond_var = null; $cond_name = substr($self_var, 1); if (strpos($cond_name, '.') !== false) { list($cond_name, $cond_var) = explode('.', $cond_name); } if (!isset($last_cond_column[$cond_name]) && in_array($cond_name, $props)) { $props[] = $name; continue; } $cond_column = clone $last_cond_column[$cond_name]; if (isset($cond_var)) { $cond_column->column($cond_var); $cond_column->column_alias('c' . self::$_cnt_++); } array_unshift($conds, $cond_column); } else { array_unshift($conds, \ebi\Column::cond_instance($self_var, 'c' . self::$_cnt_++, $this->table(), $root_table_alias)); } $column->table($ref_table); $column->table_alias($ref_table_alias); $_alias_[$column->column_alias()] = $name; if (sizeof($conds) % 2 != 0) { throw new \ebi\exception\InvalidQueryException($name . '[' . $column_type . '] is illegal condition'); } if ($this->prop_anon($name, 'join', false)) { $this->prop_anon($name, 'get', false, true); $this->prop_anon($name, 'set', false, true); for ($i = 0; $i < sizeof($conds); $i += 2) { $_join_conds_[$name][] = [$conds[$i], $conds[$i + 1]]; } } else { for ($i = 0; $i < sizeof($conds); $i += 2) { $_conds_[] = [$conds[$i], $conds[$i + 1]]; } } $_where_columns_[$name] = $column; } } if (!empty($conds)) { $cond_column = clone $conds[sizeof($conds) - 1]; $cond_column->column($column->column()); $cond_column->column_alias('c' . self::$_cnt_++); $last_cond_column[$name] = $cond_column; } } } else { if ($anon_cond[0] === '@') { $cond_name = substr($anon_cond, 1); if (in_array($cond_name, $props)) { $props[] = $name; continue; } if (isset($_self_columns_[$cond_name])) { $column->table($_self_columns_[$cond_name]->table()); $column->table_alias($_self_columns_[$cond_name]->table_alias()); } else { if (isset($_where_columns_[$cond_name])) { $column->table($_where_columns_[$cond_name]->table()); $column->table_alias($_where_columns_[$cond_name]->table_alias()); } else { throw new \ebi\exception\InvalidQueryException('undef var `' . $name . '`'); } } $_alias_[$column->column_alias()] = $name; $_where_columns_[$name] = $column; } } } } self::$_dao_[$this->_class_id_] = (object) ['_self_columns_' => $_self_columns_, '_where_columns_' => $_where_columns_, '_conds_' => $_conds_, '_join_conds_' => $_join_conds_, '_alias_' => $_alias_, '_has_dao_' => $_has_dao_, '_has_many_conds_' => $_has_many_conds_]; }
/** * @param \ebi\Log $log */ public function log_output(\ebi\Log $log) { $mail = new \ebi\Mail(); /** * @param mixed{} $arg1 メールにバインドする変数 */ $vars = \ebi\Conf::gets('vars'); /** * @param string $arg1 fromのメールアドレス */ $from = \ebi\Conf::get('from'); /** * @param string $arg1 toのメールアドレス */ $to = \ebi\Conf::get('to'); if (!empty($from)) { if (is_string($from)) { $mail->from($from); } else { if (isset($from['address'])) { $mail->from($from['address'], isset($from['name']) ? $from['name'] : null); } } } if (!empty($to)) { if (is_string($to)) { $mail->to($to); } else { if (isset($to['address'])) { $mail->to($to['address'], isset($to['name']) ? $to['name'] : null); } else { if (is_array($to)) { foreach ($to as $t) { if (isset($t['address'])) { $mail->to($t['address'], isset($t['name']) ? $t['name'] : null); } } } } } } if (!is_array($vars)) { $vars = []; } $template = ''; switch ($log->level()) { case 0: $template = 'logs/emergency.xml'; break; case 1: $template = 'logs/alert.xml'; break; case 2: $template = 'logs/critical.xml'; break; case 3: $template = 'logs/error.xml'; break; case 4: $template = 'logs/warning.xml'; break; case 5: $template = 'logs/notice.xml'; break; case 6: $template = 'logs/info.xml'; break; case 7: $template = 'logs/debug.xml'; break; } try { $mail->send_template($template, array_merge($vars, ['log' => $log, 'env' => new \ebi\Env()])); } catch (\ebi\exception\InvalidArgumentException $e) { } }
/** * ライブラリ一覧 * @return array */ public static function classes($parent_class = null, $ignore = true) { $result = []; $include_path = []; $ignore_class = []; if (is_dir(getcwd() . DIRECTORY_SEPARATOR . 'lib')) { $include_path[] = realpath(getcwd() . DIRECTORY_SEPARATOR . 'lib'); } if (class_exists('Composer\\Autoload\\ClassLoader')) { $r = new \ReflectionClass('Composer\\Autoload\\ClassLoader'); $vendor_dir = dirname(dirname($r->getFileName())); if (is_file($loader_php = $vendor_dir . DIRECTORY_SEPARATOR . 'autoload.php')) { $loader = (include $loader_php); // vendor以外の定義されているパスを探す foreach ($loader->getPrefixes() as $ns) { foreach ($ns as $path) { $path = realpath($path); if (strpos($path, $vendor_dir) === false) { $include_path[] = $path; } } } } } $valid_find_class_file = function ($f) { if (strpos($f->getPathname(), DIRECTORY_SEPARATOR . '.') === false && strpos($f->getPathname(), DIRECTORY_SEPARATOR . '_') === false && strpos($f->getPathname(), DIRECTORY_SEPARATOR . 'cmd' . DIRECTORY_SEPARATOR) === false && ctype_upper(substr($f->getFilename(), 0, 1)) && substr($f->getFilename(), -4) == '.php') { try { include_once $f->getPathname(); } catch (\Exeption $e) { } } }; foreach ($include_path as $libdir) { if ($libdir !== '.' && is_dir($libdir)) { foreach (\ebi\Util::ls($libdir, true) as $f) { $valid_find_class_file($f); } } } /** * @param string[] $vendor 利用するvendorのクラス */ $use_vendor = \ebi\Conf::gets('use_vendor'); /** * @param callback $callback 利用するvendorのクラス配列を返すメソッド */ $use_vendor_callback = \ebi\Conf::get('use_vendor_callback'); if (!empty($use_vendor_callback)) { $callback_result = call_user_func($use_vendor_callback); if (is_array($callback_result)) { $use_vendor = array_merge($use_vendor, $callback_result); } } if (is_array($use_vendor)) { foreach ($use_vendor as $class) { $find_package = false; if (substr($class, -1) == '*') { $class = substr($class, 0, -1); $find_package = true; } $class = str_replace('.', '\\', $class); if (class_exists($class)) { if ($find_package) { $r = new \ReflectionClass($class); foreach (\ebi\Util::ls(dirname($r->getFileName()), true) as $f) { $valid_find_class_file($f); } } } } } $valid_find_class = function ($r, $parent_class) { if (!$r->isInterface() && (empty($parent_class) || is_subclass_of($r->getName(), $parent_class)) && $r->getFileName() !== false && strpos($r->getName(), '_') === false && strpos($r->getName(), 'Composer') === false && strpos($r->getName(), 'cmdman') === false && strpos($r->getName(), 'testman') === false) { return true; } return false; }; foreach (get_declared_classes() as $class) { if ($valid_find_class($r = new \ReflectionClass($class), $parent_class)) { (yield ['filename' => $r->getFileName(), 'class' => '\\' . $r->getName()]); } } }