コード例 #1
0
 /**
  * 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)]);
     }
 }
コード例 #2
0
 /**
  * List configured queues
  *
  * Displays all configured queues, their type and the number of messages that are ready to be processed.
  *
  * @return void
  */
 public function listCommand()
 {
     $rows = [];
     foreach ($this->queueConfigurations as $queueName => $queueConfiguration) {
         $queue = $this->queueManager->getQueue($queueName);
         try {
             $numberOfMessages = $queue->count();
         } catch (\Exception $e) {
             $numberOfMessages = '-';
         }
         $rows[] = [$queue->getName(), TypeHandling::getTypeForValue($queue), $numberOfMessages];
     }
     $this->output->outputTable($rows, ['Queue', 'Type', '# messages']);
 }
コード例 #3
0
 /**
  * Set up dependencies
  */
 public function setUp()
 {
     parent::setUp();
     $configurationManager = $this->objectManager->get(ConfigurationManager::class);
     $packageKey = $this->objectManager->getPackageKeyByObjectName(TypeHandling::getTypeForValue($this));
     $packageSettings = $configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, $packageKey);
     if (!isset($packageSettings['testing']['enabled']) || $packageSettings['testing']['enabled'] !== true) {
         $this->markTestSkipped(sprintf('Queue is not configured (%s.testing.enabled != TRUE)', $packageKey));
     }
     $this->queueSettings = $packageSettings['testing'];
     $this->queue = $this->getQueue();
     $this->queue->setUp();
     $this->queue->flush();
 }
コード例 #4
0
 /**
  * Checks if the given value is valid according to the validator, and returns
  * the Error Messages object which occurred.
  *
  * @param mixed $value The value that should be validated
  * @return ErrorResult
  * @api
  */
 public function validate($value)
 {
     $this->result = new ErrorResult();
     if ($this->acceptsEmptyValues === false || $this->isEmpty($value) === false) {
         if ($value instanceof \Doctrine\ORM\PersistentCollection && !$value->isInitialized()) {
             return $this->result;
         } elseif (is_object($value) && !TypeHandling::isCollectionType(get_class($value)) && !is_array($value)) {
             $this->addError('The given subject was not a collection.', 1317204797);
             return $this->result;
         } elseif (is_object($value) && $this->isValidatedAlready($value)) {
             return $this->result;
         } else {
             $this->isValid($value);
         }
     }
     return $this->result;
 }
 /**
  * Convert an object from \Neos\Media\Domain\Model\ImageInterface to a json representation
  *
  * @param ImageInterface $source
  * @param string $targetType must be 'string'
  * @param array $convertedChildProperties
  * @param PropertyMappingConfigurationInterface $configuration
  * @return string|Error The converted Image, a Validation Error or NULL
  */
 public function convertFrom($source, $targetType, array $convertedChildProperties = array(), PropertyMappingConfigurationInterface $configuration = null)
 {
     $data = array('__identity' => $this->persistenceManager->getIdentifierByObject($source), '__type' => TypeHandling::getTypeForValue($source));
     if ($source instanceof ImageVariant) {
         $data['originalAsset'] = ['__identity' => $this->persistenceManager->getIdentifierByObject($source->getOriginalAsset())];
         $adjustments = array();
         foreach ($source->getAdjustments() as $adjustment) {
             $index = TypeHandling::getTypeForValue($adjustment);
             $adjustments[$index] = array();
             foreach (ObjectAccess::getGettableProperties($adjustment) as $propertyName => $propertyValue) {
                 $adjustments[$index][$propertyName] = $propertyValue;
             }
         }
         $data['adjustments'] = $adjustments;
     }
     return $data;
 }
コード例 #6
0
 /**
  * An onFlush event listener used to validate entities upon persistence.
  *
  * @param \Doctrine\ORM\Event\OnFlushEventArgs $eventArgs
  * @return void
  */
 public function onFlush(\Doctrine\ORM\Event\OnFlushEventArgs $eventArgs)
 {
     $unitOfWork = $this->entityManager->getUnitOfWork();
     $entityInsertions = $unitOfWork->getScheduledEntityInsertions();
     $validatedInstancesContainer = new \SplObjectStorage();
     $knownValueObjects = [];
     foreach ($entityInsertions as $entity) {
         $className = TypeHandling::getTypeForValue($entity);
         if ($this->reflectionService->getClassSchema($className)->getModelType() === ClassSchema::MODELTYPE_VALUEOBJECT) {
             $identifier = $this->getIdentifierByObject($entity);
             if (isset($knownValueObjects[$className][$identifier]) || $unitOfWork->getEntityPersister($className)->exists($entity)) {
                 unset($entityInsertions[spl_object_hash($entity)]);
                 continue;
             }
             $knownValueObjects[$className][$identifier] = true;
         }
         $this->validateObject($entity, $validatedInstancesContainer);
     }
     ObjectAccess::setProperty($unitOfWork, 'entityInsertions', $entityInsertions, true);
     foreach ($unitOfWork->getScheduledEntityUpdates() as $entity) {
         $this->validateObject($entity, $validatedInstancesContainer);
     }
 }
