/** * Execute a task * * @param string $task * @param \TYPO3\Deploy\Domain\Model\Node $node * @param \TYPO3\Deploy\Domain\Model\Application $application * @param \TYPO3\Deploy\Domain\Model\Deployment $deployment * @param array $options * @return void */ public function execute($task, \TYPO3\Deploy\Domain\Model\Node $node, \TYPO3\Deploy\Domain\Model\Application $application, \TYPO3\Deploy\Domain\Model\Deployment $deployment, array $options = array()) { list($packageKey, $taskName) = explode(':', $task, 2); $taskClassName = strtr($packageKey, '.', '\\') . '\\Task\\' . strtr($taskName, ':', '\\') . 'Task'; $taskObjectName = $this->objectManager->getCaseSensitiveObjectName($taskClassName); if (!$this->objectManager->isRegistered($taskObjectName)) { throw new \Exception('Task "' . $task . '" not registered ' . $taskClassName); } $task = $this->objectManager->create($taskObjectName); if (!$deployment->isDryRun()) { $task->execute($node, $application, $deployment, $options); } else { $task->simulate($node, $application, $deployment, $options); } $this->taskHistory[] = array('task' => $task, 'node' => $node, 'application' => $application, 'deployment' => $deployment, 'options' => $options); }
/** * Deserializes a given object tree and reinjects all dependencies. * * @param array $dataArray The serialized objects array * @return array The deserialized objects in an array */ public function deserializeObjectsArray(array $dataArray) { $this->objectsAsArray = $dataArray; $objects = array(); foreach ($this->objectsAsArray as $objectHash => $objectData) { if (!isset($objectData[self::CLASSNAME]) || !$this->objectManager->isRegistered($objectData[self::CLASSNAME])) { continue; } $objects[$objectHash] = $this->reconstituteObject($objectHash, $objectData); } return $objects; }
/** * Creates and sets the configured access decision voters * * @param array $voterClassNames Array of access decision voter class names * @return void * @throws \TYPO3\FLOW3\Security\Exception\VoterNotFoundException */ protected function createAccessDecisionVoters(array $voterClassNames) { foreach ($voterClassNames as $voterClassName) { if (!$this->objectManager->isRegistered($voterClassName)) { throw new \TYPO3\FLOW3\Security\Exception\VoterNotFoundException('No voter of type ' . $voterClassName . ' found!', 1222267934); } $voter = $this->objectManager->get($voterClassName); if (!$voter instanceof \TYPO3\FLOW3\Security\Authorization\AccessDecisionVoterInterface) { throw new \TYPO3\FLOW3\Security\Exception\VoterNotFoundException('The found voter class did not implement \\TYPO3\\FLOW3\\Security\\Authorization\\AccessDecisionVoterInterface', 1222268008); } $this->accessDecisionVoters[] = $voter; } }
/** * Returns the class name of an appropriate validator for the given type. If no * validator is available FALSE is returned * * @param string $validatorType Either the fully qualified class name of the validator or the short name of a built-in validator * @return string|boolean Class name of the validator or FALSE if not available */ protected function resolveValidatorObjectName($validatorType) { $validatorType = ltrim($validatorType, '\\'); if ($this->objectManager->isRegistered($validatorType)) { $possibleClassName = $validatorType; } else { if (strpos($validatorType, ':') !== FALSE) { list($packageName, $packageValidatorType) = explode(':', $validatorType); $possibleClassName = sprintf('%s\\Validation\\Validator\\%sValidator', str_replace('.', '\\', $packageName), $this->getValidatorType($packageValidatorType)); } else { $possibleClassName = sprintf('TYPO3\\FLOW3\\Validation\\Validator\\%sValidator', $this->getValidatorType($validatorType)); } if (!$this->objectManager->isRegistered($possibleClassName)) { return FALSE; } } if ($this->reflectionService->isClassImplementationOf($possibleClassName, 'TYPO3\\FLOW3\\Validation\\Validator\\ValidatorInterface')) { return $possibleClassName; } return FALSE; }
/** * Dispatches a signal by calling the registered Slot methods * * @param string $signalClassName Name of the class containing the signal * @param string $signalName Name of the signal * @param array $signalArguments arguments passed to the signal method * @return void * @throws \TYPO3\FLOW3\SignalSlot\Exception\InvalidSlotException if the slot is not valid * @api */ public function dispatch($signalClassName, $signalName, array $signalArguments = array()) { if (!isset($this->slots[$signalClassName][$signalName])) { return; } foreach ($this->slots[$signalClassName][$signalName] as $slotInformation) { if (isset($slotInformation['object'])) { $object = $slotInformation['object']; } elseif (substr($slotInformation['method'], 0, 2) === '::') { if (!isset($this->objectManager)) { if (is_callable($slotInformation['class'] . $slotInformation['method'])) { $object = $slotInformation['class']; } else { throw new \TYPO3\FLOW3\SignalSlot\Exception\InvalidSlotException(sprintf('Cannot dispatch %s::%s to class %s. The object manager is not yet available in the Signal Slot Dispatcher and therefore it cannot dispatch classes.', $signalClassName, $signalName, $slotInformation['class']), 1298113624); } } else { $object = $this->objectManager->getClassNameByObjectName($slotInformation['class']); } $slotInformation['method'] = substr($slotInformation['method'], 2); } else { if (!isset($this->objectManager)) { throw new \TYPO3\FLOW3\SignalSlot\Exception\InvalidSlotException(sprintf('Cannot dispatch %s::%s to class %s. The object manager is not yet available in the Signal Slot Dispatcher and therefore it cannot dispatch classes.', $signalClassName, $signalName, $slotInformation['class']), 1298113624); } if (!$this->objectManager->isRegistered($slotInformation['class'])) { throw new \TYPO3\FLOW3\SignalSlot\Exception\InvalidSlotException('The given class "' . $slotInformation['class'] . '" is not a registered object.', 1245673367); } $object = $this->objectManager->get($slotInformation['class']); } if ($slotInformation['passSignalInformation'] === TRUE) { $signalArguments[] = $signalClassName . '::' . $signalName; } if (!method_exists($object, $slotInformation['method'])) { throw new \TYPO3\FLOW3\SignalSlot\Exception\InvalidSlotException('The slot method ' . get_class($object) . '->' . $slotInformation['method'] . '() does not exist.', 1245673368); } call_user_func_array(array($object, $slotInformation['method']), $signalArguments); } }
/** * Converts the specified node path into a Node. * * The node path must be an absolute context node path and can be specified as a string or as an array item with the * key "__contextNodePath". The latter case is for updating existing nodes. * * This conversion method does not support / allow creation of new nodes because new nodes should be created through * the createNode() method of an existing reference node. * * Also note that the context's "current node" is not affected by this object converter, you will need to set it to * whatever node your "current" node is, if any. * * All elements in the source array which start with two underscores (like __contextNodePath) are specially treated * by this converter. * * All elements in the source array which start with a *single underscore (like _hidden) are *directly* set on the Node * object. * * All other elements, not being prefixed with underscore, are properties of the node. * * @param string|array $source Either a string or array containing the absolute context node path which identifies the node. For example "/sites/mysitecom/homepage/about@user-admin" * @param string $targetType not used * @param array $subProperties not used * @param \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration not used * @return mixed An object or \TYPO3\FLOW3\Error\Error if the input format is not supported or could not be converted for other reasons * @throws \Exception */ public function convertFrom($source, $targetType, array $subProperties = array(), \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration = NULL) { if (is_string($source)) { $source = array('__contextNodePath' => $source); } if (!is_array($source) || !isset($source['__contextNodePath'])) { return new Error('Could not convert ' . gettype($source) . ' to Node object, a valid absolute context node path as a string or array is expected.', 1302879936); } preg_match(NodeInterface::MATCH_PATTERN_CONTEXTPATH, $source['__contextNodePath'], $matches); if (!isset($matches['NodePath'])) { return new Error('Could not convert array to Node object because the node path was invalid.', 1285162903); } $nodePath = $matches['NodePath']; if ($this->nodeRepository->getContext() === NULL) { $workspaceName = isset($matches['WorkspaceName']) ? $matches['WorkspaceName'] : 'live'; $contentContext = new ContentContext($workspaceName); $this->nodeRepository->setContext($contentContext); } else { $contentContext = $this->nodeRepository->getContext(); $workspaceName = $contentContext->getWorkspace()->getName(); } if ($workspaceName !== 'live') { $contentContext->setInvisibleContentShown(TRUE); if ($configuration->getConfigurationValue('TYPO3\\TYPO3\\Routing\\NodeObjectConverter', self::REMOVED_CONTENT_SHOWN) === TRUE) { $contentContext->setRemovedContentShown(TRUE); } } $workspace = $contentContext->getWorkspace(FALSE); if (!$workspace) { return new Error(sprintf('Could not convert %s to Node object because the workspace "%s" as specified in the context node path does not exist.', $source['__contextNodePath'], $workspaceName), 1285162905); } $currentAccessModeFromContext = $contentContext->isInaccessibleContentShown(); $contentContext->setInaccessibleContentShown(TRUE); $node = $contentContext->getNode($nodePath); $contentContext->setInaccessibleContentShown($currentAccessModeFromContext); if (!$node) { return new Error(sprintf('Could not convert array to Node object because the node "%s" does not exist.', $nodePath), 1285162908); } $contentTypeProperties = $node->getContentType()->getProperties(); foreach ($source as $nodePropertyKey => $nodePropertyValue) { if (substr($nodePropertyKey, 0, 2) === '__') { continue; } if ($nodePropertyKey[0] === '_') { $propertyName = substr($nodePropertyKey, 1); // TODO: Hack: we need to create DateTime objects for some properties of Node if (($propertyName === 'hiddenBeforeDateTime' || $propertyName === 'hiddenAfterDateTime') && is_string($nodePropertyValue)) { if ($nodePropertyValue !== '') { $nodePropertyValue = \DateTime::createFromFormat('!Y-m-d', $nodePropertyValue); } else { $nodePropertyValue = NULL; } } \TYPO3\FLOW3\Reflection\ObjectAccess::setProperty($node, $propertyName, $nodePropertyValue); } else { if (!isset($contentTypeProperties[$nodePropertyKey])) { throw new \Exception('TODO: content type XY does not have a property YY according to the schema'); } if (isset($contentTypeProperties[$nodePropertyKey]['type'])) { $targetType = $contentTypeProperties[$nodePropertyKey]['type']; if ($this->objectManager->isRegistered($targetType)) { $nodePropertyValue = $this->propertyMapper->convert(json_decode($nodePropertyValue, TRUE), $targetType); } } $node->setProperty($nodePropertyKey, $nodePropertyValue); } } return $node; }
/** * Wrap the $content identified by $node with the needed markup for * the backend. * $parameters can be used to further pass parameters to the content element. * * @param \TYPO3\TYPO3CR\Domain\Model\NodeInterface $node * @param string $typoscriptPath * @param string $content * @param boolean $isPage * @return string */ public function wrapContentObject(\TYPO3\TYPO3CR\Domain\Model\NodeInterface $node, $typoscriptPath, $content, $isPage = FALSE) { $contentType = $node->getContentType(); $tagBuilder = new \TYPO3\Fluid\Core\ViewHelper\TagBuilder('div'); $tagBuilder->forceClosingTag(TRUE); if (!$node->isRemoved()) { $tagBuilder->setContent($content); } if (!$isPage) { $cssClasses = array('t3-contentelement'); $cssClasses[] = str_replace(array(':', '.'), '-', strtolower($contentType->getName())); if ($node->isHidden()) { $cssClasses[] = 't3-contentelement-hidden'; } if ($node->isRemoved()) { $cssClasses[] = 't3-contentelement-removed'; } $tagBuilder->addAttribute('class', implode(' ', $cssClasses)); $tagBuilder->addAttribute('id', 'c' . $node->getIdentifier()); } try { $this->accessDecisionManager->decideOnResource('TYPO3_TYPO3_Backend_BackendController'); } catch (\TYPO3\FLOW3\Security\Exception\AccessDeniedException $e) { return $tagBuilder->render(); } $tagBuilder->addAttribute('typeof', 'typo3:' . $contentType->getName()); $tagBuilder->addAttribute('about', $node->getContextPath()); $this->addScriptTag($tagBuilder, '__workspacename', $node->getWorkspace()->getName()); $this->addScriptTag($tagBuilder, '_removed', $node->isRemoved() ? 'true' : 'false', 'boolean'); $this->addScriptTag($tagBuilder, '_typoscriptPath', $typoscriptPath); foreach ($contentType->getProperties() as $propertyName => $propertyConfiguration) { $dataType = isset($propertyConfiguration['type']) ? $propertyConfiguration['type'] : 'string'; if ($propertyName[0] === '_') { $propertyValue = \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($node, substr($propertyName, 1)); } else { $propertyValue = $node->getProperty($propertyName); } // Serialize boolean values to String if (isset($propertyConfiguration['type']) && $propertyConfiguration['type'] === 'boolean') { $propertyValue = $propertyValue ? 'true' : 'false'; } // Serialize date values to String if ($propertyValue !== NULL && isset($propertyConfiguration['type']) && $propertyConfiguration['type'] === 'date') { $propertyValue = $propertyValue->format('Y-m-d'); } // Serialize objects to JSON strings if (is_object($propertyValue) && $propertyValue !== NULL && isset($propertyConfiguration['type']) && $this->objectManager->isRegistered($propertyConfiguration['type'])) { $gettableProperties = \TYPO3\FLOW3\Reflection\ObjectAccess::getGettableProperties($propertyValue); $convertedProperties = array(); foreach ($gettableProperties as $key => $value) { if (is_object($value)) { $entityIdentifier = $this->persistenceManager->getIdentifierByObject($value); if ($entityIdentifier !== NULL) { $value = $entityIdentifier; } } $convertedProperties[$key] = $value; } $propertyValue = json_encode($convertedProperties); $dataType = 'jsonEncoded'; } $this->addScriptTag($tagBuilder, $propertyName, $propertyValue, $dataType); } if (!$isPage) { // add CSS classes $this->addScriptTag($tagBuilder, '__contenttype', $contentType->getName()); } else { $tagBuilder->addAttribute('id', 't3-page-metainformation'); $tagBuilder->addAttribute('data-__sitename', $this->nodeRepository->getContext()->getCurrentSite()->getName()); $tagBuilder->addAttribute('data-__siteroot', sprintf('/sites/%s@%s', $this->nodeRepository->getContext()->getCurrentSite()->getNodeName(), $this->nodeRepository->getContext()->getWorkspace()->getName())); } return $tagBuilder->render(); }