[TASK] Update php-cs-fixer to 2.5.0
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Classes / ContentObject / Menu / TextMenuContentObject.php
1 <?php
2 namespace TYPO3\CMS\Frontend\ContentObject\Menu;
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 use TYPO3\CMS\Core\TypoScript\TypoScriptService;
17 use TYPO3\CMS\Core\Utility\GeneralUtility;
18
19 /**
20 * Extension class creating text based menus
21 */
22 class TextMenuContentObject extends AbstractMenuContentObject
23 {
24 /**
25 * Calls procesItemStates() so that the common configuration for the menu items are resolved into individual configuration per item.
26 * Sets the result for the new "normal state" in $this->result
27 *
28 * @see AbstractMenuContentObject::procesItemStates()
29 */
30 public function generate()
31 {
32 $NOconf = [];
33 $splitCount = count($this->menuArr);
34 if ($splitCount) {
35 list($NOconf) = $this->procesItemStates($splitCount);
36 }
37 if (!empty($this->mconf['debugItemConf'])) {
38 echo '<h3>$NOconf:</h3>';
39 debug($NOconf);
40 }
41 $this->result = $NOconf;
42 }
43
44 /**
45 * Traverses the ->result array of menu items configuration (made by ->generate()) and renders each item.
46 * During the execution of this function many internal methods prefixed "extProc_" from this class is called and
47 * many of these are for now dummy functions.
48 * An instance of ContentObjectRenderer is also made and for each menu item rendered it is loaded with
49 * the record for that page so that any stdWrap properties that applies will have the current menu items record available.
50 *
51 * @return string The HTML for the menu (returns result through $this->extProc_finish(); )
52 */
53 public function writeMenu()
54 {
55 if (empty($this->result)) {
56 return '';
57 }
58
59 $this->WMresult = '';
60 $this->INPfixMD5 = substr(md5(microtime() . 'tmenu'), 0, 4);
61 $this->WMmenuItems = count($this->result);
62 $typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
63 $this->WMsubmenuObjSuffixes = $typoScriptService->explodeConfigurationForOptionSplit(['sOSuffix' => $this->mconf['submenuObjSuffixes']], $this->WMmenuItems);
64 $this->extProc_init();
65 foreach ($this->result as $key => $val) {
66 $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']++;
67 $GLOBALS['TSFE']->register['count_MENUOBJ']++;
68 // Initialize the cObj with the page record of the menu item
69 $this->WMcObj->start($this->menuArr[$key], 'pages');
70 $this->I = [];
71 $this->I['key'] = $key;
72 $this->I['INPfix'] = ($this->imgNameNotRandom ? '' : '_' . $this->INPfixMD5) . '_' . $key;
73 $this->I['val'] = $val;
74 $this->I['title'] = isset($this->I['val']['stdWrap.']) ? $this->WMcObj->stdWrap($this->getPageTitle($this->menuArr[$key]['title'], $this->menuArr[$key]['nav_title']), $this->I['val']['stdWrap.']) : $this->getPageTitle($this->menuArr[$key]['title'], $this->menuArr[$key]['nav_title']);
75 $this->I['uid'] = $this->menuArr[$key]['uid'];
76 $this->I['mount_pid'] = $this->menuArr[$key]['mount_pid'];
77 $this->I['pid'] = $this->menuArr[$key]['pid'];
78 $this->I['spacer'] = $this->menuArr[$key]['isSpacer'];
79 // Set access key
80 if ($this->mconf['accessKey']) {
81 $this->I['accessKey'] = $this->accessKey($this->I['title']);
82 } else {
83 $this->I['accessKey'] = [];
84 }
85 // Make link tag
86 $this->I['val']['ATagParams'] = $this->WMcObj->getATagParams($this->I['val']);
87 if (isset($this->I['val']['additionalParams.'])) {
88 $this->I['val']['additionalParams'] = $this->WMcObj->stdWrap($this->I['val']['additionalParams'], $this->I['val']['additionalParams.']);
89 }
90 $this->I['linkHREF'] = $this->link($key, $this->I['val']['altTarget'], $this->mconf['forceTypeValue']);
91 if (empty($this->I['linkHREF'])) {
92 $this->I['val']['doNotLinkIt'] = 1;
93 }
94 // Title attribute of links:
95 $titleAttrValue = isset($this->I['val']['ATagTitle.']) ? $this->WMcObj->stdWrap($this->I['val']['ATagTitle'], $this->I['val']['ATagTitle.']) . $this->I['accessKey']['alt'] : $this->I['val']['ATagTitle'] . $this->I['accessKey']['alt'];
96 if ($titleAttrValue !== '') {
97 $this->I['linkHREF']['title'] = $titleAttrValue;
98 }
99
100 // Calling extra processing function
101 $this->extProc_beforeLinking($key);
102 // stdWrap for doNotLinkIt
103 if (isset($this->I['val']['doNotLinkIt.'])) {
104 $this->I['val']['doNotLinkIt'] = $this->WMcObj->stdWrap($this->I['val']['doNotLinkIt'], $this->I['val']['doNotLinkIt.']);
105 }
106 // Compile link tag
107 if (!$this->I['val']['doNotLinkIt']) {
108 $this->I['val']['doNotLinkIt'] = 0;
109 }
110 if (!$this->I['spacer'] && $this->I['val']['doNotLinkIt'] != 1) {
111 $this->setATagParts();
112 } else {
113 $this->I['A1'] = '';
114 $this->I['A2'] = '';
115 }
116 // ATagBeforeWrap processing:
117 if ($this->I['val']['ATagBeforeWrap']) {
118 $wrapPartsBefore = explode('|', $this->I['val']['linkWrap']);
119 $wrapPartsAfter = ['', ''];
120 } else {
121 $wrapPartsBefore = ['', ''];
122 $wrapPartsAfter = explode('|', $this->I['val']['linkWrap']);
123 }
124 if ($this->I['val']['stdWrap2'] || isset($this->I['val']['stdWrap2.'])) {
125 $stdWrap2 = isset($this->I['val']['stdWrap2.']) ? $this->WMcObj->stdWrap('|', $this->I['val']['stdWrap2.']) : '|';
126 $wrapPartsStdWrap = explode($this->I['val']['stdWrap2'] ? $this->I['val']['stdWrap2'] : '|', $stdWrap2);
127 } else {
128 $wrapPartsStdWrap = ['', ''];
129 }
130 // Make before, middle and after parts
131 $this->I['parts'] = [];
132 $this->I['parts']['before'] = $this->getBeforeAfter('before');
133 $this->I['parts']['stdWrap2_begin'] = $wrapPartsStdWrap[0];
134 // stdWrap for doNotShowLink
135 if (isset($this->I['val']['doNotShowLink.'])) {
136 $this->I['val']['doNotShowLink'] = $this->WMcObj->stdWrap($this->I['val']['doNotShowLink'], $this->I['val']['doNotShowLink.']);
137 }
138 if (!$this->I['val']['doNotShowLink']) {
139 $this->I['parts']['notATagBeforeWrap_begin'] = $wrapPartsAfter[0];
140 $this->I['parts']['ATag_begin'] = $this->I['A1'];
141 $this->I['parts']['ATagBeforeWrap_begin'] = $wrapPartsBefore[0];
142 $this->I['parts']['title'] = $this->I['title'];
143 $this->I['parts']['ATagBeforeWrap_end'] = $wrapPartsBefore[1];
144 $this->I['parts']['ATag_end'] = $this->I['A2'];
145 $this->I['parts']['notATagBeforeWrap_end'] = $wrapPartsAfter[1];
146 }
147 $this->I['parts']['stdWrap2_end'] = $wrapPartsStdWrap[1];
148 $this->I['parts']['after'] = $this->getBeforeAfter('after');
149 // Passing I to a user function
150 if ($this->mconf['IProcFunc']) {
151 $this->I = $this->userProcess('IProcFunc', $this->I);
152 }
153 // Merge parts + beforeAllWrap
154 $this->I['theItem'] = implode('', $this->I['parts']);
155 $this->I['theItem'] = $this->extProc_beforeAllWrap($this->I['theItem'], $key);
156 // allWrap:
157 $allWrap = isset($this->I['val']['allWrap.']) ? $this->WMcObj->stdWrap($this->I['val']['allWrap'], $this->I['val']['allWrap.']) : $this->I['val']['allWrap'];
158 $this->I['theItem'] = $this->WMcObj->wrap($this->I['theItem'], $allWrap);
159 if ($this->I['val']['subst_elementUid']) {
160 $this->I['theItem'] = str_replace('{elementUid}', $this->I['uid'], $this->I['theItem']);
161 }
162 // allStdWrap:
163 if (is_array($this->I['val']['allStdWrap.'])) {
164 $this->I['theItem'] = $this->WMcObj->stdWrap($this->I['theItem'], $this->I['val']['allStdWrap.']);
165 }
166 // Calling extra processing function
167 $this->extProc_afterLinking($key);
168 }
169 return $this->extProc_finish();
170 }
171
172 /**
173 * Generates the before* and after* images for TMENUs
174 *
175 * @param string $pref Can be "before" or "after" and determines which kind of image to create (basically this is the prefix of the TypoScript properties that are read from the ->I['val'] array
176 * @return string The resulting HTML of the image, if any.
177 */
178 public function getBeforeAfter($pref)
179 {
180 $res = '';
181 if ($imgInfo = $this->WMcObj->getImgResource($this->I['val'][$pref . 'Img'], $this->I['val'][$pref . 'Img.'])) {
182 $theName = $this->imgNamePrefix . $this->I['uid'] . $this->I['INPfix'] . $pref;
183 $name = ' ' . $this->nameAttribute . '="' . $theName . '"';
184 $GLOBALS['TSFE']->imagesOnPage[] = $imgInfo[3];
185 $res = '<img' . ' src="' . $GLOBALS['TSFE']->absRefPrefix . $imgInfo[3] . '"' . ' width="' . $imgInfo[0] . '"' . ' height="' . $imgInfo[1] . '"' . $name . ($this->I['val'][$pref . 'ImgTagParams'] ? ' ' . $this->I['val'][$pref . 'ImgTagParams'] : '') . $this->parent_cObj->getBorderAttr(' border="0"');
186 if (!strstr($res, 'alt="')) {
187 // Adding alt attribute if not set.
188 $res .= ' alt=""';
189 }
190 $res .= ' />';
191 if ($this->I['val'][$pref . 'ImgLink']) {
192 $res = $this->I['A1'] . $res . $this->I['A2'];
193 }
194 }
195 $processedPref = isset($this->I['val'][$pref . '.']) ? $this->WMcObj->stdWrap($this->I['val'][$pref], $this->I['val'][$pref . '.']) : $this->I['val'][$pref];
196 if (isset($this->I['val'][$pref . 'Wrap'])) {
197 return $this->WMcObj->wrap($res . $processedPref, $this->I['val'][$pref . 'Wrap']);
198 }
199 return $res . $processedPref;
200 }
201
202 /**
203 * Called right before the traversing of $this->result begins.
204 * Can be used for various initialization
205 *
206 * @access private
207 * @see writeMenu()
208 */
209 public function extProc_init()
210 {
211 }
212
213 /**
214 * Called right before the creation of the link for the menu item
215 *
216 * @param int $key Pointer to $this->menuArr[$key] where the current menu element record is found
217 * @access private
218 * @see writeMenu()
219 */
220 public function extProc_beforeLinking($key)
221 {
222 }
223
224 /**
225 * Called right after the creation of links for the menu item. This is also the last function call before the while-loop traversing menu items goes to the next item.
226 * This function MUST set $this->WMresult.=[HTML for menu item] to add the generated menu item to the internal accumulation of items.
227 *
228 * @param int $key Pointer to $this->menuArr[$key] where the current menu element record is found
229 * @access private
230 * @see writeMenu()
231 */
232 public function extProc_afterLinking($key)
233 {
234 // Add part to the accumulated result + fetch submenus
235 if (!$this->I['spacer']) {
236 $this->I['theItem'] .= $this->subMenu($this->I['uid'], $this->WMsubmenuObjSuffixes[$key]['sOSuffix']);
237 }
238 $part = isset($this->I['val']['wrapItemAndSub.']) ? $this->WMcObj->stdWrap($this->I['val']['wrapItemAndSub'], $this->I['val']['wrapItemAndSub.']) : $this->I['val']['wrapItemAndSub'];
239 $this->WMresult .= $part ? $this->WMcObj->wrap($this->I['theItem'], $part) : $this->I['theItem'];
240 }
241
242 /**
243 * Called before the "allWrap" happens on the menu item.
244 *
245 * @param string $item The current content of the menu item, $this->I['theItem'], passed along.
246 * @param int $key Pointer to $this->menuArr[$key] where the current menu element record is found
247 * @return string The modified version of $item, going back into $this->I['theItem']
248 * @access private
249 * @see writeMenu()
250 */
251 public function extProc_beforeAllWrap($item, $key)
252 {
253 return $item;
254 }
255
256 /**
257 * Called before the writeMenu() function returns (only if a menu was generated)
258 *
259 * @return string The total menu content should be returned by this function
260 * @access private
261 * @see writeMenu()
262 */
263 public function extProc_finish()
264 {
265 // stdWrap:
266 if (is_array($this->mconf['stdWrap.'])) {
267 $this->WMresult = $this->WMcObj->stdWrap($this->WMresult, $this->mconf['stdWrap.']);
268 }
269 return $this->WMcObj->wrap($this->WMresult, $this->mconf['wrap']) . $this->WMextraScript;
270 }
271 }