コード例 #7
0
 /**
  * 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);
     }
 }
 /**
  * Returns all nodes that use the asset in a node property.
  *
  * @param AssetInterface $asset
  * @return array
  */
 public function getRelatedNodes(AssetInterface $asset)
 {
     $relationMap = [];
     $relationMap[TypeHandling::getTypeForValue($asset)] = [$this->persistenceManager->getIdentifierByObject($asset)];
     if ($asset instanceof Image) {
         foreach ($asset->getVariants() as $variant) {
             $type = TypeHandling::getTypeForValue($variant);
             if (!isset($relationMap[$type])) {
                 $relationMap[$type] = [];
             }
             $relationMap[$type][] = $this->persistenceManager->getIdentifierByObject($variant);
         }
     }
     return $this->nodeDataRepository->findNodesByRelatedEntities($relationMap);
 }
コード例 #9
0
 /**
  * Return the type of a given sub-property inside the $targetType
  *
  * @param string $targetType
  * @param string $propertyName
  * @param PropertyMappingConfigurationInterface $configuration
  * @return string
  * @api
  */
 public function getTypeOfChildProperty($targetType, $propertyName, PropertyMappingConfigurationInterface $configuration)
 {
     $parsedTargetType = TypeHandling::parseType($targetType);
     return $parsedTargetType['elementType'];
 }
コード例 #10
0
 /**
  * Traverses the given object structure in order to transform it into an
  * array structure.
  *
  * @param object $object Object to traverse
  * @param array $configuration Configuration for transforming the given object or NULL
  * @return array Object structure as an array
  */
 protected function transformObject($object, array $configuration)
 {
     if ($object instanceof \DateTimeInterface) {
         return $object->format(\DateTime::ISO8601);
     } else {
         $propertyNames = ObjectAccess::getGettablePropertyNames($object);
         $propertiesToRender = [];
         foreach ($propertyNames as $propertyName) {
             if (isset($configuration['_only']) && is_array($configuration['_only']) && !in_array($propertyName, $configuration['_only'])) {
                 continue;
             }
             if (isset($configuration['_exclude']) && is_array($configuration['_exclude']) && in_array($propertyName, $configuration['_exclude'])) {
                 continue;
             }
             $propertyValue = ObjectAccess::getProperty($object, $propertyName);
             if (!is_array($propertyValue) && !is_object($propertyValue)) {
                 $propertiesToRender[$propertyName] = $propertyValue;
             } elseif (isset($configuration['_descend']) && array_key_exists($propertyName, $configuration['_descend'])) {
                 $propertiesToRender[$propertyName] = $this->transformValue($propertyValue, $configuration['_descend'][$propertyName]);
             }
         }
         if (isset($configuration['_exposeObjectIdentifier']) && $configuration['_exposeObjectIdentifier'] === true) {
             if (isset($configuration['_exposedObjectIdentifierKey']) && strlen($configuration['_exposedObjectIdentifierKey']) > 0) {
                 $identityKey = $configuration['_exposedObjectIdentifierKey'];
             } else {
                 $identityKey = '__identity';
             }
             $propertiesToRender[$identityKey] = $this->persistenceManager->getIdentifierByObject($object);
         }
         if (isset($configuration['_exposeClassName']) && ($configuration['_exposeClassName'] === self::EXPOSE_CLASSNAME_FULLY_QUALIFIED || $configuration['_exposeClassName'] === self::EXPOSE_CLASSNAME_UNQUALIFIED)) {
             $className = TypeHandling::getTypeForValue($object);
             $classNameParts = explode('\\', $className);
             $propertiesToRender['__class'] = $configuration['_exposeClassName'] === self::EXPOSE_CLASSNAME_FULLY_QUALIFIED ? $className : array_pop($classNameParts);
         }
         return $propertiesToRender;
     }
 }
コード例 #11
0
 /**
  * Delete an asset
  *
  * @param \Neos\Media\Domain\Model\Asset $asset
  * @return void
  */
 public function deleteAction(\Neos\Media\Domain\Model\Asset $asset)
 {
     $relationMap = [];
     $relationMap[TypeHandling::getTypeForValue($asset)] = array($this->persistenceManager->getIdentifierByObject($asset));
     if ($asset instanceof \Neos\Media\Domain\Model\Image) {
         foreach ($asset->getVariants() as $variant) {
             $type = TypeHandling::getTypeForValue($variant);
             if (!isset($relationMap[$type])) {
                 $relationMap[$type] = [];
             }
             $relationMap[$type][] = $this->persistenceManager->getIdentifierByObject($variant);
         }
     }
     $relatedNodes = $this->nodeDataRepository->findNodesByRelatedEntities($relationMap);
     if (count($relatedNodes) > 0) {
         $this->addFlashMessage('Asset could not be deleted, because there are still Nodes using it.', '', Message::SEVERITY_WARNING, array(), 1412422767);
         $this->redirect('index');
     }
     // FIXME: Resources are not deleted, because we cannot be sure that the resource isn't used anywhere else.
     $this->assetRepository->remove($asset);
     $this->addFlashMessage(sprintf('Asset "%s" has been deleted.', $asset->getLabel()), null, null, array(), 1412375050);
     $this->redirect('index');
 }
