/**
  * Handles the web request. The response will automatically be sent to the client.
  *
  * @return void
  * @author Robert Lemke <*****@*****.**>
  */
 public function handleRequest()
 {
     $request = $this->requestBuilder->build();
     $response = $this->objectManager->create('F3\\FLOW3\\MVC\\Web\\Response');
     $this->dispatcher->dispatch($request, $response);
     $response->send();
 }
示例#2
0
 public function addTransaction($action, $method, $data, $tid, $packageKey, $subpackageKey)
 {
     $transaction = $this->objectManager->create('F3\\ExtJS\\ExtDirect\\Transaction', $this);
     $transaction->setAction($action);
     $transaction->setMethod($method);
     $transaction->setData($data);
     $transaction->setTid($tid);
     $transaction->setPackageKey($packageKey);
     $transaction->setSubpackageKey($subpackageKey);
     $this->transactions[] = $transaction;
 }
 /**
  * Commits new objects and changes to objects in the current persistence
  * session into the backend
  *
  * @return void
  * @author Robert Lemke <*****@*****.**>
  * @author Karsten Dambekalns <*****@*****.**>
  * @api
  */
 public function persistAll()
 {
     $aggregateRootObjects = new \SplObjectStorage();
     $deletedEntities = new \SplObjectStorage();
     // fetch and inspect objects from all known repositories
     $repositoryClassNames = $this->reflectionService->getAllImplementationClassNamesForInterface('F3\\FLOW3\\Persistence\\RepositoryInterface');
     foreach ($repositoryClassNames as $repositoryClassName) {
         $repository = $this->objectManager->getObject($repositoryClassName);
         $aggregateRootObjects->addAll($repository->getAddedObjects());
         $deletedEntities->addAll($repository->getRemovedObjects());
     }
     $aggregateRootObjects->addAll($this->persistenceSession->getReconstitutedObjects());
     // hand in only aggregate roots, leaving handling of subobjects to
     // the underlying storage layer
     $this->backend->setAggregateRootObjects($aggregateRootObjects);
     $this->backend->setDeletedEntities($deletedEntities);
     $this->backend->commit();
     // this needs to unregister more than just those, as at least some of
     // the subobjects are supposed to go away as well...
     // OTOH those do no harm, changes to the unused ones should not happen,
     // so all they do is eat some memory.
     foreach ($deletedEntities as $deletedEntity) {
         $this->persistenceSession->unregisterReconstitutedObject($deletedEntity);
     }
 }
 /**
  * Dispatches a signal by calling the registered Slot methods
  *
  * @param string $signalClassName Name of the class containing the signal
  * @param string $signalMethodName Method name of the signal
  * @param array $signalArguments arguments passed to the signal method
  * @return void
  * @throws \F3\FLOW3\SignalSlot\Exception\InvalidSlotException if the slot is not valid
  * @author Robert Lemke <*****@*****.**>
  * @api
  */
 public function dispatch($signalClassName, $signalMethodName, array $signalArguments)
 {
     if (!isset($this->slots[$signalClassName][$signalMethodName])) {
         return;
     }
     $this->systemLogger->log(sprintf('Dispatching signal %s::%s ...', $signalClassName, $signalMethodName), LOG_DEBUG);
     foreach ($this->slots[$signalClassName][$signalMethodName] as $slotInformation) {
         if (isset($slotInformation['object'])) {
             $object = $slotInformation['object'];
         } else {
             if (!$this->objectManager->isObjectRegistered($slotInformation['class'])) {
                 throw new \F3\FLOW3\SignalSlot\Exception\InvalidSlotException('The given class "' . $slotInformation['class'] . '" is not a registered object.', 1245673367);
             }
             $object = $this->objectManager->getObject($slotInformation['class']);
         }
         $slotArguments = $signalArguments;
         if ($slotInformation['omitSignalInformation'] !== TRUE) {
             array_unshift($slotArguments, $signalClassName . '::' . $signalMethodName);
         }
         $this->systemLogger->log(sprintf('  to slot %s::%s.', get_class($object), $slotInformation['method']), LOG_DEBUG);
         if (!method_exists($object, $slotInformation['method'])) {
             throw new \F3\FLOW3\SignalSlot\Exception\InvalidSlotException('The slot method ' . get_class($object) . '->' . $slotInformation['method'] . '() does not exist.', 1245673368);
         }
         call_user_func_array(array($object, $slotInformation['method']), $slotArguments);
     }
 }
 /**
  * Adds a custom filter to the poincut filter composite
  *
  * @param string $operator The operator
  * @param string $filterObjectName Object Name of the custom filter (value of the designator)
  * @param \F3\FLOW3\AOP\Pointcut\PointcutFilterComposite $pointcutFilterComposite An instance of the pointcut filter composite. The result (ie. the custom filter) will be added to this composite object.
  * @return void
  * @author Robert Lemke <*****@*****.**>
  */
 protected function parseDesignatorFilter($operator, $filterObjectName, \F3\FLOW3\AOP\Pointcut\PointcutFilterComposite $pointcutFilterComposite)
 {
     $customFilter = $this->objectManager->getObject($filterObjectName);
     if (!$customFilter instanceof \F3\FLOW3\AOP\Pointcut\PointcutFilterInterface) {
         throw new \F3\FLOW3\AOP\Exception\InvalidPointcutExpressionException('Invalid custom filter: "' . $filterObjectName . '" does not implement the required PoincutFilterInterface.', 1231871755);
     }
     $pointcutFilterComposite->addFilter($operator, $customFilter);
 }
 /**
  * @test
  * @expectedException \F3\FLOW3\AOP\Exception\InvalidPointcutExpressionException
  * @author Robert Lemke <*****@*****.**>
  */
 public function parseDesignatorFilterThrowsAnExceptionIfACustomFilterDoesNotImplementThePointcutFilterInterface()
 {
     $mockFilter = new \ArrayObject();
     $mockPointcutFilterComposite = $this->getMock('F3\\FLOW3\\AOP\\Pointcut\\PointcutFilterComposite', array(), array(), '', FALSE);
     $this->mockObjectManager->expects($this->once())->method('getObject')->with('F3\\Foo\\Custom\\Filter')->will($this->returnValue($mockFilter));
     $parser = $this->getMock($this->buildAccessibleProxy('F3\\FLOW3\\AOP\\Pointcut\\PointcutExpressionParser'), array('dummy'), array(), '', FALSE);
     $parser->injectObjectManager($this->mockObjectManager);
     $parser->_call('parseDesignatorFilter', '&&', 'F3\\Foo\\Custom\\Filter', $mockPointcutFilterComposite);
 }
 /**
  * @test
  * @author Robert Lemke <*****@*****.**>
  * @expectedException \F3\FLOW3\Object\Exception
  */
 public function autoWiringThrowsExceptionForUnmatchedDependenciesOfRequiredSetterInjectedDependencies()
 {
     $this->mockObjectManager->expects($this->once())->method('getObject')->with('stdClass')->will($this->throwException(new \F3\FLOW3\Object\Exception()));
     $objectName = 'F3\\FLOW3\\Tests\\Object\\Fixture\\ClassWithUnmatchedRequiredSetterDependency';
     $setterParameters = array(array('position' => 0, 'byReference' => FALSE, 'array' => FALSE, 'optional' => FALSE, 'allowsNull' => FALSE, 'class' => 'stdClass'));
     $this->mockReflectionService->expects($this->at(1))->method('getMethodParameters')->with($objectName, 'injectRequiredSetterArgument')->will($this->returnValue($setterParameters));
     $objectConfiguration = new \F3\FLOW3\Object\Configuration\Configuration($objectName);
     $this->objectBuilder->createObject($objectName, $objectConfiguration);
 }
 /**
  * @test
  * @author Bastian Waidelich <*****@*****.**>
  */
 public function registeredRoutePartHandlerIsInvokedWhenCallingResolve()
 {
     $this->route->setUriPattern('{key1}/{key2}');
     $this->route->setRoutePartsConfiguration(array('key1' => array('handler' => 'F3\\FLOW3\\MVC\\Fixture\\Web\\Routing\\MockRoutePartHandler')));
     $this->routeValues = array('key2' => 'value2');
     $mockRoutePartHandler = new \F3\FLOW3\MVC\Fixture\Web\Routing\MockRoutePartHandler();
     $this->mockObjectManager->expects($this->once())->method('getObject')->with('F3\\FLOW3\\MVC\\Fixture\\Web\\Routing\\MockRoutePartHandler')->will($this->returnValue($mockRoutePartHandler));
     $this->route->resolves($this->routeValues);
     $this->assertEquals('_resolve_invoked_/value2', $this->route->getMatchingUri());
 }
