Esempio n. 1
0
 public function __construct()
 {
     $c = get_class($this);
     if (!isset(self::$_m[$c])) {
         self::$_m[$c] = \ebi\Annotation::get_class($c, 'var', null, __CLASS__);
     }
     if (method_exists($this, '__init__')) {
         $args = func_get_args();
         call_user_func_array([$this, '__init__'], $args);
     }
 }
Esempio n. 2
0
 public static function parse($varname, $doc)
 {
     $result = [];
     if (preg_match_all("/@" . $varname . "\\s+([^\\s]+)\\s+\\\$(\\w+)(.*)/", $doc, $m)) {
         foreach (array_keys($m[2]) as $n) {
             $summary = $m[3][$n];
             $opt = [];
             if (strpos($summary, '@[') !== false) {
                 list($summary, $anon) = explode('@[', $summary, 2);
                 $opt = \ebi\Annotation::activation('@[' . $anon);
             }
             $result[] = new static($m[2][$n], $m[1][$n], $summary, $opt);
         }
     }
     return $result;
 }
Esempio n. 3
0
 /**
  * 前処理、入力値のバリデーションやログイン処理を行う
  * __before__メソッドを定義することで拡張する
  */
 public function before()
 {
     list(, $method) = explode('::', $this->get_selected_pattern()['action']);
     $annon = \ebi\Annotation::get_method(get_class($this), $method, ['http_method', 'request', 'user_role']);
     if (isset($annon['http_method']['value']) && strtoupper($annon['http_method']['value']) != \ebi\Request::method()) {
         throw new \ebi\exception\BadMethodCallException('Method Not Allowed');
     }
     if (isset($annon['request'])) {
         foreach ($annon['request'] as $k => $an) {
             if (isset($an['type'])) {
                 try {
                     \ebi\Validator::type($k, $this->in_vars($k), $an);
                 } catch (\ebi\exception\InvalidArgumentException $e) {
                     \ebi\Exceptions::add($e, $k);
                 }
                 \ebi\Validator::value($k, $this->in_vars($k), $an);
             }
         }
     }
     \ebi\Exceptions::throw_over();
     if (method_exists($this, '__before__')) {
         $this->__before__();
     }
     if ($this->has_object_plugin('before_flow_action_request')) {
         /**
          * 前処理
          * @param \ebi\flow\Request $arg1
          */
         $this->call_object_plugin_funcs('before_flow_action_request', $this);
     }
     if (!$this->is_user_logged_in() && (isset($this->login_anon) || $this->has_object_plugin('login_condition'))) {
         $this->login_required();
     }
     if ($this->is_user_logged_in() && (isset($annon['user_role']) || isset($this->login_anon['user_role']))) {
         if (!in_array(\ebi\UserRole::class, \ebi\Util::get_class_traits(get_class($this->user()))) || isset($this->login_anon['user_role']) && !in_array($this->login_anon['user_role'], $this->user()->get_role()) || isset($annon['user_role']['value']) && !in_array($annon['user_role']['value'], $this->user()->get_role())) {
             throw new \ebi\exception\NotPermittedException();
         }
     }
 }
Esempio n. 4
0
 private static function automap($url, $class, $name, $idx)
 {
     $result = [];
     try {
         $r = new \ReflectionClass(str_replace('.', '\\', $class));
         $d = substr($r->getFilename(), 0, -4);
         foreach ($r->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) {
             if (!$m->isStatic() && substr($m->getName(), 0, 1) != '_') {
                 $suffix = '';
                 $auto_anon = \ebi\Annotation::get_method($r->getName(), $m->getName(), 'automap');
                 if (is_array($auto_anon)) {
                     $base_name = $m->getName();
                     if (isset($auto_anon['suffix'])) {
                         $suffix = $auto_anon['suffix'];
                         unset($auto_anon['suffix']);
                     }
                     if (isset($auto_anon['name'])) {
                         $base_name = $auto_anon['name'];
                         unset($auto_anon['name']);
                     }
                     $murl = $url . ($m->getName() == 'index' ? '' : ($url == '' ? '' : '/') . $base_name) . str_repeat('/(.+)', $m->getNumberOfRequiredParameters());
                     $result[$murl . $suffix] = ['name' => $name . '/' . $base_name, 'action' => $class . '::' . $m->getName(), '@' => $d, 'idx' => $idx];
                     if (!empty($auto_anon)) {
                         $result[$murl . $suffix] = array_merge($result[$murl . $suffix], $auto_anon);
                     }
                 }
             }
         }
     } catch (\ReflectionException $e) {
         throw new \ebi\exception\InvalidArgumentException($class . ' not found');
     }
     return $result;
 }
Esempio n. 5
0
 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_];
 }
