/** * @Flow\Before("method(TYPO3\Neos\Controller\Backend\ContentController->uploadAssetAction())") * @param JoinPointInterface $joinPoint The current join point * @return void */ public function rewriteSiteAssetCollection(JoinPointInterface $joinPoint) { if ($this->lookupNodeFilter === NULL || $this->lookupPropertyName === NULL) { return; } /** @var ContentController $contentController */ $contentController = $joinPoint->getProxy(); /** @var ActionRequest $actionRequest */ $actionRequest = ObjectAccess::getProperty($contentController, 'request', TRUE); $nodeContextPath = $actionRequest->getInternalArgument('__node'); if ($nodeContextPath === NULL) { return; } $node = $this->propertyMapper->convert($nodeContextPath, NodeInterface::class); $flowQuery = new FlowQuery(array($node)); /** @var NodeInterface $documentNode */ $documentNode = $flowQuery->closest($this->lookupNodeFilter)->get(0); if (!$documentNode->hasProperty($this->lookupPropertyName)) { return; } /** @var AssetCollection $assetCollection */ $assetCollection = $this->assetCollectionRepository->findByIdentifier($documentNode->getProperty($this->lookupPropertyName)); if ($assetCollection === NULL) { return; } /** @var Asset $asset */ $asset = $joinPoint->getMethodArgument('asset'); $assetCollection->addAsset($asset); $this->assetCollectionRepository->update($assetCollection); }
/** * @test */ public function convertFromUsesAppropriatePropertyPopulationMethodsInOrderConstructorSetterPublic() { $convertedObject = $this->converter->convertFrom('irrelevant', \TYPO3\Flow\Tests\Functional\Property\Fixtures\TestClass::class, array('propertyMeantForConstructorUsage' => 'theValue', 'propertyMeantForSetterUsage' => 'theValue', 'propertyMeantForPublicUsage' => 'theValue'), new PropertyMappingConfiguration()); $this->assertEquals('theValue set via Constructor', ObjectAccess::getProperty($convertedObject, 'propertyMeantForConstructorUsage', true)); $this->assertEquals('theValue set via Setter', ObjectAccess::getProperty($convertedObject, 'propertyMeantForSetterUsage', true)); $this->assertEquals('theValue', ObjectAccess::getProperty($convertedObject, 'propertyMeantForPublicUsage', true)); }
public function boot(\TYPO3\Flow\Core\Bootstrap $bootstrap) { // 1. Make Gedmo\Translatable\Entity\Translation known to Doctrine, so that it can participate in Database Schema Generation // // Internally, we use a MappingDriverChain for that, which delegates almost all of its behavior to the already-existing // FlowAnnotationDriver. We additionally add the (default doctrine) Annotation Driver for the Gedmo namespace. // // Note: We replace FlowAnnotationDriver *on a very low level* with the *MappingDriverChain* object; because this class // is only used inside EntityManagerFactory -- so we know quite exactly what methods are called on that object. $bootstrap->getSignalSlotDispatcher()->connect('TYPO3\\Flow\\Core\\Booting\\Sequence', 'beforeInvokeStep', function ($step) use($bootstrap) { if ($step->getIdentifier() === 'typo3.flow:resources') { $flowAnnotationDriver = $bootstrap->getObjectManager()->get('TYPO3\\Flow\\Persistence\\Doctrine\\Mapping\\Driver\\FlowAnnotationDriver'); $driverChain = new MappingDriverChainWithFlowAnnotationDriverAsDefault($flowAnnotationDriver); $driverChain->addDriver(new AnnotationDriver(ObjectAccess::getProperty($flowAnnotationDriver, 'reader', TRUE), FLOW_PATH_PACKAGES . 'Libraries/gedmo/doctrine-extensions/lib/Gedmo/Translatable/Entity'), 'Gedmo'); $bootstrap->getObjectManager()->setInstance('TYPO3\\Flow\\Persistence\\Doctrine\\Mapping\\Driver\\FlowAnnotationDriver', $driverChain); } }); // 2. Work around a bug in TYPO3\Flow\Persistence\Doctrine\PersistenceManager::onFlush which expects that all objects in the // Doctrine subsystem are entities known to Flow. // // The line $this->reflectionService->getClassSchema($entity)->getModelType() triggers a fatal error, for get_class($entity) == 'Gedmo\Translatable\Entity\Translation' // because this class is known only to Doctrine (see 1. above), but not to the Flow reflection service. // // As a workaround, we just add an empty placeholder class schema to the Class Schemata cache, right before the class schema is saved // inside the TYPO3\Flow\Core\Bootstrap::bootstrapShuttingDown signal (which is fired directly after "finishedCompiletimeRun"). $bootstrap->getSignalSlotDispatcher()->connect('TYPO3\\Flow\\Core\\Bootstrap', 'finishedCompiletimeRun', function () use($bootstrap) { $classSchemataCache = $bootstrap->getObjectManager()->get('TYPO3\\Flow\\Cache\\CacheManager')->getCache('Flow_Reflection_RuntimeClassSchemata'); if (!$classSchemataCache->has('Gedmo_Translatable_Entity_Translation')) { $classSchemataCache->set('Gedmo_Translatable_Entity_Translation', new ClassSchema('Gedmo\\Translatable\\Entity\\Translation')); } }); }
/** * Change the property on the given node. * * @param NodeData $node * @return void */ public function execute(NodeData $node) { foreach ($node->getNodeType()->getProperties() as $propertyName => $propertyConfiguration) { if (isset($propertyConfiguration['type']) && in_array(trim($propertyConfiguration['type']), $this->getHandledObjectTypes())) { if (!isset($nodeProperties)) { $nodeRecordQuery = $this->entityManager->getConnection()->prepare('SELECT properties FROM typo3_typo3cr_domain_model_nodedata WHERE persistence_object_identifier=?'); $nodeRecordQuery->execute([$this->persistenceManager->getIdentifierByObject($node)]); $nodeRecord = $nodeRecordQuery->fetch(\PDO::FETCH_ASSOC); $nodeProperties = unserialize($nodeRecord['properties']); } if (!isset($nodeProperties[$propertyName]) || !is_object($nodeProperties[$propertyName])) { continue; } /** @var Asset $assetObject */ $assetObject = $nodeProperties[$propertyName]; $nodeProperties[$propertyName] = null; $stream = $assetObject->getResource()->getStream(); if ($stream === false) { continue; } fclose($stream); $objectType = TypeHandling::getTypeForValue($assetObject); $objectIdentifier = ObjectAccess::getProperty($assetObject, 'Persistence_Object_Identifier', true); $nodeProperties[$propertyName] = array('__flow_object_type' => $objectType, '__identifier' => $objectIdentifier); } } if (isset($nodeProperties)) { $nodeUpdateQuery = $this->entityManager->getConnection()->prepare('UPDATE typo3_typo3cr_domain_model_nodedata SET properties=? WHERE persistence_object_identifier=?'); $nodeUpdateQuery->execute([serialize($nodeProperties), $this->persistenceManager->getIdentifierByObject($node)]); } }
/** * @return void */ public function up() { $affectedViewHelperClassNames = array(); $allPathsAndFilenames = Files::readDirectoryRecursively($this->targetPackageData['path'], '.php', TRUE); foreach ($allPathsAndFilenames as $pathAndFilename) { if (substr($pathAndFilename, -14) !== 'ViewHelper.php') { continue; } $fileContents = file_get_contents($pathAndFilename); $className = (new PhpAnalyzer($fileContents))->extractFullyQualifiedClassName(); if ($className === NULL) { $this->showWarning(sprintf('could not extract class name from file "%s"', $pathAndFilename)); continue; } /** @noinspection PhpIncludeInspection */ require_once $pathAndFilename; if (!class_exists($className)) { $this->showWarning(sprintf('could not load class "%s" extracted from file "%s"', $className, $pathAndFilename)); continue; } $instance = new $className(); $escapeOutput = ObjectAccess::getProperty($instance, 'escapeOutput', TRUE); if ($escapeOutput !== NULL) { continue; } $affectedViewHelperClassNames[] = $className; $this->searchAndReplaceRegex('/\\R\\s*class[^\\{]+\\R?\\{(\\s*)(?=.*?\\})/s', '$0' . "\n\t" . '/**' . "\n\t" . ' * NOTE: This property has been introduced via code migration to ensure backwards-compatibility.' . "\n\t" . ' * @see AbstractViewHelper::isOutputEscapingEnabled()' . "\n\t" . ' * @var boolean' . "\n\t" . ' */' . "\n\t" . 'protected $escapeOutput = FALSE;$1', $pathAndFilename); } if ($affectedViewHelperClassNames !== array()) { $this->showWarning('Added "escapeOutput" property to following ViewHelpers:' . PHP_EOL . ' * ' . implode(PHP_EOL . ' * ', $affectedViewHelperClassNames) . PHP_EOL . PHP_EOL . 'If an affected ViewHelper does not render HTML output, you should set this property TRUE in order to ensure sanitization of the output!'); } $this->addWarningsForAffectedViewHelpers($this->targetPackageData['path']); }
public function assertPersistedPropertyValue($entity, $propertyName, $expectedPropertyValue, $forceDirectAccess = true) { $this->entityManager->refresh($entity); $persistedPropertyValue = ObjectAccess::getProperty($entity, $propertyName, $forceDirectAccess); $this->test->assertSame($expectedPropertyValue, $persistedPropertyValue, 'The property ' . $propertyName . ' did not have the expected persistent value'); return $this; }
/** * See the configuration in Testing/Objects.yaml * @test */ public function configuredObjectDWillGetAssignedObjectFWithCorrectlyConfiguredConstructorValue() { $instance = $this->objectManager->get(\TYPO3\Flow\Tests\Functional\Object\Fixtures\PrototypeClassD::class); /** @var $instanceE Fixtures\PrototypeClassE */ $instanceE = ObjectAccess::getProperty($instance, 'objectE', TRUE); $this->assertEquals('The constructor set value', $instanceE->getNullValue()); }
/** * Log a message if a post is deleted * * @param \TYPO3\Flow\Aop\JoinPointInterface $joinPoint * @Flow\Around("method(TYPO3\Neos\View\TypoScriptView->render())") * @return void */ public function replacePlaceholdersIfNecessary(\TYPO3\Flow\Aop\JoinPointInterface $joinPoint) { $result = $joinPoint->getAdviceChain()->proceed($joinPoint); /* @var $typoScriptView TypoScriptView */ $typoScriptView = $joinPoint->getProxy(); $viewVariables = ObjectAccess::getProperty($typoScriptView, 'variables', TRUE); if (!isset($viewVariables['value']) || !$viewVariables['value']->getNodeType()->isOfType('Sandstorm.Newsletter:Newsletter')) { // No newsletter, so logic does not apply return $result; } /* @var $httpRequest Request */ $httpRequest = $this->controllerContext->getRequest()->getHttpRequest(); $arguments = $httpRequest->getUri()->getArguments(); if (!isset($arguments['hmac'])) { if ($this->securityContext->isInitialized() && $this->securityContext->hasRole('TYPO3.Neos:Editor')) { // Logged into backend, so we don't need to do anything. return $result; } else { // No HMAC sent -- so we return the email INCLUDING placeholders (as per customer's request) return $result; //return '<h1>Error: HMAC not included in the link.</h1>'; } } $actualHmac = $arguments['hmac']; $uriWithoutHmac = str_replace('&hmac=' . $actualHmac, '', (string) $httpRequest->getUri()); $expectedHmac = hash_hmac('sha1', urldecode($uriWithoutHmac), $this->hmacUrlSecret); if ($expectedHmac !== $actualHmac) { return '<h1>Error: Wrong link clicked.</h1>Please contact your administrator for help'; } $result = preg_replace_callback(ReplacePlaceholdersInLiveImplementation::PLACEHOLDER_REGEX, function ($element) use($arguments) { return ObjectAccess::getPropertyPath($arguments, $element[1]); }, $result); return $result; }
/** * Add DQL function * * @param \TYPO3\Flow\Aop\JoinPointInterface $joinPoint The current join point * @Flow\Before("method(TYPO3\Flow\Persistence\Doctrine\Service->runDql())") * @return void */ public function addDqlFunction(\TYPO3\Flow\Aop\JoinPointInterface $joinPoint) { $entityManager = \TYPO3\Flow\Reflection\ObjectAccess::getProperty($joinPoint->getProxy(), 'entityManager', TRUE); $configuration = \TYPO3\Flow\Reflection\ObjectAccess::getProperty($entityManager, 'config', TRUE); $configuration->addCustomStringFunction('DAY', 'Lelesys\\Plugin\\News\\Doctrine\\Query\\Mysql\\Day'); $configuration->addCustomStringFunction('MONTH', 'Lelesys\\Plugin\\News\\Doctrine\\Query\\Mysql\\Month'); $configuration->addCustomStringFunction('YEAR', 'Lelesys\\Plugin\\News\\Doctrine\\Query\\Mysql\\Year'); }
/** * Returns TRUE if the given node is of the node type this filter expects. * * @param \TYPO3\TYPO3CR\Domain\Model\NodeInterface $node * @return boolean */ public function matches(\TYPO3\TYPO3CR\Domain\Model\NodeInterface $node) { if ($this->withSubTypes === TRUE) { return $this->nodeTypeManager->getNodeType($node->getNodeType())->isOfType($this->nodeTypeName); } else { $nodeData = \TYPO3\Flow\Reflection\ObjectAccess::getProperty($node, 'nodeData', TRUE); $nodeType = \TYPO3\Flow\Reflection\ObjectAccess::getProperty($nodeData, 'nodeType', TRUE); return $nodeType === $this->nodeTypeName; } }
/** * Advice for uncached segments when rendering from a cached version * * @Flow\AfterReturning("method(TYPO3\TypoScript\Core\Cache\RuntimeContentCache->evaluateUncached())") * @param JoinPointInterface $joinPoint */ public function registerEvaluateUncached(JoinPointInterface $joinPoint) { $path = $joinPoint->getMethodArgument('path'); $proxy = $joinPoint->getProxy(); /** @var Runtime $runtime */ $runtime = ObjectAccess::getProperty($proxy, 'runtime', TRUE); $mocVarnishIgnoreUncached = $runtime->evaluate($path . '/__meta/cache/mocVarnishIgnoreUncached'); if ($mocVarnishIgnoreUncached !== TRUE) { $this->evaluatedUncached = TRUE; } }
/** * @test */ public function ignoredClassesCanBeOverwrittenBySettings() { $object = new ApplicationContext('Development'); $this->assertEquals('TYPO3\\Flow\\Core\\ApplicationContext prototype object', Debugger::renderDump($object, 10, TRUE)); Debugger::clearState(); $currentConfiguration = ObjectAccess::getProperty($this->configurationManager, 'configurations', TRUE); $configurationOverwrite['Settings']['TYPO3']['Flow']['error']['debugger']['ignoredClasses']['TYPO3\\\\Flow\\\\Core\\\\.*'] = FALSE; $newConfiguration = Arrays::arrayMergeRecursiveOverrule($currentConfiguration, $configurationOverwrite); ObjectAccess::setProperty($this->configurationManager, 'configurations', $newConfiguration, TRUE); $this->assertContains('rootContextString', Debugger::renderDump($object, 10, TRUE)); }
/** * Finds ort as per entered search string * * @param string $searchString The entered search string * @return \TYPO3\Flow\Persistence\QueryResultInterface The ort */ public function findOrtBySearchString($searchString) { $searchString = trim($searchString); $searchString = '%' . $searchString . '%'; $query = $this->createQuery(); /** @var $queryBuilder \Doctrine\ORM\QueryBuilder **/ $queryBuilder = ObjectAccess::getProperty($query, 'queryBuilder', true); $queryBuilder->resetDQLParts()->select('ort')->from('\\Subugoe\\GermaniaSacra\\Domain\\Model\\Ort', 'ort')->innerJoin('ort.bistum', 'bistum')->where('ort.ort LIKE :ort')->orderBy('ort.ort', 'ASC'); $queryBuilder->setParameter('ort', $searchString); return $query->execute(); }
/** * @Given /^I have the following policies:$/ */ public function iHaveTheFollowingPolicies($string) { self::$testingPolicyPathAndFilename = $this->environment->getPathToTemporaryDirectory() . 'Policy.yaml'; file_put_contents(self::$testingPolicyPathAndFilename, $string->getRaw()); $configurationManager = $this->objectManager->get('TYPO3\\Flow\\Configuration\\ConfigurationManager'); $configurations = \TYPO3\Flow\Reflection\ObjectAccess::getProperty($configurationManager, 'configurations', TRUE); unset($configurations[\TYPO3\Flow\Configuration\ConfigurationManager::CONFIGURATION_PROCESSING_TYPE_POLICY]); \TYPO3\Flow\Reflection\ObjectAccess::setProperty($configurationManager, 'configurations', $configurations, TRUE); $policyService = $this->objectManager->get('TYPO3\\Flow\\Security\\Policy\\PolicyService'); \TYPO3\Flow\Reflection\ObjectAccess::setProperty($policyService, 'initialized', FALSE, TRUE); }
/** * Advice for uncached segments when rendering from a cached version * * @Flow\AfterReturning("method(TYPO3\TypoScript\Core\Cache\RuntimeContentCache->evaluateUncached())") * @param JoinPointInterface $joinPoint */ public function registerEvaluateUncached(JoinPointInterface $joinPoint) { $path = $joinPoint->getMethodArgument('path'); $proxy = $joinPoint->getProxy(); /** @var Runtime $runtime */ $runtime = ObjectAccess::getProperty($proxy, 'runtime', TRUE); $mocVarnishIgnoreUncached = $runtime->evaluate($path . '/__meta/cache/mocVarnishIgnoreUncached'); if ($mocVarnishIgnoreUncached !== TRUE) { $this->logger->log(sprintf('Varnish cache disabled due to uncached path "%s" (can be prevented using "mocVarnishIgnoreUncached")', $path . '/__meta/cache/mocVarnishIgnoreUncached'), LOG_DEBUG); $this->evaluatedUncached = TRUE; } }
/** * @param JoinPointInterface $joinPoint * @return mixed Result of the target method * @Flow\Around("class(TYPO3\Flow\Cli\CommandManager) && method(.*->getAvailableCommands()) && setting(Etg24.EventSourcing.Command.Controller.enabled)") */ public function registerDomainModelCommands(JoinPointInterface $joinPoint) { $proxy = $joinPoint->getProxy(); $currentCommands = ObjectAccess::getProperty($proxy, 'availableCommands', TRUE); // commands have been initialized if ($currentCommands !== NULL) { return $joinPoint->getAdviceChain()->proceed($joinPoint); } $commands = $joinPoint->getAdviceChain()->proceed($joinPoint); $domainCommands = $this->getDomainCommands(); $allCommands = array_merge($commands, $domainCommands); ObjectAccess::setProperty($proxy, 'availableCommands', $allCommands, TRUE); return $allCommands; }
/** * Returns TRUE if the given node is of the node type this filter expects. * * @param \TYPO3\TYPO3CR\Domain\Model\NodeData $node * @return boolean */ public function matches(\TYPO3\TYPO3CR\Domain\Model\NodeData $node) { if ($this->withSubTypes === true) { $nodeIsMatchingNodeType = $node->getNodeType()->isOfType($this->nodeTypeName); } else { // This is needed to get the raw string NodeType to prevent errors for NodeTypes that no longer exist. $nodeType = \TYPO3\Flow\Reflection\ObjectAccess::getProperty($node, 'nodeType', true); $nodeIsMatchingNodeType = $nodeType === $this->nodeTypeName; } if ($this->exclude === true) { return !$nodeIsMatchingNodeType; } return $nodeIsMatchingNodeType; }
/** * WARNING: If using this step definition, IT MUST RUN AS ABSOLUTELY FIRST STEP IN A SCENARIO! * * @Given /^I have the following policies:$/ */ public function iHaveTheFollowingPolicies($string) { if ($this->subProcess !== null) { // This check ensures that this statement is ran *before* a subprocess is opened; as the Policy.yaml // which is set here influences the Proxy Building Process. throw new \Exception('Step "I have the following policies:" must run as FIRST step in a scenario, because otherwise the proxy-classes are already built in the wrong manner!'); } self::$testingPolicyPathAndFilename = $this->environment->getPathToTemporaryDirectory() . 'Policy.yaml'; file_put_contents(self::$testingPolicyPathAndFilename, $string->getRaw()); $configurationManager = $this->objectManager->get(\TYPO3\Flow\Configuration\ConfigurationManager::class); $configurations = \TYPO3\Flow\Reflection\ObjectAccess::getProperty($configurationManager, 'configurations', true); unset($configurations[\TYPO3\Flow\Configuration\ConfigurationManager::CONFIGURATION_PROCESSING_TYPE_POLICY]); \TYPO3\Flow\Reflection\ObjectAccess::setProperty($configurationManager, 'configurations', $configurations, true); $policyService = $this->objectManager->get(\TYPO3\Flow\Security\Policy\PolicyService::class); \TYPO3\Flow\Reflection\ObjectAccess::setProperty($policyService, 'initialized', false, true); }
/** * @test */ public function setParentRolesMakesSureThatParentRolesDontContainDuplicates() { $role = new Role('Acme.Demo:Test'); $role->initializeObject(); $parentRole1 = new Role('Acme.Demo:Parent1'); $parentRole2 = new Role('Acme.Demo:Parent2'); $parentRole2->addParentRole($parentRole1); $role->setParentRoles(array($parentRole1, $parentRole2, $parentRole2, $parentRole1)); $expectedParentRoles = array('Acme.Demo:Parent1' => $parentRole1, 'Acme.Demo:Parent2' => $parentRole2); // Internally, parentRoles might contain duplicates which Doctrine will try // to persist - even though getParentRoles() will return an array which // does not contain duplicates: $internalParentRolesCollection = ObjectAccess::getProperty($role, 'parentRoles', TRUE); $this->assertEquals(2, count($internalParentRolesCollection->toArray())); $this->assertEquals($expectedParentRoles, $role->getParentRoles()); }
/** * @Flow\Around("setting(Ttree.Embedly.logApiRequest) && within(Ttree\Embedly\Embedly) && method(public .*->(oembed|preview|objectify|extract|services)())") * @param JoinPointInterface $joinPoint The current join point * @return mixed */ public function getResponseFromCache(JoinPointInterface $joinPoint) { $proxy = $joinPoint->getProxy(); $key = ObjectAccess::getProperty($proxy, 'key'); $params = $joinPoint->getMethodArgument('params'); $cacheKey = md5($joinPoint->getClassName() . $joinPoint->getMethodName() . $key . json_encode($params)); if ($this->responseCache->has($cacheKey)) { $this->systemLogger->log(sprintf(' cache hit Embedly::%s', $joinPoint->getMethodName()), LOG_DEBUG); return $this->responseCache->get($cacheKey); } else { $this->systemLogger->log(sprintf(' cache miss Embedly::%s', $joinPoint->getMethodName()), LOG_DEBUG); } $response = $joinPoint->getAdviceChain()->proceed($joinPoint); $this->responseCache->set($cacheKey, $response); return $response; }
public function searchCertainNumberOfOrden($offset, $limit, $orderings, $searchArr, $mode = 1) { $query = $this->createQuery(); /** @var $queryBuilder \Doctrine\ORM\QueryBuilder **/ $queryBuilder = ObjectAccess::getProperty($query, 'queryBuilder', true); $queryBuilder->resetDQLParts()->select('orden')->from('\\Subugoe\\GermaniaSacra\\Domain\\Model\\Orden', 'orden'); $operator = 'LIKE'; $isOrdenInSearchArray = false; if (is_array($searchArr) && count($searchArr) > 0) { $i = 1; foreach ($searchArr as $k => $v) { $entity = $this->entities[$k]; $parameter = $k; $searchStr = trim($v); $value = '%' . $searchStr . '%'; $filter = $entity . '.' . $k; if ($k === 'ordenstyp') { $queryBuilder->innerJoin('orden.ordenstyp', 'ordenstyp'); $isOrdenInSearchArray = true; } if ($i === 1) { $queryBuilder->where($filter . ' ' . $operator . ' :' . $parameter); $queryBuilder->setParameter($parameter, $value); } else { $queryBuilder->andWhere($filter . ' ' . $operator . ' :' . $parameter); $queryBuilder->setParameter($parameter, $value); } $i++; } } if ($orderings[0] === 'ordenstyp' && !$isOrdenInSearchArray) { $queryBuilder->innerJoin('orden.ordenstyp', 'ordenstyp'); } if ($mode === 1) { $sort = $this->entities[$orderings[0]] . '.' . $orderings[0]; $order = $orderings[1]; $queryBuilder->orderBy($sort, $order); $queryBuilder->setFirstResult($offset); $queryBuilder->setMaxResults($limit); return $query->execute(); } else { return $query->count(); } }
/** * Get a single property reduced to a simple type (no objects) representation * * @param NodeInterface $node * @param string $propertyName * @return mixed */ public function getProperty(NodeInterface $node, $propertyName) { if ($propertyName[0] === '_') { $propertyValue = ObjectAccess::getProperty($node, ltrim($propertyName, '_')); } else { $propertyValue = $node->getProperty($propertyName); } $dataType = $node->getNodeType()->getPropertyType($propertyName); try { $convertedValue = $this->convertValue($propertyValue, $dataType); } catch (PropertyException $exception) { $this->systemLogger->logException($exception); $convertedValue = null; } if ($convertedValue === null) { $convertedValue = $this->getDefaultValueForProperty($node->getNodeType(), $propertyName); } return $convertedValue; }
/** * Get a value of the context * * This basically acts as a safe access to non-existing properties, unified array and * property access (using getters) and access to the current value (empty path). * * If a property or key did not exist this method will return NULL. * * @param string|integer|Context $path The path as string or Context value, will be unwrapped for convenience * @return mixed The value * @throws EvaluationException */ public function get($path) { if ($path instanceof Context) { $path = $path->unwrap(); } if ($path === NULL) { return NULL; } elseif (is_string($path) || is_integer($path)) { if (is_array($this->value)) { return array_key_exists($path, $this->value) ? $this->value[$path] : NULL; } elseif (is_object($this->value)) { try { return \TYPO3\Flow\Reflection\ObjectAccess::getProperty($this->value, $path); } catch (\TYPO3\Flow\Reflection\Exception\PropertyNotAccessibleException $exception) { return NULL; } } } else { throw new EvaluationException('Path is not of type string or integer, got ' . gettype($path), 1344418464); } }
/** * Gets a property path from a given object or array. * * If propertyPath is "bla.blubb", then we first call getProperty($object, 'bla'), * and on the resulting object we call getProperty(..., 'blubb'). * * For arrays the keys are checked likewise. * * @param mixed $subject An object or array * @param string $propertyPath * @param RenderingContextInterface $renderingContext * @return mixed Value of the property */ public static function getPropertyPath($subject, $propertyPath, RenderingContextInterface $renderingContext) { $propertyPathSegments = explode('.', $propertyPath); foreach ($propertyPathSegments as $pathSegment) { try { $subject = ObjectAccess::getProperty($subject, $pathSegment); } catch (PropertyNotAccessibleException $exception) { $subject = NULL; } if ($subject === NULL) { break; } if ($subject instanceof RenderingContextAwareInterface) { $subject->setRenderingContext($renderingContext); } if ($subject instanceof TemplateObjectAccessInterface) { $subject = $subject->objectAccess(); } } return $subject; }
/** * @test */ public function ignoredPropertiesShouldNotBeUsedAsMatcher() { $path = 'page/body/content/main'; $ignoredProperties = array('nodePath'); $mockTsRuntime = $this->getMock('TYPO3\\TypoScript\\Core\\Runtime', array(), array(), '', false); $mockTsRuntime->expects($this->any())->method('evaluate')->will($this->returnCallback(function ($evaluatePath, $that) use($path, $ignoredProperties) { $relativePath = str_replace($path . '/', '', $evaluatePath); switch ($relativePath) { case '__meta/ignoreProperties': return $ignoredProperties; } return ObjectAccess::getProperty($that, $relativePath, true); })); $typoScriptObjectName = 'TYPO3.Neos:PrimaryContent'; $renderer = new \TYPO3\TypoScript\TypoScriptObjects\CaseImplementation($mockTsRuntime, $path, $typoScriptObjectName); $renderer->setIgnoreProperties($ignoredProperties); $renderer['nodePath'] = 'main'; $renderer['default'] = array('condition' => 'true'); $mockTsRuntime->expects($this->once())->method('render')->with('page/body/content/main/default<TYPO3.TypoScript:Matcher>')->will($this->returnValue('rendered matcher')); $result = $renderer->evaluate(); $this->assertEquals('rendered matcher', $result); }
/** * Set user information on the raven context */ protected function setUserContext() { $objectManager = \TYPO3\Flow\Core\Bootstrap::$staticObjectManager; /** @var \TYPO3\Flow\Security\Context $securityContext */ $securityContext = $objectManager->get('TYPO3\\Flow\\Security\\Context'); $userContext = array(); if ($securityContext->isInitialized()) { $account = $securityContext->getAccount(); if ($account !== NULL) { $userContext['username'] = $account->getAccountIdentifier(); } $party = $securityContext->getParty(); if ($party instanceof Person && $party->getPrimaryElectronicAddress() !== NULL) { $userContext['email'] = (string) $party->getPrimaryElectronicAddress(); } elseif ($party !== NULL && ObjectAccess::isPropertyGettable($party, 'emailAddress')) { $userContext['email'] = (string) ObjectAccess::getProperty($party, 'emailAddress'); } } if ($userContext !== array()) { $this->client->user_context($userContext); } }
/** * Checks if the given value is a unique entity depending on it's identity properties or * custom configured identity properties. * * @param mixed $value The value that should be validated * @return void * @throws \TYPO3\Flow\Validation\Exception\InvalidValidationOptionsException * @api */ protected function isValid($value) { if (!is_object($value)) { throw new InvalidValidationOptionsException('The value supplied for the UniqueEntityValidator must be an object.', 1358454270); } $classSchema = $this->reflectionService->getClassSchema($value); if ($classSchema === NULL || $classSchema->getModelType() !== \TYPO3\Flow\Reflection\ClassSchema::MODELTYPE_ENTITY) { throw new InvalidValidationOptionsException('The object supplied for the UniqueEntityValidator must be an entity.', 1358454284); } if ($this->options['identityProperties'] !== NULL) { $identityProperties = $this->options['identityProperties']; foreach ($identityProperties as $propertyName) { if ($classSchema->hasProperty($propertyName) === FALSE) { throw new InvalidValidationOptionsException(sprintf('The custom identity property name "%s" supplied for the UniqueEntityValidator does not exists in "%s".', $propertyName, $classSchema->getClassName()), 1358960500); } } } else { $identityProperties = array_keys($classSchema->getIdentityProperties()); } if (count($identityProperties) === 0) { throw new InvalidValidationOptionsException('The object supplied for the UniqueEntityValidator must have at least one identity property.', 1358459831); } $identifierProperties = $this->reflectionService->getPropertyNamesByAnnotation($classSchema->getClassName(), 'Doctrine\\ORM\\Mapping\\Id'); if (count($identifierProperties) > 1) { throw new InvalidValidationOptionsException('The object supplied for the UniqueEntityValidator must only have one identifier property @ORM\\Id.', 1358501745); } $identifierPropertyName = count($identifierProperties) > 0 ? array_shift($identifierProperties) : 'Persistence_Object_Identifier'; $query = $this->persistenceManager->createQueryForType($classSchema->getClassName()); $constraints = array($query->logicalNot($query->equals($identifierPropertyName, $this->persistenceManager->getIdentifierByObject($value)))); foreach ($identityProperties as $propertyName) { $constraints[] = $query->equals($propertyName, ObjectAccess::getProperty($value, $propertyName)); } if ($query->matching($query->logicalAnd($constraints))->count() > 0) { $this->addError('Another entity with the same unique identifiers already exists', 1355785874); } }
/** * Autogenerated Proxy Method */ private function searchForEntitiesAndStoreIdentifierArray($path, $propertyValue, $originalPropertyName) { if (is_array($propertyValue) || is_object($propertyValue) && ($propertyValue instanceof \ArrayObject || $propertyValue instanceof \SplObjectStorage)) { foreach ($propertyValue as $key => $value) { $this->searchForEntitiesAndStoreIdentifierArray($path . '.' . $key, $value, $originalPropertyName); } } elseif ($propertyValue instanceof \TYPO3\Flow\Persistence\Aspect\PersistenceMagicInterface && !\TYPO3\Flow\Core\Bootstrap::$staticObjectManager->get('TYPO3\\Flow\\Persistence\\PersistenceManagerInterface')->isNewObject($propertyValue) || $propertyValue instanceof \Doctrine\ORM\Proxy\Proxy) { if (!property_exists($this, 'Flow_Persistence_RelatedEntities') || !is_array($this->Flow_Persistence_RelatedEntities)) { $this->Flow_Persistence_RelatedEntities = array(); $this->Flow_Object_PropertiesToSerialize[] = 'Flow_Persistence_RelatedEntities'; } if ($propertyValue instanceof \Doctrine\ORM\Proxy\Proxy) { $className = get_parent_class($propertyValue); } else { $className = \TYPO3\Flow\Core\Bootstrap::$staticObjectManager->getObjectNameByClassName(get_class($propertyValue)); } $identifier = \TYPO3\Flow\Core\Bootstrap::$staticObjectManager->get('TYPO3\\Flow\\Persistence\\PersistenceManagerInterface')->getIdentifierByObject($propertyValue); if (!$identifier && $propertyValue instanceof \Doctrine\ORM\Proxy\Proxy) { $identifier = current(\TYPO3\Flow\Reflection\ObjectAccess::getProperty($propertyValue, '_identifier', TRUE)); } $this->Flow_Persistence_RelatedEntities[$originalPropertyName . '.' . $path] = array('propertyName' => $originalPropertyName, 'entityType' => $className, 'identifier' => $identifier, 'entityPath' => $path); $this->{$originalPropertyName} = \TYPO3\Flow\Utility\Arrays::setValueByPath($this->{$originalPropertyName}, $path, NULL); } }
/** * Check the property value for allowed types and throw exceptions for * unsupported types. * * @param object $object The object with the property to check * @param string $propertyName The name of the property to check * @param array $propertyMetaData Property metadata * @return mixed The value of the property * @throws \TYPO3\Flow\Persistence\Generic\Exception\UnexpectedTypeException * @throws \TYPO3\Flow\Persistence\Exception * @throws \TYPO3\Flow\Persistence\Exception\IllegalObjectTypeException * @api */ protected function checkPropertyValue($object, $propertyName, array $propertyMetaData) { $propertyValue = \TYPO3\Flow\Reflection\ObjectAccess::getProperty($object, $propertyName, true); $propertyType = $propertyMetaData['type']; if ($propertyType === 'ArrayObject') { throw new \TYPO3\Flow\Persistence\Exception('ArrayObject properties are not supported - missing feature?!?', 1283524355); } if (is_object($propertyValue)) { if ($propertyType === 'object') { if (!$propertyValue instanceof \TYPO3\Flow\Persistence\Aspect\PersistenceMagicInterface) { throw new \TYPO3\Flow\Persistence\Exception\IllegalObjectTypeException('Property of generic type object holds "' . get_class($propertyValue) . '", which is not persistable (no entity or value object), in ' . get_class($object) . '::' . $propertyName, 1283531761); } } elseif (!$propertyValue instanceof $propertyType) { throw new \TYPO3\Flow\Persistence\Generic\Exception\UnexpectedTypeException('Expected property of type ' . $propertyType . ', but got ' . get_class($propertyValue) . ' for ' . get_class($object) . '::' . $propertyName, 1244465558); } } elseif ($propertyValue !== null && $propertyType !== $this->getType($propertyValue)) { throw new \TYPO3\Flow\Persistence\Generic\Exception\UnexpectedTypeException('Expected property of type ' . $propertyType . ', but got ' . gettype($propertyValue) . ' for ' . get_class($object) . '::' . $propertyName, 1244465559); } return $propertyValue; }
/** * @test */ public function parseDesignatorMethodAnnotatedWithObservesAnnotationPropertyConstraints() { $this->mockObjectManager->expects($this->any())->method('get')->will($this->returnValue($this->getMock(\TYPO3\Flow\Log\SystemLoggerInterface::class))); $pointcutFilterComposite = new \TYPO3\Flow\Aop\Pointcut\PointcutFilterComposite(); $parser = $this->getAccessibleMock(\TYPO3\Flow\Aop\Pointcut\PointcutExpressionParser::class, array('dummy'), array(), '', false); $parser->injectReflectionService($this->mockReflectionService); $parser->injectObjectManager($this->mockObjectManager); $parser->_call('parseDesignatorMethodAnnotatedWith', '&&', 'foo(bar == FALSE)', $pointcutFilterComposite); $expectedAnnotation = 'foo'; $expectedAnnotationValueConstraints = array('bar' => array('operator' => array(0 => '=='), 'value' => array(0 => 'FALSE'))); $filters = \TYPO3\Flow\Reflection\ObjectAccess::getProperty($pointcutFilterComposite, 'filters', true); $filter = $filters[0][1]; $annotation = \TYPO3\Flow\Reflection\ObjectAccess::getProperty($filter, 'annotation', true); $annotationValueConstraints = \TYPO3\Flow\Reflection\ObjectAccess::getProperty($filter, 'annotationValueConstraints', true); $this->assertEquals($expectedAnnotation, $annotation); $this->assertEquals($expectedAnnotationValueConstraints, $annotationValueConstraints); }