/**
  */
 public function setUp()
 {
     ComposerUtility::flushCaches();
     vfsStream::setup('Packages');
     $this->mockPackageManager = $this->getMockBuilder(\Neos\Flow\Package\PackageManager::class)->disableOriginalConstructor()->getMock();
     ObjectAccess::setProperty($this->mockPackageManager, 'composerManifestData', array(), true);
 }
 /**
  * @param string $term
  * @return string
  */
 public function autocompleteAction($term)
 {
     $searchProperty = $this->widgetConfiguration['searchProperty'];
     /** @var $queryResult QueryResultInterface */
     $queryResult = $this->widgetConfiguration['objects'];
     $query = clone $queryResult->getQuery();
     $constraint = $query->getConstraint();
     if ($constraint !== null) {
         $query->matching($query->logicalAnd($constraint, $query->like($searchProperty, '%' . $term . '%', false)));
     } else {
         $query->matching($query->like($searchProperty, '%' . $term . '%', false));
     }
     if (isset($this->configuration['limit'])) {
         $query->setLimit((int) $this->configuration['limit']);
     }
     $results = $query->execute();
     $output = array();
     $values = array();
     foreach ($results as $singleResult) {
         $val = ObjectAccess::getPropertyPath($singleResult, $searchProperty);
         if (isset($values[$val])) {
             continue;
         }
         $values[$val] = true;
         $output[] = array('id' => $val, 'label' => $val, 'value' => $val);
     }
     return json_encode($output);
 }
 /**
  * See the configuration in Testing/Objects.yaml
  * @test
  */
 public function configuredObjectDWillGetAssignedObjectFWithCorrectlyConfiguredConstructorValue()
 {
     $instance = $this->objectManager->get(Fixtures\PrototypeClassD::class);
     /** @var $instanceE Fixtures\PrototypeClassE */
     $instanceE = ObjectAccess::getProperty($instance, 'objectE', true);
     $this->assertEquals('The constructor set value', $instanceE->getNullValue());
 }
 /**
  * @test
  */
 public function convertFromUsesAppropriatePropertyPopulationMethodsInOrderConstructorSetterPublic()
 {
     $convertedObject = $this->converter->convertFrom('irrelevant', Fixtures\TestClass::class, ['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));
 }
 /**
  * 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']);
 }
 /**
  * The input is assumed to be an array or Collection of objects. Groups this input by the $groupingKey property of each element.
  *
  * @param array|Collection $set
  * @param string $groupingKey
  * @return array
  */
 public function groupBy($set, $groupingKey)
 {
     $result = array();
     foreach ($set as $element) {
         $result[ObjectAccess::getPropertyPath($element, $groupingKey)][] = $element;
     }
     return $result;
 }
Esempio n. 8
0
 /**
  * @return void
  */
 public function up()
 {
     $this->processConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, function (array &$configuration) {
         $presetsConfiguration = ObjectAccess::getPropertyPath($configuration, 'Neos.Form.presets');
         if (!is_array($presetsConfiguration)) {
             return;
         }
         $presetsConfiguration = $this->renameTranslationPackage($presetsConfiguration);
         $configuration['TYPO3']['Form']['presets'] = $presetsConfiguration;
     }, true);
 }
 /**
  * @test
  */
 public function ignoredClassesCanBeOverwrittenBySettings()
 {
     $object = new ApplicationContext('Development');
     $this->assertEquals(sprintf('%s prototype object', ApplicationContext::class), Debugger::renderDump($object, 10, true));
     Debugger::clearState();
     $currentConfiguration = ObjectAccess::getProperty($this->configurationManager, 'configurations', true);
     $configurationOverwrite['Settings']['Neos']['Flow']['error']['debugger']['ignoredClasses']['Neos\\\\Flow\\\\Core\\\\.*'] = false;
     $newConfiguration = Arrays::arrayMergeRecursiveOverrule($currentConfiguration, $configurationOverwrite);
     ObjectAccess::setProperty($this->configurationManager, 'configurations', $newConfiguration, true);
     $this->assertContains('rootContextString', Debugger::renderDump($object, 10, true));
 }
 /**
  * Builds a transformation object from the given configuration.
  *
  * @param array $transformationConfiguration
  * @return TransformationInterface
  * @throws MigrationException if a given setting is not supported
  */
 protected function buildTransformationObject($transformationConfiguration)
 {
     $transformationClassName = $this->resolveTransformationClassName($transformationConfiguration['type']);
     $transformation = new $transformationClassName();
     foreach ($transformationConfiguration['settings'] as $settingName => $settingValue) {
         if (!ObjectAccess::setProperty($transformation, $settingName, $settingValue)) {
             throw new MigrationException('Cannot set setting "' . $settingName . '" on transformation "' . $transformationClassName . '" , check your configuration.', 1343293094);
         }
     }
     return $transformation;
 }
 /**
  * Renders the view
  *
  * @return string The rendered view
  * @api
  */
 public function render()
 {
     $source = $this->getOption('templateSource');
     $templatePathAndFilename = $this->getOption('templatePathAndFilename');
     if ($templatePathAndFilename !== null) {
         $source = file_get_contents($templatePathAndFilename);
     }
     return preg_replace_callback('/\\{([a-zA-Z0-9\\-_.]+)\\}/', function ($matches) {
         return ObjectAccess::getPropertyPath($this->variables, $matches[1]);
     }, $source);
 }
 /**
  * Returns contents of Composer manifest - or part there of.
  *
  * @param string $manifestPath
  * @param string $configurationPath Optional. Only return the part of the manifest indexed by configurationPath
  * @return array|mixed
  */
 public static function getComposerManifest($manifestPath, $configurationPath = null)
 {
     $composerManifest = static::readComposerManifest($manifestPath);
     if ($composerManifest === null) {
         return null;
     }
     if ($configurationPath !== null) {
         return ObjectAccess::getPropertyPath($composerManifest, $configurationPath);
     } else {
         return $composerManifest;
     }
 }
 /**
  * Updates the password credential from the POST vars, if the POST parameters
  * are available. Sets the authentication status to AUTHENTICATION_NEEDED, if credentials have been sent.
  *
  * Note: You need to send the password in this POST parameter:
  *       __authentication[TYPO3][Flow][Security][Authentication][Token][PasswordToken][password]
  *
  * @param ActionRequest $actionRequest The current action request
  * @return void
  */
 public function updateCredentials(ActionRequest $actionRequest)
 {
     if ($actionRequest->getHttpRequest()->getMethod() !== 'POST') {
         return;
     }
     $postArguments = $actionRequest->getInternalArguments();
     $password = ObjectAccess::getPropertyPath($postArguments, '__authentication.TYPO3.Flow.Security.Authentication.Token.PasswordToken.password');
     if (!empty($password)) {
         $this->credentials['password'] = $password;
         $this->setAuthenticationStatus(self::AUTHENTICATION_NEEDED);
     }
 }
 /**
  * Returns TRUE if the given node is of the node type this filter expects.
  *
  * @param NodeData $node
  * @return boolean
  */
 public function matches(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 = ObjectAccess::getProperty($node, 'nodeType', true);
         $nodeIsMatchingNodeType = $nodeType === $this->nodeTypeName;
     }
     if ($this->exclude === true) {
         return !$nodeIsMatchingNodeType;
     }
     return $nodeIsMatchingNodeType;
 }
 /**
  * {@inheritdoc}
  *
  * @param FlowQuery $flowQuery the FlowQuery object
  * @param array $arguments the property path to use (in index 0)
  * @return mixed
  */
 public function evaluate(FlowQuery $flowQuery, array $arguments)
 {
     if (!isset($arguments[0]) || empty($arguments[0])) {
         throw new FlowQueryException('property() must be given an attribute name when used on objects, fetching all attributes is not supported.', 1332492263);
     } else {
         $context = $flowQuery->getContext();
         if (!isset($context[0])) {
             return null;
         }
         $element = $context[0];
         $propertyPath = $arguments[0];
         return ObjectAccess::getPropertyPath($element, $propertyPath);
     }
 }
 /**
  * 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(ConfigurationManager::class);
     $configurations = ObjectAccess::getProperty($configurationManager, 'configurations', true);
     unset($configurations[ConfigurationManager::CONFIGURATION_PROCESSING_TYPE_POLICY]);
     ObjectAccess::setProperty($configurationManager, 'configurations', $configurations, true);
     $policyService = $this->objectManager->get(PolicyService::class);
     ObjectAccess::setProperty($policyService, 'initialized', false, true);
 }
 /**
  * @test
  * @dataProvider attributeExamples
  */
 public function evaluateTests($properties, $expectedOutput)
 {
     $path = 'attributes/test';
     $this->mockTsRuntime->expects($this->any())->method('evaluate')->will($this->returnCallback(function ($evaluatePath, $that) use($path, $properties) {
         $relativePath = str_replace($path . '/', '', $evaluatePath);
         return ObjectAccess::getPropertyPath($properties, str_replace('/', '.', $relativePath));
     }));
     $typoScriptObjectName = 'Neos.Fusion:Attributes';
     $renderer = new AttributesImplementation($this->mockTsRuntime, $path, $typoScriptObjectName);
     if ($properties !== null) {
         foreach ($properties as $name => $value) {
             ObjectAccess::setProperty($renderer, $name, $value);
         }
     }
     $result = $renderer->evaluate();
     $this->assertEquals($expectedOutput, $result);
 }
 /**
  * @param string $dataSourceIdentifier
  * @param NodeInterface $node
  * @return string
  * @throws NeosException
  */
 public function indexAction($dataSourceIdentifier, NodeInterface $node = null)
 {
     $dataSources = static::getDataSources($this->objectManager);
     if (!isset($dataSources[$dataSourceIdentifier])) {
         throw new NeosException(sprintf('Data source with identifier "%s" does not exist.', $dataSourceIdentifier), 1414088186);
     }
     /** @var $dataSource DataSourceInterface */
     $dataSource = new $dataSources[$dataSourceIdentifier]();
     if (ObjectAccess::isPropertySettable($dataSource, 'controllerContext')) {
         ObjectAccess::setProperty($dataSource, 'controllerContext', $this->controllerContext);
     }
     $arguments = $this->request->getArguments();
     unset($arguments['dataSourceIdentifier']);
     unset($arguments['node']);
     $values = $dataSource->getData($node, $arguments);
     $this->view->assign('value', $values);
 }
