コード例 #1
0
ファイル: Select_Controller.php プロジェクト: TuxBoy/Demo-saf
 /**
  * @param $class                   Reflection_Class
  * @param $composite_class_name    string
  * @return Reflection_Property_Value[]
  */
 protected function getProperties(Reflection_Class $class, $composite_class_name = null)
 {
     $properties = [];
     if (isset($composite_class_name) && isA($class->name, Component::class)) {
         $composite_property = call_user_func([$class->name, 'getCompositeProperties'], $composite_class_name);
         $composite_property = reset($composite_property);
     } else {
         $composite_property = null;
     }
     if ($class->getAnnotation('link')->value) {
         $link_class = new Link_Class($class->name);
         $composite_link_property = $link_class->getCompositeProperty();
         foreach ($link_class->getProperties([T_EXTENDS, T_USE]) as $property) {
             if ((!$composite_property || $property->name !== $composite_property->name) && (!$composite_link_property || $property->name !== $composite_link_property->name) && !$property->isStatic() && !$property->getListAnnotation('user')->has(User_Annotation::INVISIBLE)) {
                 $properties[] = $property;
             }
         }
     } else {
         foreach ($class->getProperties([T_EXTENDS, T_USE]) as $property) {
             if ((empty($composite_property) || $property->name !== $composite_property->name) && !$property->isStatic() && !$property->getListAnnotation('user')->has(User_Annotation::INVISIBLE)) {
                 $properties[] = $property;
             }
         }
     }
     return $properties;
 }
コード例 #2
0
ファイル: Remover_Tool.php プロジェクト: TuxBoy/Demo-saf
 /**
  * Default remover removes an object from all collections properties of the object
  *
  * @param $composite object The object that contains the given object
  * @param $object    object contained object to remove
  * @return integer removed instances count
  */
 public static function removeObjectFromComposite($composite, $object)
 {
     $count = 0;
     foreach ((new Reflection_Class(get_class($composite)))->accessProperties() as $property) {
         $type = $property->getType();
         if ($type->isClass() && isA($object, $type->getElementTypeAsString())) {
             $property_name = $property->name;
             if ($type->isMultiple()) {
                 $remover = $property->getAnnotation('remover');
                 if ($remover->value) {
                     $count += call_user_func([$composite, $remover->value], $object);
                 } else {
                     foreach ($composite->{$property_name} as $key => $value) {
                         if ($value === $object) {
                             unset($composite->{$property_name}[$key]);
                             $count++;
                         }
                     }
                 }
             } elseif ($property->getValue($composite) === $object) {
                 unset($composite->{$property_name});
                 $count++;
             }
         }
     }
     return $count;
 }
コード例 #3
0
ファイル: Call_Stack.php プロジェクト: TuxBoy/Demo-saf
 /**
  * Get top object that is an instance of $class_name from the call stack
  *
  * @param $class_name string Can be a the name of a class, interface or trait
  * @return object|null
  */
 public function getObject($class_name)
 {
     foreach ($this->stack as $stack) {
         if (isset($stack['object']) && isA($stack['object'], $class_name)) {
             return $stack['object'];
         }
     }
     return null;
 }
コード例 #4
0
ファイル: Has_Counter.php プロジェクト: TuxBoy/Demo-saf
 /**
  * @before SAF\Framework\Dao\Data_Link::write($this)
  */
 public function setNumber()
 {
     if (isA($this, Has_Counter::class)) {
         /** @var $counter Counter */
         $counter = Dao::searchOne(['class_name' => get_class($this)], Counter::class);
         if (!isset($counter)) {
             $counter = Builder::create(Counter::class, [get_class($this)]);
         }
         $this->setCounter($counter->increment());
     }
 }