示例#9
0
 /**
  * Returns the object name of the controller defined by the package key and
  * controller name
  *
  * @return string The controller's Object Name
  * @author Robert Lemke <*****@*****.**>
  * @author Bastian Waidelich <*****@*****.**>
  * @api
  */
 public function getControllerObjectName()
 {
     $possibleObjectName = $this->controllerObjectNamePattern;
     $possibleObjectName = str_replace('@package', $this->controllerPackageKey, $possibleObjectName);
     $possibleObjectName = str_replace('@subpackage', $this->controllerSubpackageKey, $possibleObjectName);
     $possibleObjectName = str_replace('@controller', $this->controllerName, $possibleObjectName);
     $possibleObjectName = str_replace('\\\\', '\\', $possibleObjectName);
     $lowercaseObjectName = strtolower($possibleObjectName);
     $objectName = $this->objectManager->getCaseSensitiveObjectName($lowercaseObjectName);
     return $objectName !== FALSE ? $objectName : '';
 }
 /**
  * Returns an object of an appropriate validator for the given type. If no
  * validator is available NULL is returned
  *
  * @param string $validatorType Either the fully qualified class name of the validator or the short name of a built-in validator
  * @return string Name of the validator object or FALSE
  * @author Robert Lemke <*****@*****.**>
  */
 protected function resolveValidatorObjectName($validatorType)
 {
     if ($this->objectManager->isObjectRegistered($validatorType)) {
         return $validatorType;
     }
     $possibleClassName = 'F3\\FLOW3\\Validation\\Validator\\' . $this->getValidatorType($validatorType) . 'Validator';
     if ($this->objectManager->isObjectRegistered($possibleClassName)) {
         return $possibleClassName;
     }
     return FALSE;
 }