Esempio n. 19
0
 /**
  * Factory method which creates the specified transport with the given options.
  *
  * @param string $transportType Object name of the transport to create
  * @param array $transportOptions Options for the transport
  * @param array $transportArguments Constructor arguments for the transport
  * @return \Neos\SwiftMailer\TransportInterface The created transport instance
  * @throws Exception
  */
 public function create($transportType, array $transportOptions = array(), array $transportArguments = null)
 {
     if (!class_exists($transportType)) {
         throw new Exception('The specified transport backend "' . $transportType . '" does not exist.', 1269351207);
     }
     if (is_array($transportArguments)) {
         $class = new \ReflectionClass($transportType);
         $transport = $class->newInstanceArgs($transportArguments);
     } else {
         $transport = new $transportType();
     }
     foreach ($transportOptions as $optionName => $optionValue) {
         if (ObjectAccess::isPropertySettable($transport, $optionName)) {
             ObjectAccess::setProperty($transport, $optionName, $optionValue);
         }
     }
     return $transport;
 }
 /**
  * {@inheritdoc}
  *
  * @param FlowQuery $flowQuery the FlowQuery object
  * @param array $arguments the arguments for this operation
  * @return mixed
  */
 public function evaluate(FlowQuery $flowQuery, array $arguments)
 {
     if (!isset($arguments[0]) || empty($arguments[0])) {
         throw new FlowQueryException('property() does not support returning all attributes yet', 1332492263);
     } else {
         $context = $flowQuery->getContext();
         $propertyPath = $arguments[0];
         if (!isset($context[0])) {
             return null;
         }
         $element = $context[0];
         if ($propertyPath[0] === '_') {
             return ObjectAccess::getPropertyPath($element, substr($propertyPath, 1));
         } else {
             return $element->getProperty($propertyPath);
         }
     }
 }
 /**
  * {@inheritdoc}
  *
  * First argument is the node property to sort by. Works with internal arguments (_xyz) as well.
  * Second argument is the sort direction (ASC or DESC).
  *
  * @param FlowQuery $flowQuery the FlowQuery object
  * @param array $arguments the arguments for this operation.
  * @return mixed
  */
 public function evaluate(FlowQuery $flowQuery, array $arguments)
 {
     $nodes = $flowQuery->getContext();
     // Check sort property
     if (isset($arguments[0]) && !empty($arguments[0])) {
         $sortProperty = $arguments[0];
     } else {
         throw new \Neos\Eel\FlowQuery\FlowQueryException('Please provide a node property to sort by.', 1467881104);
     }
     // Check sort direction
     if (isset($arguments[1]) && !empty($arguments[1]) && in_array(strtoupper($arguments[1]), ['ASC', 'DESC'])) {
         $sortOrder = strtoupper($arguments[1]);
     } else {
         throw new \Neos\Eel\FlowQuery\FlowQueryException('Please provide a valid sort direction (ASC or DESC)', 1467881105);
     }
     $sortedNodes = [];
     $sortSequence = [];
     $nodesByIdentifier = [];
     // Determine the property value to sort by
     /** @var Node $node */
     foreach ($nodes as $node) {
         if ($sortProperty[0] === '_') {
             $propertyValue = \Neos\Utility\ObjectAccess::getPropertyPath($node, substr($sortProperty, 1));
         } else {
             $propertyValue = $node->getProperty($sortProperty);
         }
         if ($propertyValue instanceof \DateTime) {
             $propertyValue = $propertyValue->getTimestamp();
         }
         $sortSequence[$node->getIdentifier()] = $propertyValue;
         $nodesByIdentifier[$node->getIdentifier()] = $node;
     }
     // Create the sort sequence
     if ($sortOrder === 'DESC') {
         arsort($sortSequence);
     } elseif ($sortOrder === 'ASC') {
         asort($sortSequence);
     }
     // Build the sorted context that is returned
     foreach ($sortSequence as $nodeIdentifier => $value) {
         $sortedNodes[] = $nodesByIdentifier[$nodeIdentifier];
     }
     $flowQuery->setContext($sortedNodes);
 }
 /**
  * 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;
 }
Esempio n. 23
0
 /**
  * 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 ObjectAccess::getProperty($this->value, $path);
             } catch (PropertyNotAccessibleException $exception) {
                 return null;
             }
         }
     } else {
         throw new EvaluationException('Path is not of type string or integer, got ' . gettype($path), 1344418464);
     }
 }
 /**
  * Get a variable by dotted path expression, retrieving the
  * variable from nested arrays/objects one segment at a time.
  * If the second argument is provided, it must be an array of
  * accessor names which can be used to extract each value in
  * the dotted path.
  *
  * @param string $path
  * @param array $accessors
  * @return mixed
  */
 public function getByPath($path, array $accessors = [])
 {
     $propertyPathSegments = explode('.', $path);
     $subject = $this->variables;
     foreach ($propertyPathSegments as $propertyName) {
         if ($subject === null) {
             break;
         }
         try {
             $subject = ObjectAccess::getProperty($subject, $propertyName);
         } catch (PropertyNotAccessibleException $exception) {
             $subject = null;
         }
         if ($subject instanceof TemplateObjectAccessInterface) {
             $subject = $subject->objectAccess();
         }
     }
     if ($subject === null) {
         $subject = $this->getBooleanValue($path);
     }
     return $subject;
 }
