Example #1
0
 public function getDatabaseIdentifierValue($id)
 {
     $idType = $this->fieldMappings[$this->identifier]['type'];
     return Types\Type::getType($idType)->convertToDatabaseValue($id);
 }
 /** {@inheritdoc} */
 public function exchangeArray(array $data, IBaseObjectItem $instance = null)
 {
     if (empty($data)) {
         return $this;
     }
     $properties = (new \ReflectionClass($this))->getProperties();
     foreach ($properties as $property) {
         // do some checks
         if ($property->isStatic() || false !== stripos($docComment = $property->getDocComment(), CHAOS_ANNOTATION_IGNORE)) {
             unset($data[$property->name]);
             continue;
         }
         if (!$property->isPublic()) {
             $property->setAccessible(true);
         }
         // check if given name not exist in data
         if (!array_key_exists($property->name, $data)) {
             $data[$property->name] = $property->getValue($this);
             // continue;
         }
         // do we have any defined TYPE(s)?
         $types = $this->getTypes($property);
         $isCollection = isset($types[1]);
         $value = $data[$property->name];
         // switch...
         if ($types['is_scalar']) {
             // type juggling
             if (false === stripos($docComment, CHAOS_ANNOTATION_IGNORE_TYPE_JUGGLING)) {
                 $value = Types\Type::getType(strtolower($types[0]))->convertToPHPValue($value);
             }
             // do we have any defined filters & validators?
             if (false === stripos($docComment, CHAOS_ANNOTATION_IGNORE_RULES)) {
                 $this->addRules($property);
             }
         } elseif (isset($instance) && $types[0] === @get_class($instance)) {
             // check for circular object references
             if ($isCollection) {
                 $value = $this->addToCollection($instance, $types[1]);
             } else {
                 $value =& $instance;
             }
         } elseif (class_exists($types[0]) && is_array($value)) {
             if (is_subclass_of($types[0], __NAMESPACE__ . '\\IBaseObjectItem')) {
                 $obj = $isCollection ? $types[1] : null;
                 if (!empty($value) && false === stripos($docComment, CHAOS_ANNOTATION_IGNORE_DATA)) {
                     if ($isCollection) {
                         /** @var IBaseObjectItem $cls */
                         $method = method_exists($obj, 'add') ? 'add' : 'append';
                         // guess supported method
                         $firstKey = key($value);
                         $isMulti = is_array($value[$firstKey]) || is_object($value[$firstKey]);
                         if (!$isMulti) {
                             $value = [$value];
                         }
                         if (0 === iterator_count($obj)) {
                             foreach ($value as $v) {
                                 $cls = new $types[0]();
                                 is_object($v) ? $v instanceof $cls ? $cls = $v : $cls->exchangeObject($v) : $cls->exchangeArray($v, $this);
                                 $this->addToCollection($cls, $obj, $method);
                             }
                         } else {
                             $identifier = array_flip($this->getIdentifier());
                             $tmp = [];
                             foreach ($obj as $k => $v) {
                                 if (is_object($v)) {
                                     $v = get_object_vars($v);
                                 }
                                 if ($v = array_intersect_key($v, $identifier)) {
                                     $tmp[$k] = $v;
                                 }
                             }
                             foreach ($value as $v) {
                                 if (is_object($v)) {
                                     $v = get_object_vars($v);
                                 }
                                 if (($v = array_intersect_key($v, $identifier)) && false !== ($k = array_search($v, $tmp))) {
                                     if ($obj[$k] instanceof IBaseObjectItem) {
                                         $obj[$k]->exchangeArray($v, $this);
                                     } else {
                                         foreach ($obj[$k] as $key => $val) {
                                             if (array_key_exists($key, $v)) {
                                                 $obj[$k]->{$key} = $v[$key];
                                             }
                                         }
                                     }
                                 } else {
                                     $cls = new $types[0]();
                                     $cls->exchangeArray($v, $this);
                                     $this->addToCollection($cls, $obj, $method);
                                 }
                             }
                         }
                     } else {
                         /** @var IBaseObjectItem $obj */
                         $obj = new $types[0]();
                         $obj->exchangeArray($value, $this);
                     }
                 }
                 $value = $obj;
             } else {
                 try {
                     // unknown object, we use a kind of default instance
                     $obj = new $types[0]($value);
                     if ($isCollection) {
                         $obj = $this->addToCollection($obj, $types[1]);
                     }
                     $value = $obj;
                 } catch (\Exception $ex) {
                 }
             }
         }
         // set our new value (if any)
         $property->setValue($this, $value);
         unset($data[$property->name]);
         // for next loop
     }
     return $this;
 }