示例#11
0
 /**
  *
  * @param \F3\ExtJS\ExtDirect\Transaction $transaction
  * @return F3\FLOW3\MVC\Web\Request A request for dispatching the transaction
  */
 protected function buildDispatchRequest(\F3\ExtJS\ExtDirect\Transaction $transaction)
 {
     $dispatchRequest = $this->objectManager->create('F3\\FLOW3\\MVC\\Web\\Request');
     $dispatchRequest->injectEnvironment($this->environment);
     $dispatchRequest->setControllerPackageKey($transaction->getPackageKey());
     $dispatchRequest->setControllerSubpackageKey($transaction->getSubpackageKey());
     $dispatchRequest->setControllerName($transaction->getAction());
     $dispatchRequest->setControllerActionName($transaction->getMethod());
     $dispatchRequest->setFormat('extdirect');
     $arguments = $this->getArgumentsFromTransaction($dispatchRequest, $transaction);
     $dispatchRequest->setArguments($arguments);
     return $dispatchRequest;
 }
 /**
  * Creates and sets the configured access decision voters
  *
  * @param array $voterClassNames Array of access decision voter class names
  * @return void
  * @author Andreas Förthner <*****@*****.**>
  */
 protected function createAccessDecisionVoters(array $voterClassNames)
 {
     foreach ($voterClassNames as $voterClassName) {
         if (!$this->objectManager->isObjectRegistered($voterClassName)) {
             throw new \F3\FLOW3\Security\Exception\VoterNotFoundException('No voter of type ' . $voterClassName . ' found!', 1222267934);
         }
         $voter = $this->objectManager->getObject($voterClassName);
         if (!$voter instanceof \F3\FLOW3\Security\Authorization\AccessDecisionVoterInterface) {
             throw new \F3\FLOW3\Security\Exception\VoterNotFoundException('The found voter class did not implement \\F3\\FLOW3\\Security\\Authorization\\AccessDecisionVoterInterface', 1222268008);
         }
         $this->accessDecisionVoters[] = $voter;
     }
 }
 /**
  * Maps arguments delivered by the request object to the local controller arguments.
  *
  * @return void
  * @author Robert Lemke <*****@*****.**>
  */
 protected function mapRequestArgumentsToControllerArguments()
 {
     $optionalArgumentNames = array();
     $allArgumentNames = $this->arguments->getArgumentNames();
     foreach ($allArgumentNames as $argumentName) {
         if ($this->arguments[$argumentName]->isRequired() === FALSE) {
             $optionalArgumentNames[] = $argumentName;
         }
     }
     $validator = $this->objectManager->getObject('F3\\FLOW3\\MVC\\Controller\\ArgumentsValidator');
     $this->propertyMapper->mapAndValidate($allArgumentNames, $this->request->getArguments(), $this->arguments, $optionalArgumentNames, $validator);
     $this->argumentsMappingResults = $this->propertyMapper->getMappingResults();
 }
 /**
  * @test
  * @author Robert Lemke <*****@*****.**>
  */
 public function createRegistersShutdownObjectsAtTheComponentManager()
 {
     $className = 'SomeClass' . uniqid();
     eval('class ' . $className . ' {}');
     $object = new $className();
     $objectName = 'F3\\Virtual\\BasicClass';
     $objectConfiguration = new \F3\FLOW3\Object\Configuration\Configuration($objectName);
     $objectConfiguration->setScope('prototype');
     $this->mockObjectManager->expects($this->once())->method('isObjectRegistered')->with($objectName)->will($this->returnValue(TRUE));
     $this->mockObjectManager->expects($this->once())->method('getObjectConfiguration')->with($objectName)->will($this->returnValue($objectConfiguration));
     $this->mockObjectManager->expects($this->once())->method('registerShutdownObject')->with($object, 'shutdownObject');
     $this->mockObjectBuilder->expects($this->once())->method('createObject')->will($this->returnValue($object));
     $this->objectFactory->create($objectName);
 }
 /**
  * Factory method which creates the specified cache along with the specified kind of backend.
  * After creating the cache, it will be registered at the cache manager.
  *
  * @param string $cacheIdentifier The name / identifier of the cache to create
  * @param string $cacheObjectName Object name of the cache frontend
  * @param string $backendObjectName Object name of the cache backend
  * @param array $backendOptions (optional) Array of backend options
  * @return \F3\FLOW3\Cache\Frontend\FrontendInterface The created cache frontend
  * @author Robert Lemke <*****@*****.**>
  * @api
  */
 public function create($cacheIdentifier, $cacheObjectName, $backendObjectName, array $backendOptions = array())
 {
     $context = $this->objectManager->getContext();
     $backend = $this->objectFactory->create($backendObjectName, $context, $backendOptions);
     if (!$backend instanceof \F3\FLOW3\Cache\Backend\BackendInterface) {
         throw new \F3\FLOW3\Cache\Exception\InvalidBackendException('"' . $backendObjectName . '" is not a valid cache backend object.', 1216304301);
     }
     $cache = $this->objectFactory->create($cacheObjectName, $cacheIdentifier, $backend);
     if (!$cache instanceof \F3\FLOW3\Cache\Frontend\FrontendInterface) {
         throw new \F3\FLOW3\Cache\Exception\InvalidCacheException('"' . $cacheObjectName . '" is not a valid cache frontend object.', 1216304300);
     }
     $this->cacheManager->registerCache($cache);
     return $cache;
 }
 /**
  * Analyzes the raw request and tries to find a request handler which can handle
  * it. If none is found, an exception is thrown.
  *
  * @return \F3\FLOW3\MVC\RequestHandler A request handler
  * @throws \F3\FLOW3\MVC\Exception
  * @author Robert Lemke <*****@*****.**>
  */
 public function resolveRequestHandler()
 {
     $availableRequestHandlerClassNames = $this->reflectionService->getAllImplementationClassNamesForInterface('F3\\FLOW3\\MVC\\RequestHandlerInterface');
     $suitableRequestHandlers = array();
     foreach ($availableRequestHandlerClassNames as $requestHandlerClassName) {
         if (!$this->objectManager->isObjectRegistered($requestHandlerClassName)) {
             continue;
         }
         $requestHandler = $this->objectManager->getObject($requestHandlerClassName);
         if ($requestHandler->canHandleRequest()) {
             $priority = $requestHandler->getPriority();
             if (isset($suitableRequestHandlers[$priority])) {
                 throw new \F3\FLOW3\MVC\Exception('More than one request handler with the same priority can handle the request, but only one handler may be active at a time!', 1176475350);
             }
             $suitableRequestHandlers[$priority] = $requestHandler;
         }
     }
     if (count($suitableRequestHandlers) === 0) {
         throw new \F3\FLOW3\MVC\Exception('No suitable request handler found.', 1205414233);
     }
     ksort($suitableRequestHandlers);
     return array_pop($suitableRequestHandlers);
 }
 /**
  * @test
  * @author Robert Lemke <*****@*****.**>
  */
 public function setNewValidatorConjunctionCanHandleShortValidatorNames()
 {
     $mockValidator1 = $this->getMock('F3\\FLOW3\\Validation\\Validator\\ValidatorInterface');
     $mockValidator2 = $this->getMock('F3\\FLOW3\\Validation\\Validator\\ValidatorInterface');
     $mockValidatorChain = $this->getMock('F3\\FLOW3\\Validation\\Validator\\ConjunctionValidator', array(), array(), '', FALSE);
     $mockValidatorChain->expects($this->at(0))->method('addValidator')->with($mockValidator1);
     $mockValidatorChain->expects($this->at(1))->method('addValidator')->with($mockValidator2);
     $this->mockObjectFactory->expects($this->once())->method('create')->with('F3\\FLOW3\\Validation\\Validator\\ConjunctionValidator')->will($this->returnValue($mockValidatorChain));
     $this->mockObjectManager->expects($this->any())->method('isObjectRegistered')->will($this->returnValue(FALSE));
     $this->mockObjectManager->expects($this->exactly(2))->method('getObject')->will($this->onConsecutiveCalls($mockValidator1, $mockValidator2));
     $argument = $this->getMock($this->buildAccessibleProxy('F3\\FLOW3\\MVC\\Controller\\Argument'), array('dummy'), array(), '', FALSE);
     $argument->_set('objectManager', $this->mockObjectManager);
     $argument->_set('objectFactory', $this->mockObjectFactory);
     $argument->setNewValidatorConjunction(array('Validator1', 'Validator2'));
 }
 /**
  * Checks, resolves and injects dependencies as properties through calling the setter methods or setting
  * properties directly through reflection.
  *
  * @param array $properties Array of \F3\FLOW3\Object\Configuration\ConfigurationProperty for the current object
  * @param object $object The recently created instance of the current object. Dependencies will be injected to it.
  * @return void
  * @author Robert Lemke <*****@*****.**>
  */
 protected function injectProperties($properties, $object)
 {
     foreach ($properties as $propertyName => $property) {
         $propertyValue = $property->getValue();
         switch ($property->getType()) {
             case \F3\FLOW3\Object\Configuration\ConfigurationProperty::PROPERTY_TYPES_OBJECT:
                 if ($propertyValue instanceof \F3\FLOW3\Object\Configuration\Configuration) {
                     $preparedValue = $this->createObject($propertyValue->getObjectName(), $propertyValue);
                 } else {
                     if (strpos($propertyValue, '.') !== FALSE) {
                         $settingPath = explode('.', $propertyValue);
                         $settings = $this->configurationManager->getConfiguration(\F3\FLOW3\Configuration\ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, array_shift($settingPath));
                         $propertyValue = \F3\FLOW3\Utility\Arrays::getValueByPath($settings, $settingPath);
                     }
                     $preparedValue = $this->objectManager->getObject($propertyValue);
                 }
                 break;
             case \F3\FLOW3\Object\Configuration\ConfigurationProperty::PROPERTY_TYPES_STRAIGHTVALUE:
                 $preparedValue = $propertyValue;
                 break;
             case \F3\FLOW3\Object\Configuration\ConfigurationProperty::PROPERTY_TYPES_SETTING:
                 if (strpos($propertyValue, '.') !== FALSE) {
                     $settingPath = explode('.', $propertyValue);
                     $settings = $this->configurationManager->getConfiguration(\F3\FLOW3\Configuration\ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, array_shift($settingPath));
                     $preparedValue = \F3\FLOW3\Utility\Arrays::getValueByPath($settings, $settingPath);
                 } else {
                     $preparedValue = $this->configurationManager->getConfiguration(\F3\FLOW3\Configuration\ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, $propertyValue);
                 }
                 break;
         }
         $setterMethodName = 'inject' . ucfirst($propertyName);
         if (method_exists($object, $setterMethodName)) {
             $object->{$setterMethodName}($preparedValue);
             continue;
         }
         $setterMethodName = 'set' . ucfirst($propertyName);
         if (method_exists($object, $setterMethodName)) {
             $object->{$setterMethodName}($preparedValue);
             continue;
         }
         if (property_exists($object, $propertyName)) {
             $propertyReflection = new \ReflectionProperty($object, $propertyName);
             $propertyReflection->setAccessible(TRUE);
             $propertyReflection->setValue($object, $preparedValue);
         }
     }
 }
 /**
  * Creates a fresh instance of the object specified by $objectName.
  *
  * This factory method can only create objects of the scope prototype.
  * Singleton objects must be either injected by some type of Dependency Injection or
  * if that is not possible, be retrieved by the getObject() method of the
  * Object Manager
  *
  * You must use either Dependency Injection or this factory method for instantiation
  * of your objects if you need FLOW3's object management capabilities (including
  * AOP, Security and Persistence). It is absolutely okay and often advisable to
  * use the "new" operator for instantiation in your automated tests.
  *
  * @param string $objectName The name of the object to create
  * @return object The new object instance
  * @throws \InvalidArgumentException if the object name starts with a backslash
  * @throws \F3\FLOW3\Object\Exception\UnknownObjectException if an object with the given name does not exist
  * @throws \F3\FLOW3\Object\Exception\WrongScopeException if the specified object is not configured as Prototype
  * @author Robert Lemke <*****@*****.**>
  * @api
  */
 public function create($objectName)
 {
     if ($objectName[0] === '\\') {
         throw new \InvalidArgumentException('The object name must not start with a backslash, "' . $objectName . '" given.', 1243272770);
     }
     if (!$this->objectManager->isObjectRegistered($objectName)) {
         throw new \F3\FLOW3\Object\Exception\UnknownObjectException('Object "' . $objectName . '" is not registered.', 1166550023);
     }
     $objectConfiguration = $this->objectManager->getObjectConfiguration($objectName);
     if ($objectConfiguration->getScope() != 'prototype') {
         throw new \F3\FLOW3\Object\Exception\WrongScopeException('Object "' . $objectName . '" is of scope ' . $objectConfiguration->getScope() . ' but only prototype is supported by create()', 1225385285);
     }
     $overridingArguments = self::convertArgumentValuesToArgumentObjects(array_slice(func_get_args(), 1));
     $object = $this->objectBuilder->createObject($objectName, $objectConfiguration, $overridingArguments);
     $this->objectManager->registerShutdownObject($object, $objectConfiguration->getLifecycleShutdownMethodName());
     return $object;
 }
