Skip to content

Instantly share code, notes, and snippets.

@htuscher
Created June 14, 2016 12:00
Show Gist options
  • Save htuscher/f5ea17f7ef6465081a249a9ad864a85c to your computer and use it in GitHub Desktop.
Save htuscher/f5ea17f7ef6465081a249a9ad864a85c to your computer and use it in GitHub Desktop.
Neos Menu DFS
<?php
namespace Onedrop\Manuals\TypoScript\Helper;
use TYPO3\Flow\Annotations as Flow;
use TYPO3\Eel\ProtectedContextAwareInterface;
use TYPO3\TYPO3CR\Domain\Model\NodeInterface;
/***************************************************************
* Copyright notice
*
* (c) 2016 Hans Höchtl <[email protected]>
* All rights reserved
*
* This script is part of the TYPO3 project. The TYPO3 project is
* free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* The GNU General Public License can be found at
* http://www.gnu.org/copyleft/gpl.html.
* A copy is found in the textfile GPL.txt and important notices to the license
* from the author is found in LICENSE.txt distributed with these scripts.
*
*
* This script is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/
class MenuHelper implements ProtectedContextAwareInterface
{
const DOC_FILTER = 'TYPO3.Neos:Document';
/**
* @param NodeInterface $node
* @return NodeInterface
*/
public function dfsPrevNode(NodeInterface $node) {
$previousNode = $this->getPrevForNode($node);
if ($previousNode instanceof NodeInterface) {
// We return the last deepest child
if ($previousNode->hasChildNodes(self::DOC_FILTER)) {
return $this->getLastDeepestNode($previousNode);
}
// If the prev sibling doesn't have children, return itself
return $previousNode;
}
// If no sibling was present, we return the parent
return $node->getParent();
}
/**
* @param NodeInterface $node
* @return NodeInterface
*/
public function dfsNextNode(NodeInterface $node) {
if ($node->hasChildNodes(self::DOC_FILTER)) {
$childDocuments = $node->getChildNodes(self::DOC_FILTER);
return $childDocuments[0];
}
$nextNode = $this->getNextForNode($node);
if ($nextNode instanceof NodeInterface) {
return $nextNode;
}
return $this->getFirstHighestNode($node);
}
/**
* @param string $methodName
* @return boolean
*/
public function allowsCallOfMethod($methodName)
{
return true;
}
/**
* @param NodeInterface $contextNode The node for which the preceding node should be found
* @return NodeInterface The preceding node of $contextNode or NULL
*/
protected function getPrevForNode(NodeInterface $contextNode)
{
$nodesInContext = $contextNode->getParent()->getChildNodes();
for ($i = 0; $i < count($nodesInContext) - 1; $i++) {
if ($nodesInContext[$i + 1] === $contextNode) {
return $nodesInContext[$i];
}
}
return null;
}
/**
* @param NodeInterface $contextNode The node for which the preceding node should be found
* @return NodeInterface The following node of $contextNode or NULL
*/
protected function getNextForNode($contextNode)
{
$nodesInContext = $contextNode->getParent()->getChildNodes();
for ($i = 1; $i < count($nodesInContext); $i++) {
if ($nodesInContext[$i - 1] === $contextNode) {
return $nodesInContext[$i];
}
}
return null;
}
/**
* @param NodeInterface $contextNode
* @return NodeInterface
*/
protected function getLastDeepestNode(NodeInterface $contextNode)
{
if (!$contextNode->hasChildNodes(self::DOC_FILTER)) {
return $contextNode;
}
$children = $contextNode->getChildNodes(self::DOC_FILTER);
return $this->getLastDeepestNode($children[count($children)-1]);
}
/**
* @param NodeInterface $contextNode
* @return NodeInterface
*/
protected function getFirstHighestNode(NodeInterface $contextNode)
{
$parentSibling = $this->getNextForNode($contextNode->getParent());
if ($parentSibling instanceof NodeInterface) {
return $parentSibling;
}
return $this->getFirstHighestNode($contextNode->getParent());
}
}
prevPage = ${q(DfsMenu.dfsPrevNode(documentNode)).closest('[instanceof TYPO3.Neos:Document]').get(0)}
nextPage = ${DfsMenu.dfsNextNode(documentNode)}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment