/** * @param \Doctrine\Common\Annotations\AnnotationException $e * * @return string */ public static function highlightAnnotationLine(AnnotationException $e) { foreach ($e->getTrace() as $step) { if (@$step['class'] . @$step['type'] . @$step['function'] !== 'Doctrine\\Common\\Annotations\\DocParser->parse') { continue; } $context = Strings::match($step['args'][1], '~^(?P<type>[^\\s]+)\\s*(?P<class>[^:]+)(?:::\\$?(?P<property>[^\\(]+))?$~i'); break; } if (!isset($context)) { return FALSE; } $refl = Nette\Reflection\ClassType::from($context['class']); $file = $refl->getFileName(); $line = NULL; if ($context['type'] === 'property') { $refl = $refl->getProperty($context['property']); $line = Kdyby\Doctrine\Helpers::getPropertyLine($refl); } elseif ($context['type'] === 'method') { $refl = $refl->getProperty($context['method']); } if (($errorLine = self::calculateErrorLine($refl, $e, $line)) === NULL) { return FALSE; } $dump = BlueScreen::highlightFile($file, $errorLine); return '<p><b>File:</b> ' . self::editorLink($file, $errorLine) . '</p>' . $dump; }
/** * Store options from the Vlabs\Media annotation * * @param array $options * @throws \Doctrine\Common\Annotations\AnnotationException */ public function __construct($options) { if (isset($options['identifier'])) { $this->identifier = $options['identifier']; } else { $e = new AnnotationException(); throw $e->requiredError('identifier', 'Vlabs\\Media', 'entity', 'configuration entity identifier'); } if (isset($options['upload_dir'])) { $this->uploadDir = $options['upload_dir']; } else { $e = new AnnotationException(); throw $e->requiredError('upload_dir', 'Vlabs\\Media', 'entity', 'configuration media upload directory'); } }
/** * * @param array $values * @throws AnnotationException on missing parameters */ public function __construct(array $values = array()) { if (array_key_exists('filepath', $values)) { $this->filepath_property = $values['filepath']; } else { throw AnnotationException::requiredError('filepath', '@FileUpload'); } if (array_key_exists('file', $values)) { $this->file_property = $values['file']; } else { throw AnnotationException::requiredError('fileProperty', '@FileUpload'); } if (array_key_exists('tempFilePath', $values)) { $this->temp_filepath_property = $values['tempFilePath']; } else { throw AnnotationException::requiredError('tempFilePath', '@FileUpload', get_class($this), 'expected'); } if (array_key_exists('filenameMethod', $values)) { $this->filename_method = $values['filenameMethod']; } else { throw AnnotationException::requiredError('filenameMethod', '@FileUpload'); } if (array_key_exists('uploadSubDirectory', $values)) { $this->upload_sub_directory = $values['uploadSubDirectory']; } else { throw AnnotationException::requiredError('uploadSubDirectory', '@FileUpload'); } }
/** * {@inheritdoc} */ public function __construct(array $values) { $string = $values['value']; // Handle classes. if (strpos($string, '::') !== FALSE) { list($class, $constant) = explode('::', $string); try { $reflection = new \ReflectionClass($class); if ($reflection->hasConstant($constant)) { $this->value = $reflection->getConstant($constant); return; } } catch (\ReflectionException $e) { } } // Handle procedural constants. if (!$this->value && defined($string)) { $this->value = constant($string); return; } throw AnnotationException::semanticalErrorConstants($this->value); }
/** * Constructor. * * Initializes a new AnnotationReader. */ public function __construct() { if (extension_loaded('Zend Optimizer+') && (ini_get('zend_optimizerplus.save_comments') === "0" || ini_get('opcache.save_comments') === "0")) { throw AnnotationException::optimizerPlusSaveComments(); } if (extension_loaded('Zend OPcache') && ini_get('opcache.save_comments') == 0) { throw AnnotationException::optimizerPlusSaveComments(); } if (PHP_VERSION_ID < 70000) { if (extension_loaded('Zend Optimizer+') && (ini_get('zend_optimizerplus.load_comments') === "0" || ini_get('opcache.load_comments') === "0")) { throw AnnotationException::optimizerPlusLoadComments(); } if (extension_loaded('Zend OPcache') && ini_get('opcache.load_comments') == 0) { throw AnnotationException::optimizerPlusLoadComments(); } } AnnotationRegistry::registerFile(Mockingjay::getVendorRoot() . '/doctrine/annotations/lib/Doctrine/Common/Annotations/Annotation/IgnoreAnnotation.php'); $this->parser = new DocParser(); $this->preParser = new DocParser(); $this->preParser->setImports(self::$globalImports); $this->preParser->setIgnoreNotImportedAnnotations(true); $this->phpParser = new PhpParser(); }
/** * @param \Doctrine\ORM\Event\LoadClassMetadataEventArgs $eventArgs * @throws AnnotationException */ public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs) { $reader = new AnnotationReader(); $meta = $eventArgs->getClassMetadata(); foreach ($meta->getReflectionClass()->getProperties() as $property) { if ($meta->isMappedSuperclass && !$property->isPrivate() || $meta->isInheritedField($property->name) || isset($meta->associationMappings[$property->name]['inherited'])) { continue; } if ($annotation = $reader->getPropertyAnnotation($property, 'Leapt\\CoreBundle\\Doctrine\\Mapping\\File')) { $property->setAccessible(true); $field = $property->getName(); if (null === $annotation->mappedBy) { throw AnnotationException::requiredError('mappedBy', 'LeaptCore\\File', $meta->getReflectionClass()->getName(), 'another class property to map onto'); } if (null === $annotation->path && null === $annotation->pathCallback) { throw AnnotationException::syntaxError(sprintf('Annotation @%s declared on %s expects "path" or "pathCallback". One of them should not be null.', 'LeaptCore\\File', $meta->getReflectionClass()->getName())); } if (!$meta->hasField($annotation->mappedBy)) { throw AnnotationException::syntaxError(sprintf('The entity "%s" has no field named "%s", but it is documented in the annotation @%s', $meta->getReflectionClass()->getName(), $annotation->mappedBy, 'LeaptCore\\File')); } $this->config[$meta->getName()]['fields'][$field] = array('property' => $property, 'path' => $annotation->path, 'mappedBy' => $annotation->mappedBy, 'filename' => $annotation->filename, 'meta' => $meta, 'nameCallback' => $annotation->nameCallback, 'pathCallback' => $annotation->pathCallback); } } }
/** * Constructor. * * Initializes a new AnnotationReader. */ public function __construct() { if (extension_loaded('Zend Optimizer+') && (ini_get('zend_optimizerplus.save_comments') === "0" || ini_get('opcache.save_comments') === "0")) { throw AnnotationException::optimizerPlusSaveComments(); } if (extension_loaded('Zend OPcache') && ini_get('opcache.save_comments') == 0) { throw AnnotationException::optimizerPlusSaveComments(); } AnnotationRegistry::registerFile(__DIR__ . '/Annotation/IgnoreAnnotation.php'); $this->parser = new DocParser(); $this->preParser = new DocParser(); $this->preParser->setImports(self::$globalImports); $this->preParser->setIgnoreNotImportedAnnotations(true); $this->phpParser = new PhpParser(); }
/** * Generates a new syntax error. * * @param string $expected Expected string. * @param array $token Optional token. * @throws AnnotationException */ private function syntaxError($expected, $token = null) { if ($token === null) { $token = $this->lexer->lookahead; } $message = "Expected {$expected}, got "; if ($this->lexer->lookahead === null) { $message .= 'end of string'; } else { $message .= "'{$token['value']}' at position {$token['position']}"; } if (strlen($this->context)) { $message .= ' in ' . $this->context; } $message .= '.'; throw AnnotationException::syntaxError($message); }
/** * Constant ::= integer | string | float | boolean * * @throws AnnotationException * @return mixed */ private function Constant() { $identifier = $this->Identifier(); if (!defined($identifier) && false !== strpos($identifier, '::') && '\\' !== $identifier[0]) { list($className, $const) = explode('::', $identifier); $alias = false === ($pos = strpos($className, '\\')) ? $className : substr($className, 0, $pos); $found = false; switch (true) { case !empty($this->namespaces): foreach ($this->namespaces as $ns) { if (class_exists($ns . '\\' . $className) || interface_exists($ns . '\\' . $className)) { $className = $ns . '\\' . $className; $found = true; break; } } break; case isset($this->imports[$loweredAlias = strtolower($alias)]): $found = true; if (false !== $pos) { $className = $this->imports[$loweredAlias] . substr($className, $pos); } else { $className = $this->imports[$loweredAlias]; } break; default: if (isset($this->imports['__NAMESPACE__'])) { $ns = $this->imports['__NAMESPACE__']; if (class_exists($ns . '\\' . $className) || interface_exists($ns . '\\' . $className)) { $className = $ns . '\\' . $className; $found = true; } } break; } if ($found) { $identifier = $className . '::' . $const; } } if (!defined($identifier)) { throw AnnotationException::semanticalErrorConstants($identifier, $this->context); } return constant($identifier); }
/** * Annotation ::= "@" AnnotationName ["(" [Values] ")"] * AnnotationName ::= QualifiedName | SimpleName * QualifiedName ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName * NameSpacePart ::= identifier | null | false | true * SimpleName ::= identifier | null | false | true * * @return mixed False if it is not a valid annotation. */ private function Annotation() { $this->match(DocLexer::T_AT); // check if we have an annotation if ($this->lexer->isNextTokenAny(self::$classIdentifiers)) { $this->lexer->moveNext(); $name = $this->lexer->token['value']; } else { if ($this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) { $name = ''; } else { $this->syntaxError('namespace separator or identifier'); } } while ($this->lexer->lookahead['position'] === $this->lexer->token['position'] + strlen($this->lexer->token['value']) && $this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) { $this->match(DocLexer::T_NAMESPACE_SEPARATOR); $this->matchAny(self::$classIdentifiers); $name .= '\\' . $this->lexer->token['value']; } // only process names which are not fully qualified, yet // fully qualified names must start with a \ $originalName = $name; if ('\\' !== $name[0]) { $alias = false === ($pos = strpos($name, '\\')) ? $name : substr($name, 0, $pos); $found = false; if ($this->namespaces) { foreach ($this->namespaces as $namespace) { if ($this->classExists($namespace . '\\' . $name)) { $name = $namespace . '\\' . $name; $found = true; break; } } } elseif (isset($this->imports[$loweredAlias = strtolower($alias)])) { if (false !== $pos) { $name = $this->imports[$loweredAlias] . substr($name, $pos); } else { $name = $this->imports[$loweredAlias]; } $found = true; } elseif (isset($this->imports['__NAMESPACE__']) && $this->classExists($this->imports['__NAMESPACE__'] . '\\' . $name)) { $name = $this->imports['__NAMESPACE__'] . '\\' . $name; $found = true; } elseif ($this->classExists($name)) { $found = true; } if (!$found) { if ($this->ignoreNotImportedAnnotations || isset($this->ignoredAnnotationNames[$name])) { return false; } throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s was never imported. Did you maybe forget to add a "use" statement for this annotation?', $name, $this->context)); } } if (!$this->classExists($name)) { throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s does not exist, or could not be auto-loaded.', $name, $this->context)); } // at this point, $name contains the fully qualified class name of the // annotation, and it is also guaranteed that this class exists, and // that it is loaded // collects the metadata annotation only if there is not yet if (!isset(self::$annotationMetadata[$name])) { $this->collectAnnotationMetadata($name); } // verify that the class is really meant to be an annotation and not just any ordinary class if (self::$annotationMetadata[$name]['is_annotation'] === false) { if (isset($this->ignoredAnnotationNames[$originalName])) { return false; } throw AnnotationException::semanticalError(sprintf('The class "%s" is not annotated with @Annotation. Are you sure this class can be used as annotation? If so, then you need to add @Annotation to the _class_ doc comment of "%s". If it is indeed no annotation, then you need to add @IgnoreAnnotation("%s") to the _class_ doc comment of %s.', $name, $name, $originalName, $this->context)); } //if target is nested annotation $target = $this->isNestedAnnotation ? Target::TARGET_ANNOTATION : $this->target; // Next will be nested $this->isNestedAnnotation = true; //if anotation does not support current target if (0 === (self::$annotationMetadata[$name]['targets'] & $target) && $target) { throw AnnotationException::semanticalError(sprintf('Annotation @%s is not allowed to be declared on %s. You may only use this annotation on these code elements: %s.', $originalName, $this->context, self::$annotationMetadata[$name]['targets_literal'])); } $values = array(); if ($this->lexer->isNextToken(DocLexer::T_OPEN_PARENTHESIS)) { $this->match(DocLexer::T_OPEN_PARENTHESIS); if (!$this->lexer->isNextToken(DocLexer::T_CLOSE_PARENTHESIS)) { $values = $this->Values(); } $this->match(DocLexer::T_CLOSE_PARENTHESIS); } // checks all declared attributes foreach (self::$annotationMetadata[$name]['attribute_types'] as $property => $type) { if ($property === self::$annotationMetadata[$name]['default_property'] && !isset($values[$property]) && isset($values['value'])) { $property = 'value'; } // handle a not given attribute or null value if (!isset($values[$property])) { if ($type['required']) { throw AnnotationException::requiredError($property, $originalName, $this->context, 'a(n) ' . $type['value']); } continue; } if ($type['type'] === 'array') { // handle the case of a single value if (!is_array($values[$property])) { $values[$property] = array($values[$property]); } // checks if the attribute has array type declaration, such as "array<string>" if (isset($type['array_type'])) { foreach ($values[$property] as $item) { if (gettype($item) !== $type['array_type'] && !$item instanceof $type['array_type']) { throw AnnotationException::typeError($property, $originalName, $this->context, 'either a(n) ' . $type['array_type'] . ', or an array of ' . $type['array_type'] . 's', $item); } } } } elseif (gettype($values[$property]) !== $type['type'] && !$values[$property] instanceof $type['type']) { throw AnnotationException::typeError($property, $originalName, $this->context, 'a(n) ' . $type['value'], $values[$property]); } } // check if the annotation expects values via the constructor, // or directly injected into public properties if (self::$annotationMetadata[$name]['has_constructor'] === true) { return new $name($values); } $instance = new $name(); foreach ($values as $property => $value) { if (!isset(self::$annotationMetadata[$name]['properties'][$property])) { if ('value' !== $property) { throw AnnotationException::creationError(sprintf('The annotation @%s declared on %s does not have a property named "%s". Available properties: %s', $originalName, $this->context, $property, implode(', ', self::$annotationMetadata[$name]['properties']))); } // handle the case if the property has no annotations if (!($property = self::$annotationMetadata[$name]['default_property'])) { throw AnnotationException::creationError(sprintf('The annotation @%s declared on %s does not accept any values, but got %s.', $originalName, $this->context, json_encode($values))); } } $instance->{$property} = $value; } return $instance; }
/** * Annotation ::= "@" AnnotationName ["(" [Values] ")"] * AnnotationName ::= QualifiedName | SimpleName | AliasedName * QualifiedName ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName * AliasedName ::= Alias ":" SimpleName * NameSpacePart ::= identifier * SimpleName ::= identifier * Alias ::= identifier * * @return mixed False if it is not a valid annotation. */ private function Annotation() { $this->match(DocLexer::T_AT); // check if we have an annotation if ($this->lexer->isNextToken(DocLexer::T_IDENTIFIER)) { $this->lexer->moveNext(); $name = $this->lexer->token['value']; } else { if ($this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) { $name = ''; } else { $this->syntaxError('namespace separator or identifier'); } } while ($this->lexer->lookahead['position'] === $this->lexer->token['position'] + strlen($this->lexer->token['value']) && $this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) { $this->match(DocLexer::T_NAMESPACE_SEPARATOR); $this->match(DocLexer::T_IDENTIFIER); $name .= '\\' . $this->lexer->token['value']; } // check if name is supposed to be ignored if (!$this->isNestedAnnotation && in_array($name, $this->ignoredAnnotationNames, true)) { return false; } // only process names which are not fully qualified, yet if ('\\' !== $name[0] && !$this->classExists($name)) { $alias = false === ($pos = strpos($name, '\\')) ? $name : substr($name, 0, $pos); if (isset($this->imports[$loweredAlias = strtolower($alias)])) { if (false !== $pos) { $name = $this->imports[$loweredAlias] . substr($name, $pos); } else { $name = $this->imports[$loweredAlias]; } } elseif (isset($this->imports['__NAMESPACE__']) && $this->classExists($this->imports['__NAMESPACE__'] . '\\' . $name)) { $name = $this->imports['__NAMESPACE__'] . '\\' . $name; } else { if ($this->ignoreNotImportedAnnotations) { return false; } throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s was never imported.', $name, $this->context)); } } if (!$this->classExists($name)) { throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s does not exist, or could not be auto-loaded.', $name, $this->context)); } // at this point, $name contains the fully qualified class name of the // annotation, and it is also guaranteed that this class exists, and // that it is loaded // Next will be nested $this->isNestedAnnotation = true; $values = array(); if ($this->lexer->isNextToken(DocLexer::T_OPEN_PARENTHESIS)) { $this->match(DocLexer::T_OPEN_PARENTHESIS); if (!$this->lexer->isNextToken(DocLexer::T_CLOSE_PARENTHESIS)) { $values = $this->Values(); } $this->match(DocLexer::T_CLOSE_PARENTHESIS); } return new $name($values); }
/** * Annotation ::= "@" AnnotationName ["(" [Values] ")"] * AnnotationName ::= QualifiedName | SimpleName | AliasedName * QualifiedName ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName * AliasedName ::= Alias ":" SimpleName * NameSpacePart ::= identifier * SimpleName ::= identifier * Alias ::= identifier * * @return mixed False if it is not a valid annotation. */ public function Annotation() { $values = array(); $nameParts = array(); $this->match(Lexer::T_AT); $this->match(Lexer::T_IDENTIFIER); $nameParts[] = $this->lexer->token['value']; while ($this->lexer->isNextToken(Lexer::T_NAMESPACE_SEPARATOR)) { $this->match(Lexer::T_NAMESPACE_SEPARATOR); $this->match(Lexer::T_IDENTIFIER); $nameParts[] = $this->lexer->token['value']; } // Effectively pick the name of the class (append default NS if none, grab from NS alias, etc) $namespacedAnnotation = false; if (strpos($nameParts[0], ':')) { list($alias, $nameParts[0]) = explode(':', $nameParts[0]); // If the namespace alias doesnt exist, skip until next annotation if (!isset($this->namespaceAliases[$alias])) { $this->lexer->skipUntil(Lexer::T_AT); return false; } $name = $this->namespaceAliases[$alias] . implode('\\', $nameParts); $namespacedAnnotation = true; } else { if (count($nameParts) == 1) { $name = $this->defaultAnnotationNamespace . $nameParts[0]; } else { $name = implode('\\', $nameParts); } } // Does the annotation class exist? if (!class_exists($name, $this->autoloadAnnotations)) { if ($namespacedAnnotation) { throw AnnotationException::semanticalError('Annotation class "' . $name . '" does not exist.'); } $this->lexer->skipUntil(Lexer::T_AT); return false; } // Next will be nested $this->isNestedAnnotation = true; if ($this->lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) { $this->match(Lexer::T_OPEN_PARENTHESIS); if (!$this->lexer->isNextToken(Lexer::T_CLOSE_PARENTHESIS)) { $values = $this->Values(); } $this->match(Lexer::T_CLOSE_PARENTHESIS); } if ($this->annotationCreationFunction !== null) { $func = $this->annotationCreationFunction; $annot = $func($name, $values); } return isset($annot) ? $annot : $this->newAnnotation($name, $values); }
/** * Annotation ::= "@" AnnotationName ["(" [Values] ")"] * AnnotationName ::= QualifiedName | SimpleName * QualifiedName ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName * NameSpacePart ::= identifier | null | false | true * SimpleName ::= identifier | null | false | true * * @return mixed False if it is not a valid annotation. */ private function Annotation() { $this->match(DocLexer::T_AT); // check if we have an annotation if ($this->lexer->isNextTokenAny(self::$classIdentifiers)) { $this->lexer->moveNext(); $name = $this->lexer->token['value']; } else if ($this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) { $name = ''; } else { $this->syntaxError('namespace separator or identifier'); } while ($this->lexer->lookahead['position'] === $this->lexer->token['position'] + strlen($this->lexer->token['value']) && $this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) { $this->match(DocLexer::T_NAMESPACE_SEPARATOR); $this->matchAny(self::$classIdentifiers); $name .= '\\'.$this->lexer->token['value']; } // only process names which are not fully qualified, yet $originalName = $name; if ('\\' !== $name[0] && !$this->classExists($name)) { $alias = (false === $pos = strpos($name, '\\'))? $name : substr($name, 0, $pos); if (isset($this->imports[$loweredAlias = strtolower($alias)])) { if (false !== $pos) { $name = $this->imports[$loweredAlias].substr($name, $pos); } else { $name = $this->imports[$loweredAlias]; } } elseif (isset($this->imports['__NAMESPACE__']) && $this->classExists($this->imports['__NAMESPACE__'].'\\'.$name)) { $name = $this->imports['__NAMESPACE__'].'\\'.$name; } else { if ($this->ignoreNotImportedAnnotations || isset($this->ignoredAnnotationNames[$name])) { return false; } throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s was never imported.', $name, $this->context)); } } if (!$this->classExists($name)) { throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s does not exist, or could not be auto-loaded.', $name, $this->context)); } // at this point, $name contains the fully qualified class name of the // annotation, and it is also guaranteed that this class exists, and // that it is loaded // verify that the class is really meant to be an annotation and not just any ordinary class if (!isset($this->isAnnotation[$name])) { $ref = new \ReflectionClass($name); if (false === strpos($ref->getDocComment(), '@Annotation')) { if (isset($this->ignoredAnnotationNames[$originalName])) { return false; } throw AnnotationException::semanticalError(sprintf('The class "%s" is not annotated with @Annotation. Are you sure this class can be used as annotation? If so, then you need to add @Annotation to the _class_ doc comment of "%s". If it is indeed no annotation, then you need to add @IgnoreAnnotation("%s") to the _class_ doc comment of %s.', $name, $name, $originalName, $this->context)); } $this->isAnnotation[$name] = true; } // Next will be nested $this->isNestedAnnotation = true; $values = array(); if ($this->lexer->isNextToken(DocLexer::T_OPEN_PARENTHESIS)) { $this->match(DocLexer::T_OPEN_PARENTHESIS); if ( ! $this->lexer->isNextToken(DocLexer::T_CLOSE_PARENTHESIS)) { $values = $this->Values(); } $this->match(DocLexer::T_CLOSE_PARENTHESIS); } return new $name($values); }
private function complementType($type, $context) { static $builtin = ['int', 'integer', 'bool', 'boolean', 'float', 'double', 'string', 'array', 'mixed', 'string', 'null']; if (($p = strrpos($type, '[]')) !== false) { return $this->complementType(substr($type, 0, $p), $context) . '[]'; } if (in_array($type, $builtin)) { return $type; } foreach ($this->uses as $u) { $fqcn = $u . '\\' . $type; if (class_exists($fqcn)) { return $fqcn; } } if (class_exists($type)) { return $type; } throw AnnotationException::semanticalErrorConstants($type, $context); }
private function loadReceiverProperties() { $receiverProperties = array(); //Add widgetItems to widgets $widgetItems = $this->widgetItemChain->getWidgetItems(); $widgets = array_merge($this->widgets, $widgetItems); foreach ($widgets as $widget) { $class = new \ReflectionClass($widget['class']); $properties = $class->getProperties(); foreach ($properties as $property) { $annotations = $this->reader->getPropertyAnnotations($property); foreach ($annotations as $key => $annotationObj) { if ($annotationObj instanceof ReceiverProperty && !in_array($class, $receiverProperties)) { if (!$annotations[$key]->getTypes()) { $message = $class->name . ':$' . $property->name . '" field'; throw AnnotationException::requiredError('type', 'BusinessProperty annotation', $message, 'array or string'); } foreach ($annotations[$key]->getTypes() as $type) { $receiverProperties[$widget['name']][$type][$property->name] = $property->name; } } } } } return $receiverProperties; }
/** * Load receiver properties and NotBlank constraints from ReflectionClass. * * @param \ReflectionClass $class * * @throws AnnotationException * * @return array */ protected function loadReceiverProperties(\ReflectionClass $class) { $receiverPropertiesTypes = []; $properties = $class->getProperties(); //Store receiver properties foreach ($properties as $property) { $annotations = $this->reader->getPropertyAnnotations($property); foreach ($annotations as $key => $annotationObj) { if ($annotationObj instanceof ReceiverPropertyAnnotation && !in_array($class, $receiverPropertiesTypes)) { if (!$annotations[$key]->getTypes()) { $message = $class->name . ':$' . $property->name . '" field'; throw AnnotationException::requiredError('type', 'ReceiverProperty annotation', $message, 'array or string'); } foreach ($annotations[$key]->getTypes() as $type) { $receiverProperty = new ReceiverProperty(); $receiverProperty->setFieldName($property->name); $receiverPropertiesTypes[$type][] = $receiverProperty; } } } } //Set receiver properties as required if necessary foreach ($receiverPropertiesTypes as $type => $receiverProperties) { /* @var ReceiverProperty[] $receiverProperties */ foreach ($receiverProperties as $receiverProperty) { $receiverPropertyName = $receiverProperty->getFieldName(); $refProperty = $class->getProperty($receiverPropertyName); $annotations = $this->reader->getPropertyAnnotations($refProperty); foreach ($annotations as $key => $annotationObj) { if ($annotationObj instanceof Column && $annotationObj->nullable === false) { throw new Exception(sprintf('Property "%s" in class "%s" has a @ReceiverProperty annotation and by consequence must have "nullable=true" for ORM\\Column annotation', $refProperty->name, $refProperty->class)); } elseif ($annotationObj instanceof NotBlank) { throw new Exception(sprintf('Property "%s" in class "%s" has a @ReceiverProperty annotation and by consequence can not use NotBlank annotation', $refProperty->name, $refProperty->class)); } elseif ($annotationObj instanceof NotNull) { throw new Exception(sprintf('Property "%s" in class "%s" has a @ReceiverProperty annotation and by consequence can not use NotNull annotation', $refProperty->name, $refProperty->class)); } elseif ($annotationObj instanceof ReceiverPropertyAnnotation && $annotationObj->isRequired()) { $receiverProperty->setRequired(true); } } } } return $receiverPropertiesTypes; }
/** * Gets the Lucene index to the related object * * @param object $object * * @return ZendSearch\Lucene\SearchIndexInterface */ private function getIndexForObject($object) { $reflClass = new ReflectionClass($object); $annotation = $this->reader->getClassAnnotation($reflClass, '\\Keratine\\Lucene\\Mapping\\Annotation\\Indexable'); if (!$annotation) { // throw new \Exception(sprintf('%s must define annotation @%s', get_class($object), '\Keratine\Lucene\Mapping\Annotation\Indexable')); return; } if (empty($annotation->index)) { AnnotationException::requiredError('index', '\\Keratine\\Lucene\\Mapping\\Annotation\\Indexable', $object, 'string'); } if (false === isset($this->indices[$annotation->index])) { throw new \Exception(sprintf('Unknown index "%s".', $annotation->index)); } if (false === $this->indices[$annotation->index] instanceof SearchIndexInterface) { throw new \Exception(sprintf('Index "%s" must be an instance of "ZendSearch\\Lucene\\SearchIndexInterface". "%s" given.', $annotation->index, is_object($this->indices[$annotation->index]) ? get_class($this->indices[$annotation->index]) : $this->indices[$annotation->index])); } return $this->indices[$annotation->index]; }
/** * Annotation ::= "@" AnnotationName ["(" [Values] ")"] * AnnotationName ::= QualifiedName | SimpleName * QualifiedName ::= NameSpacePart "\" {NameSpacePart "\"}* SimpleName * NameSpacePart ::= identifier | null | false | true * SimpleName ::= identifier | null | false | true * * @return mixed False if it is not a valid annotation. */ private function Annotation() { $this->match(DocLexer::T_AT); // check if we have an annotation if ($this->lexer->isNextTokenAny(self::$classIdentifiers)) { $this->lexer->moveNext(); $name = $this->lexer->token['value']; } else { if ($this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) { $name = ''; } else { $this->syntaxError('namespace separator or identifier'); } } while ($this->lexer->lookahead['position'] === $this->lexer->token['position'] + strlen($this->lexer->token['value']) && $this->lexer->isNextToken(DocLexer::T_NAMESPACE_SEPARATOR)) { $this->match(DocLexer::T_NAMESPACE_SEPARATOR); $this->matchAny(self::$classIdentifiers); $name .= '\\' . $this->lexer->token['value']; } if (strpos($name, ":") !== false) { list($alias, $name) = explode(':', $name); // If the namespace alias doesnt exist, skip until next annotation if (!isset($this->namespaceAliases[$alias])) { $this->lexer->skipUntil(DocLexer::T_AT); return false; } $name = $this->namespaceAliases[$alias] . $name; } // only process names which are not fully qualified, yet if ('\\' !== $name[0] && !$this->classExists($name)) { $alias = false === ($pos = strpos($name, '\\')) ? $name : substr($name, 0, $pos); if (isset($this->imports[$loweredAlias = strtolower($alias)])) { if (false !== $pos) { $name = $this->imports[$loweredAlias] . substr($name, $pos); } else { $name = $this->imports[$loweredAlias]; } } elseif (isset($this->imports['__DEFAULT__']) && $this->classExists($this->imports['__DEFAULT__'] . $name)) { $name = $this->imports['__DEFAULT__'] . $name; } elseif (isset($this->imports['__NAMESPACE__']) && $this->classExists($this->imports['__NAMESPACE__'] . '\\' . $name)) { $name = $this->imports['__NAMESPACE__'] . '\\' . $name; } else { if ($this->ignoreNotImportedAnnotations || isset($this->ignoredAnnotationNames[$name])) { return false; } throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s was never imported.', $name, $this->context)); } } if (!$this->classExists($name)) { throw AnnotationException::semanticalError(sprintf('The annotation "@%s" in %s does not exist, or could not be auto-loaded.', $name, $this->context)); } if (!$this->isAnnotation($name)) { return false; } // Verifies that the annotation class extends any class that contains "Annotation". // This is done to avoid coupling of Doctrine Annotations against other libraries. // at this point, $name contains the fully qualified class name of the // annotation, and it is also guaranteed that this class exists, and // that it is loaded // Next will be nested $this->isNestedAnnotation = true; $values = array(); if ($this->lexer->isNextToken(DocLexer::T_OPEN_PARENTHESIS)) { $this->match(DocLexer::T_OPEN_PARENTHESIS); if (!$this->lexer->isNextToken(DocLexer::T_CLOSE_PARENTHESIS)) { $values = $this->Values(); } $this->match(DocLexer::T_CLOSE_PARENTHESIS); } return $this->newAnnotation($name, $values); }