示例#20
0
 /**
  * Maps a single record into the object it represents and registers it as
  * reconstituted with the session.
  *
  * @param array $objectData
  * @return object
  * @author Karsten Dambekalns <*****@*****.**>
  */
 public function mapToObject(array $objectData)
 {
     if ($this->persistenceSession->hasIdentifier($objectData['identifier'])) {
         return $this->persistenceSession->getObjectByIdentifier($objectData['identifier']);
     } else {
         $className = $objectData['classname'];
         $classSchema = $this->reflectionService->getClassSchema($className);
         $objectConfiguration = $this->objectManager->getObjectConfiguration($className);
         $object = $this->objectBuilder->createEmptyObject($className, $objectConfiguration);
         $this->persistenceSession->registerObject($object, $objectData['identifier']);
         $this->objectBuilder->reinjectDependencies($object, $objectConfiguration);
         $this->thawProperties($object, $objectData['identifier'], $objectData, $classSchema);
         $object->FLOW3_Persistence_memorizeCleanState();
         $this->persistenceSession->registerReconstitutedObject($object);
         return $object;
     }
 }
 /**
  * Transforms strings with UUIDs or arrays with UUIDs/identity properties
  * into the requested type, if possible.
  *
  * @param mixed $propertyValue The value to transform, string or array
  * @param string $targetType The type to transform to
  * @param string $propertyName In case of an error we add this to the error message
  * @return object The object, when no transformation was possible this may return NULL as well
  */
 protected function transformToObject($propertyValue, $targetType, $propertyName)
 {
     if (is_string($propertyValue) && preg_match(self::PATTERN_MATCH_UUID, $propertyValue) === 1) {
         $object = $this->persistenceManager->getObjectByIdentifier($propertyValue);
         if ($object === FALSE) {
             $this->mappingResults->addError($this->objectManager->getObject('F3\\FLOW3\\Error\\Error', 'Querying the repository for the specified object with UUID ' . $propertyValue . ' was not successful.', 1249379517), $propertyName);
         }
     } elseif (is_array($propertyValue)) {
         if (isset($propertyValue['__identity'])) {
             $existingObject = is_array($propertyValue['__identity']) ? $this->findObjectByIdentityProperties($propertyValue['__identity'], $targetType) : $this->persistenceManager->getObjectByIdentifier($propertyValue['__identity']);
             if ($existingObject === FALSE) {
                 throw new \F3\FLOW3\Property\Exception\TargetNotFoundException('Querying the repository for the specified object was not successful.', 1237305720);
             }
             unset($propertyValue['__identity']);
             if (count($propertyValue) === 0) {
                 $object = $existingObject;
             } elseif ($existingObject !== NULL) {
                 $newObject = clone $existingObject;
                 if ($this->map(array_keys($propertyValue), $propertyValue, $newObject)) {
                     $object = $newObject;
                 }
             }
         } else {
             if (isset($this->objectConverters[$targetType])) {
                 $conversionResult = $this->objectConverters[$targetType]->convertFrom($propertyValue);
                 if ($conversionResult instanceof \F3\FLOW3\Error\Error) {
                     $this->mappingResults->addError($conversionResult, $propertyName);
                     return NULL;
                 } elseif (is_object($conversionResult) || $conversionResult === NULL) {
                     return $conversionResult;
                 }
             }
             $newObject = $this->objectManager->getObject($targetType);
             if ($this->map(array_keys($propertyValue), $propertyValue, $newObject)) {
                 return $newObject;
             }
             throw new \F3\FLOW3\Property\Exception\InvalidTargetException('Values could not be mapped to new object of type ' . $targetType . ' for property "' . $propertyName . '". (Map errors: ' . implode(' - ', $this->mappingResults->getErrors()) . ')', 1259770027);
         }
     } else {
         throw new \InvalidArgumentException('transformToObject() accepts only strings and arrays.', 1251814355);
     }
     return $object;
 }
 /**
  * Traverses the Tests directory of the given package and returns an
  * array of filenames (including path) of all files ending with "Test.php".
  *
  * @return array Filenames of all found testcase files
  * @author Robert Lemke <*****@*****.**>
  * @author Karsten Dambekalns <*****@*****.**>
  */
 protected function getTestcaseFilenames()
 {
     $packageManager = $this->objectManager->getObject('F3\\FLOW3\\Package\\PackageManagerInterface');
     $packages = array();
     $testcaseFilenames = array(self::TYPE_UNIT => array(), self::TYPE_INTEGRATION => array(), self::TYPE_SYSTEM => array());
     $testcaseClassNameMatches = array();
     preg_match('/F3\\\\([^\\\\]*)\\\\(.*)/', $this->testcaseClassName, $testcaseClassNameMatches);
     if (count($testcaseClassNameMatches) === 3) {
         $this->testcaseClassName = $testcaseClassNameMatches[2];
         if ($testcaseClassNameMatches[1] === '.*') {
             $packages = $packageManager->getActivePackages();
         } elseif ($packageManager->isPackageActive($testcaseClassNameMatches[1])) {
             $packages = array($packageManager->getPackage($testcaseClassNameMatches[1]));
         }
     } elseif ($this->packageKey == '*') {
         $packages = $packageManager->getActivePackages();
         $this->testcaseClassName = '.*Test';
     } elseif ($packageManager->isPackageActive($this->packageKey)) {
         $packages = array($packageManager->getPackage($this->packageKey));
         $this->testcaseClassName = '.*Test';
     }
     shuffle($packages);
     foreach ($packages as $package) {
         if (in_array($package->getPackageKey(), $this->testBlacklist)) {
             continue;
         }
         foreach (array(self::TYPE_UNIT => \F3\FLOW3\Package\Package::DIRECTORY_TESTS_UNIT, self::TYPE_INTEGRATION => \F3\FLOW3\Package\Package::DIRECTORY_TESTS_INTEGRATION, self::TYPE_SYSTEM => \F3\FLOW3\Package\Package::DIRECTORY_TESTS_SYSTEM) as $type => $directory) {
             $testPath = $package->getPackagePath() . $directory;
             if (is_dir($testPath)) {
                 try {
                     $testsDirectoryIterator = new \RecursiveDirectoryIterator($testPath);
                     $testcaseFilenames[$type] = $this->readDirectories($testcaseFilenames[$type], $testsDirectoryIterator);
                     \PHPUnit_Util_Filter::removeDirectoryFromFilter($package->getPackagePath() . 'Classes');
                 } catch (\Exception $exception) {
                     throw new \RuntimeException($exception->getMessage(), 1170236926);
                 }
             }
             shuffle($testcaseFilenames[$type]);
         }
     }
     return $testcaseFilenames;
 }
 /**
  * Builds the provider and token objects based on the given configuration
  *
  * @param array $providerConfigurations The configured provider settings
  * @return void
  * @author Andreas Förthner <*****@*****.**>
  */
 protected function buildProvidersAndTokensFromConfiguration(array $providerConfigurations)
 {
     foreach ($providerConfigurations as $providerName => $providerConfiguration) {
         if (!is_array($providerConfiguration) || !isset($providerConfiguration['providerClass'])) {
             throw new \F3\FLOW3\Security\Exception\InvalidAuthenticationProviderException('The configured authentication provider "' . $providerConfiguration['providerClass'] . '" could not be found!', 1248209521);
         }
         $providerObjectName = $this->providerResolver->resolveProviderClass((string) $providerConfiguration['providerClass']);
         if ($providerObjectName === NULL) {
             throw new \F3\FLOW3\Security\Exception\InvalidAuthenticationProviderException('The configured authentication provider "' . $providerConfiguration['providerClass'] . '" could not be found!', 1237330453);
         }
         $providerOptions = array();
         if (isset($providerConfiguration['options']) && is_array($providerConfiguration['options'])) {
             $providerOptions = $providerConfiguration['options'];
         }
         $providerInstance = $this->objectManager->getObject($providerObjectName, $providerName, $providerOptions);
         $this->providers[] = $providerInstance;
         foreach ($providerInstance->getTokenClassNames() as $tokenClassName) {
             $tokenInstance = $this->objectManager->getObject($tokenClassName);
             $tokenInstance->setAuthenticationProviderName($providerName);
             $this->tokens[] = $tokenInstance;
         }
         if (isset($providerConfiguration['requestPatterns']) && is_array($providerConfiguration['requestPatterns'])) {
             $requestPatterns = array();
             foreach ($providerConfiguration['requestPatterns'] as $patternType => $patternConfiguration) {
                 $requestPattern = $this->objectManager->getObject($this->requestPatternResolver->resolveRequestPatternClass($patternType));
                 $requestPattern->setPattern($patternConfiguration);
                 $requestPatterns[] = $requestPattern;
             }
             $tokenInstance->setRequestPatterns($requestPatterns);
         }
         if (isset($providerConfiguration['entryPoint']) && is_array($providerConfiguration['entryPoint'])) {
             reset($providerConfiguration['entryPoint']);
             $entryPointObjectName = key($providerConfiguration['entryPoint']);
             $entryPoint = $this->objectManager->getObject($this->entryPointResolver->resolveEntryPointClass($entryPointObjectName));
             $entryPoint->setOptions($providerConfiguration['entryPoint'][$entryPointObjectName]);
             $tokenInstance->setAuthenticationEntryPoint($entryPoint);
         }
     }
 }
