Reflection of classes of all active packages is triggered through the bootstrap's initializeReflectionService() method. In a development context, single classes may be re-reflected once files are modified whereas in a production context reflection is done once and successive requests read from the frozen caches for performance reasons. The list of available classes is determined by the CompiletimeObjectManager which also triggers the initial build of reflection data in this service. The invalidation of reflection cache entries is done by the CacheManager which in turn is triggered by signals sent by the file monitor. The internal representation of cache data is optimized for memory consumption and speed by using constants which have an integer value.
 /**
  * Adds all validators that extend the AssetValidatorInterface.
  *
  * @return void
  */
 protected function initializeObject()
 {
     $assetValidatorImplementationClassNames = $this->reflectionService->getAllImplementationClassNamesForInterface(AssetValidatorInterface::class);
     foreach ($assetValidatorImplementationClassNames as $assetValidatorImplementationClassName) {
         $this->addValidator($this->objectManager->get($assetValidatorImplementationClassName));
     }
 }
 /**
  * This method is used to optimize the matching process.
  *
  * @param \Neos\Flow\Aop\Builder\ClassNameIndex $classNameIndex
  * @return \Neos\Flow\Aop\Builder\ClassNameIndex
  */
 public function reduceTargetClassNames(\Neos\Flow\Aop\Builder\ClassNameIndex $classNameIndex)
 {
     $classNames = $this->reflectionService->getClassNamesByAnnotation(Flow\ValueObject::class);
     $annotatedIndex = new \Neos\Flow\Aop\Builder\ClassNameIndex();
     $annotatedIndex->setClassNames($classNames);
     return $classNameIndex->intersect($annotatedIndex);
 }
 /**
  * Only convert if the given target class has a constructor with one argument being of type given type
  *
  * @param string $source
  * @param string $targetType
  * @return bool
  */
 public function canConvertFrom($source, $targetType)
 {
     $methodParameters = $this->reflectionService->getMethodParameters($targetType, '__construct');
     if (count($methodParameters) !== 1) {
         return false;
     }
     $methodParameter = array_shift($methodParameters);
     return $methodParameter['type'] === gettype($source);
 }
 /**
  * Prepare test objects
  */
 protected function setUp()
 {
     $this->nodeFactory = $this->getMockBuilder(NodeFactory::class)->setMethods(array('filterNodeByContext'))->getMock();
     $this->nodeFactory->expects(self::any())->method('filterNodeByContext')->willReturnArgument(0);
     $this->reflectionServiceMock = $this->createMock(ReflectionService::class);
     $this->reflectionServiceMock->expects(self::any())->method('getAllImplementationClassNamesForInterface')->with(NodeInterface::class)->willReturn(array(Node::class));
     $this->objectManagerMock = $this->createMock(ObjectManagerInterface::class);
     $this->objectManagerMock->expects(self::any())->method('get')->with(ReflectionService::class)->willReturn($this->reflectionServiceMock);
     $this->objectManagerMock->expects(self::any())->method('getClassNameByObjectName')->with(NodeInterface::class)->willReturn(Node::class);
     $this->inject($this->nodeFactory, 'objectManager', $this->objectManagerMock);
 }
 /**
  * Sets up this test case
  */
 public function setUp()
 {
     $this->identityRoutePart = $this->getAccessibleMock(IdentityRoutePart::class, ['createPathSegmentForObject']);
     $this->mockPersistenceManager = $this->createMock(PersistenceManagerInterface::class);
     $this->identityRoutePart->_set('persistenceManager', $this->mockPersistenceManager);
     $this->mockReflectionService = $this->createMock(ReflectionService::class);
     $this->mockClassSchema = $this->getMockBuilder(ClassSchema::class)->disableOriginalConstructor()->getMock();
     $this->mockReflectionService->expects($this->any())->method('getClassSchema')->will($this->returnValue($this->mockClassSchema));
     $this->identityRoutePart->_set('reflectionService', $this->mockReflectionService);
     $this->mockObjectPathMappingRepository = $this->createMock(ObjectPathMappingRepository::class);
     $this->identityRoutePart->_set('objectPathMappingRepository', $this->mockObjectPathMappingRepository);
 }
 /**
  * @param JoinPointInterface $joinPoint The current join point
  * @return mixed
  * @Flow\Around("methodAnnotatedWith(Flowpack\JobQueue\Common\Annotations\Defer)")
  */
 public function queueMethodCallAsJob(JoinPointInterface $joinPoint)
 {
     if ($this->processingJob) {
         return $joinPoint->getAdviceChain()->proceed($joinPoint);
     }
     /** @var Defer $deferAnnotation */
     $deferAnnotation = $this->reflectionService->getMethodAnnotation($joinPoint->getClassName(), $joinPoint->getMethodName(), Defer::class);
     $queueName = $deferAnnotation->queueName;
     $job = new StaticMethodCallJob($joinPoint->getClassName(), $joinPoint->getMethodName(), $joinPoint->getMethodArguments());
     $this->jobManager->queue($queueName, $job, $deferAnnotation->options);
     return null;
 }
 /**
  * Only convert if the given target class has a constructor with one argument being of type given type
  *
  * @param string $source
  * @param string $targetType
  * @return bool
  */
 public function canConvertFrom($source, $targetType)
 {
     if (($this->reflectionService->isClassAnnotatedWith($targetType, Flow\Entity::class) || $this->reflectionService->isClassAnnotatedWith($targetType, Flow\ValueObject::class) || $this->reflectionService->isClassAnnotatedWith($targetType, Entity::class)) === true) {
         return false;
     }
     $methodParameters = $this->reflectionService->getMethodParameters($targetType, '__construct');
     if (count($methodParameters) !== 1) {
         return false;
     }
     $methodParameter = array_shift($methodParameters);
     return $methodParameter['type'] === gettype($source);
 }
 /**
  * @test
  */
 public function getAvailableCommandsReturnsAllAvailableCommands()
 {
     $commandManager = new CommandManager();
     $mockCommandControllerClassNames = array(Fixtures\Command\MockACommandController::class, Fixtures\Command\MockBCommandController::class);
     $this->mockReflectionService->expects($this->once())->method('getAllSubClassNamesForClass')->with(Cli\CommandController::class)->will($this->returnValue($mockCommandControllerClassNames));
     $mockObjectManager = $this->createMock(ObjectManagerInterface::class);
     $mockObjectManager->expects($this->any())->method('get')->with(ReflectionService::class)->willReturn($this->mockReflectionService);
     $commandManager->injectObjectManager($mockObjectManager);
     $commands = $commandManager->getAvailableCommands();
     $this->assertEquals(3, count($commands));
     $this->assertEquals('neos.flow.tests.unit.cli.fixtures:mocka:foo', $commands[0]->getCommandIdentifier());
     $this->assertEquals('neos.flow.tests.unit.cli.fixtures:mocka:bar', $commands[1]->getCommandIdentifier());
     $this->assertEquals('neos.flow.tests.unit.cli.fixtures:mockb:baz', $commands[2]->getCommandIdentifier());
 }
 /**
  * Get all class names inside this namespace and return them as array.
  *
  * @param string $namespace
  * @return array Array of all class names inside a given namespace.
  */
 protected function getClassNamesInNamespace($namespace)
 {
     $affectedViewHelperClassNames = array();
     $allViewHelperClassNames = $this->reflectionService->getAllSubClassNamesForClass(\Neos\FluidAdaptor\Core\ViewHelper\AbstractViewHelper::class);
     foreach ($allViewHelperClassNames as $viewHelperClassName) {
         if ($this->reflectionService->isClassAbstract($viewHelperClassName)) {
             continue;
         }
         if (strncmp($namespace, $viewHelperClassName, strlen($namespace)) === 0) {
             $affectedViewHelperClassNames[] = $viewHelperClassName;
         }
     }
     sort($affectedViewHelperClassNames);
     return $affectedViewHelperClassNames;
 }
 /**
  * @test
  */
 public function methodParametersGetNormalizedType()
 {
     $methodParameters = $this->reflectionService->getMethodParameters(Reflection\Fixtures\AnnotatedClass::class, 'intAndIntegerParameters');
     foreach ($methodParameters as $methodParameter) {
         $this->assertEquals('integer', $methodParameter['type']);
     }
 }
 /**
  * After returning advice, generates the value hash for the object
  *
  * @param JoinPointInterface $joinPoint The current join point
  * @return void
  * @Flow\After("Neos\Flow\Persistence\Aspect\PersistenceMagicAspect->isNonEmbeddedValueObject && method(.*->__construct()) && filter(Neos\Flow\Persistence\Doctrine\Mapping\Driver\FlowAnnotationDriver)")
  */
 public function generateValueHash(JoinPointInterface $joinPoint)
 {
     $proxy = $joinPoint->getProxy();
     $proxyClassName = get_class($proxy);
     $hashSourceParts = [];
     $classSchema = $this->reflectionService->getClassSchema($proxyClassName);
     foreach ($classSchema->getProperties() as $property => $propertySchema) {
         // Currently, private properties are transient. Should this behaviour change, they need to be included
         // in the value hash generation
         if ($classSchema->isPropertyTransient($property) || $this->reflectionService->isPropertyPrivate($proxyClassName, $property)) {
             continue;
         }
         $propertyValue = ObjectAccess::getProperty($proxy, $property, true);
         if (is_object($propertyValue) === true) {
             // The persistence manager will return NULL if the given object is unknown to persistence
             $propertyValue = $this->persistenceManager->getIdentifierByObject($propertyValue) ?: $propertyValue;
         }
         $hashSourceParts[$property] = $propertyValue;
     }
     ksort($hashSourceParts);
     $hashSourceParts['__class_name__'] = $proxyClassName;
     $serializedSource = $this->useIgBinary === true ? igbinary_serialize($hashSourceParts) : serialize($hashSourceParts);
     $proxy = $joinPoint->getProxy();
     ObjectAccess::setProperty($proxy, 'Persistence_Object_Identifier', sha1($serializedSource), true);
 }
 /**
  * @test
  */
 public function isTagIgnoredWorksWithOldConfiguration()
 {
     $settings = ['reflection' => ['ignoredTags' => ['ignored']]];
     $this->reflectionService->injectSettings($settings);
     $this->assertTrue($this->reflectionService->_call('isTagIgnored', 'ignored'));
     $this->assertFalse($this->reflectionService->_call('isTagIgnored', 'notignored'));
 }
 /**
  * Traverses all aspect containers, their aspects and their advisors and adds the
  * methods and their advices to the (usually empty) array of intercepted methods.
  *
  * @param array &$interceptedMethods An array (empty or not) which contains the names of the intercepted methods and additional information
  * @param array $methods An array of class and method names which are matched against the pointcut (class name = name of the class or interface the method was declared)
  * @param string $targetClassName Name of the class the pointcut should match with
  * @param array &$aspectContainers All aspects to take into consideration
  * @return void
  */
 protected function addAdvicedMethodsToInterceptedMethods(array &$interceptedMethods, array $methods, $targetClassName, array &$aspectContainers)
 {
     $pointcutQueryIdentifier = 0;
     foreach ($aspectContainers as $aspectContainer) {
         if (!$aspectContainer->getCachedTargetClassNameCandidates()->hasClassName($targetClassName)) {
             continue;
         }
         foreach ($aspectContainer->getAdvisors() as $advisor) {
             $pointcut = $advisor->getPointcut();
             foreach ($methods as $method) {
                 list($methodDeclaringClassName, $methodName) = $method;
                 if ($this->reflectionService->isMethodFinal($targetClassName, $methodName)) {
                     continue;
                 }
                 if ($this->reflectionService->isMethodStatic($targetClassName, $methodName)) {
                     continue;
                 }
                 if ($pointcut->matches($targetClassName, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier)) {
                     $advice = $advisor->getAdvice();
                     $interceptedMethods[$methodName]['groupedAdvices'][get_class($advice)][] = ['advice' => $advice, 'runtimeEvaluationsClosureCode' => $pointcut->getRuntimeEvaluationsClosureCode()];
                     $interceptedMethods[$methodName]['declaringClassName'] = $methodDeclaringClassName;
                 }
                 $pointcutQueryIdentifier++;
             }
         }
     }
 }
 /**
  * Checks if the specified method matches against the method name
  * expression.
  *
  * Returns TRUE if method name, visibility and arguments constraints match and the target
  * method is not final.
  *
  * @param string $className Ignored in this pointcut filter
  * @param string $methodName Name of the method to match against
  * @param string $methodDeclaringClassName Name of the class the method was originally declared in
  * @param mixed $pointcutQueryIdentifier Some identifier for this query - must at least differ from a previous identifier. Used for circular reference detection.
  * @return boolean TRUE if the class matches, otherwise FALSE
  * @throws Exception
  */
 public function matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier)
 {
     $matchResult = preg_match('/^' . $this->methodNameFilterExpression . '$/', $methodName);
     if ($matchResult === false) {
         throw new Exception('Error in regular expression', 1168876915);
     } elseif ($matchResult !== 1) {
         return false;
     }
     switch ($this->methodVisibility) {
         case 'public':
             if (!($methodDeclaringClassName !== null && $this->reflectionService->isMethodPublic($methodDeclaringClassName, $methodName))) {
                 return false;
             }
             break;
         case 'protected':
             if (!($methodDeclaringClassName !== null && $this->reflectionService->isMethodProtected($methodDeclaringClassName, $methodName))) {
                 return false;
             }
             break;
     }
     if ($methodDeclaringClassName !== null && $this->reflectionService->isMethodFinal($methodDeclaringClassName, $methodName)) {
         return false;
     }
     $methodArguments = $methodDeclaringClassName === null ? [] : $this->reflectionService->getMethodParameters($methodDeclaringClassName, $methodName);
     foreach (array_keys($this->methodArgumentConstraints) as $argumentName) {
         $objectAccess = explode('.', $argumentName, 2);
         $argumentName = $objectAccess[0];
         if (!array_key_exists($argumentName, $methodArguments)) {
             $this->systemLogger->log('The argument "' . $argumentName . '" declared in pointcut does not exist in method ' . $methodDeclaringClassName . '->' . $methodName, LOG_NOTICE);
             return false;
         }
     }
     return true;
 }
 /**
  * Generate a view with the given name for the given package and controller
  *
  * @param string $packageKey The package key of the controller's package
  * @param string $subpackage An optional subpackage name
  * @param string $controllerName The name of the new controller
  * @param string $viewName The name of the view
  * @param string $templateName The name of the view
  * @param boolean $overwrite Overwrite any existing files?
  * @return array An array of generated filenames
  */
 public function generateView($packageKey, $subpackage, $controllerName, $viewName, $templateName, $overwrite = false)
 {
     list($baseNamespace) = $this->getPrimaryNamespaceAndEntryPath($this->packageManager->getPackage($packageKey));
     $viewName = ucfirst($viewName);
     $templatePathAndFilename = 'resource://Neos.Kickstarter/Private/Generator/View/' . $templateName . 'Template.html';
     $contextVariables = array();
     $contextVariables['packageKey'] = $packageKey;
     $contextVariables['subpackage'] = $subpackage;
     $contextVariables['isInSubpackage'] = $subpackage != '';
     $contextVariables['controllerName'] = $controllerName;
     $contextVariables['viewName'] = $viewName;
     $contextVariables['modelName'] = strtolower($controllerName[0]) . substr($controllerName, 1);
     $contextVariables['repositoryClassName'] = '\\' . trim($baseNamespace, '\\') . ($subpackage != '' ? '\\' . $subpackage : '') . '\\Domain\\Repository\\' . $controllerName . 'Repository';
     $contextVariables['modelFullClassName'] = '\\' . trim($baseNamespace, '\\') . ($subpackage != '' ? '\\' . $subpackage : '') . '\\Domain\\Model\\' . $controllerName;
     $contextVariables['modelClassName'] = ucfirst($contextVariables['modelName']);
     $modelClassSchema = $this->reflectionService->getClassSchema($contextVariables['modelFullClassName']);
     if ($modelClassSchema !== null) {
         $contextVariables['properties'] = $modelClassSchema->getProperties();
         if (isset($contextVariables['properties']['Persistence_Object_Identifier'])) {
             unset($contextVariables['properties']['Persistence_Object_Identifier']);
         }
     }
     if (!isset($contextVariables['properties']) || $contextVariables['properties'] === array()) {
         $contextVariables['properties'] = array('name' => array('type' => 'string'));
     }
     $fileContent = $this->renderTemplate($templatePathAndFilename, $contextVariables);
     $subpackagePath = $subpackage != '' ? $subpackage . '/' : '';
     $viewFilename = $viewName . '.html';
     $viewPath = 'resource://' . $packageKey . '/Private/Templates/' . $subpackagePath . $controllerName . '/';
     $targetPathAndFilename = $viewPath . $viewFilename;
     $this->generateFile($targetPathAndFilename, $fileContent, $overwrite);
     return $this->generatedFiles;
 }
 /**
  * Returns a proxy class object for the specified original class.
  *
  * If no such proxy class has been created yet by this renderer,
  * this function will create one and register it for later use.
  *
  * If the class is not proxable, FALSE will be returned
  *
  * @param string $fullClassName Name of the original class
  * @return ProxyClass|boolean
  */
 public function getProxyClass($fullClassName)
 {
     if (interface_exists($fullClassName) || in_array(BaseTestCase::class, class_parents($fullClassName))) {
         return false;
     }
     if (class_exists($fullClassName) === false) {
         return false;
     }
     $classReflection = new \ReflectionClass($fullClassName);
     if ($classReflection->isInternal() === true) {
         return false;
     }
     $proxyAnnotation = $this->reflectionService->getClassAnnotation($fullClassName, Flow\Proxy::class);
     if ($proxyAnnotation !== null && $proxyAnnotation->enabled === false) {
         return false;
     }
     if (in_array(substr($fullClassName, 0, $this->blacklistedSubPackagesLength), $this->blacklistedSubPackages)) {
         return false;
     }
     // Annotation classes (like \Neos\Flow\Annotations\Entity) must never be proxied because that would break the Doctrine AnnotationParser
     if ($classReflection->isFinal() && preg_match('/^\\s?\\*\\s?\\@Annotation\\s/m', $classReflection->getDocComment()) === 1) {
         return false;
     }
     if (!isset($this->proxyClasses[$fullClassName])) {
         $this->proxyClasses[$fullClassName] = new ProxyClass($fullClassName);
         $this->proxyClasses[$fullClassName]->injectReflectionService($this->reflectionService);
     }
     return $this->proxyClasses[$fullClassName];
 }
 /**
  * This method is used to optimize the matching process.
  *
  * @param ClassNameIndex $classNameIndex
  * @return ClassNameIndex
  */
 public function reduceTargetClassNames(ClassNameIndex $classNameIndex)
 {
     $classNames = $this->reflectionService->getClassesContainingMethodsAnnotatedWith($this->annotation);
     $annotatedIndex = new ClassNameIndex();
     $annotatedIndex->setClassNames($classNames);
     return $classNameIndex->intersect($annotatedIndex);
 }
 /**
  * @return void
  */
 public function initializeObject()
 {
     $this->imageVariantClassNames = $this->reflectionService->getAllSubClassNamesForClass(ImageVariant::class);
     array_unshift($this->imageVariantClassNames, ImageVariant::class);
     $this->assetClassNames = $this->reflectionService->getAllImplementationClassNamesForInterface(AssetInterface::class);
     $this->dateTimeClassNames = $this->reflectionService->getAllSubClassNamesForClass('DateTime');
     array_unshift($this->dateTimeClassNames, 'DateTime');
 }
 /**
  * Returns the method's visibility string found by the reflection service
  * Note: If the reflection service has no information about this method,
  * 'public' is returned.
  *
  * @return string One of 'public', 'protected' or 'private'
  */
 protected function getMethodVisibilityString()
 {
     if ($this->reflectionService->isMethodProtected($this->fullOriginalClassName, $this->methodName)) {
         return 'protected';
     } elseif ($this->reflectionService->isMethodPrivate($this->fullOriginalClassName, $this->methodName)) {
         return 'private';
     }
     return 'public';
 }
 /**
  * @test
  */
 public function getTypeOfChildPropertyShouldRemoveLeadingBackslashesForAnnotationParameters()
 {
     $this->mockReflectionService->expects($this->any())->method('getMethodParameters')->with('TheTargetType', '__construct')->will($this->returnValue([]));
     $this->mockReflectionService->expects($this->any())->method('hasMethod')->with('TheTargetType', 'setThePropertyName')->will($this->returnValue(false));
     $this->mockReflectionService->expects($this->any())->method('getClassPropertyNames')->with('TheTargetType')->will($this->returnValue(['thePropertyName']));
     $this->mockReflectionService->expects($this->any())->method('getPropertyTagValues')->with('TheTargetType', 'thePropertyName')->will($this->returnValue(['\\TheTypeOfSubObject']));
     $configuration = new PropertyMappingConfiguration();
     $configuration->setTypeConverterOptions(ObjectConverter::class, []);
     $this->assertEquals('TheTypeOfSubObject', $this->converter->getTypeOfChildProperty('TheTargetType', 'thePropertyName', $configuration));
 }
 /**
  * @test
  */
 public function resolveValidatorObjectNameCallsGetValidatorType()
 {
     $mockObjectManager = $this->createMock(ObjectManagerInterface::class);
     $mockObjectManager->expects($this->any())->method('get')->with(ReflectionService::class)->will($this->returnValue($this->mockReflectionService));
     $this->mockReflectionService->expects($this->any())->method('getAllImplementationClassNamesForInterface')->with(ValidatorInterface::class)->will($this->returnValue([]));
     $validatorResolver = $this->getAccessibleMock(ValidatorResolver::class, ['getValidatorType']);
     $validatorResolver->_set('objectManager', $mockObjectManager);
     $validatorResolver->expects($this->once())->method('getValidatorType')->with('someDataType');
     $validatorResolver->_call('resolveValidatorObjectName', 'someDataType');
 }
 /**
  * Builds a base validator conjunction for the given data type.
  *
  * The base validation rules are those which were declared directly in a class (typically
  * a model) through some validate annotations on properties.
  *
  * If a property holds a class for which a base validator exists, that property will be
  * checked as well, regardless of a validate annotation
  *
  * Additionally, if a custom validator was defined for the class in question, it will be added
  * to the end of the conjunction. A custom validator is found if it follows the naming convention
  * "Replace '\Model\' by '\Validator\' and append 'Validator'".
  *
  * Example: $targetClassName is Neos\Foo\Domain\Model\Quux, then the validator will be found if it has the
  * name Neos\Foo\Domain\Validator\QuuxValidator
  *
  * @param string $indexKey The key to use as index in $this->baseValidatorConjunctions; calculated from target class name and validation groups
  * @param string $targetClassName The data type to build the validation conjunction for. Needs to be the fully qualified class name.
  * @param array $validationGroups The validation groups to build the validator for
  * @return void
  * @throws Exception\NoSuchValidatorException
  * @throws \InvalidArgumentException
  */
 protected function buildBaseValidatorConjunction($indexKey, $targetClassName, array $validationGroups)
 {
     $conjunctionValidator = new ConjunctionValidator();
     $this->baseValidatorConjunctions[$indexKey] = $conjunctionValidator;
     if (!TypeHandling::isSimpleType($targetClassName) && class_exists($targetClassName)) {
         // Model based validator
         $classSchema = $this->reflectionService->getClassSchema($targetClassName);
         if ($classSchema !== null && $classSchema->isAggregateRoot()) {
             $objectValidator = new AggregateBoundaryValidator(array());
         } else {
             $objectValidator = new GenericObjectValidator([]);
         }
         $conjunctionValidator->addValidator($objectValidator);
         foreach ($this->reflectionService->getClassPropertyNames($targetClassName) as $classPropertyName) {
             $classPropertyTagsValues = $this->reflectionService->getPropertyTagsValues($targetClassName, $classPropertyName);
             if (!isset($classPropertyTagsValues['var'])) {
                 throw new \InvalidArgumentException(sprintf('There is no @var annotation for property "%s" in class "%s".', $classPropertyName, $targetClassName), 1363778104);
             }
             try {
                 $parsedType = TypeHandling::parseType(trim(implode('', $classPropertyTagsValues['var']), ' \\'));
             } catch (InvalidTypeException $exception) {
                 throw new \InvalidArgumentException(sprintf(' @var annotation of ' . $exception->getMessage(), 'class "' . $targetClassName . '", property "' . $classPropertyName . '"'), 1315564744, $exception);
             }
             if ($this->reflectionService->isPropertyAnnotatedWith($targetClassName, $classPropertyName, Flow\IgnoreValidation::class)) {
                 continue;
             }
             $propertyTargetClassName = $parsedType['type'];
             if (TypeHandling::isCollectionType($propertyTargetClassName) === true) {
                 $collectionValidator = $this->createValidator(Validator\CollectionValidator::class, ['elementType' => $parsedType['elementType'], 'validationGroups' => $validationGroups]);
                 $objectValidator->addPropertyValidator($classPropertyName, $collectionValidator);
             } elseif (!TypeHandling::isSimpleType($propertyTargetClassName) && $this->objectManager->isRegistered($propertyTargetClassName) && $this->objectManager->getScope($propertyTargetClassName) === Configuration::SCOPE_PROTOTYPE) {
                 $validatorForProperty = $this->getBaseValidatorConjunction($propertyTargetClassName, $validationGroups);
                 if (count($validatorForProperty) > 0) {
                     $objectValidator->addPropertyValidator($classPropertyName, $validatorForProperty);
                 }
             }
             $validateAnnotations = $this->reflectionService->getPropertyAnnotations($targetClassName, $classPropertyName, Flow\Validate::class);
             foreach ($validateAnnotations as $validateAnnotation) {
                 if (count(array_intersect($validateAnnotation->validationGroups, $validationGroups)) === 0) {
                     // In this case, the validation groups for the property do not match current validation context
                     continue;
                 }
                 $newValidator = $this->createValidator($validateAnnotation->type, $validateAnnotation->options);
                 if ($newValidator === null) {
                     throw new Exception\NoSuchValidatorException('Invalid validate annotation in ' . $targetClassName . '::' . $classPropertyName . ': Could not resolve class name for  validator "' . $validateAnnotation->type . '".', 1241098027);
                 }
                 $objectValidator->addPropertyValidator($classPropertyName, $newValidator);
             }
         }
         if (count($objectValidator->getPropertyValidators()) === 0) {
             $conjunctionValidator->removeValidator($objectValidator);
         }
     }
     $this->addCustomValidators($targetClassName, $conjunctionValidator);
 }
 /**
  * Returns all registered asset usage strategies
  *
  * @return array<\Neos\Media\Domain\Strategy\AssetUsageStrategyInterface>
  * @throws \Neos\Flow\ObjectManagement\Exception\UnknownObjectException
  */
 protected function getUsageStrategies()
 {
     if (is_array($this->usageStrategies)) {
         return $this->usageStrategies;
     }
     $assetUsageStrategieImplementations = $this->reflectionService->getAllImplementationClassNamesForInterface(AssetUsageStrategyInterface::class);
     foreach ($assetUsageStrategieImplementations as $assetUsageStrategieImplementationClassName) {
         $this->usageStrategies[] = $this->objectManager->get($assetUsageStrategieImplementationClassName);
     }
     return $this->usageStrategies;
 }
