Exemplo n.º 1
0
 /**
  * Write a component collection property value
  *
  * Ie when you write an order, it's implicitly needed to write it's lines
  *
  * @param $object     object
  * @param $property   Reflection_Property
  * @param $collection Component[]
  */
 private function writeCollection($object, Reflection_Property $property, $collection)
 {
     // old collection
     $class_name = get_class($object);
     $old_object = Search_Object::create($class_name);
     $this->setObjectIdentifier($old_object, $this->getObjectIdentifier($object));
     $aop_getter_ignore = Getter::$ignore;
     Getter::$ignore = false;
     $old_collection = $property->getValue($old_object);
     Getter::$ignore = $aop_getter_ignore;
     $element_class = $property->getType()->asReflectionClass();
     /** @var $element_link Class_\Link_Annotation */
     $element_link = $element_class->getAnnotation('link');
     // collection properties : write each of them
     $id_set = [];
     if ($collection) {
         foreach ($collection as $key => $element) {
             if (!is_a($element, $element_class->getName())) {
                 $collection[$key] = $element = Builder::createClone($element, $element_class->getName(), [$element_link->getLinkClass()->getCompositeProperty()->name => $element]);
             }
             $element->setComposite($object, $property->getAnnotation('foreign')->value);
             $id = $element_link->value ? $this->getLinkObjectIdentifier($element, $element_link) : $this->getObjectIdentifier($element);
             if (!empty($id)) {
                 $id_set[$id] = true;
             }
             $this->write($element);
         }
     }
     // remove old unused elements
     foreach ($old_collection as $old_element) {
         $id = $element_link->value ? $this->getLinkObjectIdentifier($old_element, $element_link) : $this->getObjectIdentifier($old_element);
         if (!isset($id_set[$id])) {
             $this->delete($old_element);
         }
     }
 }
Exemplo n.º 2
0
 /**
  * Create a clone of the object, using a built class if needed
  *
  * @param $object            object
  * @param $class_name        string if set, the new object will use the matching built class
  *                           this class name must inherit from the object's class
  * @param $properties_values array some properties values for the cloned object
  * @param $same_identifier   boolean
  * @return object
  */
 public static function createClone($object, $class_name = null, $properties_values = [], $same_identifier = true)
 {
     $class_name = self::className($class_name);
     $source_class_name = get_class($object);
     if (!isset($class_name)) {
         $class_name = self::className($source_class_name);
     }
     if ($class_name !== $source_class_name) {
         // initialises cloned object
         $clone = self::create($class_name);
         $destination_class = new Link_Class($class_name);
         // deactivate AOP
         if (isset($clone->_)) {
             $save_aop = $clone->_;
             unset($clone->_);
         }
         // copy official properties values from the source object
         $properties = (new Reflection_Class($source_class_name))->accessProperties();
         foreach ($properties as $property) {
             if (!isset($save_aop[$property->name])) {
                 $property->setValue($clone, $property->getValue($object));
             }
         }
         // copy unofficial properties values from the source object (ie AOP properties aliases)
         // clone collection objects using the destination collection property type
         $clone_collection = [];
         foreach (get_object_vars($object) as $property_name => $value) {
             if ($property_name !== '_' && !isset($properties[$property_name])) {
                 $clone->{$property_name} = $value;
                 if (isset($properties[rtrim($property_name, '_')])) {
                     $property = $properties[rtrim($property_name, '_')];
                     if ($property->getAnnotation('link') == Link_Annotation::COLLECTION) {
                         $element_class_from = $property->getType()->getElementTypeAsString();
                         $property = $destination_class->getProperty($property->name);
                         $element_class_to = $property->getType()->getElementTypeAsString();
                         if ($element_class_to != $element_class_from) {
                             $clone_collection[substr($property_name, 0, -1)] = $element_class_to;
                         }
                     }
                 }
             }
         }
         // reactivate AOP
         if (isset($save_aop)) {
             $clone->_ = $save_aop;
         }
         foreach ($clone_collection as $property_name => $element_class_to) {
             $elements = [];
             foreach ($object->{$property_name} as $key => $element) {
                 $elements[$key] = Builder::createClone($element, $element_class_to, [], $same_identifier);
             }
             $clone->{$property_name} = $elements;
         }
         // linked class object to link class object : store source object to linked object
         $destination_class = new Link_Class($class_name);
         if ($linked_class_name = $destination_class->getLinkedClassName()) {
             if ($linked_class_name == $source_class_name) {
                 $destination_class->getLinkProperty()->setValue($clone, $object);
             }
         }
         // identify destination object = source object, or disconnect destination object
         if ($same_identifier) {
             Dao::replace($clone, $object, false);
         } else {
             Dao::disconnect($clone);
         }
     } else {
         $clone = clone $object;
     }
     // copy added properties values to the cloned object
     if ($properties_values) {
         $properties = (new Reflection_Class($class_name))->accessProperties();
         foreach ($properties_values as $property_name => $value) {
             $properties[$property_name]->setValue($clone, $value);
         }
     }
     return $clone;
 }
Exemplo n.º 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;
 }