示例#24
0
 /**
  * (For now) evaluates the package configuration
  *
  * @param \F3\FLOW3\Package\PackageInterface $package The package
  * @param array $packageConfiguration The configuration to evaluate
  * @return void
  * @author Robert Lemke <*****@*****.**>
  * @see initializePackages()
  * @todo needs refactoring and be moved to elsewhere (package manager)
  */
 protected function evaluatePackageConfiguration(\F3\FLOW3\Package\PackageInterface $package, array $packageConfiguration)
 {
     if (isset($packageConfiguration['classLoader'])) {
         if (isset($packageConfiguration['classLoader']['specialClassNameAndPaths'])) {
             $classLoader = $this->objectManager->getObject('F3\\FLOW3\\Resource\\ClassLoader');
             foreach ($packageConfiguration['classLoader']['specialClassNameAndPaths'] as $className => $classFilePathAndName) {
                 $classFilePathAndName = str_replace('%PATH_PACKAGE%', $package->getPackagePath(), $classFilePathAndName);
                 $classFilePathAndName = str_replace('%PATH_PACKAGE_CLASSES%', $package->getClassesPath(), $classFilePathAndName);
                 $classFilePathAndName = str_replace('%PATH_PACKAGE_RESOURCES%', $package->getResourcesPath(), $classFilePathAndName);
                 $classLoader->setSpecialClassNameAndPath($className, $classFilePathAndName);
             }
         }
         if (isset($packageConfiguration['classLoader']['includePaths'])) {
             foreach ($packageConfiguration['classLoader']['includePaths'] as $includePath) {
                 $includePath = str_replace('%PATH_PACKAGE%', $package->getPackagePath(), $includePath);
                 $includePath = str_replace('%PATH_PACKAGE_CLASSES%', $package->getClassesPath(), $includePath);
                 $includePath = str_replace('%PATH_PACKAGE_RESOURCES%', $package->getResourcesPath(), $includePath);
                 $includePath = str_replace('/', DIRECTORY_SEPARATOR, $includePath);
                 set_include_path($includePath . PATH_SEPARATOR . get_include_path());
             }
         }
     }
 }
 /**
  * Parses the tokens, starting at the current index and replaces the "new"
  * operator with a call to the object manager if the class to be instantiated
  * is registered as an object.
  *
  * @param array $tokens Tokens to parse
  * @param integer &$index Token index to start at
  * @param string &$targetCode Target source code for replacement
  * @return boolean Returns TRUE if the new operator really has been replaced, otherwise FALSE
  * @author Robert Lemke <*****@*****.**>
  */
 protected function replaceNewOperator(array $tokens, &$index, &$targetCode)
 {
     $index++;
     $newOperatorHasBeenReplaced = FALSE;
     $whitespace = '';
     while ($tokens[$index][0] === T_WHITESPACE) {
         $whitespace .= $tokens[$index][1];
         $index++;
     }
     switch ($tokens[$index][0]) {
         case T_STRING:
             $className = $tokens[$index][1];
             if ($tokens[$index + 1][0] === '(') {
                 $index++;
                 $constructorArguments = $this->parseConstructorArguments($tokens, $index);
                 if ($this->objectManager->isObjectRegistered($className)) {
                     $targetCode .= '$GLOBALS[\'TYPO3\']->getObjectManager()->getObject' . '(\'' . $className . '\', ' . $constructorArguments . ')' . $whitespace;
                     $newOperatorHasBeenReplaced = TRUE;
                 } else {
                     $targetCode .= 'new' . $whitespace . $className . '(' . $constructorArguments . ')';
                 }
             } else {
                 if ($this->objectManager->isObjectRegistered($className)) {
                     $targetCode .= '$GLOBALS[\'TYPO3\']->getObjectManager()->getObject' . '(\'' . $className . '\')' . $whitespace;
                     $newOperatorHasBeenReplaced = TRUE;
                 } else {
                     $targetCode .= 'new' . $whitespace . $className;
                 }
             }
             break;
         case T_VARIABLE:
         default:
             $targetCode .= 'new' . $whitespace;
             $targetCode .= $tokens[$index][1];
     }
     return $newOperatorHasBeenReplaced;
 }
