public function get($being) { $c = array(); if (isset($this->settings["Defaults"])) { $classRaw = $this->settings["Defaults"]; $propertyRaw = $classRaw["properties"]; unset($classRaw["properties"]); $c = $this->convert($classRaw); if (class_exists($being, false)) { $propertyDefaults = $this->convert($propertyRaw); $schema = $this->reflectionService->getClassSchema($being); if (is_object($schema)) { $properties = $schema->getProperties(); } else { $properties = array_flip($this->reflectionService->getClassPropertyNames($being)); } foreach ($properties as $property => $meta) { if ($property == "FLOW3_Persistence_Identifier") { continue; } $c["properties"][$property] = $propertyDefaults; } } } return $c; }
/** * Add the Annotated Method to the Navigation * * @param \TYPO3\FLOW3\AOP\JoinPointInterface $joinPoint * @FLOW3\Before("method(public .*\Controller\.*Controller->.*Action(.*))") * @return void */ public function addNavigationitem(\TYPO3\FLOW3\AOP\JoinPointInterface $joinPoint) { $currentClassName = $joinPoint->getClassName(); $currentMethodName = $joinPoint->getMethodName(); $controllers = $this->reflectionService->getAllSubClassNamesForClass("\\TYPO3\\FLOW3\\MVC\\Controller\\ActionController"); foreach ($controllers as $className) { $methods = get_class_methods($className); if (is_array($methods)) { foreach ($methods as $methodName) { if ($this->reflectionService->isMethodAnnotatedWith($className, $methodName, "Admin\\Annotations\\Navigation")) { $annotations = $this->reflectionService->getMethodAnnotations($className, $methodName, "Admin\\Annotations\\Navigation"); foreach ($annotations as $annotation) { $action = str_replace("Action", "", $methodName); $controller = $this->helper->getControllerByClassName($className); $package = $this->objectManager->getPackageKeyByObjectName($className); $arguments = array("action" => $action, "controller" => $controller, "package" => $package); $title = !is_null($annotation->title) ? $annotation->title : sprintf("%s (%s)", $controller, $action); \Admin\Core\API::addNavigationitem($title, $annotation->position, $arguments, $annotation->priority, $annotation->parent); } } } } } $settings = $this->helper->getSettings("Admin.Navigation"); foreach ($settings as $position => $items) { foreach ($items as $title => $conf) { $priority = isset($conf["priority"]) ? $conf["priority"] : 100; $arguments = $conf["Arguments"]; \Admin\Core\API::addNavigationitem($title, strtolower($position), $arguments, $priority); } } }
/** * @test */ public function getTypeOfChildPropertyShouldUseReflectionServiceToDetermineType() { $this->mockReflectionService->expects($this->any())->method('hasMethod')->with('TheTargetType', 'setThePropertyName')->will($this->returnValue(FALSE)); $this->mockReflectionService->expects($this->any())->method('getMethodParameters')->with('TheTargetType', '__construct')->will($this->returnValue(array('thePropertyName' => array('type' => 'TheTypeOfSubObject', 'elementType' => NULL)))); $configuration = new \TYPO3\FLOW3\Property\PropertyMappingConfiguration(); $configuration->setTypeConverterOptions('TYPO3\\FLOW3\\Property\\TypeConverter\\ObjectConverter', array()); $this->assertEquals('TheTypeOfSubObject', $this->converter->getTypeOfChildProperty('TheTargetType', 'thePropertyName', $configuration)); }
/** * @test */ public function getAvailableCommandsReturnsAllAvailableCommands() { $commandManager = new CommandManager(); $commandManager->injectReflectionService($this->mockReflectionService); $mockCommandControllerClassNames = array('TYPO3\\FLOW3\\Tests\\Unit\\Cli\\Fixtures\\Command\\MockACommandController', 'TYPO3\\FLOW3\\Tests\\Unit\\Cli\\Fixtures\\Command\\MockBCommandController'); $this->mockReflectionService->expects($this->once())->method('getAllSubClassNamesForClass')->with('TYPO3\\FLOW3\\Cli\\CommandController')->will($this->returnValue($mockCommandControllerClassNames)); $commands = $commandManager->getAvailableCommands(); $this->assertEquals(3, count($commands)); $this->assertEquals('typo3.flow3.tests.unit.cli.fixtures:mocka:foo', $commands[0]->getCommandIdentifier()); $this->assertEquals('typo3.flow3.tests.unit.cli.fixtures:mocka:bar', $commands[1]->getCommandIdentifier()); $this->assertEquals('typo3.flow3.tests.unit.cli.fixtures:mockb:baz', $commands[2]->getCommandIdentifier()); }
/** * Sets up this test case */ public function setUp() { $this->identityRoutePart = $this->getAccessibleMock('TYPO3\\FLOW3\\Mvc\\Routing\\IdentityRoutePart', array('createPathSegmentForObject')); $this->mockPersistenceManager = $this->getMock('TYPO3\\FLOW3\\Persistence\\PersistenceManagerInterface'); $this->identityRoutePart->_set('persistenceManager', $this->mockPersistenceManager); $this->mockReflectionService = $this->getMock('TYPO3\\FLOW3\\Reflection\\ReflectionService'); $this->mockClassSchema = $this->getMock('TYPO3\\FLOW3\\Reflection\\ClassSchema', array(), array(), '', FALSE); $this->mockReflectionService->expects($this->any())->method('getClassSchema')->will($this->returnValue($this->mockClassSchema)); $this->identityRoutePart->_set('reflectionService', $this->mockReflectionService); $this->mockObjectPathMappingRepository = $this->getMock('TYPO3\\FLOW3\\Mvc\\Routing\\ObjectPathMappingRepository'); $this->identityRoutePart->_set('objectPathMappingRepository', $this->mockObjectPathMappingRepository); }
/** * Lifecycle method, called after all dependencies have been injected. * Here, the typeConverter array gets initialized. * * @return void * @throws \TYPO3\FLOW3\Property\Exception\DuplicateTypeConverterException */ public function initializeObject() { foreach ($this->reflectionService->getAllImplementationClassNamesForInterface('TYPO3\\FLOW3\\Property\\TypeConverterInterface') as $typeConverterClassName) { $typeConverter = $this->objectManager->get($typeConverterClassName); foreach ($typeConverter->getSupportedSourceTypes() as $supportedSourceType) { if (isset($this->typeConverters[$supportedSourceType][$typeConverter->getSupportedTargetType()][$typeConverter->getPriority()])) { throw new \TYPO3\FLOW3\Property\Exception\DuplicateTypeConverterException('There exist at least two converters which handle the conversion from "' . $supportedSourceType . '" to "' . $typeConverter->getSupportedTargetType() . '" with priority "' . $typeConverter->getPriority() . '": ' . get_class($this->typeConverters[$supportedSourceType][$typeConverter->getSupportedTargetType()][$typeConverter->getPriority()]) . ' and ' . get_class($typeConverter), 1297951378); } $this->typeConverters[$supportedSourceType][$typeConverter->getSupportedTargetType()][$typeConverter->getPriority()] = $typeConverter; } } }
/** * Checks if the specified method matches with the method tag filter pattern * * @param string $className Name of the class to check against - not used here * @param string $methodName Name of the method * @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 - not used here * @return boolean TRUE if the class matches, otherwise FALSE * @throws \TYPO3\FLOW3\Aop\Exception */ public function matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier) { if ($methodDeclaringClassName === NULL || !method_exists($methodDeclaringClassName, $methodName)) { return FALSE; } foreach ($this->reflectionService->getMethodTagsValues($methodDeclaringClassName, $methodName) as $tag => $values) { $matchResult = preg_match('/^' . $this->methodTagFilterExpression . '$/i', $tag); if ($matchResult === FALSE) { throw new \TYPO3\FLOW3\Aop\Exception('Error in regular expression "' . $this->methodTagFilterExpression . '" in pointcut method tag filter', 1229343988); } if ($matchResult === 1) { return TRUE; } } return FALSE; }
/** * 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 \TYPO3\FLOW3\Aop\Exception */ public function matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier) { $matchResult = preg_match('/^' . $this->methodNameFilterExpression . '$/', $methodName); if ($matchResult === FALSE) { throw new \TYPO3\FLOW3\Aop\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 ? array() : $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; }
/** * This method is used to optimize the matching process. * * @param \TYPO3\FLOW3\Aop\Builder\ClassNameIndex $classNameIndex * @return \TYPO3\FLOW3\Aop\Builder\ClassNameIndex */ public function reduceTargetClassNames(\TYPO3\FLOW3\Aop\Builder\ClassNameIndex $classNameIndex) { $classNames = $this->reflectionService->getClassesContainingMethodsAnnotatedWith($this->annotation); $annotatedIndex = new \TYPO3\FLOW3\Aop\Builder\ClassNameIndex(); $annotatedIndex->setClassNames($classNames); return $classNameIndex->intersect($annotatedIndex); }
/** * @test */ public function resolveValidatorObjectNameCanResolveShortNamesOfBuiltInValidators() { $this->mockObjectManager->expects($this->at(0))->method('isRegistered')->with('Foo')->will($this->returnValue(FALSE)); $this->mockObjectManager->expects($this->at(1))->method('isRegistered')->with('TYPO3\\FLOW3\\Validation\\Validator\\FooValidator')->will($this->returnValue(TRUE)); $this->mockReflectionService->expects($this->atLeastOnce())->method('isClassImplementationOf')->with('TYPO3\\FLOW3\\Validation\\Validator\\FooValidator', 'TYPO3\\FLOW3\\Validation\\Validator\\ValidatorInterface')->will($this->returnValue(TRUE)); $this->assertSame('TYPO3\\FLOW3\\Validation\\Validator\\FooValidator', $this->validatorResolver->_call('resolveValidatorObjectName', 'Foo')); }
/** * 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 \TYPO3\FLOW3\Object\Proxy\ProxyClass|boolean */ public function getProxyClass($fullClassName) { if (interface_exists($fullClassName) || in_array('TYPO3\\FLOW3\\Tests\\BaseTestCase', 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, 'TYPO3\\FLOW3\\Annotations\\Proxy'); if ($proxyAnnotation !== NULL && $proxyAnnotation->enabled === FALSE) { return FALSE; } if (in_array(substr($fullClassName, 0, 15), $this->blacklistedSubPackages)) { return FALSE; } if (!isset($this->proxyClasses[$fullClassName])) { $this->proxyClasses[$fullClassName] = new ProxyClass($fullClassName); $this->proxyClasses[$fullClassName]->injectReflectionService($this->reflectionService); } return $this->proxyClasses[$fullClassName]; }
/** * Builds code which registers the lifecycle shutdown method, if any. * * @param \TYPO3\FLOW3\Object\Configuration\Configuration $objectConfiguration * @return string */ protected function buildLifecycleShutdownCode(\TYPO3\FLOW3\Object\Configuration\Configuration $objectConfiguration) { $lifecycleShutdownMethodName = $objectConfiguration->getLifecycleShutdownMethodName(); if (!$this->reflectionService->hasMethod($objectConfiguration->getClassName(), $lifecycleShutdownMethodName)) { return ''; } return "\n" . ' \\TYPO3\\FLOW3\\Core\\Bootstrap::$staticObjectManager->registerShutdownObject($this, \'' . $lifecycleShutdownMethodName . '\');' . PHP_EOL; }
/** * Serializes an object as property array. * * @param object $object The object to store in the registry * @param boolean $isTopLevelItem Internal flag for managing the recursion * @return array The property array */ public function serializeObjectAsPropertyArray($object, $isTopLevelItem = TRUE) { if ($isTopLevelItem) { $this->objectReferences = new \SplObjectStorage(); } $this->objectReferences->attach($object); $className = get_class($object); $propertyArray = array(); foreach ($this->reflectionService->getClassPropertyNames($className) as $propertyName) { if ($this->reflectionService->isPropertyTaggedWith($className, $propertyName, 'transient')) { continue; } $propertyReflection = new \TYPO3\FLOW3\Reflection\PropertyReflection($className, $propertyName); $propertyValue = $propertyReflection->getValue($object); if (is_object($propertyValue) && isset($this->objectReferences[$propertyValue])) { $propertyArray[$propertyName][self::TYPE] = 'object'; $propertyArray[$propertyName][self::VALUE] = \spl_object_hash($propertyValue); continue; } $propertyClassName = is_object($propertyValue) ? get_class($propertyValue) : ''; if ($propertyClassName === 'SplObjectStorage') { $propertyArray[$propertyName][self::TYPE] = 'SplObjectStorage'; $propertyArray[$propertyName][self::VALUE] = array(); foreach ($propertyValue as $storedObject) { $propertyArray[$propertyName][self::VALUE][] = spl_object_hash($storedObject); $this->serializeObjectAsPropertyArray($storedObject, FALSE); } } elseif (is_object($propertyValue) && $propertyValue instanceof \Doctrine\Common\Collections\Collection) { $propertyArray[$propertyName][self::TYPE] = 'Collection'; $propertyArray[$propertyName][self::CLASSNAME] = get_class($propertyValue); $propertyArray[$propertyName][self::VALUE] = $this->buildStorageArrayForArrayProperty($propertyValue->toArray()); } elseif (is_object($propertyValue) && $propertyValue instanceof \ArrayObject) { $propertyArray[$propertyName][self::TYPE] = 'ArrayObject'; $propertyArray[$propertyName][self::VALUE] = $this->buildStorageArrayForArrayProperty($propertyValue->getArrayCopy()); } elseif (is_object($propertyValue) && $this->persistenceManager->isNewObject($propertyValue) === FALSE && ($this->reflectionService->isClassAnnotatedWith($propertyClassName, 'TYPO3\\FLOW3\\Annotations\\Entity') || $this->reflectionService->isClassAnnotatedWith($propertyClassName, 'TYPO3\\FLOW3\\Annotations\\ValueObject') || $this->reflectionService->isClassAnnotatedWith($propertyClassName, 'Doctrine\\ORM\\Mapping\\Entity'))) { $propertyArray[$propertyName][self::TYPE] = 'persistenceObject'; $propertyArray[$propertyName][self::VALUE] = get_class($propertyValue) . ':' . $this->persistenceManager->getIdentifierByObject($propertyValue); } elseif (is_object($propertyValue)) { $propertyObjectName = $this->objectManager->getObjectNameByClassName($propertyClassName); if ($propertyObjectName != '' && $this->objectManager->getScope($propertyObjectName) === \TYPO3\FLOW3\Object\Configuration\Configuration::SCOPE_SINGLETON) { continue; } $propertyArray[$propertyName][self::TYPE] = 'object'; $propertyArray[$propertyName][self::VALUE] = spl_object_hash($propertyValue); $this->serializeObjectAsPropertyArray($propertyValue, FALSE); } elseif (is_array($propertyValue)) { $propertyArray[$propertyName][self::TYPE] = 'array'; $propertyArray[$propertyName][self::VALUE] = $this->buildStorageArrayForArrayProperty($propertyValue); } else { $propertyArray[$propertyName][self::TYPE] = 'simple'; $propertyArray[$propertyName][self::VALUE] = $propertyValue; } } $this->objectsAsArray[spl_object_hash($object)] = array(self::CLASSNAME => $className, self::PROPERTIES => $propertyArray); if ($isTopLevelItem) { return $this->objectsAsArray; } }
/** * Returns an array of all commands * * @return array<Command> * @api */ public function getAvailableCommands() { if ($this->availableCommands === NULL) { $this->availableCommands = array(); $commandControllerClassNames = $this->reflectionService->getAllSubClassNamesForClass('TYPO3\\FLOW3\\Cli\\CommandController'); foreach ($commandControllerClassNames as $className) { if (!class_exists($className)) { continue; } foreach (get_class_methods($className) as $methodName) { if (substr($methodName, -7, 7) === 'Command') { $this->availableCommands[] = new Command($className, substr($methodName, 0, -7)); } } } } return $this->availableCommands; }
/** * 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'; }
/** * Takes an array of unparsed command line arguments and options and converts it separated * by named arguments, options and unnamed arguments. * * @param array $rawCommandLineArguments The unparsed command parts (such as "--foo") as an array * @param string $controllerObjectName Object name of the designated command controller * @param string $controllerCommandName Command name of the recognized command (ie. method name without "Command" suffix) * @return array All and exceeding command line arguments * @throws \TYPO3\FLOW3\Mvc\Exception\InvalidArgumentMixingException */ protected function parseRawCommandLineArguments(array $rawCommandLineArguments, $controllerObjectName, $controllerCommandName) { $commandLineArguments = array(); $exceedingArguments = array(); $commandMethodName = $controllerCommandName . 'Command'; $commandMethodParameters = $this->reflectionService->getMethodParameters($controllerObjectName, $commandMethodName); $requiredArguments = array(); $optionalArguments = array(); $argumentNames = array(); foreach ($commandMethodParameters as $parameterName => $parameterInfo) { $argumentNames[] = $parameterName; if ($parameterInfo['optional'] === FALSE) { $requiredArguments[strtolower($parameterName)] = array('parameterName' => $parameterName, 'type' => $parameterInfo['type']); } else { $optionalArguments[strtolower($parameterName)] = array('parameterName' => $parameterName, 'type' => $parameterInfo['type']); } } $decidedToUseNamedArguments = FALSE; $decidedToUseUnnamedArguments = FALSE; $argumentIndex = 0; while (count($rawCommandLineArguments) > 0) { $rawArgument = array_shift($rawCommandLineArguments); if ($rawArgument[0] === '-') { if ($rawArgument[1] === '-') { $rawArgument = substr($rawArgument, 2); } else { $rawArgument = substr($rawArgument, 1); } $argumentName = $this->extractArgumentNameFromCommandLinePart($rawArgument); if (isset($optionalArguments[$argumentName])) { $argumentValue = $this->getValueOfCurrentCommandLineOption($rawArgument, $rawCommandLineArguments, $optionalArguments[$argumentName]['type']); $commandLineArguments[$optionalArguments[$argumentName]['parameterName']] = $argumentValue; } elseif (isset($requiredArguments[$argumentName])) { if ($decidedToUseUnnamedArguments) { throw new \TYPO3\FLOW3\Mvc\Exception\InvalidArgumentMixingException(sprintf('Unexpected named argument "%s". If you use unnamed arguments, all required arguments must be passed without a name.', $argumentName), 1309971821); } $decidedToUseNamedArguments = TRUE; $argumentValue = $this->getValueOfCurrentCommandLineOption($rawArgument, $rawCommandLineArguments, $requiredArguments[$argumentName]['type']); $commandLineArguments[$requiredArguments[$argumentName]['parameterName']] = $argumentValue; unset($requiredArguments[$argumentName]); } } else { if (count($requiredArguments) > 0) { if ($decidedToUseNamedArguments) { throw new \TYPO3\FLOW3\Mvc\Exception\InvalidArgumentMixingException(sprintf('Unexpected unnamed argument "%s". If you use named arguments, all required arguments must be passed named.', $rawArgument), 1309971820); } $argument = array_shift($requiredArguments); $commandLineArguments[$argument['parameterName']] = $rawArgument; $decidedToUseUnnamedArguments = TRUE; } else { $exceedingArguments[] = $rawArgument; } } $argumentIndex++; } return array($commandLineArguments, $exceedingArguments); }
/** * Checks, if the given constraint holds for the passed result. * * @param array $constraintDefinition The constraint definition array * @param object $result The result object returned by the persistence manager * @return boolean TRUE if the query result is valid for the given constraint * @throws \TYPO3\FLOW3\Security\Exception\InvalidQueryRewritingConstraintException */ protected function checkSingleConstraintDefinitionOnResultObject(array $constraintDefinition, $result) { $referenceToThisFound = FALSE; if (!is_array($constraintDefinition['leftValue']) && strpos($constraintDefinition['leftValue'], 'this.') === 0) { $referenceToThisFound = TRUE; $propertyPath = substr($constraintDefinition['leftValue'], 5); $leftOperand = $this->getObjectValueByPath($result, $propertyPath); } else { $leftOperand = $this->getValueForOperand($constraintDefinition['leftValue']); } if (!is_array($constraintDefinition['rightValue']) && strpos($constraintDefinition['rightValue'], 'this.') === 0) { $referenceToThisFound = TRUE; $propertyPath = substr($constraintDefinition['rightValue'], 5); $rightOperand = $this->getObjectValueByPath($result, $propertyPath); } else { $rightOperand = $this->getValueForOperand($constraintDefinition['rightValue']); } if ($referenceToThisFound === FALSE) { throw new \TYPO3\FLOW3\Security\Exception\InvalidQueryRewritingConstraintException('An entity security constraint must have at least one operand that references to "this.". Got: "' . $constraintDefinition['leftValue'] . '" and "' . $constraintDefinition['rightValue'] . '"', 1277218400); } if (is_object($leftOperand) && ($this->reflectionService->isClassAnnotatedWith($this->reflectionService->getClassNameByObject($leftOperand), 'TYPO3\\FLOW3\\Annotations\\Entity') || $this->reflectionService->isClassAnnotatedWith($this->reflectionService->getClassNameByObject($leftOperand), 'Doctrine\\ORM\\Mapping\\Entity'))) { $leftOperand = $this->persistenceManager->getIdentifierByObject($leftOperand); } if (is_object($rightOperand) && ($this->reflectionService->isClassAnnotatedWith($this->reflectionService->getClassNameByObject($rightOperand), 'TYPO3\\FLOW3\\Annotations\\Entity') || $this->reflectionService->isClassAnnotatedWith($this->reflectionService->getClassNameByObject($rightOperand), 'Doctrine\\ORM\\Mapping\\Entity'))) { $rightOperand = $this->persistenceManager->getIdentifierByObject($rightOperand); } switch ($constraintDefinition['operator']) { case '!=': return $leftOperand !== $rightOperand; break; case '==': return $leftOperand === $rightOperand; break; case '<': return $leftOperand < $rightOperand; break; case '>': return $leftOperand > $rightOperand; break; case '<=': return $leftOperand <= $rightOperand; break; case '>=': return $leftOperand >= $rightOperand; break; case 'in': return in_array($leftOperand, $rightOperand); break; case 'contains': return in_array($rightOperand, $leftOperand); break; case 'matches': return count(array_intersect($leftOperand, $rightOperand)) !== 0; break; } throw new \TYPO3\FLOW3\Security\Exception\InvalidQueryRewritingConstraintException('The configured operator of the entity constraint is not valid. Got: ' . $constraintDefinition['operator'], 1277222521); }
/** * 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('TYPO3\\FLOW3\\Annotations\\ValueObject'), $this->reflectionService->getClassNamesByAnnotation('TYPO3\\FLOW3\\Annotations\\Entity'), $this->reflectionService->getClassNamesByAnnotation('Doctrine\\ORM\\Mapping\\Entity'), $this->reflectionService->getClassNamesByAnnotation('Doctrine\\ORM\\Mapping\\MappedSuperclass')); $this->classNames = array_filter($this->classNames, function ($className) { return !interface_exists($className, FALSE) && strpos($className, \TYPO3\FLOW3\Object\Proxy\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(\TYPO3\FLOW3\Configuration\ConfigurationManager::CONFIGURATION_TYPE_OBJECTS); $configurationBuilder = new \TYPO3\FLOW3\Object\Configuration\ConfigurationBuilder(); $configurationBuilder->injectReflectionService($this->reflectionService); $configurationBuilder->injectSystemLogger($this->systemLogger); $this->objectConfigurations = $configurationBuilder->buildObjectConfigurations($this->registeredClassNames, $rawCustomObjectConfigurations); $this->setObjects($this->buildObjectsArray()); }
/** * 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 \TYPO3\FLOW3\Reflection\ClassReflection($this->fullOriginalClassName); $classDescription = $classReflection->getDescription(); $classDocumentation .= ' * ' . str_replace("\n", "\n * ", $classDescription) . "\n"; foreach ($this->reflectionService->getClassAnnotations($this->fullOriginalClassName) as $annotation) { $classDocumentation .= ' * ' . \TYPO3\FLOW3\Object\Proxy\Compiler::renderAnnotation($annotation) . "\n"; } $classDocumentation .= " */\n"; return $classDocumentation; }
/** * Adds a CSRF token as argument in the URI builder * * @FLOW3\Before("setting(TYPO3.FLOW3.security.enable) && method(TYPO3\FLOW3\Mvc\Routing\UriBuilder->build())") * @param \TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint The current join point * @return void */ public function addCsrfTokenToUri(\TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint) { $uriBuilder = $joinPoint->getProxy(); $arguments = $joinPoint->getMethodArgument('arguments'); $packageKey = isset($arguments['@package']) ? $arguments['@package'] : ''; $subpackageKey = isset($arguments['@subpackage']) ? $arguments['@subpackage'] : ''; $controllerName = isset($arguments['@controller']) ? $arguments['@controller'] : 'Standard'; $actionName = (isset($arguments['@action']) ? $arguments['@action'] : 'index') . 'Action'; $possibleObjectName = '@package\\@subpackage\\Controller\\@controllerController'; $possibleObjectName = str_replace('@package', str_replace('.', '\\', $packageKey), $possibleObjectName); $possibleObjectName = str_replace('@subpackage', $subpackageKey, $possibleObjectName); $possibleObjectName = str_replace('@controller', $controllerName, $possibleObjectName); $possibleObjectName = str_replace('\\\\', '\\', $possibleObjectName); $lowercaseObjectName = strtolower($possibleObjectName); $className = $this->objectManager->getClassNameByObjectName($this->objectManager->getCaseSensitiveObjectName($lowercaseObjectName)); if ($this->policyService->hasPolicyEntryForMethod($className, $actionName) && !$this->reflectionService->isMethodAnnotatedWith($className, $actionName, 'TYPO3\\FLOW3\\Annotations\\SkipCsrfProtection')) { $internalArguments = $uriBuilder->getArguments(); $internalArguments['__csrfToken'] = $this->securityContext->getCsrfProtectionToken(); $uriBuilder->setArguments($internalArguments); } }
/** * Matches a \TYPO3\FLOW3\Mvc\RequestInterface against the configured CSRF pattern rules and searches for invalid * csrf tokens. * * @param \TYPO3\FLOW3\Mvc\RequestInterface $request The request that should be matched * @return boolean TRUE if the pattern matched, FALSE otherwise * @throws \TYPO3\FLOW3\Security\Exception\AuthenticationRequiredException */ public function matchRequest(\TYPO3\FLOW3\Mvc\RequestInterface $request) { if ($this->authenticationManager->isAuthenticated() === FALSE) { return FALSE; } $controllerClassName = $this->objectManager->getClassNameByObjectName($request->getControllerObjectName()); $actionName = $request->getControllerActionName() . 'Action'; if ($this->policyService->hasPolicyEntryForMethod($controllerClassName, $actionName) && !$this->reflectionService->isMethodTaggedWith($controllerClassName, $actionName, 'skipcsrfprotection')) { $internalArguments = $request->getInternalArguments(); if (!isset($internalArguments['__csrfToken'])) { return TRUE; } $csrfToken = $internalArguments['__csrfToken']; if (!$this->securityContext->hasCsrfProtectionTokens()) { throw new \TYPO3\FLOW3\Security\Exception\AuthenticationRequiredException('No tokens in security context, possible session timeout', 1317309673); } if ($this->securityContext->isCsrfProtectionTokenValid($csrfToken) === FALSE) { return TRUE; } } return FALSE; }
/** * 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; }
/** * Advices the dispatch method so that illegal requests are blocked before invoking * any controller. * * @FLOW3\Around("method(TYPO3\FLOW3\MVC\Dispatcher->dispatch())") * @param \TYPO3\FLOW3\AOP\JoinPointInterface $joinPoint The current joinpoint * @return mixed Result of the advice chain */ public function checkAccess(\TYPO3\FLOW3\AOP\JoinPointInterface $joinPoint) { $this->securityManager->setRequest($joinPoint->getMethodArgument('request')); $this->securityManager->setResponse($joinPoint->getMethodArgument('response')); $request = $joinPoint->getMethodArgument('request'); if (is_a($request, "\\TYPO3\\FLOW3\\MVC\\Web\\Request")) { $className = $request->getControllerObjectName(); $methodName = $request->getControllerActionName() . 'Action'; try { if (!empty($className) && $this->reflectionService->isMethodAnnotatedWith($className, $methodName, "Admin\\Annotations\\Access")) { $annotation = $this->reflectionService->getMethodAnnotation($className, $methodName, "Admin\\Annotations\\Access"); if (!is_object($user = $this->securityManager->getUser())) { return $this->securityManager->redirectToLogin($joinPoint); } if ($annotation->admin && !$user->isAdmin()) { return $this->securityManager->redirectToLogin($joinPoint); } if ($annotation->role !== null) { $hasRole = false; foreach ($user->getRoles() as $role) { if ($role->getName() == $annotation->role) { $hasRole = true; } } if (!$hasRole) { $message = new \TYPO3\FLOW3\Error\Error("You don't have access to this page!"); $this->flashMessageContainer->addMessage($message); return $this->securityManager->redirectToLogin($joinPoint); } } } } catch (\Exception $e) { } } if (is_object($adviceChain = $joinPoint->getAdviceChain())) { $result = $adviceChain->proceed($joinPoint); return $result; } }
public function getActions() { $actions = array(); $blacklist = explode(",", "index,list"); foreach ($this->reflectionService->getAllImplementationClassNamesForInterface('\\Admin\\Core\\Actions\\ActionInterface') as $actionClassName) { $a = new $actionClassName(); if (!in_array($a->getAction(), $blacklist)) { $actions[$a->getAction()] = $a->__toString(); } } ksort($actions); return $actions; }
/** * Returns all Properties of a Specified Model * * @param $model String Name of the Model * @return $properties Array of Model Properties * @author Marc Neuhaus <*****@*****.**> **/ public function getModelProperties($model) { $tmpProperties = $this->reflectionService->getClassPropertyNames($model); foreach ($tmpProperties as $property) { $properties[$property] = $this->reflectionService->getPropertyTagsValues($model, $property); if (!in_array("var", array_keys($properties[$property]))) { continue; } $properties[$property]["identity"] = in_array("identity", array_keys($properties[$property])) ? "true" : "false"; } unset($tmpProperties); return $properties; }
/** * This method is used to optimize the matching process. * * @param \TYPO3\FLOW3\Aop\Builder\ClassNameIndex $classNameIndex * @return \TYPO3\FLOW3\Aop\Builder\ClassNameIndex */ public function reduceTargetClassNames(\TYPO3\FLOW3\Aop\Builder\ClassNameIndex $classNameIndex) { if (interface_exists($this->interfaceOrClassName)) { $classNames = $this->reflectionService->getAllImplementationClassNamesForInterface($this->interfaceOrClassName); } elseif (class_exists($this->interfaceOrClassName)) { $classNames = $this->reflectionService->getAllSubClassNamesForClass($this->interfaceOrClassName); $classNames[] = $this->interfaceOrClassName; } else { $classNames = array(); } $filteredIndex = new \TYPO3\FLOW3\Aop\Builder\ClassNameIndex(); $filteredIndex->setClassNames($classNames); return $classNameIndex->intersect($filteredIndex); }
/** * Returns the identifier for the given object either from * the session, if the object was registered, or from the object * itself using a special uuid property or the internal * properties set by AOP. * * Note: this returns an UUID even if the object has not been persisted * in case of AOP-managed entities. Use isNewObject() if you need * to distinguish those cases. * * @param object $object * @return string * @api */ public function getIdentifierByObject($object) { if ($this->hasObject($object)) { return $this->objectMap[$object]; } $idPropertyNames = $this->reflectionService->getPropertyNamesByTag(get_class($object), 'id'); if (count($idPropertyNames) === 1) { $idPropertyName = $idPropertyNames[0]; return \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($object, $idPropertyName, TRUE); } elseif (property_exists($object, 'FLOW3_Persistence_Identifier')) { return \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($object, 'FLOW3_Persistence_Identifier', TRUE); } return NULL; }
public function getProperties($source) { if ($source instanceof \Doctrine\ORM\Proxy\Proxy) { $class = get_parent_class($source); } else { $class = get_class($source); } $schema = $this->reflectionService->getClassSchema($class); if (is_object($schema)) { $properties = $schema->getProperties(); } else { $properties = array_flip($this->reflectionService->getClassPropertyNames($class)); } return $properties; }
/** * This function tries to find yet unmatched dependencies which need to be injected via "inject*" setter methods. * * @param array &$objectConfigurations * @return void * @throws \TYPO3\FLOW3\Object\Exception if an injected property is private */ protected function autowireProperties(array &$objectConfigurations) { foreach ($objectConfigurations as $objectConfiguration) { $className = $objectConfiguration->getClassName(); $properties = $objectConfiguration->getProperties(); foreach (get_class_methods($className) as $methodName) { if (substr($methodName, 0, 6) === 'inject') { $propertyName = strtolower(substr($methodName, 6, 1)) . substr($methodName, 7); $autowiringAnnotation = $this->reflectionService->getMethodAnnotation($className, $methodName, 'TYPO3\\FLOW3\\Annotations\\Autowiring'); if ($autowiringAnnotation !== NULL && $autowiringAnnotation->enabled === FALSE) { continue; } if ($methodName === 'injectSettings') { $packageKey = $objectConfiguration->getPackageKey(); if ($packageKey !== NULL) { $properties[$propertyName] = new ConfigurationProperty($propertyName, $packageKey, ConfigurationProperty::PROPERTY_TYPES_SETTING); } } else { if (array_key_exists($propertyName, $properties)) { continue; } $methodParameters = $this->reflectionService->getMethodParameters($className, $methodName); if (count($methodParameters) !== 1) { $this->systemLogger->log(sprintf('Could not autowire property %s because %s() expects %s instead of exactly 1 parameter.', "{$className}::{$propertyName}", $methodName, count($methodParameters) ?: 'none'), LOG_DEBUG); continue; } $methodParameter = array_pop($methodParameters); if ($methodParameter['class'] === NULL) { $this->systemLogger->log(sprintf('Could not autowire property %s because the method parameter in %s() contained no class type hint.', "{$className}::{$propertyName}", $methodName), LOG_DEBUG); continue; } $properties[$propertyName] = new ConfigurationProperty($propertyName, $methodParameter['class'], ConfigurationProperty::PROPERTY_TYPES_OBJECT); } } } foreach ($this->reflectionService->getPropertyNamesByAnnotation($className, 'TYPO3\\FLOW3\\Annotations\\Inject') as $propertyName) { if ($this->reflectionService->isPropertyPrivate($className, $propertyName)) { $exceptionMessage = 'The property "' . $propertyName . '" in class "' . $className . '" must not be private when annotated for injection.'; throw new \TYPO3\FLOW3\Object\Exception($exceptionMessage, 1328109641); } if (!array_key_exists($propertyName, $properties)) { $objectName = trim(implode('', $this->reflectionService->getPropertyTagValues($className, $propertyName, 'var')), ' \\'); $properties[$propertyName] = new ConfigurationProperty($propertyName, $objectName, ConfigurationProperty::PROPERTY_TYPES_OBJECT); } } $objectConfiguration->setProperties($properties); } }