/** * 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)]); } }
/** * Creates a node from the given NodeData container. * * If this factory has previously created a Node for the given $node and it's dimensions, * it will return the same node again. * * @param NodeData $nodeData * @param Context $context * @return NodeInterface * @throws NodeConfigurationException if a configured 'class' for a Node does not exist or does not inherit NodeInterface */ public function createFromNodeData(NodeData $nodeData, Context $context) { if ($nodeData->isInternal()) { return null; } $internalNodeIdentifier = $nodeData->getIdentifier() . spl_object_hash($context); // In case there is a Node with an internal NodeData (because the NodeData was changed in the meantime) we need to flush it. if (isset($this->nodes[$internalNodeIdentifier]) && $this->nodes[$internalNodeIdentifier]->getNodeData()->isInternal()) { unset($this->nodes[$internalNodeIdentifier]); } if (!isset($this->nodes[$internalNodeIdentifier])) { // Warning: Alternative node implementations are considered internal for now, feature can change or be removed anytime. We want to be sure it works well and makes sense before declaring it public. $class = $nodeData->getNodeType()->getConfiguration('class') ?: $this->objectManager->getClassNameByObjectName(NodeInterface::class); if (!in_array($class, static::getNodeInterfaceImplementations($this->objectManager))) { throw new NodeConfigurationException('The configured implementation class name "' . $class . '" for NodeType "' . $nodeData->getNodeType() . '" does not inherit from ' . NodeInterface::class . '.', 1406884014); } $this->nodes[$internalNodeIdentifier] = new $class($nodeData, $context); } $node = $this->nodes[$internalNodeIdentifier]; return $this->filterNodeByContext($node, $context); }
/** * @test */ public function getNodeTypeReturnsFallbackNodeTypeForUnknownNodeType() { $mockFallbackNodeType = $this->getMockBuilder(NodeType::class)->disableOriginalConstructor()->getMock(); $mockNonExistingNodeType = $this->getMockBuilder(NodeType::class)->disableOriginalConstructor()->getMock(); $mockNonExistingNodeType->expects($this->atLeastOnce())->method('getName')->willReturn('definitelyNotAvailableNodeType'); /** @var NodeTypeManager|\PHPUnit_Framework_MockObject_MockObject $mockNodeTypeManager */ $mockNodeTypeManager = $this->getMockBuilder(NodeTypeManager::class)->disableOriginalConstructor()->getMock(); $mockNodeTypeManager->expects($this->atLeastOnce())->method('getNodeType')->with('definitelyNotAvailableNodeType')->will($this->returnValue($mockFallbackNodeType)); $this->inject($this->nodeData, 'nodeTypeManager', $mockNodeTypeManager); $this->inject($this->nodeData, 'nodeType', $mockNonExistingNodeType); $this->assertSame($mockFallbackNodeType, $this->nodeData->getNodeType()); }
/** * 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; }
/** * 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']) && ($propertyConfiguration['type'] === ImageInterface::class || preg_match('/array\\<.*\\>/', $propertyConfiguration['type']))) { 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]) || empty($nodeProperties[$propertyName])) { continue; } if ($propertyConfiguration['type'] === ImageInterface::class) { $adjustments = array(); $oldVariantConfiguration = $nodeProperties[$propertyName]; if (is_array($oldVariantConfiguration)) { foreach ($oldVariantConfiguration as $variantPropertyName => $property) { switch (substr($variantPropertyName, 3)) { case 'originalImage': /** * @var $originalAsset Image */ $originalAsset = $this->assetRepository->findByIdentifier($this->persistenceManager->getIdentifierByObject($property)); break; case 'processingInstructions': $adjustments = $this->processingInstructionsConverter->convertFrom($property, 'array'); break; } } $nodeProperties[$propertyName] = null; if (isset($originalAsset)) { $stream = $originalAsset->getResource()->getStream(); if ($stream === false) { continue; } fclose($stream); $newImageVariant = new ImageVariant($originalAsset); foreach ($adjustments as $adjustment) { $newImageVariant->addAdjustment($adjustment); } $originalAsset->addVariant($newImageVariant); $this->assetRepository->update($originalAsset); $nodeProperties[$propertyName] = $this->persistenceManager->getIdentifierByObject($newImageVariant); } } } elseif (preg_match('/array\\<.*\\>/', $propertyConfiguration['type'])) { if (is_array($nodeProperties[$propertyName])) { $convertedValue = []; foreach ($nodeProperties[$propertyName] as $entryValue) { if (!is_object($entryValue)) { continue; } $stream = $entryValue->getResource()->getStream(); if ($stream === false) { continue; } fclose($stream); $existingObjectIdentifier = null; try { $existingObjectIdentifier = $this->persistenceManager->getIdentifierByObject($entryValue); if ($existingObjectIdentifier !== null) { $convertedValue[] = $existingObjectIdentifier; } } catch (\Exception $exception) { } } $nodeProperties[$propertyName] = $convertedValue; } } } } 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)]); } }
/** * Returns the node type of this node. * * @return NodeType * @api */ public function getNodeType() { return $this->nodeData->getNodeType(); }