示例#26
0
 /**
  * Initializes the AOP framework.
  *
  * During initialization the specified configuration of objects is searched for possible
  * aspect annotations. If an aspect class is found, the poincut expressions are parsed and
  * a new aspect with one or more advisors is added to the aspect registry of the AOP framework.
  * Finally all advices are woven into their target classes by generating proxy classes.
  *
  * The class names of all proxied classes is stored back in the $objectConfigurations array.
  *
  * @param array &$objectConfigurations
  * @return void
  * @author Robert Lemke <*****@*****.**>
  */
 public function initialize(array &$objectConfigurations)
 {
     if ($this->isInitialized) {
         throw new \F3\FLOW3\AOP\Exception('The AOP framework has already been initialized!', 1169550994);
     }
     $this->isInitialized = TRUE;
     if ($this->proxyBuildInformationCache->has('targetAndProxyClassNames')) {
         $this->targetAndProxyClassNames = $this->proxyBuildInformationCache->get('targetAndProxyClassNames');
     }
     if (!$this->proxyBuildInformationCache->has('allProxyClassesUpToDate')) {
         $allAvailableClassNames = $this->getAllImplementationClassesFromObjectConfigurations($objectConfigurations);
         $cachedTargetClassNames = $this->proxyBuildInformationCache->has('targetClassNames') ? $this->proxyBuildInformationCache->get('targetClassNames') : array();
         $cachedAspectClassNames = $this->proxyBuildInformationCache->has('aspectClassNames') ? $this->proxyBuildInformationCache->get('aspectClassNames') : array();
         $actualTargetClassNames = $this->getProxyableClasses($allAvailableClassNames);
         $actualAspectClassNames = $this->reflectionService->getClassNamesByTag('aspect');
         sort($actualTargetClassNames);
         sort($actualAspectClassNames);
         $this->aspectContainers = $this->buildAspectContainers($allAvailableClassNames);
         $dirtyTargetClassNames = $actualTargetClassNames;
         if ($cachedAspectClassNames === $actualAspectClassNames) {
             $validProxyClassesCount = 0;
             $outdatedProxyClassesCount = 0;
             foreach ($this->targetAndProxyClassNames as $targetClassName => $proxyClassName) {
                 if ($this->proxyClassesCache->has(str_replace('\\', '_', $proxyClassName))) {
                     $validProxyClassesCount++;
                     $dirtyTargetClassNames = array_diff($dirtyTargetClassNames, array($targetClassName));
                 } else {
                     $outdatedProxyClassesCount++;
                     unset($this->targetAndProxyClassNames[$targetClassName]);
                 }
             }
             $this->systemLogger->log(sprintf('At least one target class changed, aspects unchanged. Found %s valid and %s outdated proxy classes.', $validProxyClassesCount, $outdatedProxyClassesCount), LOG_INFO);
         } else {
             $this->systemLogger->log(sprintf('At least one aspect changed, rebuilding proxy classes for %s target classes.', count($actualTargetClassNames)), LOG_INFO);
             $this->proxyClassesCache->flush();
             $this->targetAndProxyClassNames = array();
         }
         foreach ($dirtyTargetClassNames as $targetClassName) {
             $proxyBuildResult = $this->proxyClassBuilder->buildProxyClass($targetClassName, $this->aspectContainers, $this->objectManager->getContext());
             if ($proxyBuildResult !== FALSE) {
                 $this->targetAndProxyClassNames[$targetClassName] = $proxyBuildResult['proxyClassName'];
                 $this->systemLogger->log(sprintf('Built proxy class "%s" for target class "%s" (length: %s).', $proxyBuildResult['proxyClassName'], $targetClassName, strlen($proxyBuildResult['proxyClassCode'])), LOG_DEBUG);
                 $this->proxyClassesCache->set(str_replace('\\', '_', $proxyBuildResult['proxyClassName']), $proxyBuildResult['proxyClassCode'], array($this->proxyClassesCache->getClassTag($targetClassName)));
             } else {
                 unset($this->targetAndProxyClassNames[$targetClassName]);
             }
         }
         $aspectClassesTags = array();
         foreach ($actualAspectClassNames as $aspectClassName) {
             $aspectClassesTags[] = $this->proxyBuildInformationCache->getClassTag($aspectClassName);
         }
         $this->proxyBuildInformationCache->set('targetAndProxyClassNames', $this->targetAndProxyClassNames);
         $this->proxyBuildInformationCache->set('aspectClassNames', $actualAspectClassNames, $aspectClassesTags);
         $this->proxyBuildInformationCache->set('targetClassNames', $actualTargetClassNames);
         $this->proxyBuildInformationCache->set('allProxyClassesUpToDate', '', array($this->proxyClassesCache->getClassTag()));
     }
     foreach ($this->targetAndProxyClassNames as $targetClassName => $proxyClassName) {
         if (class_exists($proxyClassName, FALSE)) {
             throw new \F3\FLOW3\AOP\Exception('Class ' . $proxyClassName . ' already exists.', 1229361833);
         }
         if (!$this->proxyClassesCache->has(str_replace('\\', '_', $proxyClassName))) {
             throw new \F3\FLOW3\AOP\Exception('No proxy class code for class "' . $proxyClassName . '" found in cache.', 1229362833);
         }
         $this->proxyClassesCache->requireOnce(str_replace('\\', '_', $proxyClassName));
         foreach ($objectConfigurations as $objectName => $objectConfiguration) {
             if ($objectConfiguration->getClassName() === $targetClassName) {
                 $objectConfigurations[$objectName]->setClassName($proxyClassName);
             }
         }
     }
 }
