[FEATURE] PHP 8.0 support
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Provider / PageTsBackendLayoutDataProvider.php
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
16 namespace TYPO3\CMS\Backend\Provider;
17
18 use TYPO3\CMS\Backend\Utility\BackendUtility;
19 use TYPO3\CMS\Backend\View\BackendLayout\BackendLayout;
20 use TYPO3\CMS\Backend\View\BackendLayout\BackendLayoutCollection;
21 use TYPO3\CMS\Backend\View\BackendLayout\DataProviderContext;
22 use TYPO3\CMS\Backend\View\BackendLayout\DataProviderInterface;
23 use TYPO3\CMS\Core\Utility\ArrayUtility;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25
26 /**
27 * This Provider adds Backend Layouts based on PageTsConfig
28 *
29 * = Example =
30 * mod {
31 * web_layout {
32 * BackendLayouts {
33 * example {
34 * title = Example
35 * config {
36 * backend_layout {
37 * colCount = 1
38 * rowCount = 2
39 * rows {
40 * 1 {
41 * columns {
42 * 1 {
43 * name = LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:colPos.I.3
44 * colPos = 3
45 * colspan = 1
46 * }
47 * }
48 * }
49 * 2 {
50 * columns {
51 * 1 {
52 * name = Main
53 * colPos = 0
54 * colspan = 1
55 * }
56 * }
57 * }
58 * }
59 * }
60 * }
61 * icon = EXT:example_extension/Resources/Public/Images/BackendLayouts/default.gif
62 * }
63 * }
64 * }
65 * }
66 */
67 class PageTsBackendLayoutDataProvider implements DataProviderInterface
68 {
69 /**
70 * Internal Backend Layout stack
71 *
72 * @var array
73 */
74 protected $backendLayouts = [];
75
76 /**
77 * PageTs Config
78 *
79 * @var array
80 */
81 protected $pageTsConfig = [];
82
83 /**
84 * PageId
85 *
86 * @var int
87 */
88 protected $pageId = 0;
89
90 /**
91 * Set PageTsConfig
92 *
93 * @param array $pageTsConfig
94 */
95 protected function setPageTsConfig(array $pageTsConfig)
96 {
97 $this->pageTsConfig = $pageTsConfig;
98 }
99
100 /**
101 * Get PageTsConfig
102 *
103 * @return array
104 */
105 protected function getPageTsConfig()
106 {
107 return $this->pageTsConfig;
108 }
109
110 /**
111 * Set PageId
112 *
113 * @param int $pageId
114 */
115 protected function setPageId($pageId)
116 {
117 $this->pageId = (int)$pageId;
118 }
119
120 /**
121 * Get PageId
122 *
123 * @return int
124 */
125 protected function getPageId()
126 {
127 return (int)$this->pageId;
128 }
129
130 /**
131 * Gets PageTsConfig from DataProviderContext if available,
132 * if not it will be generated for the current Page.
133 *
134 * @param DataProviderContext $dataProviderContext
135 */
136 protected function generatePageTsConfig($dataProviderContext = null)
137 {
138 if ($dataProviderContext === null) {
139 $pageId = $this->getPageId();
140 $pageId = $pageId > 0 ? $pageId : (int)GeneralUtility::_GP('id');
141 $pageTsConfig = BackendUtility::getPagesTSconfig($pageId);
142 } else {
143 $pageTsConfig = $dataProviderContext->getPageTsConfig();
144 }
145 $this->setPageTsConfig($pageTsConfig);
146 }
147
148 /**
149 * Generate the Backend Layout configs
150 *
151 * @param DataProviderContext $dataProviderContext
152 */
153 protected function generateBackendLayouts($dataProviderContext = null)
154 {
155 $this->generatePageTsConfig($dataProviderContext);
156 $pageTsConfig = $this->getPageTsConfig();
157 if (!empty($pageTsConfig['mod.']['web_layout.']['BackendLayouts.'])) {
158 $backendLayouts = (array)$pageTsConfig['mod.']['web_layout.']['BackendLayouts.'];
159 foreach ($backendLayouts as $identifier => $data) {
160 $backendLayout = $this->generateBackendLayoutFromTsConfig($identifier, $data);
161 $this->attachBackendLayout($backendLayout);
162 }
163 }
164 }
165
166 /**
167 * Generates a Backend Layout from PageTsConfig array
168 *
169 * @param string $identifier
170 * @param array $data
171 * @return mixed
172 */
173 protected function generateBackendLayoutFromTsConfig($identifier, $data)
174 {
175 $backendLayout = [];
176 if (!empty($data['config.']['backend_layout.']) && is_array($data['config.']['backend_layout.'])) {
177 $backendLayout['uid'] = substr($identifier, 0, -1);
178 $backendLayout['title'] = $data['title'] ?? $backendLayout['uid'];
179 $backendLayout['icon'] = $data['icon'] ?? '';
180 // Convert PHP array back to plain TypoScript so it can be processed
181 $config = ArrayUtility::flatten($data['config.'] ?? []);
182 $backendLayout['config'] = '';
183 foreach ($config as $row => $value) {
184 $backendLayout['config'] .= $row . ' = ' . $value . "\r\n";
185 }
186 return $backendLayout;
187 }
188 return null;
189 }
190
191 /**
192 * Attach Backend Layout to internal Stack
193 *
194 * @param mixed $backendLayout
195 */
196 protected function attachBackendLayout($backendLayout = null)
197 {
198 if ($backendLayout) {
199 $this->backendLayouts[$backendLayout['uid']] = $backendLayout;
200 }
201 }
202
203 /**
204 * @param DataProviderContext $dataProviderContext
205 * @param BackendLayoutCollection $backendLayoutCollection
206 */
207 public function addBackendLayouts(DataProviderContext $dataProviderContext, BackendLayoutCollection $backendLayoutCollection)
208 {
209 $this->generateBackendLayouts($dataProviderContext);
210 foreach ($this->backendLayouts as $backendLayoutConfig) {
211 $backendLayout = $this->createBackendLayout($backendLayoutConfig);
212 $backendLayoutCollection->add($backendLayout);
213 }
214 }
215
216 /**
217 * Gets a backend layout by (regular) identifier.
218 *
219 * @param string $identifier
220 * @param int $pageId
221 * @return BackendLayout|null
222 */
223 public function getBackendLayout($identifier, $pageId)
224 {
225 $this->setPageId($pageId);
226 $this->generateBackendLayouts();
227 $backendLayout = null;
228 if (array_key_exists($identifier, $this->backendLayouts)) {
229 return $this->createBackendLayout($this->backendLayouts[$identifier]);
230 }
231 return $backendLayout;
232 }
233
234 /**
235 * Creates a new backend layout using the given record data.
236 *
237 * @param array $data
238 * @return BackendLayout
239 */
240 protected function createBackendLayout(array $data)
241 {
242 $backendLayout = BackendLayout::create($data['uid'], $data['title'], $data['config']);
243 $backendLayout->setIconPath($this->getIconPath($data['icon']));
244 $backendLayout->setData($data);
245 return $backendLayout;
246 }
247
248 /**
249 * Gets and sanitizes the icon path.
250 *
251 * @param string $icon Name of the icon file
252 * @return string
253 */
254 protected function getIconPath($icon)
255 {
256 $iconPath = '';
257 if (!empty($icon)) {
258 $iconPath = $icon;
259 }
260 return $iconPath;
261 }
262 }