Esempio n. 25
0
 /**
  * @test
  */
 public function ignoredPropertiesShouldNotBeUsedAsMatcher()
 {
     $path = 'page/body/content/main';
     $ignoredProperties = array('nodePath');
     $mockTsRuntime = $this->getMockBuilder(Runtime::class)->disableOriginalConstructor()->getMock();
     $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 = 'Neos.Neos:PrimaryContent';
     $renderer = new 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<Neos.Fusion:Matcher>')->will($this->returnValue('rendered matcher'));
     $result = $renderer->evaluate();
     $this->assertEquals('rendered matcher', $result);
 }
 /**
  * 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 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(TypeHandling::getTypeForValue($value));
     if ($classSchema === null || $classSchema->getModelType() !== 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 = [$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);
     }
 }
 /**
  * Serialize entities that are inside an array or SplObjectStorage
  *
  * @param string $path
  * @param mixed $propertyValue
  * @param string $originalPropertyName
  * @return void
  */
 private function Flow_searchForEntitiesAndStoreIdentifierArray($path, $propertyValue, $originalPropertyName)
 {
     if (is_array($propertyValue) || is_object($propertyValue) && ($propertyValue instanceof \ArrayObject || $propertyValue instanceof \SplObjectStorage)) {
         foreach ($propertyValue as $key => $value) {
             $this->Flow_searchForEntitiesAndStoreIdentifierArray($path . '.' . $key, $value, $originalPropertyName);
         }
     } elseif ($propertyValue instanceof PersistenceMagicInterface && !Bootstrap::$staticObjectManager->get(PersistenceManagerInterface::class)->isNewObject($propertyValue) || $propertyValue instanceof OrmProxy) {
         if (!property_exists($this, 'Flow_Persistence_RelatedEntities') || !is_array($this->Flow_Persistence_RelatedEntities)) {
             $this->Flow_Persistence_RelatedEntities = [];
             $this->Flow_Object_PropertiesToSerialize[] = 'Flow_Persistence_RelatedEntities';
         }
         if ($propertyValue instanceof OrmProxy) {
             $className = get_parent_class($propertyValue);
         } else {
             $className = Bootstrap::$staticObjectManager->getObjectNameByClassName(get_class($propertyValue));
         }
         $identifier = Bootstrap::$staticObjectManager->get(PersistenceManagerInterface::class)->getIdentifierByObject($propertyValue);
         if (!$identifier && $propertyValue instanceof OrmProxy) {
             $identifier = current(ObjectAccess::getProperty($propertyValue, '_identifier', true));
         }
         $this->Flow_Persistence_RelatedEntities[$originalPropertyName . '.' . $path] = ['propertyName' => $originalPropertyName, 'entityType' => $className, 'identifier' => $identifier, 'entityPath' => $path];
         $this->{$originalPropertyName} = Arrays::setValueByPath($this->{$originalPropertyName}, $path, null);
     }
 }
 /**
  * Convert an object from $source to an object.
  *
  * @param mixed $source
  * @param string $targetType
  * @param array $convertedChildProperties
  * @param PropertyMappingConfigurationInterface $configuration
  * @return object the target type
  * @throws InvalidTargetException
  * @throws InvalidDataTypeException
  * @throws InvalidPropertyMappingConfigurationException
  */
 public function convertFrom($source, $targetType, array $convertedChildProperties = [], PropertyMappingConfigurationInterface $configuration = null)
 {
     $object = $this->buildObject($convertedChildProperties, $targetType);
     foreach ($convertedChildProperties as $propertyName => $propertyValue) {
         $result = ObjectAccess::setProperty($object, $propertyName, $propertyValue);
         if ($result === false) {
             $exceptionMessage = sprintf('Property "%s" having a value of type "%s" could not be set in target object of type "%s". Make sure that the property is accessible properly, for example via an appropriate setter method.', $propertyName, is_object($propertyValue) ? get_class($propertyValue) : gettype($propertyValue), $targetType);
             throw new InvalidTargetException($exceptionMessage, 1304538165);
         }
     }
     return $object;
 }
 /**
  * Set a specific option of this object
  *
  * @param string $optionName
  * @param mixed $value
  * @return void
  */
 public function setOption($optionName, $value)
 {
     $this->options[$optionName] = $value;
     if (ObjectAccess::isPropertySettable($this, $optionName)) {
         ObjectAccess::setProperty($this, $optionName, $value);
     }
 }
 /**
  * Checks if the given $nodeType is allowed as a childNode of the given $childNodeName
  * (which must be auto-created in $this NodeType).
  *
  * Only allowed to be called if $childNodeName is auto-created.
  *
  * @param string $childNodeName The name of a configured childNode of this NodeType
  * @param NodeType $nodeType The NodeType to check constraints for.
  * @return boolean TRUE if the $nodeType is allowed as grandchild node, FALSE otherwise.
  * @throws \InvalidArgumentException If the given $childNodeName is not configured to be auto-created in $this.
  */
 public function allowsGrandchildNodeType($childNodeName, NodeType $nodeType)
 {
     $autoCreatedChildNodes = $this->getAutoCreatedChildNodes();
     if (!isset($autoCreatedChildNodes[$childNodeName])) {
         throw new \InvalidArgumentException('The method "allowsGrandchildNodeType" can only be used on auto-created childNodes, given $childNodeName "' . $childNodeName . '" is not auto-created.', 1403858395);
     }
     $constraints = $autoCreatedChildNodes[$childNodeName]->getConfiguration('constraints.nodeTypes') ?: array();
     $childNodeConfiguration = [];
     foreach ($this->getConfiguration('childNodes') as $name => $configuration) {
         $childNodeConfiguration[Utility::renderValidNodeName($name)] = $configuration;
     }
     $childNodeConstraintConfiguration = ObjectAccess::getPropertyPath($childNodeConfiguration, $childNodeName . '.constraints.nodeTypes') ?: array();
     $constraints = Arrays::arrayMergeRecursiveOverrule($constraints, $childNodeConstraintConfiguration);
     return $this->isNodeTypeAllowedByConstraints($nodeType, $constraints);
 }