Example #3
0
 /**
  * Get property type(s)
  *
  * @param   \ReflectionProperty $property
  * @return  array
  */
 private function getTypes(\ReflectionProperty $property)
 {
     $getter = 'get' . $property->name . 'DataType';
     // check if getXyzDataType() method exists
     if (method_exists($this, $getter)) {
         $types = @call_user_func([$this, $getter]);
         if (!is_array($types)) {
             $types = [$types];
         }
     } else {
         $docComment = $property->getDocComment();
         if (false !== stripos($docComment, '@var')) {
             // e.g. @var int
             //  return ['int']
             // e.g. @var \Doctrine\Common\Collections\ArrayCollection(Channel)
             //  return ['Doctrine\Common\Collections\ArrayCollection', 'Channel'];
             preg_match(CHAOS_MATCH_VAR, $docComment, $types);
         } elseif (false !== stripos($docComment, 'orm\\') || false !== stripos($docComment, 'customcolumn')) {
             // e.g. @Doctrine\ORM\Mapping\Column(type="integer")
             //  return ['integer']
             if (0 === preg_match(CHAOS_MATCH_COLUMN_TYPE, $docComment, $types)) {
                 // e.g. @Doctrine\ORM\Mapping\Column(columnDefinition="tinyint(4) DEFAULT NULL")
                 //  return ['tinyint']
                 if (0 === preg_match(CHAOS_MATCH_COLUMN_DEFINITION, $docComment, $types)) {
                     // e.g. @Doctrine\ORM\Mapping\OneToMany(targetEntity="Channel")
                     //  return ['Doctrine\Common\Collections\ArrayCollection', 'Channel'];
                     preg_match(CHAOS_MATCH_ONE_MANY, $docComment, $types);
                     if (isset($types[1]) && isset($types[2])) {
                         if ('OneToMany' === $types[1] || 'ManyToMany' === $types[1]) {
                             $types[1] = DOCTRINE_ARRAY_COLLECTION;
                         }
                     }
                 }
             }
         }
         if (!empty($types)) {
             array_shift($types);
         }
     }
     if (empty($types)) {
         return [gettype($property->getValue($this)), 'is_scalar' => true];
     }
     // parse the found "types[1]" if any
     $scalars = Types\Type::getTypesMap();
     if (isset($types[1])) {
         // e.g. ['Channel', 'Doctrine\Common\Collections\ArrayCollection'];
         $types = array_reverse($types);
         $value = $property->getValue($this);
         // check if this property has been instanced
         if (isset($value)) {
             $types[1] = $value;
         } elseif (!isset($scalars[strtolower($types[1])])) {
             if (false === strpos($types[1], '\\')) {
                 $types[1] = $property->getDeclaringClass()->getNamespaceName() . '\\' . $types[1];
             }
             if (is_subclass_of($types[1], __NAMESPACE__ . '\\IBaseObjectCollection')) {
                 $types[1] = new $types[1]();
             } elseif (class_exists($types[1], false)) {
                 // unknown object, we use a kind of default instance
                 $types[1] = (new \ReflectionClass($types[1]))->newInstanceWithoutConstructor();
             }
         }
         // currently we only support type \Traversable
         if (!$types[1] instanceof \Traversable) {
             unset($types[1]);
         }
     }
     // define default namespace for the primary type if any
     $types['is_scalar'] = isset($scalars[strtolower($types[0])]);
     if (!$types['is_scalar'] && false === strpos($types[0], '\\')) {
         $types[0] = $property->getDeclaringClass()->getNamespaceName() . '\\' . $types[0];
     }
     // bye!
     return $types;
 }