示例#1
0
 /**
  * @param $object object
  */
 public function createDuplicate($object)
 {
     if ($this->dao->getObjectIdentifier($object)) {
         // duplicate @link Collection and Map properties values
         $class_name = get_class($object);
         $class = new Reflection_Class($class_name);
         /** @var $link Link_Annotation */
         $link = $class->getAnnotation('link');
         $exclude_properties = $link->value ? array_keys((new Reflection_Class($link->value))->getProperties([T_EXTENDS, T_USE])) : [];
         foreach ($class->accessProperties() as $property) {
             if (!$property->isStatic() && !in_array($property->name, $exclude_properties)) {
                 $property_link = $property->getAnnotation('link')->value;
                 // @link Collection : must disconnect objects
                 // @link Collection | Map : duplicate and remove reference to the parent id
                 if (in_array($property_link, [Link_Annotation::COLLECTION, Link_Annotation::MAP])) {
                     $elements = $property->getValue($object);
                     if ($property_link == Link_Annotation::COLLECTION) {
                         foreach ($elements as $element) {
                             $this->createDuplicate($element);
                         }
                     }
                     $this->removeCompositeFromComponents($elements, $class_name);
                 }
             }
         }
         // duplicate object
         $this->dao->disconnect($object);
         // after duplicate
         $this->onDuplicate($object, $class);
     }
 }
示例#2
0
 /**
  * @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;
 }
示例#3
0
 /**
  * @param $array
  * @param $object
  * @return array
  */
 private function initLinkObject(&$array, &$object)
 {
     /** @var $link Class_\Link_Annotation */
     $link = $this->class->getAnnotation('link');
     if ($link->value) {
         $id_property_value = null;
         $linked_class_name = null;
         $link_properties = $link->getLinkProperties();
         $search = [];
         foreach ($link_properties as $property) {
             if ($property->getType()->isClass()) {
                 $property_name = $property->getName();
                 $id_property_name = 'id_' . $property_name;
                 if (isset($array[$id_property_name]) && $array[$id_property_name]) {
                     $search[$property_name] = $array[$id_property_name];
                 }
                 $property_class_name = $property->getType()->asString();
                 if (is_a($property_class_name, $link->value, true)) {
                     $id_property_value = isset($array[$id_property_name]) ? $array[$id_property_name] : null;
                     $linked_class_name = $property_class_name;
                     if (!isset($array[$id_property_name]) && !isset($array[$property_name])) {
                         $linked_array = $array;
                         foreach (array_keys($link_properties) as $link_property_name) {
                             unset($linked_array[$link_property_name]);
                         }
                         $builder = new Object_Builder_Array($property_class_name, $this->from_form);
                         $array[$property_name] = $builder->build($linked_array);
                     }
                 }
             }
         }
         if (count($search) >= 2) {
             $object = Dao::searchOne($search, $this->class->name);
         }
         if ($id_property_value && !$object) {
             $object = Builder::createClone(Dao::read($id_property_value, $linked_class_name), $this->class->name);
         }
         return $search;
     }
     return null;
 }
示例#4
0
文件: Joins.php 项目: TuxBoy/Demo-saf
 /**
  * Add a link class (using the 'link' class annotation) to joins
  *
  * @param $path               string     the property path
  * @param $class              Link_Class the link class itself (which contains the @link)
  * @param $linked_class_name  string     the linked class name (the value of @link)
  * @param $join_mode          string
  * @return Reflection_Property[] the properties that come from the linked class,
  * for further exclusion
  */
 private function addLinkedClass($path, $class, $linked_class_name, $join_mode)
 {
     $linked_class = new Reflection_Class($linked_class_name);
     $join = new Join();
     $join->master_alias = 't' . ($this->alias_counter - 1);
     $join->master_column = 'id_' . $class->getCompositeProperty($linked_class_name)->getAnnotation('storage')->value;
     $join->foreign_alias = 't' . $this->alias_counter++;
     $join->foreign_column = 'id';
     $join->foreign_class = Builder::className($linked_class_name);
     $join->foreign_table = Dao::storeNameOf($join->foreign_class);
     $join->mode = $join_mode == Join::LEFT ? Join::LEFT : Join::INNER;
     $join->type = Join::LINK;
     if (!isset($this->joins[$path])) {
         // this ensures that the main path is set before the linked path
         $this->joins[$path] = null;
     }
     $this->joins[($path ? $path . '-' : '') . $join->foreign_table . '-@link'] = $join;
     $this->id_link_joins[$path] = $join;
     $this->link_joins[$path] = $join;
     $more_linked_class_name = $linked_class->getAnnotation('link')->value;
     $exclude_properties = $more_linked_class_name ? $this->addLinkedClass($path, $class, $more_linked_class_name, $join_mode) : [];
     foreach ($linked_class->getProperties([T_EXTENDS, T_USE]) as $property) {
         if (!$property->isStatic()) {
             if (!isset($exclude_properties[$property->name])) {
                 $this->properties[$linked_class_name][$property->name] = $property;
                 $property_path = ($path ? $path . DOT : '') . $property->name;
                 $type = $property->getType();
                 if ($type->isClass()) {
                     $this->classes[$property_path] = $property->getType()->getElementTypeAsString();
                 }
                 $this->link_joins[$property_path] = $join;
                 $exclude_properties[$property->name] = true;
             }
         }
     }
     return $exclude_properties;
 }