コード例 #12
0
 /**
  * @param DoctrineSqlFilter $sqlFilter
  * @param QuoteStrategy $quoteStrategy
  * @param ClassMetadata $targetEntity
  * @param string $targetTableAlias
  * @param string $targetEntityPropertyName
  * @return string
  * @throws InvalidQueryRewritingConstraintException
  * @throws \Exception
  */
 protected function getSqlForManyToOneAndOneToOneRelationsWithoutPropertyPath(DoctrineSqlFilter $sqlFilter, QuoteStrategy $quoteStrategy, ClassMetadata $targetEntity, $targetTableAlias, $targetEntityPropertyName)
 {
     $associationMapping = $targetEntity->getAssociationMapping($targetEntityPropertyName);
     $constraints = [];
     foreach ($associationMapping['joinColumns'] as $joinColumn) {
         $quotedColumnName = $quoteStrategy->getJoinColumnName($joinColumn, $targetEntity, $this->entityManager->getConnection()->getDatabasePlatform());
         $propertyPointer = $targetTableAlias . '.' . $quotedColumnName;
         $operandAlias = $this->operandDefinition;
         if (is_array($this->operandDefinition)) {
             $operandAlias = key($this->operandDefinition);
         }
         $currentReferencedOperandName = $operandAlias . $joinColumn['referencedColumnName'];
         if (is_object($this->operand)) {
             $operandMetadataInfo = $this->entityManager->getClassMetadata(TypeHandling::getTypeForValue($this->operand));
             $currentReferencedValueOfOperand = $operandMetadataInfo->getFieldValue($this->operand, $operandMetadataInfo->getFieldForColumn($joinColumn['referencedColumnName']));
             $this->setParameter($sqlFilter, $currentReferencedOperandName, $currentReferencedValueOfOperand, $associationMapping['type']);
         } elseif (is_array($this->operandDefinition)) {
             foreach ($this->operandDefinition as $operandIterator => $singleOperandValue) {
                 if (is_object($singleOperandValue)) {
                     $operandMetadataInfo = $this->entityManager->getClassMetadata(TypeHandling::getTypeForValue($singleOperandValue));
                     $currentReferencedValueOfOperand = $operandMetadataInfo->getFieldValue($singleOperandValue, $operandMetadataInfo->getFieldForColumn($joinColumn['referencedColumnName']));
                     $this->setParameter($sqlFilter, $operandIterator, $currentReferencedValueOfOperand, $associationMapping['type']);
                 } elseif ($singleOperandValue === null) {
                     $this->setParameter($sqlFilter, $operandIterator, null, $associationMapping['type']);
                 }
             }
         }
         $constraints[] = $this->getConstraintStringForSimpleProperty($sqlFilter, $propertyPointer, $currentReferencedOperandName);
     }
     return ' (' . implode(' ) AND ( ', $constraints) . ') ';
 }
コード例 #13
0
 /**
  * Tries to find a suitable type converter for the given source and target type.
  *
  * @param string $source The actual source value
  * @param string $sourceType Type of the source to convert from
  * @param string $targetType Name of the target type to find a type converter for
  * @return mixed Either the matching object converter or NULL
  * @throws Exception\InvalidTargetException
  */
 protected function findFirstEligibleTypeConverterInObjectHierarchy($source, $sourceType, $targetType)
 {
     $targetClass = TypeHandling::truncateElementType($targetType);
     if (!class_exists($targetClass) && !interface_exists($targetClass)) {
         throw new Exception\InvalidTargetException(sprintf('Could not find a suitable type converter for "%s" because no such the class/interface "%s" does not exist.', $targetType, $targetClass), 1297948764);
     }
     if (!isset($this->typeConverters[$sourceType])) {
         return null;
     }
     $convertersForSource = $this->typeConverters[$sourceType];
     if (isset($convertersForSource[$targetClass])) {
         $converter = $this->findEligibleConverterWithHighestPriority($convertersForSource[$targetClass], $source, $targetType);
         if ($converter !== null) {
             return $converter;
         }
     }
     foreach (class_parents($targetClass) as $parentClass) {
         if (!isset($convertersForSource[$parentClass])) {
             continue;
         }
         $converter = $this->findEligibleConverterWithHighestPriority($convertersForSource[$parentClass], $source, $targetType);
         if ($converter !== null) {
             return $converter;
         }
     }
     $converters = $this->getConvertersForInterfaces($convertersForSource, class_implements($targetClass));
     $converter = $this->findEligibleConverterWithHighestPriority($converters, $source, $targetType);
     if ($converter !== null) {
         return $converter;
     }
     if (isset($convertersForSource['object'])) {
         return $this->findEligibleConverterWithHighestPriority($convertersForSource['object'], $source, $targetType);
     } else {
         return null;
     }
 }
コード例 #14
0
 /**
  * Converts the given source object to an array containing the type and identity.
  *
  * @param object $source
  * @param string $targetType
  * @param array $convertedChildProperties
  * @param PropertyMappingConfigurationInterface $configuration
  * @return array
  */
 public function convertFrom($source, $targetType, array $convertedChildProperties = array(), PropertyMappingConfigurationInterface $configuration = null)
 {
     return ['__identity' => $this->persistenceManager->getIdentifierByObject($source), '__type' => TypeHandling::getTypeForValue($source)];
 }
