public function testNodeConfigurator_LinkingWithButton() { $newNode = $this->rootCC->createNode(uniqid('node-'), $this->nodeTypeManager->getNodeType('M12.Foundation:RevealModal')); $this->assertEquals(2, $newNode->getNumberOfChildNodes()); $buttonNodes = $this->rootCC->getChildNodes('M12.Foundation:Button'); /** @var NodeInterface $lastButton */ $lastButton = array_pop($buttonNodes); $this->assertNotEmpty($lastButton); $this->assertNotEmpty($lastButton->getProperty('htmlDataRevealId')); $this->assertContains('link-node', $lastButton->getProperty('htmlDataRevealId')); }
/** * Publishes the given node to the specified target workspace. If no workspace is specified, the base workspace * is assumed. * * If the given node is a Document or has ContentCollection child nodes, these nodes are published as well. * * @param NodeInterface $node * @param Workspace $targetWorkspace If not set the base workspace is assumed to be the publishing target * @return void * @api */ public function publishNode(NodeInterface $node, Workspace $targetWorkspace = null) { if ($targetWorkspace === null) { $targetWorkspace = $node->getWorkspace()->getBaseWorkspace(); } if (!$targetWorkspace instanceof Workspace) { return; } $nodes = array($node); $nodeType = $node->getNodeType(); if ($nodeType->isOfType('TYPO3.Neos:Document') || $nodeType->hasConfiguration('childNodes')) { foreach ($node->getChildNodes('TYPO3.Neos:ContentCollection') as $contentCollectionNode) { array_push($nodes, $contentCollectionNode); } } $sourceWorkspace = $node->getWorkspace(); $sourceWorkspace->publishNodes($nodes, $targetWorkspace); $this->emitNodePublished($node, $targetWorkspace); }
/** * @param integer $currentPage * @return void * @throws \TYPO3\TYPO3CR\Exception\PageNotFoundException */ public function indexAction($currentPage = 1) { $this->currentPage = (int) $currentPage; if ($this->currentPage < 1) { $this->currentPage = 1; } elseif ($this->currentPage > $this->numberOfPages) { throw new PageNotFoundException(); } $itemsPerPage = (int) $this->configuration['itemsPerPage']; if ($this->maximumNumberOfNodes > 0 && $this->maximumNumberOfNodes < $itemsPerPage) { $itemsPerPage = $this->maximumNumberOfNodes; } $offset = $this->currentPage > 1 ? (int) ($itemsPerPage * ($this->currentPage - 1)) : null; if ($this->parentNode === null) { $nodes = array_slice($this->nodes, $offset, $itemsPerPage); } else { $nodes = $this->parentNode->getChildNodes($this->nodeTypeFilter, $itemsPerPage, $offset); } $this->view->assign('contentArguments', array($this->widgetConfiguration['as'] => $nodes)); $this->view->assign('configuration', $this->configuration); $this->view->assign('pagination', $this->buildPagination()); }
/** * @param NodeInterface $article * @return array */ protected function buildSingleItemJson(NodeInterface $article) { $contentCollection = $article->getChildNodes('TYPO3.Neos:ContentCollection')[0]; $articleBody = ''; if ($contentCollection instanceof NodeInterface) { $content = $contentCollection->getChildNodes(); if (is_array($content) && array_key_exists(0, $content)) { foreach ($content as $node) { /** @var NodeInterface $node */ if ($node->getNodeType()->getName() === 'TYPO3.Neos.NodeTypes:Text' || $node->getNodeType()->getName() === 'TYPO3.Neos.NodeTypes:TextWithImage') { $articleBody .= $node->getProperty('text'); } } } } $thumbnailConfiguration = new ThumbnailConfiguration(125, 125, 125, 125, true, true, false); $detailConfiguration = new ThumbnailConfiguration(300, 300, 200, 200, true, true, false); /** @var Image $image */ $image = $article->getProperty('headerImage'); $properties = ['@context' => 'http://schema.org', '@type' => 'Article', '@id' => $article->getIdentifier(), 'id' => $article->getIdentifier(), 'shortIdentifier' => explode('-', $article->getIdentifier())[0], 'title' => $article->getProperty('title'), 'articleBody' => $articleBody, 'publicationDate' => $article->getProperty('publicationDate')->format('D M d Y H:i:s O'), 'teaser' => $article->getProperty('article'), 'listImage' => $this->assetService->getThumbnailUriAndSizeForAsset($image, $thumbnailConfiguration)['src'], 'image' => $this->assetService->getThumbnailUriAndSizeForAsset($image, $detailConfiguration)['src']]; $this->processProperties($properties); return $properties; }
/** * @param array $nodes * @param NodeInterface $node * @param array $roles * @param int $depth * @param int $recursionPointer * @param string $nodeTypeFilter */ protected function getChildNodeData(array &$nodes, $node, $roles, $depth = 0, $recursionPointer = 1, $nodeTypeFilter = 'TYPO3.Neos:Document') { foreach ($node->getChildNodes($nodeTypeFilter) as $childNode) { /** @var NodeInterface $childNode */ $expand = $depth === 0 || $recursionPointer < $depth; $properties = $this->getACLPropertiesForNode($childNode); $properties['acl'] = $this->checkNodeForRoles($node, $roles); if ($expand && $childNode->hasChildNodes($nodeTypeFilter)) { $properties['childNodes'] = []; $this->getChildNodeData($properties['childNodes'], $childNode, $roles, $depth, $recursionPointer + 1, $nodeTypeFilter); } array_push($nodes, $properties); } }
/** * Traverses through the tree starting at the given root node and sets the uriPathSegment property derived from * the node label. * * @param NodeInterface $node The node where the traversal starts * @param boolean $dryRun * @return void */ protected function generateUriPathSegmentsForNode(NodeInterface $node, $dryRun) { if ((string) $node->getProperty('uriPathSegment') === '') { $name = $node->getLabel() ?: $node->getName(); $uriPathSegment = Utility::renderValidNodeName($name); if ($dryRun === FALSE) { $node->setProperty('uriPathSegment', $uriPathSegment); $this->output->outputLine('Added missing URI path segment for "%s" (%s) => %s', array($node->getPath(), $name, $uriPathSegment)); } else { $this->output->outputLine('Found missing URI path segment for "%s" (%s) => %s', array($node->getPath(), $name, $uriPathSegment)); } } foreach ($node->getChildNodes('TYPO3.Neos:Document') as $childNode) { $this->generateUriPathSegmentsForNode($childNode, $dryRun); } }
/** * Removes all auto created child nodes that existed in the previous nodeType. * * @param NodeInterface $node * @param NodeType $oldNodeType * @return void */ public function cleanUpAutoCreatedChildNodes(NodeInterface $node, NodeType $oldNodeType) { $newNodeType = $node->getNodeType(); $autoCreatedChildNodesForNewNodeType = $newNodeType->getAutoCreatedChildNodes(); $autoCreatedChildNodesForOldNodeType = $oldNodeType->getAutoCreatedChildNodes(); $removedChildNodesFromOldNodeType = array_diff(array_keys($autoCreatedChildNodesForOldNodeType), array_keys($autoCreatedChildNodesForNewNodeType)); /** @var NodeInterface $childNode */ foreach ($node->getChildNodes() as $childNode) { if (in_array($childNode->getName(), $removedChildNodesFromOldNodeType)) { $childNode->remove(); } } }
/** * @param \TYPO3\TYPO3CR\Domain\Model\NodeInterface $node * @param $targetWorkspaceName * @return void */ public function publishNode(\TYPO3\TYPO3CR\Domain\Model\NodeInterface $node, $targetWorkspaceName = 'live') { $nodes = array($node); $contentType = $node->getContentType(); if ($contentType->isOfType('TYPO3.Phoenix.ContentTypes:Page') || $contentType->hasStructure()) { foreach ($node->getChildNodes('TYPO3.Phoenix.ContentTypes:Section') as $sectionNode) { array_push($nodes, $sectionNode); } } $sourceWorkspace = $node->getWorkspace(); $sourceWorkspace->publishNodes($nodes, $targetWorkspaceName); }
/** * Recursively called method which builds the actual items array. * * @param \TYPO3\TYPO3CR\Domain\Model\NodeInterface $entryParentNode The parent node whose children should be listed as items * @param \TYPO3\TYPO3CR\Domain\Model\NodeInterface $lastParentNode The last parent node whose children should be listed. NULL = no limit defined through lastLevel * @param \TYPO3\TYPO3\Domain\Service\ContentContext $contentContext $contentContext The current content context * @param integer $currentLevel Level count for the recursion – don't use. * @return array A nested array of menu item information * @see buildItems() */ private function buildRecursiveItemsArray(\TYPO3\TYPO3CR\Domain\Model\NodeInterface $entryParentNode, $lastParentNode, \TYPO3\TYPO3\Domain\Service\ContentContext $contentContext, $currentLevel = 1) { $items = array(); foreach ($entryParentNode->getChildNodes('TYPO3.Phoenix.ContentTypes:Page,TYPO3.Phoenix.ContentTypes:Shortcut') as $currentNode) { if ($currentNode->isVisible() === FALSE || $currentNode->isHiddenInIndex() === TRUE || $currentNode->isAccessible() === FALSE) { continue; } $item = array('label' => $currentNode->getProperty('title'), 'node' => $currentNode, 'state' => self::STATE_NORMAL); if ($currentNode === $contentContext->getCurrentNode()) { $item['state'] = self::STATE_CURRENT; } if ($currentLevel < $this->getMaximumLevels() && $entryParentNode !== $lastParentNode) { $subItems = $this->buildRecursiveItemsArray($currentNode, $lastParentNode, $contentContext, $currentLevel + 1); if ($subItems !== array()) { $item['subItems'] = $subItems; if ($item['state'] !== self::STATE_CURRENT) { foreach ($subItems as $subItem) { if ($subItem['state'] === self::STATE_CURRENT || $subItem['state'] === self::STATE_ACTIVE) { $item['state'] = self::STATE_ACTIVE; break; } } } } } $items[] = $item; } return $items; }
/** * Collect node data and traverse child nodes * * @param array &$nodes * @param NodeInterface $node * @param string $nodeTypeFilter * @param integer $depth levels of child nodes to fetch. 0 = unlimited * @param \TYPO3\TYPO3CR\Domain\Model\NodeInterface $untilNode if given, expand all nodes on the rootline towards $untilNode, no matter what is defined with $depth. * @param integer $recursionPointer current recursion level * @return void */ protected function collectChildNodeData(array &$nodes, NodeInterface $node, $nodeTypeFilter, $depth = 0, NodeInterface $untilNode = NULL, $recursionPointer = 1) { foreach ($node->getChildNodes($nodeTypeFilter) as $childNode) { if (!$this->privilegeManager->isGranted(NodeTreePrivilege::class, new NodePrivilegeSubject($childNode))) { continue; } /** @var NodeInterface $childNode */ $expand = $depth === 0 || $recursionPointer < $depth; if ($expand === FALSE && $untilNode !== NULL && strpos($untilNode->getPath(), $childNode->getPath()) === 0 && $childNode !== $untilNode) { // in case $untilNode is set, and the current childNode is on the rootline of $untilNode (and not the node itself), expand the node. $expand = TRUE; } switch ($this->outputStyle) { case self::STYLE_LIST: $nodeType = $childNode->getNodeType()->getName(); $properties = $childNode->getProperties(); $properties['__contextNodePath'] = $childNode->getContextPath(); $properties['__workspaceName'] = $childNode->getWorkspace()->getName(); $properties['__nodeName'] = $childNode->getName(); $properties['__nodeType'] = $nodeType; $properties['__title'] = $nodeType === 'TYPO3.Neos:Document' ? $childNode->getProperty('title') : $childNode->getLabel(); array_push($nodes, $properties); if ($expand) { $this->collectChildNodeData($nodes, $childNode, $nodeTypeFilter, $depth, $untilNode, $recursionPointer + 1); } break; case self::STYLE_TREE: $children = array(); $hasChildNodes = $childNode->hasChildNodes($nodeTypeFilter) === TRUE; if ($expand && $hasChildNodes) { $this->collectChildNodeData($children, $childNode, $nodeTypeFilter, $depth, $untilNode, $recursionPointer + 1); } array_push($nodes, $this->collectTreeNodeData($childNode, $expand, $children, $hasChildNodes)); } } }
/** * Collect node data and recurse into child nodes * * @param array &$nodes * @param \TYPO3\TYPO3CR\Domain\Model\NodeInterface $node * @param string $contentTypeFilter * @param integer $depth levels of child nodes to fetch. 0 = unlimited * @param integer $recursionPointer current recursion level * @return void */ protected function collectChildNodeData(array &$nodes, \TYPO3\TYPO3CR\Domain\Model\NodeInterface $node, $contentTypeFilter, $depth = 0, $recursionPointer = 1) { foreach ($node->getChildNodes($contentTypeFilter) as $childNode) { $contextNodePath = $childNode->getContextPath(); $workspaceName = $childNode->getWorkspace()->getName(); $nodeName = $childNode->getName(); $contentType = $childNode->getContentType()->getName(); $title = $childNode->getContentType() === 'TYPO3.Phoenix.ContentTypes:Page' ? $childNode->getProperty('title') : $childNode->getLabel(); $abstract = $childNode->getAbstract(); $expand = $depth === 0 || $recursionPointer < $depth; switch ($this->outputStyle) { case self::STYLE_LIST: $properties = $childNode->getProperties(); $properties['__contextNodePath'] = $contextNodePath; $properties['__workspaceName'] = $workspaceName; $properties['__nodeName'] = $nodeName; $properties['__contentType'] = $contentType; $properties['__title'] = $title; $properties['__abstract'] = $abstract; array_push($nodes, $properties); if ($expand) { $this->collectChildNodeData($nodes, $childNode, $contentTypeFilter, $depth, $recursionPointer + 1); } break; case self::STYLE_TREE: $children = array(); if ($expand && $childNode->hasChildNodes($contentTypeFilter) === TRUE) { $this->collectChildNodeData($children, $childNode, $contentTypeFilter, $depth, $recursionPointer + 1); } array_push($nodes, $this->collectTreeNodeData($childNode, $expand, $children, $contentTypeFilter)); } } }