コード例 #5
0
ファイル: Link_Annotation.php プロジェクト: TuxBoy/Demo-saf
 /**
  * Guess value for @link using the type of the property (@var)
  * - property is a Date_Time (or a child class) : @link will be 'DateTime'
  * - property is a single object : @link will be 'Object'
  * - property is a collection object with '@var Object[] All' : @link will be 'All'
  * - property is a collection object with '@var Object[] Collection' : @link will be 'Collection'
  * - property is a collection object with '@var Object[] Map' : @link will be 'Map'
  * - property is a collection object without telling anything :
  *   - @link will be 'Collection' if the object is a Component
  *   - @link will be 'Map' if the object is not a Component
  *
  * @param $property Reflection_Property
  * @return string returned guessed value for @link
  */
 private function guessValue(Reflection_Property $property)
 {
     if ($property->getType()->isMultiple()) {
         /** @var $var_annotation Var_Annotation */
         $value = lParse($property->getAnnotation('var'), SP);
         if (empty($value)) {
             $value = isA($property->getType()->getElementTypeAsString(), Component::class) ? self::COLLECTION : self::MAP;
         }
     } else {
         $value = isA($property->getType()->asString(), Date_Time::class) ? self::DATETIME : self::OBJECT;
     }
     return $value;
 }
コード例 #6
0
ファイル: Component.php プロジェクト: TuxBoy/Demo-saf
 /**
  * Default disposer call the remove
  *
  * @param $class_name    string|object The composite class name or object
  * @param $property_name string The composite property name
  */
 public function dispose($class_name = null, $property_name = null)
 {
     foreach (self::getCompositeProperties($class_name, $property_name) as $property) {
         $composite = $property->getValue($this);
         if (isset($composite)) {
             if (isA($composite, Remover::class)) {
                 /** @var $composite Remover */
                 $composite->remove($this);
             } else {
                 Remover_Tool::removeObjectFromComposite($composite, $this);
             }
         }
     }
 }
コード例 #7
0
ファイル: Getter.php プロジェクト: TuxBoy/Demo-saf
 /**
  * Generic getter for a collection of objects
  *
  * @param $stored     Component[] Actual value of the property (will be returned if not null)
  * @param $class_name string Class for each collection's object
  * @param $object     object Parent object
  * @param $property   string|Reflection_Property Parent property (or property name). Recommended
  *        but can be omitted if foreign class is a Component
  * @return object[]
  */
 public static function &getCollection(&$stored, $class_name, $object, $property = null)
 {
     if (!(self::$ignore || isset($stored))) {
         if (Dao::getObjectIdentifier($object)) {
             $search_element = Search_Object::create($class_name);
             $is_component = isA($search_element, Component::class);
             if (isset($property)) {
                 if (!$property instanceof Reflection_Property) {
                     $property = new Reflection_Property(get_class($object), $property);
                 }
                 $property_name = $property->getAnnotation('foreign')->value;
                 $dao = ($dao = $property->getAnnotation('dao')->value) ? Dao::get($dao) : Dao::current();
             } else {
                 $dao = Dao::current();
                 $property_name = null;
             }
             if ($is_component) {
                 /** @var $search_element Component */
                 $search_element->setComposite($object, $property_name);
                 $link_properties_names = (new Link_Class($class_name))->getLinkPropertiesNames();
                 $options = $link_properties_names ? [Dao::sort(), Dao::key($link_properties_names)] : [Dao::sort()];
                 $stored = $dao->search($search_element, null, $options);
             } elseif (!empty($property_name)) {
                 $property = new Reflection_Property(get_class($search_element), $property_name);
                 $accessible = $property->isPublic();
                 if (!$accessible) {
                     $property->setAccessible(true);
                 }
                 $property->setValue($search_element, $object);
                 if (!$accessible) {
                     $property->setAccessible(false);
                 }
                 $stored = $dao->search($search_element, null, [Dao::sort()]);
             } else {
                 trigger_error('getCollection() must be called for a component foreign type' . ' or with a parent property name', E_USER_ERROR);
             }
         }
         if (!isset($stored)) {
             $stored = [];
         }
     }
     return $stored;
 }