示例#5
0
 /**
  * @return string[]
  */
 protected function getProperties()
 {
     // gets all properties from collection element class
     $class = new Reflection_Class($this->class_name);
     $properties = $class->getProperties([T_EXTENDS, T_USE]);
     // remove replaced properties
     /** @var $properties Reflection_Property[] */
     $properties = Replaces_Annotations::removeReplacedProperties($properties);
     // remove linked class properties
     $linked_class = $class->getAnnotation('link')->value;
     if ($linked_class) {
         foreach (array_keys((new Reflection_Class($linked_class))->getProperties([T_EXTENDS, T_USE])) as $property_name) {
             unset($properties[$property_name]);
         }
     }
     // remove composite property
     $property_name = $this->property->getAnnotation('foreign')->value;
     if (isset($properties[$property_name])) {
         unset($properties[$property_name]);
     }
     // remove static and user-invisible properties
     foreach ($properties as $property_name => $property) {
         if ($property->isStatic() || $property->getListAnnotation('user')->has(User_Annotation::INVISIBLE)) {
             unset($properties[$property_name]);
         }
     }
     // returns properties
     return $properties;
 }
示例#6
0
文件: Link.php 项目: TuxBoy/Demo-saf
 /**
  * Delete an object from current data link
  *
  * If object was originally read from data source, matching data will be overwritten.
  * If object was not originally read from data source, nothing is done and returns false.
  *
  * @param $object object object to delete from data source
  * @return boolean true if deleted
  * @see Data_Link::delete()
  */
 public function delete($object)
 {
     $will_delete = true;
     foreach ((new Reflection_Class(get_class($object)))->getAnnotations('before_delete') as $before_delete) {
         /** @var $before_delete Method_Annotation */
         if ($before_delete->call($object, [$this]) === false) {
             $will_delete = false;
             break;
         }
     }
     if ($will_delete) {
         $id = $this->getObjectIdentifier($object);
         if ($id) {
             $class_name = get_class($object);
             $class = new Reflection_Class($class_name);
             /** @var $link Class_\Link_Annotation */
             $link = $class->getAnnotation('link');
             $exclude_properties = $link->value ? array_keys((new Reflection_Class($link->value))->getProperties([T_EXTENDS, T_USE])) : [];
             foreach ($class->accessProperties() as $property) {
                 if (!$property->isStatic() && !in_array($property->name, $exclude_properties)) {
                     if ($property->getAnnotation('link')->value == Link_Annotation::COLLECTION) {
                         if ($property->getType()->isMultiple()) {
                             $this->deleteCollection($object, $property, $property->getValue($object));
                         } else {
                             $this->delete($property->getValue($object));
                             trigger_error("Dead code into Mysql\\Link::delete() on {$property->name} is not so dead", E_USER_NOTICE);
                         }
                     }
                 }
             }
             $this->setContext($class_name);
             if ($link->value) {
                 $id = [];
                 foreach ($link->getLinkProperties() as $link_property) {
                     $property_name = $link_property->getName();
                     $column_name = ($link_property->getType()->isClass() ? 'id_' : '') . $link_property->getAnnotation('storage')->value;
                     $id[$column_name] = $this->getObjectIdentifier($object, $property_name);
                 }
             }
             $this->query(Sql\Builder::buildDelete($class_name, $id));
             $this->disconnect($object);
             return true;
         }
     }
     return false;
 }
示例#7
0
 /**
  * The internal build method builds Table objects using a Php class definition
  *
  * It is the same than build(), but enables to add an additional field
  * (link field for @link classes)
  *
  * @param $class_name string
  * @param $more_field Column
  * @return Table[]
  */
 private function buildInternal($class_name, $more_field)
 {
     $class = new Reflection_Class($class_name);
     $link = $class->getAnnotation('link')->value;
     $tables = $link ? $this->buildLinkTables($link, $class_name) : [];
     $tables[] = $this->buildClassTable($class, $more_field);
     return $tables;
 }