/** * 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)]); } }
/** * 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(); }
/** * 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']); }
/** * 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; }
/** * 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); } }
/** * 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); } }
/** * 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; }
/** * 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); }
/** * 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; } }
/** * 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'); }
/** * 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']); } }
/** * 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); }
/** * @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) . ') '; }
/** * Returns the class name of the given object. This is a convenience * method that returns the expected class names even for proxy classes. * * @param object $object * @return string The class name of the given object * @deprecated since 3.0 use \Neos\Utility\TypeHandling::getTypeForValue() instead */ public function getClassNameByObject($object) { return TypeHandling::getTypeForValue($object); }
/** * 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; }
/** * 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)]; }
/** * 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)]; } } }
/** * Apply the given adjustment to the image variant. * If an adjustment of the given type already exists, the existing one will be overridden by the new one. * * @param ImageAdjustmentInterface $adjustment * @return void */ protected function applyAdjustment(ImageAdjustmentInterface $adjustment) { $existingAdjustmentFound = false; $newAdjustmentClassName = TypeHandling::getTypeForValue($adjustment); foreach ($this->adjustments as $existingAdjustment) { if (TypeHandling::getTypeForValue($existingAdjustment) === $newAdjustmentClassName) { foreach (ObjectAccess::getGettableProperties($adjustment) as $propertyName => $propertyValue) { ObjectAccess::setProperty($existingAdjustment, $propertyName, $propertyValue); } $existingAdjustmentFound = true; } } if (!$existingAdjustmentFound) { $this->adjustments->add($adjustment); $adjustment->setImageVariant($this); $this->adjustments = $this->adjustments->matching(new Criteria(null, array('position' => 'ASC'))); } $this->lastModified = new \DateTime(); }