Esempio n. 6
0
 /**
  * クラスのドキュメント
  * @param string $class
  */
 public static function class_info($class)
 {
     $info = new \ebi\Dt\DocInfo();
     $r = new \ReflectionClass(self::get_class_name($class));
     if ($r->getFilename() === false || !is_file($r->getFileName())) {
         throw new \ebi\exception\InvalidArgumentException('`' . $class . '` file not found.');
     }
     $src = self::get_reflection_source($r);
     $document = self::trim_doc($r->getDocComment());
     $info->name($r->getName());
     $info->document(trim(preg_replace('/@.+/', '', $document)));
     $info->set_opt('filename', $r->getFileName());
     $info->set_opt('extends', $r->getParentClass() === false ? null : $r->getParentClass()->getName());
     $info->set_opt('abstract', $r->isAbstract());
     $see = [];
     if (preg_match_all("/@see\\s+([\\w\\.\\:\\\\]+)/", $document, $m)) {
         foreach ($m[1] as $v) {
             $v = trim($v);
             if (strpos($v, '://') !== false) {
                 $see[$v] = ['type' => 'url', 'url' => $v];
             } else {
                 if (strpos($v, '::') !== false) {
                     list($class, $method) = explode('::', 2);
                     $see[$v] = ['type' => 'method', 'class' => $class, 'method' => $method];
                 } else {
                     if (substr($v, -1) != ':') {
                         $see[$v] = ['type' => 'class', 'class' => $class];
                     }
                 }
             }
         }
     }
     $methods = [];
     foreach ($r->getMethods() as $method) {
         if (substr($method->getName(), 0, 1) != '_' && $method->isPublic() && !$method->isStatic()) {
             $ignore = ['getIterator'];
             if (!in_array($method->getName(), $ignore)) {
                 $method_document = self::get_method_document($method);
                 list($desc) = explode(PHP_EOL, trim(preg_replace('/@.+/', '', $method_document)));
                 $method_info = new \ebi\Dt\DocInfo();
                 $method_info->name($method->getName());
                 $method_info->document($desc);
                 $methods[] = $method_info;
             }
         }
     }
     $info->set_opt('methods', $methods);
     $properties = [];
     $anon = \ebi\Annotation::get_class(self::get_class_name($class), 'var', 'summary');
     $is_obj = $r->isSubclassOf(\ebi\Object::class);
     foreach ($r->getProperties() as $prop) {
         if ($prop->isPublic() || $is_obj && $prop->isProtected()) {
             $name = $prop->getName();
             if ($name[0] != '_' && !$prop->isStatic()) {
                 $properties[$name] = new \ebi\Dt\DocParam($name, isset($anon[$name]['type']) ? $anon[$name]['type'] : 'mixed', isset($anon[$name]['summary']) ? $anon[$name]['summary'] : null, ['hash' => $prop->isPublic() || !(isset($anon[$name]['hash']) && $anon[$name]['hash'] === false)]);
             }
         }
     }
     $info->set_opt('properties', $properties);
     $config_list = [];
     foreach (["/Conf::gets\\(([\"\\'])(.+?)\\1/" => 'mixed[]', "/Conf::get\\(([\"\\'])(.+?)\\1/" => 'mixed', "/self::get_self_conf_get\\(([\"\\'])(.+?)\\1/" => 'mixed'] as $preg => $default_type) {
         if (preg_match_all($preg, $src, $m, PREG_OFFSET_CAPTURE)) {
             foreach ($m[2] as $k => $v) {
                 // 呼び出しが重複したら先にドキュメントがあった方
                 if (!array_key_exists($v[0], $config_list) || !$config_list[$v[0]]->has_params()) {
                     $conf_info = \ebi\Dt\DocInfo::parse($v[0], $src, $m[0][$k][1]);
                     $conf_info->set_opt('def', \ebi\Conf::exists($r->getName(), $v[0]));
                     if (!$conf_info->has_params()) {
                         $conf_info->add_params(new \ebi\Dt\DocParam('val', $default_type));
                     }
                     $config_list[$v[0]] = $conf_info;
                 }
             }
         }
     }
     ksort($config_list);
     $info->set_opt('config_list', $config_list);
     $call_plugins = [];
     foreach (["/->get_object_plugin_funcs\\(([\"\\'])(.+?)\\1/", "/->call_object_plugin_funcs\\(([\"\\'])(.+?)\\1/", "/::call_class_plugin_funcs\\(([\"\\'])(.+?)\\1/", "/->call_object_plugin_func\\(([\"\\'])(.+?)\\1/", "/::call_class_plugin_func\\(([\"\\'])(.+?)\\1/"] as $preg) {
         if (preg_match_all($preg, $src, $m, PREG_OFFSET_CAPTURE)) {
             foreach ($m[2] as $k => $v) {
                 $call_plugins[$v[0]] = \ebi\Dt\DocInfo::parse($v[0], $src, $m[0][$k][1]);
                 $call_plugins[$v[0]]->set_opt('added', []);
             }
         }
     }
     $traits = [];
     $parent = new \ReflectionClass($r->getName());
     do {
         $traits = array_merge($traits, $parent->getTraitNames());
         if (($parent = $parent->getParentClass()) === false) {
             break;
         }
     } while (true);
     if (in_array('ebi\\Plugin', $traits)) {
         foreach (\ebi\Conf::get_class_plugin($r->getName()) as $o) {
             $pr = new \ReflectionClass(is_object($o) ? get_class($o) : $o);
             foreach ($pr->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) {
                 foreach (array_keys($call_plugins) as $method_name) {
                     if ($m->getName() == $method_name) {
                         $added = $call_plugins[$method_name]->opt('added');
                         $added[] = $pr->getName();
                         $call_plugins[$method_name]->set_opt('added', $added);
                     }
                 }
             }
         }
     }
     $info->set_opt('plugins', $call_plugins);
     return $info;
 }