[TASK] Remove rollover functionality from TMENU
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Classes / ContentObject / Menu / TextMenuContentObject.php
1 <?php
2 namespace TYPO3\CMS\Frontend\ContentObject\Menu;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 1999-2013 Kasper Skårhøj (kasperYYYY@typo3.com)
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the text file GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29
30 /**
31 * Extension class creating text based menus
32 *
33 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
34 */
35 class TextMenuContentObject extends \TYPO3\CMS\Frontend\ContentObject\Menu\AbstractMenuContentObject {
36
37 /**
38 * Calls procesItemStates() so that the common configuration for the menu items are resolved into individual configuration per item.
39 * Sets the result for the new "normal state" in $this->result
40 *
41 * @return void
42 * @see AbstractMenuContentObject::procesItemStates()
43 * @todo Define visibility
44 */
45 public function generate() {
46 $splitCount = count($this->menuArr);
47 if ($splitCount) {
48 list($NOconf) = $this->procesItemStates($splitCount);
49 }
50 if ($this->mconf['debugItemConf']) {
51 echo '<h3>$NOconf:</h3>';
52 debug($NOconf);
53 }
54 $this->result = $NOconf;
55 }
56
57 /**
58 * Traverses the ->result array of menu items configuration (made by ->generate()) and renders each item.
59 * During the execution of this function many internal methods prefixed "extProc_" from this class is called and many of these are for now dummy functions. But they can be used for processing as they are used by the TMENU_LAYERS
60 * An instance of ContentObjectRenderer is also made and for each menu item rendered it is loaded with the record for that page so that any stdWrap properties that applies will have the current menu items record available.
61 *
62 * @return string The HTML for the menu (returns result through $this->extProc_finish(); )
63 * @todo Define visibility
64 */
65 public function writeMenu() {
66 if (is_array($this->result) && count($this->result)) {
67 // Create new \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer for our use
68 $this->WMcObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
69 $this->WMresult = '';
70 $this->INPfixMD5 = substr(md5(microtime() . 'tmenu'), 0, 4);
71 $this->WMmenuItems = count($this->result);
72 $this->WMsubmenuObjSuffixes = $this->tmpl->splitConfArray(array('sOSuffix' => $this->mconf['submenuObjSuffixes']), $this->WMmenuItems);
73 $this->extProc_init();
74 foreach ($this->result as $key => $val) {
75 $GLOBALS['TSFE']->register['count_HMENU_MENUOBJ']++;
76 $GLOBALS['TSFE']->register['count_MENUOBJ']++;
77 // Initialize the cObj with the page record of the menu item
78 $this->WMcObj->start($this->menuArr[$key], 'pages');
79 $this->I = array();
80 $this->I['key'] = $key;
81 $this->I['INPfix'] = ($this->imgNameNotRandom ? '' : '_' . $this->INPfixMD5) . '_' . $key;
82 $this->I['val'] = $val;
83 $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']);
84 $this->I['uid'] = $this->menuArr[$key]['uid'];
85 $this->I['mount_pid'] = $this->menuArr[$key]['mount_pid'];
86 $this->I['pid'] = $this->menuArr[$key]['pid'];
87 $this->I['spacer'] = $this->menuArr[$key]['isSpacer'];
88 // Set access key
89 if ($this->mconf['accessKey']) {
90 $this->I['accessKey'] = $this->accessKey($this->I['title']);
91 } else {
92 $this->I['accessKey'] = array();
93 }
94 // Make link tag
95 $this->I['val']['ATagParams'] = $this->WMcObj->getATagParams($this->I['val']);
96 if (isset($this->I['val']['additionalParams.'])) {
97 $this->I['val']['additionalParams'] = $this->WMcObj->stdWrap($this->I['val']['additionalParams'], $this->I['val']['additionalParams.']);
98 }
99 $this->I['linkHREF'] = $this->link($key, $this->I['val']['altTarget'], $this->mconf['forceTypeValue']);
100 // Title attribute of links:
101 $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'];
102 if (strlen($titleAttrValue)) {
103 $this->I['linkHREF']['title'] = $titleAttrValue;
104 }
105
106 // Calling extra processing function
107 $this->extProc_beforeLinking($key);
108 // stdWrap for doNotLinkIt
109 if (isset($this->I['val']['doNotLinkIt.'])) {
110 $this->I['val']['doNotLinkIt'] = $this->WMcObj->stdWrap($this->I['val']['doNotLinkIt'], $this->I['val']['doNotLinkIt.']);
111 }
112 // Compile link tag
113 if (!$this->I['val']['doNotLinkIt']) {
114 $this->I['val']['doNotLinkIt'] = 0;
115 }
116 if (!$this->I['spacer'] && $this->I['val']['doNotLinkIt'] != 1) {
117 $this->setATagParts();
118 } else {
119 $this->I['A1'] = '';
120 $this->I['A2'] = '';
121 }
122 // ATagBeforeWrap processing:
123 if ($this->I['val']['ATagBeforeWrap']) {
124 $wrapPartsBefore = explode('|', $this->I['val']['linkWrap']);
125 $wrapPartsAfter = array('', '');
126 } else {
127 $wrapPartsBefore = array('', '');
128 $wrapPartsAfter = explode('|', $this->I['val']['linkWrap']);
129 }
130 if ($this->I['val']['stdWrap2'] || isset($this->I['val']['stdWrap2.'])) {
131 $stdWrap2 = isset($this->I['val']['stdWrap2.']) ? $this->WMcObj->stdWrap('|', $this->I['val']['stdWrap2.']) : '|';
132 $wrapPartsStdWrap = explode($this->I['val']['stdWrap2'] ? $this->I['val']['stdWrap2'] : '|', $stdWrap2);
133 } else {
134 $wrapPartsStdWrap = array('', '');
135 }
136 // Make before, middle and after parts
137 $this->I['parts'] = array();
138 $this->I['parts']['before'] = $this->getBeforeAfter('before');
139 $this->I['parts']['stdWrap2_begin'] = $wrapPartsStdWrap[0];
140 // stdWrap for doNotShowLink
141 if (isset($this->I['val']['doNotShowLink.'])) {
142 $this->I['val']['doNotShowLink'] = $this->WMcObj->stdWrap($this->I['val']['doNotShowLink'], $this->I['val']['doNotShowLink.']);
143 }
144 if (!$this->I['val']['doNotShowLink']) {
145 $this->I['parts']['notATagBeforeWrap_begin'] = $wrapPartsAfter[0];
146 $this->I['parts']['ATag_begin'] = $this->I['A1'];
147 $this->I['parts']['ATagBeforeWrap_begin'] = $wrapPartsBefore[0];
148 $this->I['parts']['title'] = $this->I['title'];
149 $this->I['parts']['ATagBeforeWrap_end'] = $wrapPartsBefore[1];
150 $this->I['parts']['ATag_end'] = $this->I['A2'];
151 $this->I['parts']['notATagBeforeWrap_end'] = $wrapPartsAfter[1];
152 }
153 $this->I['parts']['stdWrap2_end'] = $wrapPartsStdWrap[1];
154 $this->I['parts']['after'] = $this->getBeforeAfter('after');
155 // Passing I to a user function
156 if ($this->mconf['IProcFunc']) {
157 $this->I = $this->userProcess('IProcFunc', $this->I);
158 }
159 // Merge parts + beforeAllWrap
160 $this->I['theItem'] = implode('', $this->I['parts']);
161 $this->I['theItem'] = $this->extProc_beforeAllWrap($this->I['theItem'], $key);
162 // allWrap:
163 $allWrap = isset($this->I['val']['allWrap.']) ? $this->WMcObj->stdWrap($this->I['val']['allWrap'], $this->I['val']['allWrap.']) : $this->I['val']['allWrap'];
164 $this->I['theItem'] = $this->tmpl->wrap($this->I['theItem'], $allWrap);
165 if ($this->I['val']['subst_elementUid']) {
166 $this->I['theItem'] = str_replace('{elementUid}', $this->I['uid'], $this->I['theItem']);
167 }
168 // allStdWrap:
169 if (is_array($this->I['val']['allStdWrap.'])) {
170 $this->I['theItem'] = $this->WMcObj->stdWrap($this->I['theItem'], $this->I['val']['allStdWrap.']);
171 }
172 // Calling extra processing function
173 $this->extProc_afterLinking($key);
174 }
175 return $this->extProc_finish();
176 }
177 }
178
179 /**
180 * Generates the before* and after* images for TMENUs
181 *
182 * @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
183 * @return string The resulting HTML of the image, if any.
184 * @todo Define visibility
185 */
186 public function getBeforeAfter($pref) {
187 $res = '';
188 if ($imgInfo = $this->WMcObj->getImgResource($this->I['val'][$pref . 'Img'], $this->I['val'][$pref . 'Img.'])) {
189 $imgInfo[3] = \TYPO3\CMS\Core\Utility\GeneralUtility::png_to_gif_by_imagemagick($imgInfo[3]);
190 $theName = $this->imgNamePrefix . $this->I['uid'] . $this->I['INPfix'] . $pref;
191 $name = ' ' . $this->nameAttribute . '="' . $theName . '"';
192 $GLOBALS['TSFE']->imagesOnPage[] = $imgInfo[3];
193 $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')] : '') . \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::getBorderAttr(' border="0"');
194 if (!strstr($res, 'alt="')) {
195 // Adding alt attribute if not set.
196 $res .= ' alt=""';
197 }
198 $res .= ' />';
199 if ($this->I['val'][$pref . 'ImgLink']) {
200 $res = $this->I['A1'] . $res . $this->I['A2'];
201 }
202 }
203 $processedPref = isset($this->I['val'][$pref . '.']) ? $this->WMcObj->stdWrap($this->I['val'][$pref], $this->I['val'][$pref . '.']) : $this->I['val'][$pref];
204 if (isset($this->I['val'][$pref . 'Wrap'])) {
205 return $this->tmpl->wrap($res . $processedPref, $this->I['val'][$pref . 'Wrap']);
206 } else {
207 return $res . $processedPref;
208 }
209 }
210
211 /**
212 * Called right before the traversing of $this->result begins.
213 * Can be used for various initialization
214 *
215 * @return void
216 * @access private
217 * @see writeMenu()
218 * @todo Define visibility
219 */
220 public function extProc_init() {
221
222 }
223
224 /**
225 * Called right before the creation of the link for the menu item
226 *
227 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found
228 * @return void
229 * @access private
230 * @see writeMenu()
231 * @todo Define visibility
232 */
233 public function extProc_beforeLinking($key) {
234
235 }
236
237 /**
238 * 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.
239 * This function MUST set $this->WMresult.=[HTML for menu item] to add the generated menu item to the internal accumulation of items.
240 *
241 * @param integer Pointer to $this->menuArr[$key] where the current menu element record is found
242 * @return void
243 * @access private
244 * @see writeMenu()
245 * @todo Define visibility
246 */
247 public function extProc_afterLinking($key) {
248 // Add part to the accumulated result + fetch submenus
249 if (!$this->I['spacer']) {
250 $this->I['theItem'] .= $this->subMenu($this->I['uid'], $this->WMsubmenuObjSuffixes[$key]['sOSuffix']);
251 }
252 $part = isset($this->I['val']['wrapItemAndSub.']) ? $this->WMcObj->stdWrap($this->I['val']['wrapItemAndSub'], $this->I['val']['wrapItemAndSub.']) : $this->I['val']['wrapItemAndSub'];
253 $this->WMresult .= $part ? $this->tmpl->wrap($this->I['theItem'], $part) : $this->I['theItem'];
254 }
255
256 /**
257 * Called before the "allWrap" happens on the menu item.
258 *
259 * @param string $item The current content of the menu item, $this->I['theItem'], passed along.
260 * @param integer $key Pointer to $this->menuArr[$key] where the current menu element record is found
261 * @return string The modified version of $item, going back into $this->I['theItem']
262 * @access private
263 * @see writeMenu()
264 * @todo Define visibility
265 */
266 public function extProc_beforeAllWrap($item, $key) {
267 return $item;
268 }
269
270 /**
271 * Called before the writeMenu() function returns (only if a menu was generated)
272 *
273 * @return string The total menu content should be returned by this function
274 * @access private
275 * @see writeMenu()
276 * @todo Define visibility
277 */
278 public function extProc_finish() {
279 // stdWrap:
280 if (is_array($this->mconf['stdWrap.'])) {
281 $this->WMresult = $this->WMcObj->stdWrap($this->WMresult, $this->mconf['stdWrap.']);
282 }
283 return $this->tmpl->wrap($this->WMresult, $this->mconf['wrap']) . $this->WMextraScript;
284 }
285
286 }