コード例 #15
0
 /**
  * Convert a value to the internal object data format
  *
  * @param string $identifier The object's identifier
  * @param object $object The object with the property to flatten
  * @param string $propertyName The name of the property
  * @param array $propertyMetaData The property metadata
  * @param array $propertyData Reference to the property data array
  * @return void
  * @api
  */
 protected function flattenValue($identifier, $object, $propertyName, array $propertyMetaData, array &$propertyData)
 {
     $propertyValue = ObjectAccess::getProperty($object, $propertyName, true);
     if ($propertyValue instanceof PersistenceMagicInterface) {
         $propertyData[$propertyName] = ['type' => get_class($propertyValue), 'multivalue' => false, 'value' => $this->processObject($propertyValue, $identifier)];
     } else {
         switch ($propertyMetaData['type']) {
             case 'DateTime':
                 $propertyData[$propertyName] = ['multivalue' => false, 'value' => $this->processDateTime($propertyValue)];
                 break;
             case Collection::class:
             case ArrayCollection::class:
                 $propertyValue = $propertyValue === null ? [] : $propertyValue->toArray();
             case 'array':
                 $propertyData[$propertyName] = ['multivalue' => true, 'value' => $this->processArray($propertyValue, $identifier, $this->persistenceSession->getCleanStateOfProperty($object, $propertyName))];
                 break;
             case 'SplObjectStorage':
                 $propertyData[$propertyName] = ['multivalue' => true, 'value' => $this->processSplObjectStorage($propertyValue, $identifier, $this->persistenceSession->getCleanStateOfProperty($object, $propertyName))];
                 break;
             default:
                 if ($propertyValue === null && !TypeHandling::isSimpleType($propertyMetaData['type'])) {
                     $this->removeDeletedReference($object, $propertyName, $propertyMetaData);
                 }
                 $propertyData[$propertyName] = ['multivalue' => false, 'value' => $propertyValue];
                 break;
         }
         $propertyData[$propertyName]['type'] = $propertyMetaData['type'];
     }
 }
コード例 #16
0
 /**
  * @test
  * @dataProvider collectionTypes
  */
 public function isCollectionTypeReturnsTrueForCollectionType($type, $expected)
 {
     $this->assertSame($expected, TypeHandling::isCollectionType($type), 'Failed for ' . $type);
 }
コード例 #17
0
 /**
  * Convert an object from $source to an array
  *
  * @param AssetInterface $source
  * @param string $targetType
  * @param array $convertedChildProperties
  * @param PropertyMappingConfigurationInterface $configuration
  * @return array The converted asset or NULL
  */
 public function convertFrom($source, $targetType, array $convertedChildProperties = array(), PropertyMappingConfigurationInterface $configuration = null)
 {
     $identity = $this->persistenceManager->getIdentifierByObject($source);
     switch (true) {
         case $source instanceof ImageVariant:
             if (!isset($convertedChildProperties['originalAsset']) || !is_array($convertedChildProperties['originalAsset'])) {
                 return null;
             }
             $convertedChildProperties['originalAsset']['__identity'] = $this->persistenceManager->getIdentifierByObject($source->getOriginalAsset());
             return array('__identity' => $identity, '__type' => \Neos\Media\Domain\Model\ImageVariant::class, 'originalAsset' => $convertedChildProperties['originalAsset'], 'adjustments' => $convertedChildProperties['adjustments']);
         case $source instanceof AssetInterface:
             if (!isset($convertedChildProperties['resource']) || !is_array($convertedChildProperties['resource'])) {
                 return null;
             }
             $convertedChildProperties['resource']['__identity'] = $this->persistenceManager->getIdentifierByObject($source->getResource());
             return array('__identity' => $identity, '__type' => \Neos\Utility\TypeHandling::getTypeForValue($source), 'title' => $source->getTitle(), 'resource' => $convertedChildProperties['resource']);
     }
 }
コード例 #18
0
 /**
  * Evaluates any RequestPatterns of the given token to determine whether it is active for the current request
  * - If no RequestPattern is configured for this token, it is active
  * - Otherwise it is active only if at least one configured RequestPattern per type matches the request
  *
  * @param TokenInterface $token
  * @return bool TRUE if the given token is active, otherwise FALSE
  */
 protected function isTokenActive(TokenInterface $token)
 {
     if (!$token->hasRequestPatterns()) {
         return true;
     }
     $requestPatternsByType = [];
     /** @var $requestPattern RequestPatternInterface */
     foreach ($token->getRequestPatterns() as $requestPattern) {
         $patternType = TypeHandling::getTypeForValue($requestPattern);
         if (isset($requestPatternsByType[$patternType]) && $requestPatternsByType[$patternType] === true) {
             continue;
         }
         $requestPatternsByType[$patternType] = $requestPattern->matchRequest($this->request);
     }
     return !in_array(false, $requestPatternsByType, true);
 }