コード例 #8
0
ファイル: View.php プロジェクト: TuxBoy/Demo-saf
 /**
  * @param $view             string
  * @param $view_method_name string
  * @param $parameters       array
  * @param $form             array
  * @param $files            array
  * @param $class_name       string
  * @param $feature_name     string
  * @return mixed
  */
 private static function executeView($view, $view_method_name, $parameters, $form, $files, $class_name, $feature_name)
 {
     $object = reset($parameters);
     $view_object = is_object($object) && isA($object, $view) ? reset($parameters) : Builder::create($view);
     return $view_object->{$view_method_name}($parameters, $form, $files, $class_name, $feature_name);
 }
コード例 #9
0
ファイル: Type.php プロジェクト: TuxBoy/Demo-saf
 /**
  * Returns true if the class type uses the given trait
  *
  * This goes into parents traits
  *
  * @param $trait_name string
  * @return boolean
  */
 public function usesTrait($trait_name)
 {
     return $this->isClass() && isA($this->getElementTypeAsString(), $trait_name);
 }
コード例 #10
0
ファイル: Template.php プロジェクト: TuxBoy/Demo-saf
 /**
  * Parse a variable / function / include and returns its return value
  *
  * @param $var_name  string can be an unique var or path.of.vars
  * @param $as_string boolean if true, returned value will always be a string
  * @return string|object var value after reading value / executing specs
  */
 protected function parseValue($var_name, $as_string = true)
 {
     if ($var_name === DOT) {
         return reset($this->objects);
     } elseif ($var_name == '') {
         return '';
     } elseif ($var_name[0] === SL) {
         return $this->parseInclude($var_name);
     } elseif ($var_name[0] == '!') {
         $not = true;
         $var_name = substr($var_name, 1);
     }
     if (substr($var_name, -1) == '*') {
         $group = true;
         $var_name = substr($var_name, 0, -1);
     }
     if (strpos('-+', $var_name[0]) !== false) {
         $descendants_names = $this->descendants_names;
         $descendants = $this->descendants;
         $var_names = $this->var_names;
         $objects = $this->objects;
         while ($var_name[0] === '-') {
             array_unshift($this->descendants_names, array_shift($this->var_names));
             array_unshift($this->descendants, array_shift($this->objects));
             $var_name = substr($var_name, 1);
         }
         while ($var_name[0] === '+') {
             array_unshift($this->var_names, array_shift($this->descendants_names));
             array_unshift($this->objects, array_shift($this->descendants));
             $var_name = substr($var_name, 1);
         }
     }
     $property_name = null;
     if ($var_name === DOT) {
         $object = reset($this->objects);
     } elseif (strpos($var_name, DOT) !== false) {
         $object = null;
         if (!isset($var_names)) {
             $var_names = $this->var_names;
         }
         if (!isset($objects)) {
             $objects = $this->objects;
         }
         $parenthesis = '';
         foreach (explode(DOT, $var_name) as $property_name) {
             if ($parenthesis) {
                 $property_name = $parenthesis . DOT . $property_name;
                 $parenthesis = '';
             }
             if (strpos($property_name, '(') && substr_count($property_name, '(') > substr_count($property_name, ')')) {
                 $parenthesis = $property_name;
             } else {
                 $object = $this->parseSingleValue($property_name);
                 if (strlen($property_name)) {
                     array_unshift($this->var_names, $property_name);
                     array_unshift($this->objects, $object);
                 }
             }
         }
     } else {
         $object = $this->parseSingleValue($var_name);
     }
     // if the parse value finishes with a class name : check if the last object is any of this class
     if (isset($this->parse_class_name)) {
         $object = isA(reset($this->objects), $this->parse_class_name);
         unset($this->parse_class_name);
     }
     // parse object to string
     if ($as_string && is_object($object)) {
         if ($object instanceof File) {
             $object = $this->parseFileToString(null, $object);
         } else {
             $object = $this->parseObjectToString($object, $property_name);
         }
     }
     // parse not
     if (isset($not)) {
         $object = !$object;
     }
     // restore position arrays
     if (isset($objects)) {
         $this->objects = $objects;
     }
     if (isset($var_names)) {
         $this->var_names = $var_names;
     }
     if (isset($descendants)) {
         $this->descendants = $descendants;
     }
     if (isset($descendants_names)) {
         $this->descendants_names = $descendants_names;
     }
     return isset($group) ? $this->group($var_name, $object) : $object;
 }
