/** * Creates new Property instance from given annotation * * @param string $annotationType * @param string $annotation * @param EntityReflection $entityReflection * @param IMapper|null $mapper * @return Property * @throws InvalidAnnotationException */ public static function createFromAnnotation($annotationType, $annotation, EntityReflection $entityReflection, IMapper $mapper = null) { $aliases = $entityReflection->getAliases(); $matches = []; $matched = preg_match('~ ^(null\\|)? ((?:\\\\?[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)+) (\\[\\])? (\\|null)?\\s+ (\\$[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*) (?:\\s+=\\s*(?: "((?:\\\\"|[^"])+)" | # double quoted string \'((?:\\\\\'|[^\'])+)\' | # single quoted string ([^ ]*)) # unquoted value )? (?:\\s*\\(([^)]+)\\))? (?:\\s+(.*)\\s*)? ~xi', $annotation, $matches); if (!$matched) { throw new InvalidAnnotationException("Invalid property definition given: @{$annotationType} {$annotation} in entity {$entityReflection->getName()}."); } $propertyType = new PropertyType($matches[2], $aliases); $isWritable = $annotationType === 'property'; $containsCollection = $matches[3] !== ''; if ($propertyType->isBasicType() and $containsCollection) { throw new InvalidAnnotationException("Invalid property type definition given: @{$annotationType} {$annotation} in entity {$entityReflection->getName()}. Lean Mapper doesn't support <type>[] notation for basic types."); } $isNullable = ($matches[1] !== '' or $matches[4] !== ''); $name = substr($matches[5], 1); $hasDefaultValue = false; $defaultValue = null; if (isset($matches[6]) and $matches[6] !== '') { $defaultValue = str_replace('\\"', '"', $matches[6]); } elseif (isset($matches[7]) and $matches[7] !== '') { $defaultValue = str_replace("\\'", "'", $matches[7]); } elseif (isset($matches[8]) and $matches[8] !== '') { $defaultValue = $matches[8]; } if ($defaultValue !== null) { $hasDefaultValue = true; try { $defaultValue = self::fixDefaultValue($defaultValue, $propertyType, $isNullable); } catch (InvalidAnnotationException $e) { throw new InvalidAnnotationException("Invalid property definition given: @{$annotationType} {$annotation} in entity {$entityReflection->getName()}, " . lcfirst($e->getMessage())); } } $column = $mapper !== null ? $mapper->getColumn($entityReflection->getName(), $name) : $name; if (isset($matches[9]) and $matches[9] !== '') { $column = $matches[9]; } $relationship = null; $propertyMethods = null; $propertyFilters = null; $propertyPasses = null; $propertyValuesEnum = null; $customFlags = []; $customColumn = null; $customDefault = null; if (isset($matches[10])) { $flagMatches = []; preg_match_all('~m:([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)\\s*(?:\\(([^)]*)\\))?~', $matches[10], $flagMatches, PREG_SET_ORDER); foreach ($flagMatches as $match) { $flag = $match[1]; $flagArgument = (isset($match[2]) and $match[2] !== '') ? $match[2] : null; switch ($flag) { case 'hasOne': case 'hasMany': case 'belongsToOne': case 'belongsToMany': if ($relationship !== null) { throw new InvalidAnnotationException("It doesn't make sense to have multiple relationship definitions in property definition: @{$annotationType} {$annotation} in entity {$entityReflection->getName()}."); } $relationship = self::createRelationship($entityReflection->getName(), $propertyType, $flag, $flagArgument, $mapper); $column = null; if ($relationship instanceof Relationship\HasOne) { $column = $relationship->getColumnReferencingTargetTable(); } break; case 'useMethods': if ($propertyMethods !== null) { throw new InvalidAnnotationException("Multiple m:useMethods flags found in property definition: @{$annotationType} {$annotation} in entity {$entityReflection->getName()}."); } $propertyMethods = new PropertyMethods($name, $isWritable, $flagArgument); break; case 'filter': if ($propertyFilters !== null) { throw new InvalidAnnotationException("Multiple m:filter flags found in property definition: @{$annotationType} {$annotation} in entity {$entityReflection->getName()}."); } $propertyFilters = new PropertyFilters($flagArgument); break; case 'passThru': if ($propertyPasses !== null) { throw new InvalidAnnotationException("Multiple m:passThru flags found in property definition: @{$annotationType} {$annotation} in entity {$entityReflection->getName()}."); } $propertyPasses = new PropertyPasses($flagArgument); break; case 'enum': if ($propertyValuesEnum !== null) { throw new InvalidAnnotationException("Multiple values enumerations found in property definition: @{$annotationType} {$annotation} in entity {$entityReflection->getName()}."); } if ($flagArgument === null) { throw new InvalidAnnotationException("Parameter of m:enum flag was not found in property definition: @{$annotationType} {$annotation} in entity {$entityReflection->getName()}."); } $propertyValuesEnum = new PropertyValuesEnum($flagArgument, $entityReflection); break; case 'column': if ($customColumn !== null) { throw new InvalidAnnotationException("Multiple column name settings found in property definition: @{$annotationType} {$annotation} in entity {$entityReflection->getName()}."); } if ($flagArgument === null) { throw new InvalidAnnotationException("Parameter of m:column flag was not found in property definition: @{$annotationType} {$annotation} in entity {$entityReflection->getName()}."); } $customColumn = $flagArgument; break; case 'default': if ($customDefault !== null) { throw new InvalidAnnotationException("Multiple default value settings found in property definition: @{$annotationType} {$annotation} in entity {$entityReflection->getName()}."); } if ($flagArgument === null) { throw new InvalidAnnotationException("Parameter of m:default flag was not found in property definition: @{$annotationType} {$annotation} in entity {$entityReflection->getName()}."); } $matched = preg_match('~ ^\\s*(?: "((?:\\\\"|[^"])+)" | # double quoted string \'((?:\\\\\'|[^\'])+)\' | # single quoted string ([^ ]*) # unquoted value ) ~xi', $flagArgument, $matches); if (!$matched) { throw new \Exception(); } if (isset($matches[1]) and $matches[1] !== '') { $customDefault = str_replace('\\"', '"', $matches[1]); } elseif (isset($matches[2]) and $matches[2] !== '') { $customDefault = str_replace("\\'", "'", $matches[2]); } elseif (isset($matches[3]) and $matches[3] !== '') { $customDefault = $matches[3]; } break; default: if (array_key_exists($flag, $customFlags)) { throw new InvalidAnnotationException("Multiple m:{$flag} flags found in property definition: @{$annotationType} {$annotation} in entity {$entityReflection->getName()}."); } $customFlags[$flag] = $flagArgument; } } } $column = $customColumn ?: $column; $defaultValue = $customDefault ?: $defaultValue; return new Property($name, $entityReflection, $column, $propertyType, $isWritable, $isNullable, $containsCollection, $hasDefaultValue, $defaultValue, $relationship, $propertyMethods, $propertyFilters, $propertyPasses, $propertyValuesEnum, $customFlags); }
/** * @throws InvalidMethodCallException */ private function checkContainsEnumeration() { if (!$this->containsEnumeration()) { throw new InvalidMethodCallException("It doesn't make sense to call enumeration related method on property '{$this->name}' in entity {$this->entityReflection->getName()} since it doesn't contain enumeration."); } }