コード例 #19
0
 /**
  * Builds a base validator conjunction for the given data type.
  *
  * The base validation rules are those which were declared directly in a class (typically
  * a model) through some validate annotations on properties.
  *
  * If a property holds a class for which a base validator exists, that property will be
  * checked as well, regardless of a validate annotation
  *
  * Additionally, if a custom validator was defined for the class in question, it will be added
  * to the end of the conjunction. A custom validator is found if it follows the naming convention
  * "Replace '\Model\' by '\Validator\' and append 'Validator'".
  *
  * Example: $targetClassName is Neos\Foo\Domain\Model\Quux, then the validator will be found if it has the
  * name Neos\Foo\Domain\Validator\QuuxValidator
  *
  * @param string $indexKey The key to use as index in $this->baseValidatorConjunctions; calculated from target class name and validation groups
  * @param string $targetClassName The data type to build the validation conjunction for. Needs to be the fully qualified class name.
  * @param array $validationGroups The validation groups to build the validator for
  * @return void
  * @throws Exception\NoSuchValidatorException
  * @throws \InvalidArgumentException
  */
 protected function buildBaseValidatorConjunction($indexKey, $targetClassName, array $validationGroups)
 {
     $conjunctionValidator = new ConjunctionValidator();
     $this->baseValidatorConjunctions[$indexKey] = $conjunctionValidator;
     if (!TypeHandling::isSimpleType($targetClassName) && class_exists($targetClassName)) {
         // Model based validator
         $classSchema = $this->reflectionService->getClassSchema($targetClassName);
         if ($classSchema !== null && $classSchema->isAggregateRoot()) {
             $objectValidator = new AggregateBoundaryValidator(array());
         } else {
             $objectValidator = new GenericObjectValidator([]);
         }
         $conjunctionValidator->addValidator($objectValidator);
         foreach ($this->reflectionService->getClassPropertyNames($targetClassName) as $classPropertyName) {
             $classPropertyTagsValues = $this->reflectionService->getPropertyTagsValues($targetClassName, $classPropertyName);
             if (!isset($classPropertyTagsValues['var'])) {
                 throw new \InvalidArgumentException(sprintf('There is no @var annotation for property "%s" in class "%s".', $classPropertyName, $targetClassName), 1363778104);
             }
             try {
                 $parsedType = TypeHandling::parseType(trim(implode('', $classPropertyTagsValues['var']), ' \\'));
             } catch (InvalidTypeException $exception) {
                 throw new \InvalidArgumentException(sprintf(' @var annotation of ' . $exception->getMessage(), 'class "' . $targetClassName . '", property "' . $classPropertyName . '"'), 1315564744, $exception);
             }
             if ($this->reflectionService->isPropertyAnnotatedWith($targetClassName, $classPropertyName, Flow\IgnoreValidation::class)) {
                 continue;
             }
             $propertyTargetClassName = $parsedType['type'];
             if (TypeHandling::isCollectionType($propertyTargetClassName) === true) {
                 $collectionValidator = $this->createValidator(Validator\CollectionValidator::class, ['elementType' => $parsedType['elementType'], 'validationGroups' => $validationGroups]);
                 $objectValidator->addPropertyValidator($classPropertyName, $collectionValidator);
             } elseif (!TypeHandling::isSimpleType($propertyTargetClassName) && $this->objectManager->isRegistered($propertyTargetClassName) && $this->objectManager->getScope($propertyTargetClassName) === Configuration::SCOPE_PROTOTYPE) {
                 $validatorForProperty = $this->getBaseValidatorConjunction($propertyTargetClassName, $validationGroups);
                 if (count($validatorForProperty) > 0) {
                     $objectValidator->addPropertyValidator($classPropertyName, $validatorForProperty);
                 }
             }
             $validateAnnotations = $this->reflectionService->getPropertyAnnotations($targetClassName, $classPropertyName, Flow\Validate::class);
             foreach ($validateAnnotations as $validateAnnotation) {
                 if (count(array_intersect($validateAnnotation->validationGroups, $validationGroups)) === 0) {
                     // In this case, the validation groups for the property do not match current validation context
                     continue;
                 }
                 $newValidator = $this->createValidator($validateAnnotation->type, $validateAnnotation->options);
                 if ($newValidator === null) {
                     throw new Exception\NoSuchValidatorException('Invalid validate annotation in ' . $targetClassName . '::' . $classPropertyName . ': Could not resolve class name for  validator "' . $validateAnnotation->type . '".', 1241098027);
                 }
                 $objectValidator->addPropertyValidator($classPropertyName, $newValidator);
             }
         }
         if (count($objectValidator->getPropertyValidators()) === 0) {
             $conjunctionValidator->removeValidator($objectValidator);
         }
     }
     $this->addCustomValidators($targetClassName, $conjunctionValidator);
 }
コード例 #20
0
 /**
  * Traverses the $array and replaces known persisted objects with a tuple of
  * type and identifier.
  *
  * @param array $array
  * @return void
  * @throws \RuntimeException
  */
 protected function encodeObjectReferences(array &$array)
 {
     foreach ($array as &$value) {
         if (is_array($value)) {
             $this->encodeObjectReferences($value);
         }
         if (!is_object($value) || is_object($value) && $value instanceof DependencyProxy) {
             continue;
         }
         $propertyClassName = TypeHandling::getTypeForValue($value);
         if ($value instanceof \DateTimeInterface) {
             $value = ['date' => $value->format('Y-m-d H:i:s.u'), 'timezone' => $value->format('e'), 'dateFormat' => 'Y-m-d H:i:s.u'];
         } elseif ($value instanceof \SplObjectStorage) {
             throw new \RuntimeException('SplObjectStorage in array properties is not supported', 1375196580);
         } elseif ($value instanceof \Doctrine\Common\Collections\Collection) {
             throw new \RuntimeException('Collection in array properties is not supported', 1375196581);
         } elseif ($value instanceof \ArrayObject) {
             throw new \RuntimeException('ArrayObject in array properties is not supported', 1375196582);
         } elseif ($this->persistenceManager->isNewObject($value) === false && ($this->reflectionService->isClassAnnotatedWith($propertyClassName, Flow\Entity::class) || $this->reflectionService->isClassAnnotatedWith($propertyClassName, Flow\ValueObject::class) || $this->reflectionService->isClassAnnotatedWith($propertyClassName, \Doctrine\ORM\Mapping\Entity::class))) {
             $value = ['__flow_object_type' => $propertyClassName, '__identifier' => $this->persistenceManager->getIdentifierByObject($value)];
         }
     }
 }