Example #24
0
 /**
  * Returns the names of all mapped (non-transient) classes known to this driver.
  *
  * @return array
  */
 public function getAllClassNames()
 {
     if (is_array($this->classNames)) {
         return $this->classNames;
     }
     $this->classNames = array_merge($this->reflectionService->getClassNamesByAnnotation(Flow\ValueObject::class), $this->reflectionService->getClassNamesByAnnotation(Flow\Entity::class), $this->reflectionService->getClassNamesByAnnotation(ORM\Entity::class), $this->reflectionService->getClassNamesByAnnotation(ORM\MappedSuperclass::class), $this->reflectionService->getClassNamesByAnnotation(ORM\Embeddable::class));
     $this->classNames = array_filter($this->classNames, function ($className) {
         return !interface_exists($className, false) && strpos($className, Compiler::ORIGINAL_CLASSNAME_SUFFIX) === false;
     });
     return $this->classNames;
 }
 /**
  * Initializes the the object configurations and some other parts of this Object Manager.
  *
  * @param array $packages An array of active packages to consider
  * @return void
  */
 public function initialize(array $packages)
 {
     $this->registeredClassNames = $this->registerClassFiles($packages);
     $this->reflectionService->buildReflectionData($this->registeredClassNames);
     $rawCustomObjectConfigurations = $this->configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_OBJECTS);
     $configurationBuilder = new ConfigurationBuilder();
     $configurationBuilder->injectReflectionService($this->reflectionService);
     $configurationBuilder->injectSystemLogger($this->systemLogger);
     $this->objectConfigurations = $configurationBuilder->buildObjectConfigurations($this->registeredClassNames, $rawCustomObjectConfigurations);
     $this->setObjects($this->buildObjectsArray());
 }
 /**
  * Get the constructor argument reflection for the given object type.
  *
  * @param string $className
  * @return array<array>
  */
 protected function getConstructorArgumentsForClass($className)
 {
     if (!isset($this->constructorReflectionFirstLevelCache[$className])) {
         $constructorSignature = [];
         // TODO: Check if we can get rid of this reflection service usage, directly reflecting doesn't work as the proxy class __construct has no arguments.
         if ($this->reflectionService->hasMethod($className, '__construct')) {
             $constructorSignature = $this->reflectionService->getMethodParameters($className, '__construct');
         }
         $this->constructorReflectionFirstLevelCache[$className] = $constructorSignature;
     }
     return $this->constructorReflectionFirstLevelCache[$className];
 }
 /**
  * @test
  */
 public function prepareArgumentsRegistersAnnotationBasedArgumentsWithoutDescriptionIfDebugModeIsDisabled()
 {
     $dataCacheMock = $this->getMockBuilder(\Neos\Cache\Frontend\VariableFrontend::class)->disableOriginalConstructor()->getMock();
     $dataCacheMock->expects($this->any())->method('has')->will($this->returnValue(true));
     $dataCacheMock->expects($this->any())->method('get')->will($this->returnValue(array()));
     $viewHelper = new \Neos\FluidAdaptor\Core\Fixtures\TestViewHelper2();
     $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with(\Neos\FluidAdaptor\Core\Fixtures\TestViewHelper2::class, 'render')->will($this->returnValue($this->fixtureMethodParameters));
     $this->mockReflectionService->expects($this->once())->method('getMethodTagsValues');
     $viewHelper->injectObjectManager($this->mockObjectManager);
     $expected = array('param1' => new \Neos\FluidAdaptor\Core\ViewHelper\ArgumentDefinition('param1', 'integer', '', true, null, true), 'param2' => new \Neos\FluidAdaptor\Core\ViewHelper\ArgumentDefinition('param2', 'array', '', true, null, true), 'param3' => new \Neos\FluidAdaptor\Core\ViewHelper\ArgumentDefinition('param3', 'string', '', false, 'default', true));
     $this->assertEquals($expected, $viewHelper->prepareArguments(), 'Annotation based arguments were not registered.');
 }
 /**
  * @test
  * @expectedException \Neos\Flow\Property\Exception\InvalidTargetException
  */
 public function convertFromShouldThrowExceptionIfRequiredConstructorParameterWasNotFound()
 {
     $source = ['propertyX' => 'bar'];
     $object = new ClassWithSettersAndConstructor('param1');
     $convertedChildProperties = ['property2' => 'bar'];
     $this->mockReflectionService->expects($this->once())->method('hasMethod')->with(ClassWithSettersAndConstructor::class, '__construct')->will($this->returnValue(true));
     $this->mockReflectionService->expects($this->once())->method('getMethodParameters')->with(ClassWithSettersAndConstructor::class, '__construct')->will($this->returnValue(array('property1' => array('optional' => false, 'type' => null))));
     $this->mockObjectManager->expects($this->once())->method('getClassNameByObjectName')->with(ClassWithSettersAndConstructor::class)->will($this->returnValue(ClassWithSettersAndConstructor::class));
     $configuration = $this->buildConfiguration(array(PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED => true));
     $result = $this->converter->convertFrom($source, ClassWithSettersAndConstructor::class, $convertedChildProperties, $configuration);
     $this->assertSame($object, $result);
 }
 /**
  * Builds the class documentation block for the specified class keeping doc comments and vital annotations
  *
  * @return string $methodDocumentation DocComment for the given method
  */
 protected function buildClassDocumentation()
 {
     $classDocumentation = "/**\n";
     $classReflection = new ClassReflection($this->fullOriginalClassName);
     $classDescription = $classReflection->getDescription();
     $classDocumentation .= ' * ' . str_replace("\n", "\n * ", $classDescription) . "\n";
     foreach ($this->reflectionService->getClassAnnotations($this->fullOriginalClassName) as $annotation) {
         $classDocumentation .= ' * ' . Compiler::renderAnnotation($annotation) . "\n";
     }
     $classDocumentation .= " */\n";
     return $classDocumentation;
 }
 /**
  * If $this->uriPattern is specified, this will be returned, otherwise identity properties of $this->objectType
  * are returned in the format {property1}/{property2}/{property3}.
  * If $this->objectType does not contain identity properties, an empty string is returned.
  *
  * @return string
  */
 public function getUriPattern()
 {
     if ($this->uriPattern === null) {
         $classSchema = $this->reflectionService->getClassSchema($this->objectType);
         $identityProperties = $classSchema->getIdentityProperties();
         if (count($identityProperties) === 0) {
             $this->uriPattern = '';
         } else {
             $this->uriPattern = '{' . implode('}/{', array_keys($identityProperties)) . '}';
         }
     }
     return $this->uriPattern;
 }