コード例 #11
0
ファイル: Parser.php プロジェクト: TuxBoy/Demo-saf
 /**
  * @param $doc_comment       string
  * @param $annotation_name   string
  * @param $i                 integer
  * @param $annotation_class  string
  * @param $reflection_object Has_Doc_Comment|Reflection
  * @return Annotation
  */
 private static function parseAnnotationValue($doc_comment, $annotation_name, &$i, $annotation_class, Reflection $reflection_object)
 {
     $i += strlen($annotation_name) + 1;
     $next_char = $doc_comment[$i];
     switch ($next_char) {
         case SP:
         case TAB:
             $i++;
             $j = strlen($doc_comment);
             $next_annotation = strpos($doc_comment, SP . '* @', $i);
             $end_doc_comment = strpos($doc_comment, SP . '*/', $i);
             $next_in = strpos($doc_comment, LF . self::DOC_COMMENT_IN, $i);
             if ($next_annotation !== false && $next_annotation < $j) {
                 $j = $next_annotation;
             }
             if ($end_doc_comment !== false && $end_doc_comment < $j) {
                 $j = $end_doc_comment;
             }
             if ($next_in !== false && $next_in < $j) {
                 $j = $next_in;
             }
             if ($j === false) {
                 trigger_error('Missing doc_comment end', E_USER_ERROR);
             }
             $value = trim(preg_replace('%\\s*\\n\\s+\\*\\s*%', '', substr($doc_comment, $i, $j - $i)));
             break;
         case CR:
         case LF:
             $value = true;
             break;
         default:
             $value = null;
     }
     /** @var $annotation Annotation */
     $annotation = isset($value) ? new $annotation_class($value, $reflection_object, $annotation_name) : null;
     if (isset($annotation) && isA($annotation, Annotation_In::class)) {
         /** @var $annotation Annotation_In */
         $j = strrpos(substr($doc_comment, 0, $i), LF . self::DOC_COMMENT_IN);
         if ($j === false) {
             $annotation->class_name = $reflection_object instanceof Reflection_Class_Component ? $reflection_object->getDeclaringClassName() : $reflection_object->getName();
         } else {
             $j += strlen(self::DOC_COMMENT_IN) + 1;
             $k = strpos($doc_comment, LF, $j);
             $annotation->class_name = substr($doc_comment, $j, $k - $j);
         }
     }
     if (isset($annotation) && isA($annotation, Types_Annotation::class)) {
         $do = false;
         if (is_array($annotation->value)) {
             foreach ($annotation->value as $value) {
                 if ($value && (ctype_upper($value[0]) || $value[0] == BS)) {
                     $do = true;
                     break;
                 }
             }
         } else {
             $do = $annotation->value && ctype_upper($annotation->value[0]);
         }
         if ($do) {
             /** @var $annotation Types_Annotation */
             $j = strrpos(substr($doc_comment, 0, $i), LF . self::DOC_COMMENT_IN);
             if ($j === false) {
                 $class_name = $reflection_object instanceof Reflection_Class_Component ? $reflection_object->getDeclaringClassName() : $reflection_object->getName();
                 $namespace = Namespaces::of($class_name);
                 $use = PHP\Reflection_Class::of($class_name)->getNamespaceUse();
             } else {
                 $j += strlen(self::DOC_COMMENT_IN) + 1;
                 $k = strpos($doc_comment, LF, $j);
                 $in_class = substr($doc_comment, $j, $k - $j);
                 $namespace = Namespaces::of($in_class);
                 $use = PHP\Reflection_Class::of($in_class)->getNamespaceUse();
             }
             $annotation->applyNamespace($namespace, $use);
         } elseif (is_array($annotation->value)) {
             foreach ($annotation->value as $key => $value) {
                 $annotation->value[$key] = Builder::className($value);
             }
         } else {
             if ($annotation->value[0] === BS) {
                 $annotation->value = substr($annotation->value, 1);
             }
             $annotation->value = Builder::className($annotation->value);
         }
     }
     return $annotation;
 }
