/** * Returns a previously uploaded image. * If errors occurred during property mapping for this property, NULL is returned * * @return Image */ protected function getUploadedImage() { if ($this->getMappingResultsForProperty()->hasErrors()) { return null; } $image = $this->getValue(false); if ($image instanceof Image) { return $image; } return $this->propertyMapper->convert($image, Image::class); }
/** * Returns a previously uploaded resource. * If errors occurred during property mapping for this property, NULL is returned * * @return PersistentResource */ protected function getUploadedResource() { if ($this->getMappingResultsForProperty()->hasErrors()) { return null; } $resourceObject = $this->getValue(false); if ($resourceObject instanceof PersistentResource) { return $resourceObject; } return $this->propertyMapper->convert($resourceObject, PersistentResource::class); }
/** * Actually convert from $source to $targetType, taking into account the fully * built $convertedChildProperties and $configuration. * * The return value can be one of three types: * - an arbitrary object, or a simple type (which has been created while mapping). * This is the normal case. * - NULL, indicating that this object should *not* be mapped (i.e. a "File Upload" Converter could return NULL if no file has been uploaded, and a silent failure should occur. * - An instance of Error -- This will be a user-visible error message later on. * Furthermore, it should throw an Exception if an unexpected failure (like a security error) occurred or a configuration issue happened. * * @param mixed $source * @param string $targetType * @param array $convertedChildProperties * @param PropertyMappingConfigurationInterface $configuration * @return mixed|Error the target type, or an error object if a user-error occurred * @throws TypeConverterException thrown in case a developer error occurred * @api */ public function convertFrom($source, $targetType, array $convertedChildProperties = [], PropertyMappingConfigurationInterface $configuration = null) { $result = []; $convertElements = $configuration->getConfigurationValue(ArrayTypeConverter::class, self::CONFIGURATION_CONVERT_ELEMENTS); foreach ($source as $element) { if ($convertElements === true) { $element = $this->propertyMapper->convert($element, 'array', $configuration); } $result[] = $element; } return $result; }
/** * @test * @expectedException \Neos\Flow\Property\Exception */ public function entityWithImmutablePropertyCanNotBeUpdatedWhenImmutablePropertyChanged() { $result = $this->propertyMapper->convert($this->sourceProperties, Fixtures\TestEntityWithImmutableProperty::class); $identifier = $this->persistenceManager->getIdentifierByObject($result); $this->persistenceManager->add($result); $this->persistenceManager->persistAll(); $this->persistenceManager->clearState(); $update = ['__identity' => $identifier, 'age' => '25', 'name' => 'Christian D']; $result = $this->propertyMapper->convert($update, Fixtures\TestEntityWithImmutableProperty::class); $this->assertInstanceOf(Fixtures\TestEntityWithImmutableProperty::class, $result); $this->assertEquals('Christian M', $result->getName()); }
/** * Lists all currently active and registered type converters * * All active converters are listed with ordered by priority and grouped by * source type first and target type second. * * @return void */ public function listCommand() { foreach ($this->propertyMapper->getTypeConverters() as $sourceType => $targetTypePriorityAndInstance) { $this->outputLine(); $this->outputLine('<b>Source type "%s":</b>', [$sourceType]); foreach ($targetTypePriorityAndInstance as $targetType => $priorityAndInstance) { $this->outputFormatted('<b>Target type "%s":</b>', [$targetType], 4); krsort($priorityAndInstance); foreach ($priorityAndInstance as $priority => $instance) { $this->outputFormatted('%3s: %s', [$priority, get_class($instance)], 8); } $this->outputLine(); } $this->outputLine(); } }
/** * Converts and adds ImageAdjustments to the ImageVariant * * @param ImageInterface $asset * @param mixed $source * @param array $convertedChildProperties * @param PropertyMappingConfigurationInterface $configuration * @return ImageInterface|NULL */ protected function applyTypeSpecificHandling($asset, $source, array $convertedChildProperties, PropertyMappingConfigurationInterface $configuration) { if ($asset instanceof ImageVariant) { $adjustments = []; if (isset($source['adjustments'])) { foreach ($source['adjustments'] as $adjustmentType => $adjustmentOptions) { if (isset($adjustmentOptions['__type'])) { $adjustmentType = $adjustmentOptions['__type']; unset($adjustmentOptions['__type']); } $identity = null; if (isset($adjustmentOptions['__identity'])) { $identity = $adjustmentOptions['__identity']; unset($adjustmentOptions['__identity']); } $adjustment = $this->propertyMapper->convert($adjustmentOptions, $adjustmentType, $configuration); if ($identity !== null) { ObjectAccess::setProperty($adjustment, 'persistence_object_identifier', $identity, true); } $adjustments[] = $adjustment; } } elseif (isset($source['processingInstructions'])) { $adjustments = $this->processingInstructionsConverter->convertFrom($source['processingInstructions'], 'array'); } if (count($adjustments) > 0) { $asset->addAdjustments($adjustments); } } return $asset; }
/** * @return \DateTime */ protected function getSelectedDate() { $date = $this->getValue(); if ($date instanceof \DateTime) { return $date; } if ($date !== null) { $date = $this->propertyMapper->convert($date, 'DateTime'); if (!$date instanceof \DateTime) { return null; } return $date; } if ($this->hasArgument('initialDate')) { return new \DateTime($this->arguments['initialDate']); } }
/** * @test */ public function getTargetPropertyNameShouldReturnTheUnmodifiedPropertyNameWithoutConfiguration() { $defaultConfiguration = $this->propertyMapper->buildPropertyMappingConfiguration(); $this->assertTrue($defaultConfiguration->getConfigurationValue(\Neos\Flow\Property\TypeConverter\PersistentObjectConverter::class, \Neos\Flow\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED)); $this->assertTrue($defaultConfiguration->getConfigurationValue(\Neos\Flow\Property\TypeConverter\PersistentObjectConverter::class, \Neos\Flow\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED)); $this->assertNull($defaultConfiguration->getConfigurationFor('foo')->getConfigurationValue(\Neos\Flow\Property\TypeConverter\PersistentObjectConverter::class, \Neos\Flow\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED)); $this->assertNull($defaultConfiguration->getConfigurationFor('foo')->getConfigurationValue(\Neos\Flow\Property\TypeConverter\PersistentObjectConverter::class, \Neos\Flow\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED)); }
/** * @test */ public function handleMergesInternalArgumentsWithRoutingMatchResults() { $this->mockHttpRequest->expects($this->any())->method('getArguments')->will($this->returnValue(['__internalArgument1' => 'request', '__internalArgument2' => 'request', '__internalArgument3' => 'request'])); $this->mockHttpRequest->expects(self::any())->method('getContent')->willReturn('requestBody'); $this->mockPropertyMapper->expects($this->any())->method('convert')->will($this->returnValue(['__internalArgument2' => 'requestBody', '__internalArgument3' => 'requestBody'])); $this->mockComponentContext->expects($this->atLeastOnce())->method('getParameter')->with(RoutingComponent::class, 'matchResults')->will($this->returnValue(['__internalArgument3' => 'routing'])); $this->mockActionRequest->expects($this->once())->method('setArguments')->with(['__internalArgument1' => 'request', '__internalArgument2' => 'requestBody', '__internalArgument3' => 'routing']); $this->dispatchComponent->handle($this->mockComponentContext); }
/** * @test */ public function processConvertsValueIfDataTypeIsSpecified() { $this->processingRule->setDataType('SomeDataType'); $mockPropertyMappingConfiguration = $this->getMockBuilder(\Neos\Flow\Property\PropertyMappingConfiguration::class)->getMock(); $this->processingRule->_set('propertyMappingConfiguration', $mockPropertyMappingConfiguration); $this->mockPropertyMapper->expects($this->once())->method('convert')->with('Some Value', 'SomeDataType', $mockPropertyMappingConfiguration)->will($this->returnValue('Converted Value')); $this->mockPropertyMapper->expects($this->any())->method('getMessages')->will($this->returnValue(new \Neos\Error\Messages\Result())); $this->assertEquals('Converted Value', $this->processingRule->process('Some Value')); }
/** * @param array $contextArray * @return array */ public function unserializeContext(array $contextArray) { $unserializedContext = []; foreach ($contextArray as $variableName => $typeAndValue) { $value = $this->propertyMapper->convert($typeAndValue['value'], $typeAndValue['type']); $unserializedContext[$variableName] = $value; } return $unserializedContext; }
/** * Generates an array of strings from the given array of context variables * * @param array $contextVariables * @return array * @throws \InvalidArgumentException */ protected function serializeContext(array $contextVariables) { $serializedContextArray = []; foreach ($contextVariables as $variableName => $contextValue) { // TODO This relies on a converter being available from the context value type to string if ($contextValue !== null) { $serializedContextArray[$variableName]['type'] = $this->getTypeForContextValue($contextValue); $serializedContextArray[$variableName]['value'] = $this->propertyMapper->convert($contextValue, 'string'); } } return $serializedContextArray; }
/** * @param mixed $value * @return mixed */ public function process($value) { if ($this->dataType !== null) { $value = $this->propertyMapper->convert($value, $this->dataType, $this->propertyMappingConfiguration); $messages = $this->propertyMapper->getMessages(); } else { $messages = new \Neos\Error\Messages\Result(); } $validationResult = $this->validator->validate($value); $messages->merge($validationResult); $this->processingMessages->merge($messages); return $value; }
/** * Parses the request body according to the media type. * * @param HttpRequest $httpRequest * @return array */ protected function parseRequestBody(HttpRequest $httpRequest) { $requestBody = $httpRequest->getContent(); if ($requestBody === null || $requestBody === '') { return []; } $mediaTypeConverter = $this->objectManager->get(MediaTypeConverterInterface::class); $propertyMappingConfiguration = new PropertyMappingConfiguration(); $propertyMappingConfiguration->setTypeConverter($mediaTypeConverter); $propertyMappingConfiguration->setTypeConverterOption(MediaTypeConverterInterface::class, MediaTypeConverterInterface::CONFIGURATION_MEDIA_TYPE, $httpRequest->getHeader('Content-Type')); $arguments = $this->propertyMapper->convert($requestBody, 'array', $propertyMappingConfiguration); return $arguments; }
/** * Calls a behat step method * * @Flow\Internal * @param string $testHelperObjectName * @param string $methodName * @param boolean $withoutSecurityChecks */ public function callBehatStepCommand($testHelperObjectName, $methodName, $withoutSecurityChecks = false) { $testHelper = $this->objectManager->get($testHelperObjectName); $rawMethodArguments = $this->request->getExceedingArguments(); $mappedArguments = []; for ($i = 0; $i < count($rawMethodArguments); $i += 2) { $mappedArguments[] = $this->propertyMapper->convert($rawMethodArguments[$i + 1], $rawMethodArguments[$i]); } $result = null; try { if ($withoutSecurityChecks === true) { $this->securityContext->withoutAuthorizationChecks(function () use($testHelper, $methodName, $mappedArguments, &$result) { $result = call_user_func_array([$testHelper, $methodName], $mappedArguments); }); } else { $result = call_user_func_array([$testHelper, $methodName], $mappedArguments); } } catch (\Exception $exception) { $this->outputLine('EXCEPTION: %s %d %s in %s:%s %s', [get_class($exception), $exception->getCode(), $exception->getMessage(), $exception->getFile(), $exception->getLine(), $exception->getTraceAsString()]); return; } $this->output('SUCCESS: %s', [$result]); }
/** * @test */ public function convertFromUsesPropertyMapperToConvertNodePropertyOfArrayType() { $contextPath = '/foo/bar@user-demo'; $nodePath = '/foo/bar'; $nodeTypeProperties = array('assets' => array('type' => 'array<Neos\\Media\\Domain\\Model\\Asset>')); $decodedPropertyValue = array('8aaf4dd2-bd85-11e3-ae3d-14109fd7a2dd', '8febe94a-bd85-11e3-8401-14109fd7a2dd'); $source = array('__contextNodePath' => $contextPath, 'assets' => json_encode($decodedPropertyValue)); $convertedPropertyValue = array(new \stdClass(), new \stdClass()); $mockNode = $this->setUpNodeWithNodeType($nodePath, $nodeTypeProperties); $this->mockObjectManager->expects($this->any())->method('isRegistered')->with(Asset::class)->will($this->returnValue(true)); $this->mockPropertyMapper->expects($this->once())->method('convert')->with($decodedPropertyValue, $nodeTypeProperties['assets']['type'])->will($this->returnValue($convertedPropertyValue)); $mockNode->expects($this->once())->method('setProperty')->with('assets', $convertedPropertyValue); $this->nodeConverter->convertFrom($source, null, array(), $this->mockConverterConfiguration); }
/** * * @param string $workspaceName * @return NodeInterface */ protected function getLastVisitedNode($workspaceName) { if (!$this->session->isStarted() || !$this->session->hasKey('lastVisitedNode')) { return null; } try { $lastVisitedNode = $this->propertyMapper->convert($this->session->getData('lastVisitedNode'), NodeInterface::class); $q = new FlowQuery([$lastVisitedNode]); $lastVisitedNodeUserWorkspace = $q->context(['workspaceName' => $workspaceName])->get(0); return $lastVisitedNodeUserWorkspace; } catch (\Exception $exception) { return null; } }
/** * Checks if the optionally given node context path, affected node context path and typoscript path are set * and overrides the rendering to use those. Will also add a "X-Neos-AffectedNodePath" header in case the * actually affected node is different from the one routing resolved. * This is used in out of band rendering for the backend. * * @return void * @throws NodeNotFoundException */ protected function overrideViewVariablesFromInternalArguments() { if (($nodeContextPath = $this->request->getInternalArgument('__nodeContextPath')) !== null) { $node = $this->propertyMapper->convert($nodeContextPath, NodeInterface::class); if (!$node instanceof NodeInterface) { throw new NodeNotFoundException(sprintf('The node with context path "%s" could not be resolved', $nodeContextPath), 1437051934); } $this->view->assign('value', $node); } if (($affectedNodeContextPath = $this->request->getInternalArgument('__affectedNodeContextPath')) !== null) { $this->response->setHeader('X-Neos-AffectedNodePath', $affectedNodeContextPath); } if (($typoScriptPath = $this->request->getInternalArgument('__typoScriptPath')) !== null) { $this->view->setTypoScriptPath($typoScriptPath); } }
/** * Sets the value of this argument. * * @param mixed $rawValue The value of this argument * @return Argument $this */ public function setValue($rawValue) { if ($rawValue === null) { $this->value = null; return $this; } if (is_object($rawValue) && $rawValue instanceof $this->dataType) { $this->value = $rawValue; return $this; } $this->value = $this->propertyMapper->convert($rawValue, $this->dataType, $this->getPropertyMappingConfiguration()); $this->validationResults = $this->propertyMapper->getMessages(); if ($this->validator !== null) { $validationMessages = $this->validator->validate($this->value); $this->validationResults->merge($validationMessages); } return $this; }
/** * Returns a previously uploaded resource, or the resource specified via "value" argument if no resource has been uploaded before * If errors occurred during property mapping for this property, NULL is returned * * @return PersistentResource or NULL if no resource was uploaded and the "value" argument is not set */ protected function getUploadedResource() { $resource = null; if ($this->hasMappingErrorOccurred()) { $resource = $this->getLastSubmittedFormData(); } elseif ($this->hasArgument('value')) { $resource = $this->arguments['value']; } elseif ($this->isObjectAccessorMode()) { $resource = $this->getPropertyValue(); } if ($resource === null) { return null; } if ($resource instanceof PersistentResource) { return $resource; } return $this->propertyMapper->convert($resource, PersistentResource::class); }
/** * Returns the specified property. * * If the node has a content object attached, the property will be fetched * there if it is gettable. * * @param string $propertyName Name of the property * @param boolean $returnNodesAsIdentifiers If enabled, references to nodes are returned as node identifiers instead of NodeInterface instances * @return mixed value of the property * @api */ public function getProperty($propertyName, $returnNodesAsIdentifiers = false) { $value = $this->nodeData->getProperty($propertyName); if (empty($value)) { return null; } $nodeType = $this->getNodeType(); if (!$nodeType->hasConfiguration('properties.' . $propertyName)) { return $value; } $expectedPropertyType = $nodeType->getPropertyType($propertyName); if ($expectedPropertyType === 'references') { return $returnNodesAsIdentifiers ? $value : $this->resolvePropertyReferences($value); } if ($expectedPropertyType === 'reference') { return $returnNodesAsIdentifiers ? $value : $this->context->getNodeByIdentifier($value); } return $this->propertyMapper->convert($value, $expectedPropertyType); }
/** * @param mixed $propertyValue * @param string $dataType * @return mixed * @throws PropertyException */ protected function convertValue($propertyValue, $dataType) { $rawType = TypeHandling::truncateElementType($dataType); // This hardcoded handling is to circumvent rewriting PropertyMappers that convert objects. Usually they expect the source to be an object already and break if not. if (!TypeHandling::isSimpleType($rawType) && !is_object($propertyValue) && !is_array($propertyValue)) { return null; } if ($rawType === 'array') { $conversionTargetType = 'array<string>'; } elseif (TypeHandling::isSimpleType($rawType)) { $conversionTargetType = TypeHandling::normalizeType($rawType); } else { $conversionTargetType = 'array'; } $propertyMappingConfiguration = $this->createConfiguration($dataType); $convertedValue = $this->propertyMapper->convert($propertyValue, $conversionTargetType, $propertyMappingConfiguration); if ($convertedValue instanceof \Neos\Error\Messages\Error) { throw new PropertyException($convertedValue->getMessage(), $convertedValue->getCode()); } return $convertedValue; }
/** * @test */ public function hiddenFieldContainsDataOfAPreviouslyUploadedResource() { $mockResourceUuid = '79ecda60-1a27-69ca-17bf-a5d9e80e6c39'; $submittedData = array('foo' => array('bar' => array('name' => 'someFilename.jpg', 'type' => 'image/jpeg', 'tmp_name' => '/some/tmp/name', 'error' => 0, 'size' => 123))); /** @var Result|\PHPUnit_Framework_MockObject_MockObject $mockValidationResults */ $mockValidationResults = $this->getMockBuilder(Result::class)->disableOriginalConstructor()->getMock(); $mockValidationResults->expects($this->atLeastOnce())->method('hasErrors')->will($this->returnValue(true)); $this->request->expects($this->at(0))->method('getInternalArgument')->with('__submittedArgumentValidationResults')->will($this->returnValue($mockValidationResults)); $this->request->expects($this->at(1))->method('getInternalArgument')->with('__submittedArguments')->will($this->returnValue($submittedData)); /** @var PersistentResource|\PHPUnit_Framework_MockObject_MockObject $mockResource */ $mockResource = $this->getMockBuilder(PersistentResource::class)->disableOriginalConstructor()->getMock(); $mockPersistenceManager = $this->createMock(PersistenceManagerInterface::class); $mockPersistenceManager->expects($this->once())->method('getIdentifierByObject')->with($mockResource)->will($this->returnValue($mockResourceUuid)); $this->inject($this->viewHelper, 'persistenceManager', $mockPersistenceManager); $this->mockPropertyMapper->expects($this->atLeastOnce())->method('convert')->with($submittedData['foo']['bar'], PersistentResource::class)->will($this->returnValue($mockResource)); $mockValueResource = $this->getMockBuilder(PersistentResource::class)->disableOriginalConstructor()->getMock(); $this->viewHelper->setArguments(array('name' => 'foo[bar]', 'value' => $mockValueResource)); $expectedResult = '<input type="hidden" name="foo[bar][originallySubmittedResource][__identity]" value="' . $mockResourceUuid . '" />'; $this->viewHelper->initialize(); $actualResult = $this->viewHelper->render(); $this->assertSame($expectedResult, $actualResult); }
/** */ public function setUp() { $this->ajaxWidgetComponent = new AjaxWidgetComponent(); $this->mockObjectManager = $this->createMock(\Neos\Flow\ObjectManagement\ObjectManagerInterface::class); $this->inject($this->ajaxWidgetComponent, 'objectManager', $this->mockObjectManager); $this->mockComponentContext = $this->getMockBuilder(\Neos\Flow\Http\Component\ComponentContext::class)->disableOriginalConstructor()->getMock(); $this->mockHttpRequest = $this->getMockBuilder(\Neos\Flow\Http\Request::class)->disableOriginalConstructor()->getMock(); $this->mockHttpRequest->expects($this->any())->method('getArguments')->will($this->returnValue(array())); $this->mockComponentContext->expects($this->any())->method('getHttpRequest')->will($this->returnValue($this->mockHttpRequest)); $this->mockHttpResponse = $this->getMockBuilder(\Neos\Flow\Http\Response::class)->disableOriginalConstructor()->getMock(); $this->mockComponentContext->expects($this->any())->method('getHttpResponse')->will($this->returnValue($this->mockHttpResponse)); $this->mockAjaxWidgetContextHolder = $this->getMockBuilder(\Neos\FluidAdaptor\Core\Widget\AjaxWidgetContextHolder::class)->getMock(); $this->inject($this->ajaxWidgetComponent, 'ajaxWidgetContextHolder', $this->mockAjaxWidgetContextHolder); $this->mockHashService = $this->getMockBuilder(\Neos\Flow\Security\Cryptography\HashService::class)->getMock(); $this->inject($this->ajaxWidgetComponent, 'hashService', $this->mockHashService); $this->mockDispatcher = $this->getMockBuilder(\Neos\Flow\Mvc\Dispatcher::class)->getMock(); $this->inject($this->ajaxWidgetComponent, 'dispatcher', $this->mockDispatcher); $this->mockSecurityContext = $this->getMockBuilder(\Neos\Flow\Security\Context::class)->getMock(); $this->inject($this->ajaxWidgetComponent, 'securityContext', $this->mockSecurityContext); $this->mockPropertyMapper = $this->getMockBuilder(\Neos\Flow\Property\PropertyMapper::class)->disableOriginalConstructor()->getMock(); $this->mockPropertyMapper->expects($this->any())->method('convert')->with('', 'array', $this->mockPropertyMappingConfiguration)->will($this->returnValue(array())); $this->inject($this->ajaxWidgetComponent, 'propertyMapper', $this->mockPropertyMapper); }
/** * @test */ public function importWithLinebreakInDateTimeImportsCorrectly() { $xmlReader = new \XMLReader(); $result = $xmlReader->open(__DIR__ . '/Fixtures/SingleNodeWithLinebreaks.xml', null, LIBXML_PARSEHUGE); $this->assertTrue($result); /** @var \Neos\ContentRepository\Domain\Service\ImportExport\NodeImportService $nodeImportService */ $nodeImportService = $this->getMockBuilder(\Neos\ContentRepository\Domain\Service\ImportExport\NodeImportService::class)->setMethods(array('persistNodeData'))->getMock(); $this->inject($nodeImportService, 'propertyMapper', $this->mockPropertyMapper); $this->inject($nodeImportService, 'securityContext', $this->mockSecurityContext); $expectedNodeDatas = array(array('creationDateTime' => array('source' => '2015-12-21T21:56:53+00:00'))); $nodeImportService->expects($this->atLeastOnce())->method('persistNodeData')->will($this->returnCallback(function ($nodeData) use(&$actualNodeDatas) { unset($nodeData['Persistence_Object_Identifier']); $actualNodeDatas[] = $nodeData; return true; })); $this->mockPropertyMapper->expects($this->any())->method('convert')->will($this->returnCallback(function ($source, $targetType) { return array('targetType' => $targetType, 'source' => $source); })); $this->mockPropertyMapper->expects($this->any())->method('getMessages')->willReturn(new \Neos\Error\Messages\Result()); $nodeImportService->import($xmlReader, '/'); $this->assertCount(1, $actualNodeDatas); $this->assertArraySubset($expectedNodeDatas[0]['creationDateTime'], $actualNodeDatas[0]['creationDateTime'], true); }
/** * Publishes or discards the given nodes * * @param array $nodes <\Neos\ContentRepository\Domain\Model\NodeInterface> $nodes * @param string $action * @param Workspace $selectedWorkspace * @throws \Exception * @throws \Neos\Flow\Property\Exception * @throws \Neos\Flow\Security\Exception */ public function publishOrDiscardNodesAction(array $nodes, $action, Workspace $selectedWorkspace = null) { $propertyMappingConfiguration = $this->propertyMappingConfigurationBuilder->build(); $propertyMappingConfiguration->setTypeConverterOption(NodeConverter::class, NodeConverter::REMOVED_CONTENT_SHOWN, true); foreach ($nodes as $key => $node) { $nodes[$key] = $this->propertyMapper->convert($node, NodeInterface::class, $propertyMappingConfiguration); } switch ($action) { case 'publish': foreach ($nodes as $node) { $this->publishingService->publishNode($node); } $this->addFlashMessage($this->translator->translateById('workspaces.selectedChangesHaveBeenPublished', [], null, null, 'Modules', 'Neos.Neos')); break; case 'discard': $this->publishingService->discardNodes($nodes); $this->addFlashMessage($this->translator->translateById('workspaces.selectedChangesHaveBeenDiscarded', [], null, null, 'Modules', 'Neos.Neos')); break; default: throw new \RuntimeException('Invalid action "' . htmlspecialchars($action) . '" given.', 1346167441); } $this->redirect('show', null, null, ['workspace' => $selectedWorkspace]); }
/** * Convert an element to the value it represents. * * @param \XMLReader $reader * @param string $currentType current element (userland) type * @param string $currentEncoding date encoding of element * @param string $currentClassName class name of element * @param string $currentNodeIdentifier identifier of the node * @param string $currentProperty current property name * @return mixed * @throws ImportException */ protected function convertElementToValue(\XMLReader $reader, $currentType, $currentEncoding, $currentClassName, $currentNodeIdentifier, $currentProperty) { switch ($currentType) { case 'object': if ($currentClassName === 'DateTime') { $stringValue = trim($reader->value); $value = $this->propertyMapper->convert($stringValue, $currentClassName, $this->propertyMappingConfiguration); if ($this->propertyMapper->getMessages()->hasErrors()) { throw new ImportException(sprintf('Could not convert element <%s> to DateTime for node %s', $currentProperty, $currentNodeIdentifier), 1472992032); } } elseif ($currentEncoding === 'json') { $decodedJson = json_decode($reader->value, true); if (json_last_error() !== JSON_ERROR_NONE) { throw new ImportException(sprintf('Could not parse encoded JSON in element <%s> for node %s: %s', $currentProperty, $currentNodeIdentifier, json_last_error_msg()), 1472992033); } $value = $this->propertyMapper->convert($decodedJson, $currentClassName, $this->propertyMappingConfiguration); if ($this->propertyMapper->getMessages()->hasErrors()) { throw new ImportException(sprintf('Could not convert element <%s> to %s for node %s', $currentProperty, $currentClassName, $currentNodeIdentifier), 1472992034); } } else { throw new ImportException(sprintf('Unsupported encoding "%s"', $currentEncoding), 1404397061); } break; case 'string': $value = $reader->value; break; default: $value = $this->propertyMapper->convert($reader->value, $currentType, $this->propertyMappingConfiguration); if ($this->propertyMapper->getMessages()->hasErrors()) { throw new ImportException(sprintf('Could not convert element <%s> to %s for node %s', $currentProperty, $currentType, $currentNodeIdentifier), 1472992035); } return $value; } $this->persistEntities($value); return $value; }
/** * @test */ public function viewHelperRendersUriViaGivenNodeObject() { $targetNode = $this->propertyMapper->convert('/sites/example/home', Node::class); $this->assertSame('<a href="/en/home.html">' . $targetNode->getLabel() . '</a>', $this->viewHelper->render($targetNode)); }
/** * @test */ public function viewHelperRendersUriViaGivenNodeObject() { $targetNode = $this->propertyMapper->convert('/sites/example/home', Node::class); $this->assertOutputLinkValid('home.html', $this->viewHelper->render($targetNode)); }
/** * Remove broken entity references * * This removes references from nodes to entities which don't exist anymore. * * @param string $workspaceName * @param boolean $dryRun * @return void */ public function removeBrokenEntityReferences($workspaceName, $dryRun) { $this->output->outputLine('Checking for broken entity references ...'); /** @var \Neos\ContentRepository\Domain\Model\Workspace $workspace */ $workspace = $this->workspaceRepository->findByIdentifier($workspaceName); $nodeTypesWithEntityReferences = array(); foreach ($this->nodeTypeManager->getNodeTypes() as $nodeType) { /** @var NodeType $nodeType */ foreach (array_keys($nodeType->getProperties()) as $propertyName) { $propertyType = $nodeType->getPropertyType($propertyName); if (strpos($propertyType, '\\') !== false) { if (!isset($nodeTypesWithEntityReferences[$nodeType->getName()])) { $nodeTypesWithEntityReferences[$nodeType->getName()] = array(); } $nodeTypesWithEntityReferences[$nodeType->getName()][$propertyName] = $propertyType; } } } $nodesWithBrokenEntityReferences = array(); $brokenReferencesCount = 0; foreach ($nodeTypesWithEntityReferences as $nodeTypeName => $properties) { $nodeDatas = $this->nodeDataRepository->findByParentAndNodeTypeRecursively('/', $nodeTypeName, $workspace); foreach ($nodeDatas as $nodeData) { /** @var NodeData $nodeData */ foreach ($properties as $propertyName => $propertyType) { $propertyValue = $nodeData->getProperty($propertyName); $convertedProperty = null; if (is_object($propertyValue)) { $convertedProperty = $propertyValue; } if (is_string($propertyValue) && strlen($propertyValue) === 36) { $convertedProperty = $this->propertyMapper->convert($propertyValue, $propertyType); if ($convertedProperty === null) { $nodesWithBrokenEntityReferences[$nodeData->getIdentifier()][$propertyName] = $nodeData; $this->output->outputLine('Broken reference in "%s", property "%s" (%s) referring to %s.', array($nodeData->getPath(), $nodeData->getIdentifier(), $propertyName, $propertyType, $propertyValue)); $brokenReferencesCount++; } } if ($convertedProperty instanceof Proxy) { try { $convertedProperty->__load(); } catch (EntityNotFoundException $e) { $nodesWithBrokenEntityReferences[$nodeData->getIdentifier()][$propertyName] = $nodeData; $this->output->outputLine('Broken reference in "%s", property "%s" (%s) referring to %s.', array($nodeData->getPath(), $nodeData->getIdentifier(), $propertyName, $propertyType, $propertyValue)); $brokenReferencesCount++; } } } } } if ($brokenReferencesCount > 0) { $this->output->outputLine(); if (!$dryRun) { $self = $this; $this->askBeforeExecutingTask('Do you want to remove the broken entity references?', function () use($self, $nodesWithBrokenEntityReferences, $brokenReferencesCount, $workspaceName, $dryRun) { foreach ($nodesWithBrokenEntityReferences as $nodeIdentifier => $properties) { foreach ($properties as $propertyName => $nodeData) { /** @var NodeData $nodeData */ $nodeData->setProperty($propertyName, null); } } $self->output->outputLine('Removed %s broken entity reference%s.', array($brokenReferencesCount, $brokenReferencesCount > 1 ? 's' : '')); }); } else { $this->output->outputLine('Found %s broken entity reference%s to be removed.', array($brokenReferencesCount, $brokenReferencesCount > 1 ? 's' : '')); } $this->output->outputLine(); $this->persistenceManager->persistAll(); } }