protected static function cacheEntityClass($classname, $reflection_classname = null) { $rc_name = $reflection_classname !== null ? $reflection_classname : $classname; $reflection = new ReflectionClass($rc_name); $annotationset = new AnnotationSet($reflection->getDocComment()); if ($reflection_classname === null) { self::$_cached_entity_classes[$classname] = array('columns' => array(), 'relations' => array(), 'foreign_columns' => array()); if (!($annotation = $annotationset->getAnnotation('Table'))) { throw new Exception("The class '{$classname}' is missing a valid @Table annotation"); } else { $tablename = $annotation->getProperty('name'); } if (!\class_exists($tablename)) { throw new Exception("The class table class '{$tablename}' for class '{$classname}' does not exist"); } self::$_cached_entity_classes[$classname]['table'] = $tablename; self::_populateCachedTableClassFiles($tablename); if (($re = $reflection->getExtension()) && ($classnames = $re->getClassNames())) { foreach ($classnames as $extends_classname) { self::cacheEntityClass($classname, $extends_classname); } } } if (!\array_key_exists('name', self::$_cached_table_classes[self::$_cached_entity_classes[$classname]['table']])) { throw new Exception("The class @Table annotation in '" . self::$_cached_entity_classes[$classname]['table'] . "' is missing required 'name' property"); } $column_prefix = self::$_cached_table_classes[self::$_cached_entity_classes[$classname]['table']]['name'] . '.'; foreach ($reflection->getProperties() as $property) { $annotationset = new AnnotationSet($property->getDocComment()); if ($annotationset->hasAnnotations()) { $property_name = $property->getName(); if ($column_annotation = $annotationset->getAnnotation('Column')) { $column_name = $column_prefix . ($column_annotation->hasProperty('name') ? $column_annotation->getProperty('name') : substr($property_name, 1)); $column = array('property' => $property_name, 'name' => $column_name, 'type' => $column_annotation->getProperty('type')); $column['not_null'] = $column_annotation->hasProperty('not_null') ? $column_annotation->getProperty('not_null') : false; if ($column_annotation->hasProperty('default_value')) { $column['default_value'] = $column_annotation->getProperty('default_value'); } if ($column_annotation->hasProperty('length')) { $column['length'] = $column_annotation->getProperty('length'); } switch ($column['type']) { case 'serializable': $column['type'] = 'serializable'; break; case 'varchar': case 'string': $column['type'] = 'varchar'; break; case 'float': $column['precision'] = $column_annotation->hasProperty('precision') ? $column_annotation->getProperty('precision') : 2; case 'integer': $column['auto_inc'] = $column_annotation->hasProperty('auto_increment') ? $column_annotation->getProperty('auto_increment') : false; $column['unsigned'] = $column_annotation->hasProperty('unsigned') ? $column_annotation->getProperty('unsigned') : false; if (!isset($column['length'])) { $column['length'] = 10; } if ($column['type'] != 'float' && !isset($column['default_value'])) { $column['default_value'] = 0; } break; } self::$_cached_entity_classes[$classname]['columns'][$column_name] = $column; if ($annotationset->hasAnnotation('Id')) { self::$_cached_entity_classes[$classname]['id_column'] = $column_name; } } if ($annotation = $annotationset->getAnnotation('Relates')) { $value = $annotation->getProperty('class'); $collection = (bool) $annotation->getProperty('collection'); $manytomany = (bool) $annotation->getProperty('manytomany'); $joinclass = $annotation->getProperty('joinclass'); $foreign_column = $annotation->getProperty('foreign_column'); $orderby = $annotation->getProperty('orderby'); $f_column = $annotation->getProperty('column'); self::$_cached_entity_classes[$classname]['relations'][$property_name] = array('collection' => $collection, 'property' => $property_name, 'foreign_column' => $foreign_column, 'manytomany' => $manytomany, 'joinclass' => $joinclass, 'class' => $annotation->getProperty('class'), 'column' => $f_column, 'orderby' => $orderby); if (!$collection) { if (!$column_annotation || !isset($column)) { throw new Exception("The property '{$property_name}' in class '{$classname}' is missing an @Column annotation, or is improperly marked as not being a collection"); } $column_name = $column_prefix . ($annotation->hasProperty('name') ? $annotation->getProperty('name') : substr($property_name, 1)); $column['class'] = self::getCachedB2DBTableClass($value); $column['key'] = $annotation->hasProperty('key') ? $annotation->getProperty('key') : null; self::$_cached_entity_classes[$classname]['foreign_columns'][$column_name] = $column; } } } } if (!self::$_debug_mode) { self::storeCachedEntityClass($classname); } }
protected function loadModuleAnnotationRoutes($classname, $module) { if (!class_exists($classname)) { return; } $internal = Context::isInternalModule($module); $reflection = new \ReflectionClass($classname); $docblock = $reflection->getDocComment(); $annotationset = new AnnotationSet($docblock); $route_url_prefix = ''; $route_name_prefix = ''; $default_route_name_prefix = $internal ? '' : $module . '_'; if ($annotationset->hasAnnotation('Routes')) { $routes = $annotationset->getAnnotation('Routes'); if ($routes->hasProperty('url_prefix')) { $route_url_prefix = $routes->getProperty('url_prefix'); } if ($routes->hasProperty('name_prefix')) { $route_name_prefix = $routes->getProperty('name_prefix', $default_route_name_prefix); } } else { $route_name_prefix = $default_route_name_prefix; } foreach ($reflection->getMethods() as $method) { $annotationset = new AnnotationSet($method->getDocComment()); if ($annotationset->hasAnnotation('Route')) { if (substr($method->name, 0, 3) != 'run') { throw new exceptions\InvalidRouteException('A @Route annotation can only be used on methods prefixed with "run"'); } $options = array(); $route_annotation = $annotationset->getAnnotation('Route'); $action = substr($method->name, 3); $name = $route_name_prefix . ($route_annotation->hasProperty('name') ? $route_annotation->getProperty('name') : strtolower($action)); $route = $route_url_prefix . $route_annotation->getProperty('url'); $options['csrf_enabled'] = $annotationset->hasAnnotation('CsrfProtected'); $options['anonymous_route'] = $annotationset->hasAnnotation('AnonymousRoute'); $http_methods = $route_annotation->getProperty('methods', array()); $params = $annotationset->hasAnnotation('Parameters') ? $annotationset->getAnnotation('Parameters')->getProperties() : array(); if ($annotationset->hasAnnotation('Overrides')) { $name = $annotationset->getAnnotation('Overrides')->getProperty('name'); $this->overrideRoute($name, $module, $action); } elseif ($this->hasRoute($name)) { throw new exceptions\RoutingException('A route that overrides another route must have an @Override annotation'); } else { $this->addRoute($name, $route, $module, $action, $params, $options, $http_methods); } } } }