1<?php
2
3/*
4 * This file is part of the TYPO3 CMS project.
5 *
6 * It is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License, either version 2
8 * of the License, or any later version.
9 *
10 * For the full copyright and license information, please read the
11 * LICENSE.txt file that was distributed with this source code.
12 *
13 * The TYPO3 project - inspiring people to share!
14 */
15
16namespace TYPO3\CMS\Core\Tree\TableConfiguration;
17
18use TYPO3\CMS\Backend\Tree\AbstractTree;
19use TYPO3\CMS\Backend\Tree\Renderer\AbstractTreeRenderer;
20use TYPO3\CMS\Backend\Tree\TreeNodeCollection;
21use TYPO3\CMS\Backend\Tree\TreeRepresentationNode;
22
23/**
24 * Renders a tca tree array for the SelectElementTree
25 */
26class ArrayTreeRenderer extends AbstractTreeRenderer
27{
28    /**
29     * recursion level
30     *
31     * @var int
32     */
33    protected $recursionLevel = 0;
34
35    /**
36     * Renders a node recursive or just a single instance
37     *
38     * @param \TYPO3\CMS\Backend\Tree\TreeRepresentationNode $node
39     * @param bool $recursive
40     * @return array
41     */
42    public function renderNode(TreeRepresentationNode $node, $recursive = true)
43    {
44        $nodeArray = [];
45        $nodeArray[] = $this->getNodeArray($node);
46        if ($recursive && $node->hasChildNodes()) {
47            $this->recursionLevel++;
48            $children = $this->renderNodeCollection($node->getChildNodes());
49            foreach ($children as $child) {
50                $nodeArray[] = $child;
51            }
52            $this->recursionLevel--;
53        }
54        return $nodeArray;
55    }
56
57    /**
58     * Get node array
59     *
60     * @param \TYPO3\CMS\Backend\Tree\TreeRepresentationNode|DatabaseTreeNode $node
61     * @return array
62     */
63    protected function getNodeArray(TreeRepresentationNode $node)
64    {
65        $overlayIconName = '';
66        if (is_object($node->getIcon())) {
67            $iconName = $node->getIcon()->getIdentifier();
68            if (is_object($node->getIcon()->getOverlayIcon())) {
69                $overlayIconName = $node->getIcon()->getOverlayIcon()->getIdentifier();
70            }
71        } else {
72            $iconName = $node->getIcon();
73        }
74        $nodeArray = [
75            'identifier' => htmlspecialchars($node->getId()),
76            // No need for htmlspecialchars() here as d3 is using 'textContent' property of the HTML DOM node
77            'name' => $node->getLabel(),
78            'icon' => $iconName,
79            'overlayIcon' => $overlayIconName,
80            'depth' => $this->recursionLevel,
81            'hasChildren' => (bool)$node->hasChildNodes(),
82            'selectable' => true,
83        ];
84        if ($node instanceof DatabaseTreeNode) {
85            $nodeArray['checked'] = (bool)$node->getSelected();
86            if (!$node->getSelectable()) {
87                $nodeArray['checked'] = false;
88                $nodeArray['selectable'] = false;
89            }
90        }
91        return $nodeArray;
92    }
93
94    /**
95     * Renders a node collection recursive or just a single instance
96     *
97     * @param \TYPO3\CMS\Backend\Tree\AbstractTree $tree
98     * @param bool $recursive
99     * @return array
100     */
101    public function renderTree(AbstractTree $tree, $recursive = true)
102    {
103        $this->recursionLevel = 0;
104        return $this->renderNode($tree->getRoot(), $recursive);
105    }
106
107    /**
108     * Renders a tree recursively or just a single instance
109     *
110     * @param TreeNodeCollection $collection
111     * @param bool $recursive
112     * @return array
113     */
114    public function renderNodeCollection(TreeNodeCollection $collection, $recursive = true)
115    {
116        $treeItems = [];
117        foreach ($collection as $node) {
118            $allNodes = $this->renderNode($node, $recursive);
119            if ($allNodes[0]) {
120                $treeItems[] = $allNodes[0];
121            }
122            $nodeCount = count($allNodes);
123            if ($nodeCount > 1) {
124                for ($i = 1; $i < $nodeCount; $i++) {
125                    $treeItems[] = $allNodes[$i];
126                }
127            }
128        }
129        return $treeItems;
130    }
131}
132