/** * @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; }
/** * @param $class_name string * @param $search array * @return array */ private function createArrayReference($class_name, $search) { $array = isset($search) ? [Builder::fromArray($class_name, $search)] : null; $class = new Link_Class($class_name); $link_class = $class->getAnnotation('link')->value; if ($link_class) { $object = reset($array); $link_search = Builder::create($link_class); $composite_property_name = $class->getCompositeProperty()->name; foreach (array_keys($class->getLinkedProperties()) as $property_name) { if (isset($search[$property_name])) { $link_search->{$property_name} = $search[$property_name]; } } $object->{$composite_property_name} = Dao::searchOne($link_search) ?: $link_search; } return $array; }
/** * @param $object object * @param $property Reflection_Property * @param $map object[] */ private function writeMap($object, Reflection_Property $property, $map) { // old map $class = new Link_Class(get_class($object)); $composite_property_name = $class->getAnnotation('link')->value ? $class->getCompositeProperty()->name : null; $old_object = Search_Object::create(Link_Class::linkedClassNameOf($object)); $this->setObjectIdentifier($old_object, $this->getObjectIdentifier($object, $composite_property_name)); $aop_getter_ignore = Getter::$ignore; Getter::$ignore = false; $old_map = $property->getValue($old_object); Getter::$ignore = $aop_getter_ignore; // map properties : write each of them $insert_builder = new Map_Insert($property); $id_set = []; foreach ($map as $element) { $id = $this->getObjectIdentifier($element) ?: $this->getObjectIdentifier($this->write($element)); if (!isset($old_map[$id])) { $query = $insert_builder->buildQuery($object, $element); $this->connection->query($query); } else { $id_set[$id] = true; } } // remove old unused elements $delete_builder = new Map_Delete($property); foreach ($old_map as $old_element) { $id = $this->getObjectIdentifier($old_element); if (!isset($id_set[$id])) { $query = $delete_builder->buildQuery($object, $old_element); $this->connection->query($query); } } }
/** * Build SQL WHERE section for an object * * @param $path string Base property path pointing to the object * @param $object object The value is an object, which will be used for search * @return string */ private function buildObject($path, $object) { $class = new Link_Class(get_class($object)); $id = $this->sql_link->getObjectIdentifier($object, $class->getAnnotation('link')->value ? $class->getCompositeProperty()->name : null); if ($id) { // object is linked to stored data : search with object identifier return $this->buildValue($path, $id, $path == 'id' ? '' : 'id_'); } // object is a search object : each property is a search entry, and must join table $this->joins->add($path); $array = []; $class = new Reflection_Class(get_class($object)); foreach ($class->accessProperties() as $property_name => $property) { if (isset($object->{$property_name})) { $sub_path = $property_name; $array[$sub_path] = $object->{$property_name}; } } $sql = $this->buildArray($path, $array, 'AND'); if (!$sql) { $sql = 'FALSE'; } return $sql; }