示例#27
0
 /**
  * Set a filter
  *
  * @param mixed $filter Object name of a filter or the actual filter object
  * @return \F3\FLOW3\MVC\Controller\Argument Returns $this (used for fluent interface)
  * @author Andreas Förthner <*****@*****.**>
  */
 public function setFilter($filter)
 {
     $this->filter = $filter instanceof \F3\FLOW3\Validation\Filter\FilterInterface ? $filter : $this->objectManager->getObject($filter);
     return $this;
 }
示例#28
0
 /**
  * Iterates through all segments in $this->uriPattern and creates
  * appropriate RoutePart instances.
  *
  * @return void
  * @author Bastian Waidelich <*****@*****.**>
  */
 public function parse()
 {
     if ($this->isParsed || $this->uriPattern === NULL || $this->uriPattern === '') {
         return;
     }
     $this->routeParts = array();
     $currentRoutePartIsOptional = FALSE;
     if (substr($this->uriPattern, -1) === '/') {
         throw new \F3\FLOW3\MVC\Exception\InvalidUriPatternException('The URI pattern "' . $this->uriPattern . '" of route "' . $this->getName() . '" ends with a slash, which is not allowed. You can put the trailing slash in brackets to make it optional.', 1234782997);
     }
     if ($this->uriPattern[0] === '/') {
         throw new \F3\FLOW3\MVC\Exception\InvalidUriPatternException('The URI pattern "' . $this->uriPattern . '" of route "' . $this->getName() . '" starts with a slash, which is not allowed.', 1234782983);
     }
     $matches = array();
     preg_match_all(self::PATTERN_EXTRACTROUTEPARTS, $this->uriPattern, $matches, PREG_SET_ORDER);
     $lastRoutePart = NULL;
     foreach ($matches as $match) {
         $routePartType = empty($match['dynamic']) ? self::ROUTEPART_TYPE_STATIC : self::ROUTEPART_TYPE_DYNAMIC;
         $routePartName = $match['content'];
         if (!empty($match['optionalStart'])) {
             if ($lastRoutePart !== NULL && $lastRoutePart->isOptional()) {
                 throw new \F3\FLOW3\MVC\Exception\InvalidUriPatternException('the URI pattern "' . $this->uriPattern . '" of route "' . $this->getName() . '" contains succesive optional Route sections, which is not allowed.', 1234562050);
             }
             $currentRoutePartIsOptional = TRUE;
         }
         $routePart = NULL;
         switch ($routePartType) {
             case self::ROUTEPART_TYPE_DYNAMIC:
                 if ($lastRoutePart instanceof \F3\FLOW3\MVC\Web\Routing\DynamicRoutePartInterface) {
                     throw new \F3\FLOW3\MVC\Exception\InvalidUriPatternException('the URI pattern "' . $this->uriPattern . '" of route "' . $this->getName() . '" contains succesive Dynamic Route Parts, which is not allowed.', 1218446975);
                 }
                 if (isset($this->routePartsConfiguration[$routePartName]['handler'])) {
                     $routePart = $this->objectManager->getObject($this->routePartsConfiguration[$routePartName]['handler']);
                     if (!$routePart instanceof \F3\FLOW3\MVC\Web\Routing\DynamicRoutePartInterface) {
                         throw new \F3\FLOW3\MVC\Exception\InvalidRoutePartHandlerException('routePart handlers must implement "\\F3\\FLOW3\\MVC\\Web\\Routing\\DynamicRoutePartInterface" in route "' . $this->getName() . '"', 1218480972);
                     }
                 } else {
                     $routePart = $this->objectFactory->create('F3\\FLOW3\\MVC\\Web\\Routing\\DynamicRoutePart');
                 }
                 if (isset($this->defaults[$routePartName])) {
                     $routePart->setDefaultValue($this->defaults[$routePartName]);
                 }
                 break;
             case self::ROUTEPART_TYPE_STATIC:
                 $routePart = $this->objectFactory->create('F3\\FLOW3\\MVC\\Web\\Routing\\StaticRoutePart');
                 if ($lastRoutePart !== NULL && $lastRoutePart instanceof \F3\FLOW3\MVC\Web\Routing\DynamicRoutePartInterface) {
                     $lastRoutePart->setSplitString($routePartName);
                 }
         }
         $routePart->setName($routePartName);
         $routePart->setOptional($currentRoutePartIsOptional);
         if ($this->lowerCase) {
             $routePart->setLowerCase(TRUE);
         }
         if (isset($this->routePartsConfiguration[$routePartName]['options'])) {
             $routePart->setOptions($this->routePartsConfiguration[$routePartName]['options']);
         }
         if (isset($this->routePartsConfiguration[$routePartName]['toLowerCase'])) {
             $routePart->setLowerCase($this->routePartsConfiguration[$routePartName]['toLowerCase']);
         }
         $this->routeParts[] = $routePart;
         if (!empty($match['optionalEnd'])) {
             if (!$currentRoutePartIsOptional) {
                 throw new \F3\FLOW3\MVC\Exception\InvalidUriPatternException('The URI pattern "' . $this->uriPattern . '" of route "' . $this->getName() . '" contains an unopened optional section.', 1234564495);
             }
             $currentRoutePartIsOptional = FALSE;
         }
         $lastRoutePart = $routePart;
     }
     if ($currentRoutePartIsOptional) {
         throw new \F3\FLOW3\MVC\Exception\InvalidUriPatternException('The URI pattern "' . $this->uriPattern . '" of route "' . $this->getName() . '" contains an unterminated optional section.', 1234563922);
     }
     $this->isParsed = TRUE;
 }