コード例 #21
0
 /**
  * Tells if the value of the specified property can be retrieved by this Object Accessor.
  *
  * @param object $object Object containing the property
  * @param string $propertyName Name of the property to check
  * @return boolean
  * @throws \InvalidArgumentException
  */
 public static function isPropertyGettable($object, $propertyName)
 {
     if (!is_object($object)) {
         throw new \InvalidArgumentException('$object must be an object, ' . gettype($object) . ' given.', 1259828921);
     }
     if ($object instanceof \ArrayAccess && isset($object[$propertyName]) === true) {
         return true;
     } elseif ($object instanceof \stdClass && array_search($propertyName, array_keys(get_object_vars($object))) !== false) {
         return true;
     }
     $uppercasePropertyName = ucfirst($propertyName);
     if (is_callable([$object, 'get' . $uppercasePropertyName])) {
         return true;
     }
     if (is_callable([$object, 'is' . $uppercasePropertyName])) {
         return true;
     }
     if (is_callable([$object, 'has' . $uppercasePropertyName])) {
         return true;
     }
     $className = TypeHandling::getTypeForValue($object);
     return array_search($propertyName, array_keys(get_class_vars($className))) !== false;
 }
コード例 #22
0
ファイル: PropertyMapperTest.php プロジェクト: neos/flow
 /**
  * @test
  * @dataProvider convertCallsCanConvertFromWithTheFullNormalizedTargetTypeDataProvider
  */
 public function convertCallsCanConvertFromWithTheFullNormalizedTargetType($source, $fullTargetType)
 {
     $mockTypeConverter = $this->getMockTypeConverter();
     $mockTypeConverter->expects($this->atLeastOnce())->method('canConvertFrom')->with($source, $fullTargetType);
     $truncatedTargetType = TypeHandling::truncateElementType($fullTargetType);
     $mockTypeConverters = [gettype($source) => [$truncatedTargetType => [1 => $mockTypeConverter]]];
     $propertyMapper = $this->getAccessibleMock(PropertyMapper::class, ['dummy']);
     $propertyMapper->_set('typeConverters', $mockTypeConverters);
     $mockConfiguration = $this->getMockBuilder(PropertyMappingConfiguration::class)->disableOriginalConstructor()->getMock();
     $propertyMapper->convert($source, $fullTargetType, $mockConfiguration);
     // dummy assertion to avoid PHPUnit warning
     $this->assertTrue(true);
 }
コード例 #23
0
 /**
  * Constructs this controller argument
  *
  * @param string $name Name of this argument
  * @param string $dataType The data type of this argument
  * @throws \InvalidArgumentException if $name is not a string or empty
  * @api
  */
 public function __construct($name, $dataType)
 {
     if (!is_string($name)) {
         throw new \InvalidArgumentException('$name must be of type string, ' . gettype($name) . ' given.', 1187951688);
     }
     if (strlen($name) === 0) {
         throw new \InvalidArgumentException('$name must be a non-empty string, ' . strlen($name) . ' characters given.', 1232551853);
     }
     $this->name = $name;
     $this->dataType = TypeHandling::normalizeType($dataType);
 }
コード例 #24
0
 /**
  * Iterates through the given $properties setting them on the specified $node using the appropriate TypeConverters.
  *
  * @param object $nodeLike
  * @param NodeType $nodeType
  * @param array $properties
  * @param TYPO3CRContext $context
  * @param PropertyMappingConfigurationInterface $configuration
  * @return void
  * @throws TypeConverterException
  */
 protected function setNodeProperties($nodeLike, NodeType $nodeType, array $properties, TYPO3CRContext $context, PropertyMappingConfigurationInterface $configuration = null)
 {
     $nodeTypeProperties = $nodeType->getProperties();
     unset($properties['_lastPublicationDateTime']);
     foreach ($properties as $nodePropertyName => $nodePropertyValue) {
         if (substr($nodePropertyName, 0, 2) === '__') {
             continue;
         }
         $nodePropertyType = isset($nodeTypeProperties[$nodePropertyName]['type']) ? $nodeTypeProperties[$nodePropertyName]['type'] : null;
         switch ($nodePropertyType) {
             case 'reference':
                 $nodePropertyValue = $context->getNodeByIdentifier($nodePropertyValue);
                 break;
             case 'references':
                 $nodeIdentifiers = json_decode($nodePropertyValue);
                 $nodePropertyValue = array();
                 if (is_array($nodeIdentifiers)) {
                     foreach ($nodeIdentifiers as $nodeIdentifier) {
                         $referencedNode = $context->getNodeByIdentifier($nodeIdentifier);
                         if ($referencedNode !== null) {
                             $nodePropertyValue[] = $referencedNode;
                         }
                     }
                 } elseif ($nodeIdentifiers !== null) {
                     throw new TypeConverterException(sprintf('node type "%s" expects an array of identifiers for its property "%s"', $nodeType->getName(), $nodePropertyName), 1383587419);
                 }
                 break;
             case 'DateTime':
                 if ($nodePropertyValue !== '' && ($nodePropertyValue = \DateTime::createFromFormat(\DateTime::W3C, $nodePropertyValue)) !== false) {
                     $nodePropertyValue->setTimezone(new \DateTimeZone(date_default_timezone_get()));
                 } else {
                     $nodePropertyValue = null;
                 }
                 break;
             case 'integer':
                 $nodePropertyValue = intval($nodePropertyValue);
                 break;
             case 'boolean':
                 if (is_string($nodePropertyValue)) {
                     $nodePropertyValue = $nodePropertyValue === 'true' ? true : false;
                 }
                 break;
             case 'array':
                 $nodePropertyValue = json_decode($nodePropertyValue, true);
                 break;
         }
         if (substr($nodePropertyName, 0, 1) === '_') {
             $nodePropertyName = substr($nodePropertyName, 1);
             ObjectAccess::setProperty($nodeLike, $nodePropertyName, $nodePropertyValue);
             continue;
         }
         if (!isset($nodeTypeProperties[$nodePropertyName])) {
             if ($configuration !== null && $configuration->shouldSkipUnknownProperties()) {
                 continue;
             } else {
                 throw new TypeConverterException(sprintf('Node type "%s" does not have a property "%s" according to the schema', $nodeType->getName(), $nodePropertyName), 1359552744);
             }
         }
         $innerType = $nodePropertyType;
         if ($nodePropertyType !== null) {
             try {
                 $parsedType = TypeHandling::parseType($nodePropertyType);
                 $innerType = $parsedType['elementType'] ?: $parsedType['type'];
             } catch (InvalidTypeException $exception) {
             }
         }
         if (is_string($nodePropertyValue) && $this->objectManager->isRegistered($innerType) && $nodePropertyValue !== '') {
             $nodePropertyValue = $this->propertyMapper->convert(json_decode($nodePropertyValue, true), $nodePropertyType, $configuration);
         }
         $nodeLike->setProperty($nodePropertyName, $nodePropertyValue);
     }
 }
