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