コード例 #1
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;
 }