コード例 #25
0
 /**
  * Convert an object from $source to an entity or a value object.
  *
  * @param mixed $source
  * @param string $targetType
  * @param array $convertedChildProperties
  * @param PropertyMappingConfigurationInterface $configuration
  * @return object|TargetNotFoundError the converted entity/value object or an instance of TargetNotFoundError if the object could not be resolved
  * @throws \InvalidArgumentException|InvalidTargetException
  */
 public function convertFrom($source, $targetType, array $convertedChildProperties = [], PropertyMappingConfigurationInterface $configuration = null)
 {
     if (is_array($source)) {
         if ($this->reflectionService->isClassAnnotatedWith($targetType, ValueObject::class)) {
             if (isset($source['__identity']) && count($source) > 1) {
                 // @TODO fix that in the URI building and transfer VOs as values instead as with their identities
                 // Unset identity for value objects to use constructor mapping, since the identity is determined from
                 // property values after construction
                 unset($source['__identity']);
             }
         }
         $object = $this->handleArrayData($source, $targetType, $convertedChildProperties, $configuration);
         if ($object instanceof TargetNotFoundError) {
             return $object;
         }
     } elseif (is_string($source)) {
         if ($source === '') {
             return null;
         }
         $object = $this->fetchObjectFromPersistence($source, $targetType);
         if ($object === null) {
             return new TargetNotFoundError(sprintf('Object of type "%s" with identity "%s" not found.', $targetType, $source), 1412283033);
         }
     } else {
         throw new \InvalidArgumentException('Only strings and arrays are accepted.', 1305630314);
     }
     $objectConstructorArguments = $this->getConstructorArgumentsForClass(TypeHandling::getTypeForValue($object));
     foreach ($convertedChildProperties as $propertyName => $propertyValue) {
         // We need to check for "immutable" constructor arguments that have no setter and remove them.
         if (isset($objectConstructorArguments[$propertyName]) && !ObjectAccess::isPropertySettable($object, $propertyName)) {
             $currentPropertyValue = ObjectAccess::getProperty($object, $propertyName);
             if ($currentPropertyValue === $propertyValue) {
                 continue;
             } else {
                 $exceptionMessage = sprintf('Property "%s" having a value of type "%s" could not be set in target object of type "%s". The property has no setter and is not equal to the value in the object, in that case it would have been skipped.', $propertyName, is_object($propertyValue) ? TypeHandling::getTypeForValue($propertyValue) : gettype($propertyValue), $targetType);
                 throw new InvalidTargetException($exceptionMessage, 1421498771);
             }
         }
         $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) ? TypeHandling::getTypeForValue($propertyValue) : gettype($propertyValue), $targetType);
             throw new InvalidTargetException($exceptionMessage, 1297935345);
         }
     }
     return $object;
 }
コード例 #26
0
ファイル: ReflectionService.php プロジェクト: neos/flow
 /**
  * @param ClassSchema $classSchema
  * @param string $propertyName
  * @return boolean
  * @throws InvalidPropertyTypeException
  * @throws \InvalidArgumentException
  */
 protected function evaluateClassPropertyAnnotationsForSchema(ClassSchema $classSchema, $propertyName)
 {
     $skipArtificialIdentity = false;
     $className = $classSchema->getClassName();
     if ($this->isPropertyAnnotatedWith($className, $propertyName, Flow\Transient::class)) {
         return false;
     }
     if ($this->isPropertyAnnotatedWith($className, $propertyName, Flow\Inject::class)) {
         return false;
     }
     if (!$this->isPropertyTaggedWith($className, $propertyName, 'var')) {
         return false;
     }
     $varTagValues = $this->getPropertyTagValues($className, $propertyName, 'var');
     if (count($varTagValues) > 1) {
         throw new InvalidPropertyTypeException('More than one @var annotation given for "' . $className . '::$' . $propertyName . '"', 1367334366);
     }
     $declaredType = strtok(trim(current($varTagValues), " \n\t"), " \n\t");
     try {
         TypeHandling::parseType($declaredType);
     } catch (InvalidTypeException $exception) {
         throw new \InvalidArgumentException(sprintf($exception->getMessage(), 'class "' . $className . '" for property "' . $propertyName . '"'), 1315564475);
     }
     if ($this->isPropertyAnnotatedWith($className, $propertyName, ORM\Id::class)) {
         $skipArtificialIdentity = true;
     }
     $classSchema->addProperty($propertyName, $declaredType, $this->isPropertyAnnotatedWith($className, $propertyName, Flow\Lazy::class), $this->isPropertyAnnotatedWith($className, $propertyName, Flow\Transient::class));
     if ($this->isPropertyAnnotatedWith($className, $propertyName, Flow\Identity::class)) {
         $classSchema->markAsIdentityProperty($propertyName);
     }
     return $skipArtificialIdentity;
 }