コード例 #12
0
ファイル: Search_Controller.php プロジェクト: TuxBoy/Demo-saf
 /**
  * @param $class_name         string
  * @param $search             string
  * @param $exclude_properties string[]
  * @param $prefix             string
  * @param $depth              integer
  * @return Reflection_Property[]
  */
 protected function searchProperties($class_name, $search, $exclude_properties = [], $prefix = '', $depth = 0)
 {
     $class = new Reflection_Class($class_name);
     $all_properties = $this->getProperties($class);
     $first_properties = [];
     $properties = [];
     $more_properties = [];
     foreach ($all_properties as $property) {
         if (!isset($exclude_properties[$property->name])) {
             $property_path = $prefix . $property->name;
             if ($property->name == $search || $property_path == $search) {
                 $first_properties[$property_path] = $property;
                 $matches = true;
             } else {
                 preg_match('|^' . $search . '|', strtolower(strSimplify(Loc::tr($property->name), SP)), $matches);
                 preg_match('|^' . $search . '|', strtolower(strSimplify(Loc::tr($prefix . $property_path), DOT . SP)), $matches2);
                 if ($matches || $matches2) {
                     $properties[$property_path] = $property;
                     $matches = true;
                 } else {
                     preg_match('|' . $search . '|', strtolower(strSimplify(Loc::tr($property_path), DOT . SP)), $matches);
                     if ($matches) {
                         $more_properties[$property_path] = $property;
                     }
                 }
             }
             if ($depth < $this->max_depth && !$matches) {
                 $type = $property->getType();
                 if ($type->isClass()) {
                     $property_class = $type->getElementTypeAsString();
                     $is_component = isA($property_class, Component::class);
                     $exclude_sub_properties = $is_component ? call_user_func([$property_class, 'getCompositeProperties'], $class_name) : [];
                     $parent_classes[] = $class_name;
                     $sub_properties = $this->searchProperties($type->getElementTypeAsString(), $search, $exclude_sub_properties, $property->name . DOT, $depth + 1);
                     foreach ($sub_properties as $sub_property) {
                         if (!isset($exclude_properties[$sub_property->name])) {
                             $more_properties[] = new Reflection_Property($class_name, $property->name . DOT . $sub_property->path);
                         }
                     }
                 }
             }
         }
     }
     $properties = array_merge($first_properties, $properties, $more_properties);
     return $properties;
 }
コード例 #13
0
ファイル: Duplicator.php プロジェクト: TuxBoy/Demo-saf
 /**
  * @param $elements             object[]|Component[] the component objects
  * @param $composite_class_name string the composite class name
  */
 private function removeCompositeFromComponents($elements, $composite_class_name)
 {
     if (isA($element = reset($elements), Component::class)) {
         $getCompositeProperty = [get_class($element), 'getCompositeProperty'];
         if ($composite_property = call_user_func($getCompositeProperty, $composite_class_name)) {
             foreach ($elements as $element) {
                 $property_name = $composite_property->name;
                 $id_property_name = 'id_' . $property_name;
                 if (isset($element->{$property_name})) {
                     $this->dao->disconnect($element->{$property_name});
                 }
                 unset($element->{$id_property_name});
             }
         }
     }
 }
コード例 #14
0
ファイル: Reflection_Class.php プロジェクト: TuxBoy/Demo-saf
 /**
  * Returns true if the class has $name into its parents, interfaces or traits
  *
  * @param $name  string
  * @param $flags integer[] T_EXTENDS, T_IMPLEMENTS, T_USE
  * @return boolean
  */
 public function isA($name, $flags = [])
 {
     if ($flags) {
         $flip = array_flip($flags);
         if (isset($flip[T_USE]) && trait_exists($name)) {
             return isA($this->name, $name);
         } elseif (isset($flip[T_EXTENDS]) && class_exists($name) || isset($flip[T_IMPLEMENTS]) && interface_exists($name)) {
             return is_a($this->name, $name, true);
         }
     }
     return false;
 }