/** * The slot for the signal in DatabaseTreeDataProvider. * * @param DatabaseTreeDataProvider $dataProvider * @param TreeNode $treeData * @return void */ public function addUserPermissionsToCategoryTreeData(DatabaseTreeDataProvider $dataProvider, $treeData) { if (!$this->backendUserAuthentication->isAdmin() && $dataProvider->getTableName() === $this->categoryTableName) { // Get User permissions related to category $categoryMountPoints = $this->backendUserAuthentication->getCategoryMountPoints(); // Backup child nodes to be processed. $treeNodeCollection = $treeData->getChildNodes(); if (!empty($categoryMountPoints) && !empty($treeNodeCollection)) { // First, remove all child nodes which must be analysed to be considered as "secure". // The nodes were backed up in variable $treeNodeCollection beforehand. $treeData->removeChildNodes(); // Create an empty tree node collection to receive the secured nodes. /** @var TreeNodeCollection $securedTreeNodeCollection */ $securedTreeNodeCollection = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Tree\\TreeNodeCollection'); foreach ($categoryMountPoints as $categoryMountPoint) { $treeNode = $this->lookUpCategoryMountPointInTreeNodes((int) $categoryMountPoint, $treeNodeCollection); if (!is_null($treeNode)) { $securedTreeNodeCollection->append($treeNode); } } // Reset child nodes. $treeData->setChildNodes($securedTreeNodeCollection); } } }
/** * Returns the node in an array representation that can be used for serialization * * @param bool $addChildNodes * @return array */ public function toArray($addChildNodes = true) { $arrayRepresentation = array('serializeClassName' => get_class($this), 'id' => $this->id); if ($this->parentNode !== null) { $arrayRepresentation['parentNode'] = $this->parentNode->toArray(false); } else { $arrayRepresentation['parentNode'] = ''; } if ($this->hasChildNodes() && $addChildNodes) { $arrayRepresentation['childNodes'] = $this->childNodes->toArray(); } else { $arrayRepresentation['childNodes'] = ''; } return $arrayRepresentation; }
/** * Sets data of the node by a given data array * * @param array $data * @return void */ public function dataFromArray($data) { parent::dataFromArray($data); $this->setType($data['type']); $this->setText($data['label'], $data['t3TextSourceField'], $data['prefix'], $data['suffix']); $this->setEditableText($data['editableText']); $this->setCls($data['cls']); $this->setQTip($data['qtip']); $this->setExpanded($data['expanded']); $this->setExpandable($data['expandable']); $this->setDraggable($data['draggable']); $this->setIsDropTarget($data['isTarget']); $this->setSpriteIconCode($data['spriteIconCode']); $this->setInCopyMode($data['t3InCopyMode']); $this->setInCutMode($data['t3InCutMode']); $this->setContextInfo($data['t3ContextInfo']); $this->setLabelIsEditable($data['editable']); $this->setAllowChildren($data['allowChildren']); // only set the leaf attribute if it's applied // otherwise you cannot insert nodes into this one if (isset($data['leaf'])) { $this->setLeaf(FALSE); } }
/** * Sets data of the node by a given data array * * @param array $data * @return void */ public function dataFromArray($data) { parent::dataFromArray($data); $this->setLabel($data['label']); $this->setType($data['type']); $this->setClass($data['class']); $this->setIcon($data['icon']); $this->setCallbackAction($data['callbackAction']); }
/** * Gets node children * * @param \TYPO3\CMS\Backend\Tree\TreeNode $node * @param int $level * @return NULL|\TYPO3\CMS\Backend\Tree\TreeNodeCollection */ protected function getChildrenOf(\TYPO3\CMS\Backend\Tree\TreeNode $node, $level) { $nodeData = NULL; if ($node->getId() !== 0) { $nodeData = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow('*', $this->tableName, 'uid=' . $node->getId()); } if ($nodeData == NULL) { $nodeData = array('uid' => 0, $this->getLookupField() => ''); } $storage = NULL; $children = $this->getRelatedRecords($nodeData); if (!empty($children)) { /** @var $storage \TYPO3\CMS\Backend\Tree\TreeNodeCollection */ $storage = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\TreeNodeCollection::class); foreach ($children as $child) { $node = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\TreeNode::class); $node->setId($child); if ($level < $this->levelMaximum) { $children = $this->getChildrenOf($node, $level + 1); if ($children !== NULL) { $node->setChildNodes($children); } } $storage->append($node); } } return $storage; }
/** * @test */ public function getChildrenOfLevelMaximumSetToTwoWorks() { $expectedStorage = new TreeNodeCollection(); $expectedFirstLevelTreeNode = new TreeNode(); $expectedFirstLevelTreeNode->setId(1); $expectedSecondLevelTreeNode = new TreeNode(); $expectedSecondLevelTreeNode->setId(2); $expectedStorageOfSecondLevelChildren = new TreeNodeCollection(); $expectedStorageOfSecondLevelChildren->append($expectedSecondLevelTreeNode); $expectedFirstLevelTreeNode->setChildNodes($expectedStorageOfSecondLevelChildren); $expectedStorage->append($expectedFirstLevelTreeNode); $this->initializeSubjectMock(array('getRelatedRecords', 'getRootUid')); $this->subject->_set('levelMaximum', 2); $this->subject->expects($this->at(0))->method('getRelatedRecords')->will($this->returnValue(array(1))); $this->subject->expects($this->at(1))->method('getRelatedRecords')->will($this->returnValue(array(2))); $storage = $this->subject->_call('getChildrenOf', $this->treeData, 1); $this->assertEquals($expectedStorage, $storage); }
/** * Gets the expanded state of a given node * * @param \TYPO3\CMS\Backend\Tree\TreeNode $node * @return bool */ protected function isExpanded(\TYPO3\CMS\Backend\Tree\TreeNode $node) { return $this->getExpandAll() || \TYPO3\CMS\Core\Utility\GeneralUtility::inList($this->expandedList, $node->getId()); }
/** * Sets the CSS Class on all pages which have versioned records * in the current workspace * * @param \TYPO3\CMS\Backend\Tree\TreeNode $node * @return void */ protected function highlightVersionizedElements(\TYPO3\CMS\Backend\Tree\TreeNode $node) { if (!$node->getCls() && $this->getWorkspaceService()->hasPageRecordVersions($GLOBALS['BE_USER']->workspace, $node->getId())) { $node->setCls('ver-versions'); } }
/** * Check if given category is allowed by the access rights * * @param \TYPO3\CMS\Backend\Tree\TreeNode $child * @return bool */ protected function isCategoryAllowed($child) { $mounts = $this->backendUserAuthentication->getCategoryMountPoints(); if (empty($mounts)) { return TRUE; } return in_array($child->getId(), $mounts); }
/** * Returns a node collection of filtered nodes * * @param \TYPO3\CMS\Backend\Tree\TreeNode $node * @param string $searchFilter * @param int $mountPoint * @return \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNodeCollection the filtered nodes */ public function getFilteredNodes(\TYPO3\CMS\Backend\Tree\TreeNode $node, $searchFilter, $mountPoint = 0) { /** @var $nodeCollection \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNodeCollection */ $nodeCollection = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNodeCollection::class); $records = $this->getSubpages(-1, $searchFilter); if (!is_array($records) || empty($records)) { return $nodeCollection; } elseif (count($records) > 500) { return $nodeCollection; } // check no temporary mountpoint is used $mountPoints = (int) $GLOBALS['BE_USER']->uc['pageTree_temporaryMountPoint']; if (!$mountPoints) { $mountPoints = array_map('intval', $GLOBALS['BE_USER']->returnWebmounts()); $mountPoints = array_unique($mountPoints); } else { $mountPoints = [$mountPoints]; } $isNumericSearchFilter = is_numeric($searchFilter) && $searchFilter > 0; $searchFilterQuoted = preg_quote($searchFilter, '/'); $nodeId = (int) $node->getId(); $processedRecordIds = []; foreach ($records as $record) { if ((int) $record['t3ver_wsid'] !== (int) $GLOBALS['BE_USER']->workspace && (int) $record['t3ver_wsid'] !== 0) { continue; } $liveVersion = BackendUtility::getLiveVersionOfRecord('pages', $record['uid'], 'uid'); if ($liveVersion !== null) { $record = $liveVersion; } $record = Commands::getNodeRecord($record['uid'], false); if ((int) $record['pid'] === -1 || in_array($record['uid'], $this->hiddenRecords) || in_array($record['uid'], $processedRecordIds)) { continue; } $processedRecordIds[] = $record['uid']; $rootline = BackendUtility::BEgetRootLine($record['uid'], '', $GLOBALS['BE_USER']->workspace != 0); $rootline = array_reverse($rootline); if (!in_array(0, $mountPoints, true)) { $isInsideMountPoints = false; foreach ($rootline as $rootlineElement) { if (in_array((int) $rootlineElement['uid'], $mountPoints, true)) { $isInsideMountPoints = true; break; } } if (!$isInsideMountPoints) { continue; } } $reference = $nodeCollection; $inFilteredRootline = false; $amountOfRootlineElements = count($rootline); for ($i = 0; $i < $amountOfRootlineElements; ++$i) { $rootlineElement = $rootline[$i]; $rootlineElement['uid'] = (int) $rootlineElement['uid']; $isInWebMount = (int) $GLOBALS['BE_USER']->isInWebMount($rootlineElement['uid']); if (!$isInWebMount || $rootlineElement['uid'] === (int) $mountPoints[0] && $rootlineElement['uid'] !== $isInWebMount) { continue; } if ((int) $rootlineElement['pid'] === $nodeId || $rootlineElement['uid'] === $nodeId || $rootlineElement['uid'] === $isInWebMount && in_array($rootlineElement['uid'], $mountPoints, true)) { $inFilteredRootline = true; } if (!$inFilteredRootline || $rootlineElement['uid'] === $mountPoint) { continue; } $rootlineElement = Commands::getNodeRecord($rootlineElement['uid'], false); $ident = (int) $rootlineElement['sorting'] . (int) $rootlineElement['uid']; if ($reference && $reference->offsetExists($ident)) { /** @var $refNode \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */ $refNode = $reference->offsetGet($ident); $refNode->setExpanded(true); $refNode->setLeaf(false); $reference = $refNode->getChildNodes(); if ($reference == null) { $reference = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNodeCollection::class); $refNode->setChildNodes($reference); } } else { $refNode = Commands::getNewNode($rootlineElement, $mountPoint); $replacement = '<span class="typo3-pagetree-filteringTree-highlight">$1</span>'; if ($isNumericSearchFilter && (int) $rootlineElement['uid'] === (int) $searchFilter) { $text = str_replace('$1', $refNode->getText(), $replacement); } else { $text = preg_replace('/(' . $searchFilterQuoted . ')/iu', $replacement, $refNode->getText()); } $refNode->setText($text, $refNode->getTextSourceField(), $refNode->getPrefix(), $refNode->getSuffix()); /** @var $childCollection \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNodeCollection */ $childCollection = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNodeCollection::class); if ($i + 1 >= $amountOfRootlineElements) { $childNodes = $this->getNodes($refNode, $mountPoint); foreach ($childNodes as $childNode) { /** @var $childNode \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */ $childRecord = $childNode->getRecord(); $childIdent = (int) $childRecord['sorting'] . (int) $childRecord['uid']; $childCollection->offsetSet($childIdent, $childNode); } $refNode->setChildNodes($childNodes); } $refNode->setChildNodes($childCollection); $reference->offsetSet($ident, $refNode); $reference->ksort(); $reference = $childCollection; } } } foreach ($this->processCollectionHookObjects as $hookObject) { /** @var $hookObject \TYPO3\CMS\Backend\Tree\Pagetree\CollectionProcessorInterface */ $hookObject->postProcessFilteredNodes($node, $searchFilter, $mountPoint, $nodeCollection); } return $nodeCollection; }
/** * Compares a node with another one * * @see \TYPO3\CMS\Backend\Tree\TreeNode::compareTo * @return void * @noapi */ public function nodeCompare(\TYPO3\CMS\Backend\Tree\TreeNode $node, \TYPO3\CMS\Backend\Tree\TreeNode $otherNode) { return $node->compareTo($otherNode); }
/** * Sets the CSS Class on all pages which have versioned records * in the current workspace * * @param \TYPO3\CMS\Backend\Tree\TreeNode $node * @return void */ protected function highlightVersionizedElements(\TYPO3\CMS\Backend\Tree\TreeNode $node) { if (!$node->getCls() && count(\TYPO3\CMS\Backend\Utility\BackendUtility::countVersionsOfRecordsOnPage($GLOBALS['BE_USER']->workspace, $node->getId(), TRUE))) { $node->setCls('ver-versions'); } }
/** * Check if given category is allowed by the access rights * * @param \TYPO3\CMS\Backend\Tree\TreeNode $child * @return bool */ protected function isCategoryAllowed($child) { $mounts = Tx_News_Utility_CategoryProvider::getUserMounts(); if (empty($mounts)) { return TRUE; } return t3lib_div::inList($mounts, $child->getId()); }
/** * Gets node children * * @param \TYPO3\CMS\Backend\Tree\TreeNode $node * @param int $level * @return NULL|\TYPO3\CMS\Backend\Tree\TreeNodeCollection */ protected function getChildrenOf(\TYPO3\CMS\Backend\Tree\TreeNode $node, $level) { $nodeData = null; if ($node->getId() !== 0) { $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->getTableName()); $queryBuilder->getRestrictions()->removeAll(); $nodeData = $queryBuilder->select('*')->from($this->getTableName())->where($queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($node->getId(), \PDO::PARAM_INT)))->setMaxResults(1)->execute()->fetch(); } if (empty($nodeData)) { $nodeData = ['uid' => 0, $this->getLookupField() => '']; } $storage = null; $children = $this->getRelatedRecords($nodeData); if (!empty($children)) { /** @var $storage \TYPO3\CMS\Backend\Tree\TreeNodeCollection */ $storage = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\TreeNodeCollection::class); foreach ($children as $child) { $node = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Tree\TreeNode::class); $node->setId($child); if ($level < $this->levelMaximum) { $children = $this->getChildrenOf($node, $level + 1); if ($children !== null) { $node->setChildNodes($children); } } $storage->append($node); } } return $storage; }
/** * Returns a node collection of filtered nodes * * @param \TYPO3\CMS\Backend\Tree\TreeNode $node * @param string $searchFilter * @param integer $mountPoint * @return \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNodeCollection the filtered nodes */ public function getFilteredNodes(\TYPO3\CMS\Backend\Tree\TreeNode $node, $searchFilter, $mountPoint = 0) { /** @var $nodeCollection \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNodeCollection */ $nodeCollection = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Tree\\Pagetree\\PagetreeNodeCollection'); $records = $this->getSubpages(-1, $searchFilter); if (!is_array($records) || !count($records)) { return $nodeCollection; } elseif (count($records) > 500) { return $nodeCollection; } // check no temporary mountpoint is used $mountPoints = intval($GLOBALS['BE_USER']->uc['pageTree_temporaryMountPoint']); if (!$mountPoints) { $mountPoints = array_map('intval', $GLOBALS['BE_USER']->returnWebmounts()); $mountPoints = array_unique($mountPoints); } else { $mountPoints = array($mountPoints); } $isNumericSearchFilter = is_numeric($searchFilter) && $searchFilter > 0; $nodeId = intval($node->getId()); foreach ($records as $record) { $record = \TYPO3\CMS\Backend\Tree\Pagetree\Commands::getNodeRecord($record['uid']); if (intval($record['pid']) === -1 || in_array($record['uid'], $this->hiddenRecords)) { continue; } $rootline = \TYPO3\CMS\Backend\Utility\BackendUtility::BEgetRootLine($record['uid'], '', $GLOBALS['BE_USER']->workspace != 0); $rootline = array_reverse($rootline); if ($nodeId === 0) { array_shift($rootline); } if ($mountPoints != array(0)) { $isInsideMountPoints = FALSE; foreach ($rootline as $rootlineElement) { if (in_array(intval($rootlineElement['uid']), $mountPoints, TRUE)) { $isInsideMountPoints = TRUE; break; } } if (!$isInsideMountPoints) { continue; } } $reference = $nodeCollection; $inFilteredRootline = FALSE; $amountOfRootlineElements = count($rootline); for ($i = 0; $i < $amountOfRootlineElements; ++$i) { $rootlineElement = $rootline[$i]; if (intval($rootlineElement['pid']) === $nodeId || intval($rootlineElement['uid']) === $nodeId) { $inFilteredRootline = TRUE; } if (!$inFilteredRootline) { continue; } $rootlineElement = \TYPO3\CMS\Backend\Tree\Pagetree\Commands::getNodeRecord($rootlineElement['uid']); $ident = intval($rootlineElement['sorting']) . intval($rootlineElement['uid']); if ($reference && $reference->offsetExists($ident)) { /** @var $refNode \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */ $refNode = $reference->offsetGet($ident); $refNode->setExpanded(TRUE); $refNode->setLeaf(FALSE); $reference = $refNode->getChildNodes(); if ($reference == NULL) { $reference = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Tree\\Pagetree\\PagetreeNodeCollection'); $refNode->setChildNodes($reference); } } else { $refNode = \TYPO3\CMS\Backend\Tree\Pagetree\Commands::getNewNode($rootlineElement, $mountPoint); $replacement = '<span class="typo3-pagetree-filteringTree-highlight">$1</span>'; if ($isNumericSearchFilter && intval($rootlineElement['uid']) === intval($searchFilter)) { $text = str_replace('$1', $refNode->getText(), $replacement); } else { $text = preg_replace('/(' . $searchFilter . ')/i', $replacement, $refNode->getText()); } $refNode->setText($text, $refNode->getTextSourceField(), $refNode->getPrefix(), $refNode->getSuffix()); /** @var $childCollection \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNodeCollection */ $childCollection = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Tree\\Pagetree\\PagetreeNodeCollection'); if ($i + 1 >= $amountOfRootlineElements) { $childNodes = $this->getNodes($refNode, $mountPoint); foreach ($childNodes as $childNode) { /** @var $childNode \TYPO3\CMS\Backend\Tree\Pagetree\PagetreeNode */ $childRecord = $childNode->getRecord(); $childIdent = intval($childRecord['sorting']) . intval($childRecord['uid']); $childCollection->offsetSet($childIdent, $childNode); } $refNode->setChildNodes($childNodes); } $refNode->setChildNodes($childCollection); $reference->offsetSet($ident, $refNode); $reference->ksort(); $reference = $childCollection; } } } foreach ($this->processCollectionHookObjects as $hookObject) { /** @var $hookObject t3lib_tree_pagetree_interfaces_collectionprocessor */ $hookObject->postProcessFilteredNodes($node, $searchFilter, $mountPoint, $nodeCollection); } return $nodeCollection; }