コード例 #27
0
 /**
  * The type of a property is determined by the reflection service.
  *
  * @param string $targetType
  * @param string $propertyName
  * @param PropertyMappingConfigurationInterface $configuration
  * @return string
  * @throws InvalidTargetException
  */
 public function getTypeOfChildProperty($targetType, $propertyName, PropertyMappingConfigurationInterface $configuration)
 {
     $configuredTargetType = $configuration->getConfigurationFor($propertyName)->getConfigurationValue(ObjectConverter::class, self::CONFIGURATION_TARGET_TYPE);
     if ($configuredTargetType !== null) {
         return $configuredTargetType;
     }
     $methodParameters = $this->reflectionService->getMethodParameters($targetType, '__construct');
     if (isset($methodParameters[$propertyName]) && isset($methodParameters[$propertyName]['type'])) {
         return $methodParameters[$propertyName]['type'];
     } elseif ($this->reflectionService->hasMethod($targetType, ObjectAccess::buildSetterMethodName($propertyName))) {
         $methodParameters = $this->reflectionService->getMethodParameters($targetType, ObjectAccess::buildSetterMethodName($propertyName));
         $methodParameter = current($methodParameters);
         if (!isset($methodParameter['type'])) {
             throw new InvalidTargetException('Setter for property "' . $propertyName . '" had no type hint or documentation in target object of type "' . $targetType . '".', 1303379158);
         } else {
             return $methodParameter['type'];
         }
     } else {
         $targetPropertyNames = $this->reflectionService->getClassPropertyNames($targetType);
         if (in_array($propertyName, $targetPropertyNames)) {
             $varTagValues = $this->reflectionService->getPropertyTagValues($targetType, $propertyName, 'var');
             if (count($varTagValues) > 0) {
                 // This ensures that FQCNs are returned without leading backslashes. Otherwise, something like @var \DateTime
                 // would not find a property mapper. It is needed because the ObjectConverter doesn't use class schemata,
                 // but reads the annotations directly.
                 $declaredType = strtok(trim(current($varTagValues), " \n\t"), " \n\t");
                 try {
                     $parsedType = TypeHandling::parseType($declaredType);
                 } catch (InvalidTypeException $exception) {
                     throw new \InvalidArgumentException(sprintf($exception->getMessage(), 'class "' . $targetType . '" for property "' . $propertyName . '"'), 1467699674);
                 }
                 return $parsedType['type'] . ($parsedType['elementType'] !== null ? '<' . $parsedType['elementType'] . '>' : '');
             } else {
                 throw new InvalidTargetException(sprintf('Public property "%s" had no proper type annotation (i.e. "@var") in target object of type "%s".', $propertyName, $targetType), 1406821818);
             }
         }
     }
     throw new InvalidTargetException(sprintf('Property "%s" has neither a setter or constructor argument, nor is public, in target object of type "%s".', $propertyName, $targetType), 1303379126);
 }
コード例 #28
0
 /**
  * @param string $operand
  * @param string $value
  * @return boolean TRUE if $value is of type $operand; FALSE otherwise
  */
 protected function handleSimpleTypeOperand($operand, $value)
 {
     $operand = TypeHandling::normalizeType($operand);
     if ($operand === 'object') {
         return is_object($value);
     } elseif ($operand === 'string') {
         return is_string($value);
     } elseif ($operand === 'integer') {
         return is_integer($value);
     } elseif ($operand === 'boolean') {
         return is_bool($value);
     } elseif ($operand === 'float') {
         return is_float($value);
     } elseif ($operand === 'array') {
         return is_array($value);
     }
     return false;
 }
コード例 #29
0
 /**
  * @return string
  */
 public function getLabel()
 {
     $arguments = [];
     foreach ($this->arguments as $argumentValue) {
         if (TypeHandling::isSimpleType($argumentValue)) {
             $arguments[] = $argumentValue;
         } else {
             $arguments[] = '[' . gettype($argumentValue) . ']';
         }
     }
     return sprintf('%s::%s(%s)', $this->className, $this->methodName, implode(', ', $arguments));
 }
コード例 #30
0
 /**
  * Adds (defines) a specific property and its type.
  *
  * @param string $name Name of the property
  * @param string $type Type of the property
  * @param boolean $lazy Whether the property should be lazy-loaded when reconstituting
  * @param boolean $transient Whether the property should not be considered for persistence
  * @return void
  * @throws \InvalidArgumentException
  */
 public function addProperty($name, $type, $lazy = false, $transient = false)
 {
     try {
         $type = TypeHandling::parseType($type);
     } catch (InvalidTypeException $exception) {
         throw new \InvalidArgumentException(sprintf($exception->getMessage(), 'class "' . $name . '"'), 1315564474);
     }
     $this->properties[$name] = ['type' => $type['type'], 'elementType' => $type['elementType'], 'lazy' => $lazy, 'transient' => $transient];
 }