3e29b4ebd1950040aaea92b9eba4916994a6595e
[Packages/TYPO3.CMS.git] / typo3 / sysext / recordlist / Classes / Browser / ElementBrowser.php
1 <?php
2 namespace TYPO3\CMS\Recordlist\Browser;
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 use TYPO3\CMS\Core\Resource\File;
31 use TYPO3\CMS\Core\Resource\Folder;
32 use TYPO3\CMS\Core\Utility\GeneralUtility;
33 use TYPO3\CMS\Backend\Utility\BackendUtility;
34 use TYPO3\CMS\Backend\Utility\IconUtility;
35
36 /**
37 * class for the Element Browser window.
38 *
39 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
40 */
41 class ElementBrowser {
42
43 /**
44 * Optional instance of a record list that TBE_expandPage() should
45 * use to render the records in a page
46 *
47 * @var \TYPO3\CMS\Backend\RecordList\ElementBrowserRecordList
48 */
49 protected $recordList = NULL;
50
51 /**
52 * Current site URL (Frontend)
53 *
54 * @var string
55 * @internal
56 */
57 public $siteURL;
58
59 /**
60 * the script to link to
61 *
62 * @todo Define visibility
63 */
64 public $thisScript;
65
66 /**
67 * RTE specific TSconfig
68 *
69 * @todo Define visibility
70 */
71 public $thisConfig;
72
73 /**
74 * Target (RTE specific)
75 *
76 * @todo Define visibility
77 */
78 public $setTarget;
79
80 /**
81 * CSS Class (RTE specific)
82 *
83 * @todo Define visibility
84 */
85 public $setClass;
86
87 /**
88 * title (RTE specific)
89 *
90 * @todo Define visibility
91 */
92 public $setTitle;
93
94 /**
95 * @todo Define visibility
96 */
97 public $setParams;
98
99 /**
100 * Backend template object
101 *
102 * @todo Define visibility
103 * @var \TYPO3\CMS\Backend\Template\DocumentTemplate
104 */
105 public $doc;
106
107 /**
108 * Holds information about files
109 *
110 * @todo Define visibility
111 */
112 public $elements = array();
113
114 /**
115 * The mode determines the main kind of output from the element browser.
116 * There are these options for values: rte, db, file, filedrag, wizard.
117 * "rte" will show the link selector for the Rich Text Editor (see main_rte())
118 * "db" will allow you to browse for pages or records in the page tree (for TCEforms, see main_db())
119 * "file"/"filedrag" will allow you to browse for files or folders in the folder mounts (for TCEforms, main_file())
120 * "wizard" will allow you to browse for links (like "rte") which are passed back to TCEforms (see main_rte(1))
121 *
122 * @see main()
123 * @todo Define visibility
124 * @var string
125 */
126 public $mode;
127
128 /**
129 * Link selector action.
130 * page,file,url,mail,spec are allowed values.
131 * These are only important with the link selector function and in that case they switch
132 * between the various menu options.
133 *
134 * @todo Define visibility
135 */
136 public $act;
137
138 /**
139 * When you click a page title/expand icon to see the content of a certain page, this
140 * value will contain that value (the ID of the expanded page). If the value is NOT set,
141 * then it will be restored from the module session data (see main(), mode="db")
142 *
143 * @todo Define visibility
144 */
145 public $expandPage;
146
147 /**
148 * When you click a folder name/expand icon to see the content of a certain file folder,
149 * this value will contain that value (the path of the expanded file folder). If the
150 * value is NOT set, then it will be restored from the module session data (see main(),
151 * mode="file"/"filedrag"). Example value: "/www/htdocs/typo3/32/3dsplm/fileadmin/css/"
152 *
153 * @todo Define visibility
154 * @var string
155 */
156 public $expandFolder;
157
158 /**
159 * the folder object of a parent folder that was selected
160 *
161 * @var Folder
162 */
163 protected $selectedFolder;
164
165 /**
166 * TYPO3 Element Browser, wizard mode parameters. There is a heap of parameters there,
167 * better debug() them out if you need something... :-)
168 *
169 * @todo Define visibility
170 * @var array
171 */
172 public $P;
173
174 /**
175 * Active with TYPO3 Element Browser: Contains the name of the form field for which this window
176 * opens - thus allows us to make references back to the main window in which the form is.
177 * Example value: "data[pages][39][bodytext]|||tt_content|"
178 * or "data[tt_content][NEW3fba56fde763d][image]|||gif,jpg,jpeg,tif,bmp,pcx,tga,png,pdf,ai|"
179 *
180 * Values:
181 * 0: form field name reference, eg. "data[tt_content][123][image]"
182 * 1: htmlArea RTE parameters: editorNo:contentTypo3Language:contentTypo3Charset
183 * 2: RTE config parameters: RTEtsConfigParams
184 * 3: allowed types. Eg. "tt_content" or "gif,jpg,jpeg,tif,bmp,pcx,tga,png,pdf,ai"
185 * 4: IRRE uniqueness: target level object-id to perform actions/checks on, eg. "data[79][tt_address][1][<field>][<foreign_table>]"
186 * 5: IRRE uniqueness: name of function in opener window that checks if element is already used, eg. "inline.checkUniqueElement"
187 * 6: IRRE uniqueness: name of function in opener window that performs some additional(!) action, eg. "inline.setUniqueElement"
188 * 7: IRRE uniqueness: name of function in opener window that performs action instead of using addElement/insertElement, eg. "inline.importElement"
189 *
190 * $pArr = explode('|', $this->bparams);
191 * $formFieldName = $pArr[0];
192 * $allowedTablesOrFileTypes = $pArr[3];
193 *
194 * @todo Define visibility
195 * @var string
196 */
197 public $bparams;
198
199 /**
200 * Used with the Rich Text Editor.
201 * Example value: "tt_content:NEW3fba58c969f5c:bodytext:23:text:23:"
202 *
203 * @todo Define visibility
204 * @var string
205 */
206 public $RTEtsConfigParams;
207
208 /**
209 * Plus/Minus icon value. Used by the tree class to open/close notes on the trees.
210 *
211 * @todo Define visibility
212 */
213 public $PM;
214
215 /**
216 * Pointer, used when browsing a long list of records etc.
217 *
218 * @todo Define visibility
219 */
220 public $pointer;
221
222 /**
223 * Used with the link selector: Contains the GET input information about the CURRENT link
224 * in the RTE/TCEform field. This consists of "href", "target" and "title" keys.
225 * This information is passed around in links.
226 *
227 * @todo Define visibility
228 * @var array
229 */
230 public $curUrlArray;
231
232 /**
233 * Used with the link selector: Contains a processed version of the input values from curUrlInfo.
234 * This is splitted into pageid, content element id, label value etc.
235 * This is used for the internal processing of that information.
236 *
237 * @todo Define visibility
238 * @var array
239 */
240 public $curUrlInfo;
241
242 /**
243 * array which holds hook objects (initialised in init())
244 * @var \TYPO3\CMS\Core\ElementBrowser\ElementBrowserHookInterface[]
245 */
246 protected $hookObjects = array();
247
248 /**
249 * @var \TYPO3\CMS\Core\Utility\File\BasicFileUtility
250 */
251 public $fileProcessor;
252
253 /**
254 * Sets the script url depending on being a module or script request
255 */
256 protected function determineScriptUrl() {
257 if ($moduleName = GeneralUtility::_GP('M')) {
258 $this->thisScript = BackendUtility::getModuleUrl($moduleName);
259 } else {
260 $this->thisScript = GeneralUtility::getIndpEnv('SCRIPT_NAME');
261 }
262 }
263
264 /**
265 * @return string
266 */
267 protected function getThisScript() {
268 return strpos($this->thisScript, '?') === FALSE ? $this->thisScript . '?' : $this->thisScript . '&';
269 }
270
271 /**
272 * Constructor:
273 * Initializes a lot of variables, setting JavaScript functions in header etc.
274 *
275 * @return void
276 * @todo Define visibility
277 * @throws \UnexpectedValueException
278 */
279 public function init() {
280 $this->initVariables();
281
282 $this->RTEtsConfigParams = GeneralUtility::_GP('RTEtsConfigParams');
283 $this->initConfiguration();
284 $this->initDocumentTemplate();
285 // init hook objects:
286 $this->initHookObjects('typo3/class.browse_links.php');
287
288 $this->initCurrentUrl();
289
290 // Determine nature of current url:
291 $this->act = GeneralUtility::_GP('act');
292 if (!$this->act) {
293 $this->act = $this->curUrlInfo['act'];
294 }
295
296 // Initializing the target value (RTE)
297 $this->setTarget = $this->curUrlArray['target'] != '-' ? rawurlencode($this->curUrlArray['target']) : '';
298 if ($this->thisConfig['defaultLinkTarget'] && !isset($this->curUrlArray['target'])) {
299 $this->setTarget = $this->thisConfig['defaultLinkTarget'];
300 }
301 // Initializing the class value (RTE)
302 $this->setClass = $this->curUrlArray['class'] != '-' ? rawurlencode($this->curUrlArray['class']) : '';
303 // Initializing the title value (RTE)
304 $this->setTitle = $this->curUrlArray['title'] != '-' ? rawurlencode($this->curUrlArray['title']) : '';
305 // Initializing the params value
306 $this->setParams = $this->curUrlArray['params'] != '-' ? rawurlencode($this->curUrlArray['params']) : '';
307
308 // Finally, add the accumulated JavaScript to the template object:
309 // also unset the default jumpToUrl() function before
310 unset($this->doc->JScodeArray['jumpToUrl']);
311 $this->doc->JScode .= $this->doc->wrapScriptTags($this->getJSCode());
312 }
313
314 /**
315 * Initialize class variables
316 *
317 * @return void
318 */
319 public function initVariables() {
320 // Main GPvars:
321 $this->pointer = GeneralUtility::_GP('pointer');
322 $this->bparams = GeneralUtility::_GP('bparams');
323 $this->P = GeneralUtility::_GP('P');
324 $this->expandPage = GeneralUtility::_GP('expandPage');
325 $this->expandFolder = GeneralUtility::_GP('expandFolder');
326 $this->PM = GeneralUtility::_GP('PM');
327
328 // Site URL
329 // Current site url
330 $this->siteURL = GeneralUtility::getIndpEnv('TYPO3_SITE_URL');
331 $this->determineScriptUrl();
332
333 // Find "mode"
334 $this->mode = GeneralUtility::_GP('mode');
335 if (!$this->mode) {
336 $this->mode = 'rte';
337 }
338
339 // Init fileProcessor
340 $this->fileProcessor = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Utility\\File\\BasicFileUtility');
341 $this->fileProcessor->init(array(), $GLOBALS['TYPO3_CONF_VARS']['BE']['fileExtensions']);
342 }
343
344 /**
345 * Initializes the configuration variables
346 *
347 * @return void
348 */
349 public function initConfiguration() {
350 // Rich Text Editor specific configuration:
351 if ((string) $this->mode === 'rte') {
352 $this->thisConfig = $this->getRTEConfig();
353 }
354 }
355
356 /**
357 * Initialize document template object
358 *
359 * @return void
360 */
361 protected function initDocumentTemplate() {
362 // Creating backend template object:
363 $this->doc = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\Template\\DocumentTemplate');
364 $this->doc->bodyTagId = 'typo3-browse-links-php';
365 $this->doc->backPath = $GLOBALS['BACK_PATH'];
366 // Load the Prototype library and browse_links.js
367 $this->doc->getPageRenderer()->loadPrototype();
368 $this->doc->loadJavascriptLib('js/browse_links.js');
369 $this->doc->loadJavascriptLib('js/tree.js');
370 $this->doc->getPageRenderer()->addInlineSetting('Tree.SC_alt_db_navframe', 'ajaxUrl', BackendUtility::getAjaxUrl('SC_alt_db_navframe::expandCollapse'));
371 $this->doc->getPageRenderer()->addInlineSetting('Tree.SC_alt_file_navframe', 'ajaxUrl', BackendUtility::getAjaxUrl('SC_alt_file_navframe::expandCollapse'));
372 }
373
374 /**
375 * Initialize hook objects implementing the interface
376 *
377 * @param string $hookKey the hook key
378 * @throws \UnexpectedValueException
379 * @return void
380 */
381 protected function initHookObjects($hookKey) {
382 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][$hookKey]['browseLinksHook'])) {
383 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][$hookKey]['browseLinksHook'] as $classData) {
384 $processObject = GeneralUtility::getUserObj($classData);
385 if (!$processObject instanceof \TYPO3\CMS\Core\ElementBrowser\ElementBrowserHookInterface) {
386 throw new \UnexpectedValueException('$processObject must implement interface TYPO3\\CMS\\Core\\ElementBrowser\\ElementBrowserHookInterface', 1195039394);
387 }
388 $parameters = array();
389 $processObject->init($this, $parameters);
390 $this->hookObjects[] = $processObject;
391 }
392 }
393 }
394
395 /**
396 * Initialize $this->curUrlArray and $this->curUrlInfo based on script parameters
397 *
398 * @return void
399 */
400 protected function initCurrentUrl() {
401 // CurrentUrl - the current link url must be passed around if it exists
402 if ($this->mode == 'wizard') {
403 $currentValues = GeneralUtility::trimExplode(LF, trim($this->P['currentValue']));
404 if (count($currentValues) > 0) {
405 $currentValue = array_pop($currentValues);
406 } else {
407 $currentValue = '';
408 }
409 $currentLinkParts = GeneralUtility::unQuoteFilenames($currentValue, TRUE);
410 $initialCurUrlArray = array(
411 'href' => $currentLinkParts[0],
412 'target' => $currentLinkParts[1],
413 'class' => $currentLinkParts[2],
414 'title' => $currentLinkParts[3],
415 'params' => $currentLinkParts[4]
416 );
417 $this->curUrlArray = is_array(GeneralUtility::_GP('curUrl'))
418 ? array_merge($initialCurUrlArray, GeneralUtility::_GP('curUrl'))
419 : $initialCurUrlArray;
420 // Additional fields for page links
421 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.browse_links.php']['extendUrlArray'])
422 && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.browse_links.php']['extendUrlArray'])
423 ) {
424 $conf = array();
425 $_params = array(
426 'conf' => &$conf,
427 'linkParts' => $currentLinkParts
428 );
429 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.browse_links.php']['extendUrlArray'] as $objRef) {
430 $processor =& GeneralUtility::getUserObj($objRef);
431 $processor->extendUrlArray($_params, $this);
432 }
433 }
434 $this->curUrlInfo = $this->parseCurUrl($this->siteURL . '?id=' . $this->curUrlArray['href'], $this->siteURL);
435 // pageid == 0 means that this is not an internal (page) link
436 if ($this->curUrlInfo['pageid'] == 0 && $this->curUrlArray['href']) {
437 // Check if there is the FAL API
438 if (GeneralUtility::isFirstPartOfStr($this->curUrlArray['href'], 'file:')) {
439 $this->curUrlInfo = $this->parseCurUrl($this->curUrlArray['href'], $this->siteURL);
440 // Remove the "file:" prefix
441 $currentLinkParts[0] = rawurldecode(substr($this->curUrlArray['href'], 5));
442 } elseif (file_exists(PATH_site . rawurldecode($this->curUrlArray['href']))) {
443 if (GeneralUtility::isFirstPartOfStr($this->curUrlArray['href'], PATH_site)) {
444 $currentLinkParts[0] = \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix($this->curUrlArray['href']);
445 }
446 $this->curUrlInfo = $this->parseCurUrl($this->siteURL . $this->curUrlArray['href'], $this->siteURL);
447 } elseif (strstr($this->curUrlArray['href'], '@')) {
448 // check for email link
449 if (GeneralUtility::isFirstPartOfStr($this->curUrlArray['href'], 'mailto:')) {
450 $currentLinkParts[0] = substr($this->curUrlArray['href'], 7);
451 }
452 $this->curUrlInfo = $this->parseCurUrl('mailto:' . $this->curUrlArray['href'], $this->siteURL);
453 } else {
454 // nothing of the above. this is an external link
455 if (strpos($this->curUrlArray['href'], '://') === FALSE) {
456 $currentLinkParts[0] = 'http://' . $this->curUrlArray['href'];
457 }
458 $this->curUrlInfo = $this->parseCurUrl($currentLinkParts[0], $this->siteURL);
459 }
460 } elseif (!$this->curUrlArray['href']) {
461 $this->curUrlInfo = array();
462 $this->act = 'page';
463 } else {
464 $this->curUrlInfo = $this->parseCurUrl($this->siteURL . '?id=' . $this->curUrlArray['href'], $this->siteURL);
465 }
466 } else {
467 $this->curUrlArray = GeneralUtility::_GP('curUrl');
468 if ($this->curUrlArray['all']) {
469 $this->curUrlArray = GeneralUtility::get_tag_attributes($this->curUrlArray['all']);
470 }
471 $this->curUrlInfo = $this->parseCurUrl($this->curUrlArray['href'], $this->siteURL);
472 }
473 }
474
475 /**
476 * Get the RTE configuration from Page TSConfig
477 *
478 * @return array RTE configuration array
479 */
480 protected function getRTEConfig() {
481 $RTEtsConfigParts = explode(':', $this->RTEtsConfigParams);
482 $RTEsetup = $GLOBALS['BE_USER']->getTSConfig('RTE', BackendUtility::getPagesTSconfig($RTEtsConfigParts[5]));
483 return BackendUtility::RTEsetup($RTEsetup['properties'], $RTEtsConfigParts[0], $RTEtsConfigParts[2], $RTEtsConfigParts[4]);
484 }
485
486 /**
487 * Generate JS code to be used on the link insert/modify dialogue
488 *
489 * @return string the generated JS code
490 * @todo Define visibility
491 */
492 public function getJsCode() {
493 // Rich Text Editor specific configuration:
494 $addPassOnParams = '';
495 if ((string) $this->mode == 'rte') {
496 $addPassOnParams .= '&RTEtsConfigParams=' . rawurlencode($this->RTEtsConfigParams);
497 }
498 // BEGIN accumulation of header JavaScript:
499 $JScode = '
500 // This JavaScript is primarily for RTE/Link. jumpToUrl is used in the other cases as well...
501 var add_href=' . GeneralUtility::quoteJSvalue($this->curUrlArray['href'] ? '&curUrl[href]=' . rawurlencode($this->curUrlArray['href']) : '') . ';
502 var add_target=' . GeneralUtility::quoteJSvalue($this->setTarget ? '&curUrl[target]=' . rawurlencode($this->setTarget) : '') . ';
503 var add_class=' . GeneralUtility::quoteJSvalue($this->setClass ? '&curUrl[class]=' . rawurlencode($this->setClass) : '') . ';
504 var add_title=' . GeneralUtility::quoteJSvalue($this->setTitle ? '&curUrl[title]=' . rawurlencode($this->setTitle) : '') . ';
505 var add_params=' . GeneralUtility::quoteJSvalue($this->bparams ? '&bparams=' . rawurlencode($this->bparams) : '') . ';
506
507 var cur_href=' . GeneralUtility::quoteJSvalue($this->curUrlArray['href'] ?: '') . ';
508 var cur_target=' . GeneralUtility::quoteJSvalue($this->setTarget ?: '') . ';
509 var cur_class=' . GeneralUtility::quoteJSvalue($this->setClass ?: '') . ';
510 var cur_title=' . GeneralUtility::quoteJSvalue($this->setTitle ?: '') . ';
511 var cur_params=' . GeneralUtility::quoteJSvalue($this->setParams ?: '') . ';
512
513 function browse_links_setTarget(target) { //
514 cur_target=target;
515 add_target="&curUrl[target]="+escape(target);
516 }
517 function browse_links_setClass(cssClass) { //
518 cur_class = cssClass;
519 add_class = "&curUrl[class]=" + escape(cssClass);
520 }
521 function browse_links_setTitle(title) { //
522 cur_title=title;
523 add_title="&curUrl[title]="+escape(title);
524 }
525 function browse_links_setValue(value) { //
526 cur_href=value;
527 add_href="&curUrl[href]="+value;
528 }
529 function browse_links_setParams(params) { //
530 cur_params=params;
531 add_params="&curUrl[params]="+escape(params);
532 }
533 ';
534 // Functions used, if the link selector is in wizard mode (= TCEforms fields)
535 if ($this->mode == 'wizard') {
536 if (!$this->areFieldChangeFunctionsValid() && !$this->areFieldChangeFunctionsValid(TRUE)) {
537 $this->P['fieldChangeFunc'] = array();
538 }
539 unset($this->P['fieldChangeFunc']['alert']);
540 $update = '';
541 foreach ($this->P['fieldChangeFunc'] as $v) {
542 $update .= '
543 window.opener.' . $v;
544 }
545 $P2 = array();
546 $P2['itemName'] = $this->P['itemName'];
547 $P2['formName'] = $this->P['formName'];
548 $P2['fieldChangeFunc'] = $this->P['fieldChangeFunc'];
549 $P2['fieldChangeFuncHash'] = GeneralUtility::hmac(serialize($this->P['fieldChangeFunc']));
550 $P2['params']['allowedExtensions'] = isset($this->P['params']['allowedExtensions']) ? $this->P['params']['allowedExtensions'] : '';
551 $P2['params']['blindLinkOptions'] = isset($this->P['params']['blindLinkOptions']) ? $this->P['params']['blindLinkOptions'] : '';
552 $P2['params']['blindLinkFields'] = isset($this->P['params']['blindLinkFields']) ? $this->P['params']['blindLinkFields']: '';
553 $addPassOnParams .= GeneralUtility::implodeArrayForUrl('P', $P2);
554 $JScode .= '
555 function link_typo3Page(id,anchor) { //
556 updateValueInMainForm(id + (anchor ? anchor : ""));
557 close();
558 return false;
559 }
560 function link_folder(folder) { //
561 updateValueInMainForm(folder);
562 close();
563 return false;
564 }
565 function link_current() { //
566 if (cur_href!="http://" && cur_href!="mailto:") {
567 returnBeforeCleaned = cur_href;
568 if (returnBeforeCleaned.substr(0, 7) == "http://") {
569 returnToMainFormValue = returnBeforeCleaned.substr(7);
570 } else if (returnBeforeCleaned.substr(0, 7) == "mailto:") {
571 if (returnBeforeCleaned.substr(0, 14) == "mailto:mailto:") {
572 returnToMainFormValue = returnBeforeCleaned.substr(14);
573 } else {
574 returnToMainFormValue = returnBeforeCleaned.substr(7);
575 }
576 } else {
577 returnToMainFormValue = returnBeforeCleaned;
578 }
579 updateValueInMainForm(returnToMainFormValue);
580 close();
581 }
582 return false;
583 }
584 function checkReference() { //
585 if (window.opener && window.opener.document && window.opener.document.' . $this->P['formName']
586 . ' && window.opener.document.' . $this->P['formName'] . '["' . $this->P['itemName'] . '"] ) {
587 return window.opener.document.' . $this->P['formName'] . '["' . $this->P['itemName'] . '"];
588 } else {
589 close();
590 }
591 }
592 function updateValueInMainForm(input) { //
593 var field = checkReference();
594 if (field) {
595 if (cur_target == "" && (cur_class != "" || cur_title != "" || cur_params != "")) {
596 cur_target = "-";
597 }
598 if (cur_class == "" && (cur_title != "" || cur_params != "")) {
599 cur_class = "-";
600 }
601 cur_class = cur_class.replace(/[\'\\"]/g, "");
602 if (cur_class.indexOf(" ") != -1) {
603 cur_class = "\\"" + cur_class + "\\"";
604 }
605 if (cur_title == "" && cur_params != "") {
606 cur_title = "-";
607 }
608 cur_title = cur_title.replace(/(^\\")|(\\"$)/g, "");
609 if (cur_title.indexOf(" ") != -1) {
610 cur_title = "\\"" + cur_title + "\\"";
611 }
612 if (cur_params) {
613 cur_params = cur_params.replace(/\\bid\\=.*?(\\&|$)/, "");
614 }
615 input = input + " " + cur_target + " " + cur_class + " " + cur_title + " " + cur_params;
616 if(field.value && field.className.search(/textarea/) != -1) {
617 field.value += "\\n" + input;
618 } else {
619 field.value = input;
620 }
621 ' . $update . '
622 }
623 }
624 ';
625 } else {
626 // Functions used, if the link selector is in RTE mode:
627 $JScode .= '
628 function link_typo3Page(id,anchor) { //
629 var theLink = \'' . $this->siteURL . '?id=\'+id+(anchor?anchor:"");
630 self.parent.parent.renderPopup_addLink(theLink, cur_target, cur_class, cur_title);
631 return false;
632 }
633 function link_folder(folder) { //
634 var theLink = \'' . $this->siteURL . '\'+folder;
635 self.parent.parent.renderPopup_addLink(theLink, cur_target, cur_class, cur_title);
636 return false;
637 }
638 function link_spec(theLink) { //
639 self.parent.parent.renderPopup_addLink(theLink, cur_target, cur_class, cur_title);
640 return false;
641 }
642 function link_current() { //
643 if (cur_href!="http://" && cur_href!="mailto:") {
644 self.parent.parent.renderPopup_addLink(cur_href, cur_target, cur_class, cur_title);
645 }
646 return false;
647 }
648 ';
649 }
650 // General "jumpToUrl" function:
651 $JScode .= '
652 function jumpToUrl(URL,anchor) { //
653 var add_act = URL.indexOf("act=")==-1 ? "&act=' . $this->act . '" : "";
654 var add_mode = URL.indexOf("mode=")==-1 ? "&mode=' . $this->mode . '" : "";
655 var theLocation = URL + add_act + add_mode + add_href + add_target + add_class + add_title + add_params'
656 . ($addPassOnParams ? '+' . GeneralUtility::quoteJSvalue($addPassOnParams) : '')
657 . '+(typeof(anchor)=="string"?anchor:"");
658 window.location.href = theLocation;
659 return false;
660 }
661 ';
662 /**
663 * Splits parts of $this->bparams
664 *
665 * @see $bparams
666 */
667 $pArr = explode('|', $this->bparams);
668 // This is JavaScript especially for the TBE Element Browser!
669 $formFieldName = 'data[' . $pArr[0] . '][' . $pArr[1] . '][' . $pArr[2] . ']';
670 // insertElement - Call check function (e.g. for uniqueness handling):
671 $JScodeCheck = '';
672 if ($pArr[4] && $pArr[5]) {
673 $JScodeCheck = '
674 // Call a check function in the opener window (e.g. for uniqueness handling):
675 if (parent.window.opener) {
676 var res = parent.window.opener.' . $pArr[5] . '("' . addslashes($pArr[4]) . '",table,uid,type);
677 if (!res.passed) {
678 if (res.message) alert(res.message);
679 performAction = false;
680 }
681 } else {
682 alert("Error - reference to main window is not set properly!");
683 parent.close();
684 }
685 ';
686 }
687 // insertElement - Call helper function:
688 $JScodeHelper = '';
689 if ($pArr[4] && $pArr[6]) {
690 $JScodeHelper = '
691 // Call helper function to manage data in the opener window:
692 if (parent.window.opener) {
693 parent.window.opener.' . $pArr[6] . '("' . addslashes($pArr[4]) . '",table,uid,type,"' . addslashes($pArr[0]) . '");
694 } else {
695 alert("Error - reference to main window is not set properly!");
696 parent.close();
697 }
698 ';
699 }
700 // insertElement - perform action commands:
701 $JScodeActionMultiple = '';
702 if ($pArr[4] && $pArr[7]) {
703 // Call user defined action function:
704 $JScodeAction = '
705 if (parent.window.opener) {
706 parent.window.opener.' . $pArr[7] . '("' . addslashes($pArr[4]) . '",table,uid,type);
707 if (close) { focusOpenerAndClose(close); }
708 } else {
709 alert("Error - reference to main window is not set properly!");
710 if (close) { parent.close(); }
711 }
712 ';
713 $JScodeActionMultiple = '
714 // Call helper function to manage data in the opener window:
715 if (parent.window.opener) {
716 parent.window.opener.' . $pArr[7] . 'Multiple("' . addslashes($pArr[4]) . '",table,uid,type,"'
717 . addslashes($pArr[0]) . '");
718 } else {
719 alert("Error - reference to main window is not set properly!");
720 parent.close();
721 }
722 ';
723 } elseif ($pArr[0] && !$pArr[1] && !$pArr[2]) {
724 $JScodeAction = '
725 addElement(filename,table+"_"+uid,fp,close);
726 ';
727 } else {
728 $JScodeAction = '
729 if (setReferences()) {
730 parent.window.opener.group_change("add","' . $pArr[0] . '","' . $pArr[1] . '","' . $pArr[2]
731 . '",elRef,targetDoc);
732 } else {
733 alert("Error - reference to main window is not set properly!");
734 }
735 focusOpenerAndClose(close);
736 ';
737 }
738 $JScode .= '
739 var elRef="";
740 var targetDoc="";
741
742 function launchView(url) { //
743 var thePreviewWindow="";
744 thePreviewWindow = window.open("' . $GLOBALS['BACK_PATH'] . 'show_item.php?table="+url,"ShowItem",'
745 . '"height=300,width=410,status=0,menubar=0,resizable=0,location=0,directories=0,scrollbars=1,toolbar=0");
746 if (thePreviewWindow && thePreviewWindow.focus) {
747 thePreviewWindow.focus();
748 }
749 }
750 function setReferences() { //
751 if (parent.window.opener && parent.window.opener.content && parent.window.opener.content.document.editform'
752 . '&& parent.window.opener.content.document.editform["' . $formFieldName . '"]) {
753 targetDoc = parent.window.opener.content.document;
754 elRef = targetDoc.editform["' . $formFieldName . '"];
755 return true;
756 } else {
757 return false;
758 }
759 }
760 function insertElement(table, uid, type, filename, fp, filetype, imagefile, action, close) { //
761 var performAction = true;
762 ' . $JScodeCheck . '
763 // Call performing function and finish this action:
764 if (performAction) {
765 ' . $JScodeHelper . $JScodeAction . '
766 }
767 return false;
768 }
769 function insertMultiple(table, uid) {
770 var type = "";
771 ' . $JScodeActionMultiple . '
772 return false;
773 }
774 function addElement(elName, elValue, altElValue, close) { //
775 if (parent.window.opener && parent.window.opener.setFormValueFromBrowseWin) {
776 parent.window.opener.setFormValueFromBrowseWin("' . $pArr[0] . '",altElValue?altElValue:elValue,elName);
777 focusOpenerAndClose(close);
778 } else {
779 alert("Error - reference to main window is not set properly!");
780 parent.close();
781 }
782 }
783 function focusOpenerAndClose(close) { //
784 BrowseLinks.focusOpenerAndClose(close);
785 }
786 ';
787 // extends JavaScript code
788 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.browse_links.php']['extendJScode'])
789 && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.browse_links.php']['extendJScode'])
790 ) {
791 $conf = array();
792 $update = '';
793 $_params = array(
794 'conf' => &$conf,
795 'wizardUpdate' => $update,
796 'addPassOnParams' => $addPassOnParams
797 );
798 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.browse_links.php']['extendJScode'] as $objRef) {
799 $processor =& GeneralUtility::getUserObj($objRef);
800 $JScode .= $processor->extendJScode($_params, $this);
801 }
802 }
803 return $JScode;
804 }
805
806 /**
807 * Session data for this class can be set from outside with this method.
808 * Call after init()
809 *
810 * @param array $data Session data array
811 * @return array Session data and boolean which indicates that data needs to be stored in session because it's changed
812 * @todo Define visibility
813 */
814 public function processSessionData($data) {
815 $store = FALSE;
816 switch ((string) $this->mode) {
817 case 'db':
818 if (isset($this->expandPage)) {
819 $data['expandPage'] = $this->expandPage;
820 $store = TRUE;
821 } else {
822 $this->expandPage = $data['expandPage'];
823 }
824 break;
825 case 'file':
826
827 case 'filedrag':
828
829 case 'folder':
830 if (isset($this->expandFolder)) {
831 $data['expandFolder'] = $this->expandFolder;
832 $store = TRUE;
833 } else {
834 $this->expandFolder = $data['expandFolder'];
835 }
836 break;
837 }
838 return array($data, $store);
839 }
840
841 /******************************************************************
842 *
843 * Main functions
844 *
845 ******************************************************************/
846 /**
847 * Rich Text Editor (RTE) link selector (MAIN function)
848 * Generates the link selector for the Rich Text Editor.
849 * Can also be used to select links for the TCEforms (see $wiz)
850 *
851 * @param boolean $wiz If set, the "remove link" is not shown in the menu: Used for the "Select link" wizard which is used by the TCEforms
852 * @return string Modified content variable.
853 * @todo Define visibility
854 */
855 public function main_rte($wiz = FALSE) {
856 // Starting content:
857 $content = $this->doc->startPage('RTE link');
858
859 // Initializing the action value, possibly removing blinded values etc:
860 $blindLinkOptions = isset($this->thisConfig['blindLinkOptions'])
861 ? GeneralUtility::trimExplode(',', $this->thisConfig['blindLinkOptions'], TRUE)
862 : array();
863 $pBlindLinkOptions = isset($this->P['params']['blindLinkOptions'])
864 ? GeneralUtility::trimExplode(',', $this->P['params']['blindLinkOptions'])
865 : array();
866 $allowedItems = array_diff(array('page', 'file', 'folder', 'url', 'mail', 'spec'), $blindLinkOptions, $pBlindLinkOptions);
867
868 // Call hook for extra options
869 foreach ($this->hookObjects as $hookObject) {
870 $allowedItems = $hookObject->addAllowedItems($allowedItems);
871 }
872
873 // Removing link fields if configured
874 $blindLinkFields = isset($this->thisConfig['blindLinkFields'])
875 ? GeneralUtility::trimExplode(',', $this->thisConfig['blindLinkFields'], TRUE)
876 : array();
877 $pBlindLinkFields = isset($this->P['params']['blindLinkFields'])
878 ? GeneralUtility::trimExplode(',', $this->P['params']['blindLinkFields'], TRUE)
879 : array();
880 $allowedFields = array_diff(array('target', 'title', 'class', 'params'), $blindLinkFields, $pBlindLinkFields);
881
882 // If $this->act is not allowed, default to first allowed
883 if (!in_array($this->act, $allowedItems)) {
884 $this->act = reset($allowedItems);
885 }
886 // Making menu in top:
887 $menuDef = array();
888 if (!$wiz) {
889 $menuDef['removeLink']['isActive'] = $this->act == 'removeLink';
890 $menuDef['removeLink']['label'] = $GLOBALS['LANG']->getLL('removeLink', TRUE);
891 $menuDef['removeLink']['url'] = '#';
892 $menuDef['removeLink']['addParams'] = 'onclick="self.parent.parent.renderPopup_unLink();return false;"';
893 }
894 if (in_array('page', $allowedItems)) {
895 $menuDef['page']['isActive'] = $this->act == 'page';
896 $menuDef['page']['label'] = $GLOBALS['LANG']->getLL('page', TRUE);
897 $menuDef['page']['url'] = '#';
898 $menuDef['page']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue($this->getThisScript() . 'act=page') . ');return false;"';
899 }
900 if (in_array('file', $allowedItems)) {
901 $menuDef['file']['isActive'] = $this->act == 'file';
902 $menuDef['file']['label'] = $GLOBALS['LANG']->getLL('file', TRUE);
903 $menuDef['file']['url'] = '#';
904 $menuDef['file']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue($this->getThisScript() . 'act=file') . ');return false;"';
905 }
906 if (in_array('folder', $allowedItems)) {
907 $menuDef['folder']['isActive'] = $this->act == 'folder';
908 $menuDef['folder']['label'] = $GLOBALS['LANG']->getLL('folder', TRUE);
909 $menuDef['folder']['url'] = '#';
910 $menuDef['folder']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue($this->getThisScript() . 'act=folder') . ');return false;"';
911 }
912 if (in_array('url', $allowedItems)) {
913 $menuDef['url']['isActive'] = $this->act == 'url';
914 $menuDef['url']['label'] = $GLOBALS['LANG']->getLL('extUrl', TRUE);
915 $menuDef['url']['url'] = '#';
916 $menuDef['url']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue($this->getThisScript() . 'act=url') . ');return false;"';
917 }
918 if (in_array('mail', $allowedItems)) {
919 $menuDef['mail']['isActive'] = $this->act == 'mail';
920 $menuDef['mail']['label'] = $GLOBALS['LANG']->getLL('email', TRUE);
921 $menuDef['mail']['url'] = '#';
922 $menuDef['mail']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue($this->getThisScript() . 'act=mail') . ');return false;"';
923 }
924 if (is_array($this->thisConfig['userLinks.']) && in_array('spec', $allowedItems)) {
925 $menuDef['spec']['isActive'] = $this->act == 'spec';
926 $menuDef['spec']['label'] = $GLOBALS['LANG']->getLL('special', TRUE);
927 $menuDef['spec']['url'] = '#';
928 $menuDef['spec']['addParams'] = 'onclick="jumpToUrl(' . GeneralUtility::quoteJSvalue($this->getThisScript() . 'act=spec') . ');return false;"';
929 }
930 // Call hook for extra options
931 foreach ($this->hookObjects as $hookObject) {
932 $menuDef = $hookObject->modifyMenuDefinition($menuDef);
933 }
934 $content .= $this->doc->getTabMenuRaw($menuDef);
935 // Adding the menu and header to the top of page:
936 $content .= $this->printCurrentUrl($this->curUrlInfo['info']) . '<br />';
937 // Depending on the current action we will create the actual module content for selecting a link:
938 switch ($this->act) {
939 case 'mail':
940 $extUrl = '
941
942 <!--
943 Enter mail address:
944 -->
945 <form action="" name="lurlform" id="lurlform">
946 <table border="0" cellpadding="2" cellspacing="1" id="typo3-linkMail">
947 <tr>
948 <td style="width: 96px;">' . $GLOBALS['LANG']->getLL('emailAddress', TRUE) . ':</td>
949 <td><input type="text" name="lemail"' . $this->doc->formWidth(20) . ' value="'
950 . htmlspecialchars(($this->curUrlInfo['act'] == 'mail' ? $this->curUrlInfo['info'] : ''))
951 . '" /> ' . '<input type="submit" value="' . $GLOBALS['LANG']->getLL('setLink', TRUE)
952 . '" onclick="browse_links_setTarget(\'\');browse_links_setValue(\'mailto:\'+'
953 . 'document.lurlform.lemail.value); return link_current();" /></td>
954 </tr>
955 </table>
956 </form>';
957 $content .= $extUrl;
958 break;
959 case 'url':
960 $extUrl = '
961
962 <!--
963 Enter External URL:
964 -->
965 <form action="" name="lurlform" id="lurlform">
966 <table border="0" cellpadding="2" cellspacing="1" id="typo3-linkURL">
967 <tr>
968 <td style="width: 96px;">URL:</td>
969 <td><input type="text" name="lurl"' . $this->doc->formWidth(30) . ' value="'
970 . htmlspecialchars(($this->curUrlInfo['act'] == 'url' ? $this->curUrlInfo['info'] : 'http://'))
971 . '" /> ' . '<input type="submit" value="' . $GLOBALS['LANG']->getLL('setLink', TRUE)
972 . '" onclick="browse_links_setValue(document.lurlform.lurl.value); return link_current();" /></td>
973 </tr>
974 </table>
975 </form>';
976 $content .= $extUrl;
977 break;
978 case 'file':
979
980 case 'folder':
981 $foldertree = GeneralUtility::makeInstance('localFolderTree');
982 $foldertree->thisScript = $this->thisScript;
983 $tree = $foldertree->getBrowsableTree();
984 if (!$this->curUrlInfo['value'] || $this->curUrlInfo['act'] != $this->act) {
985 $cmpPath = '';
986 } else {
987 $cmpPath = $this->curUrlInfo['value'];
988 if (!isset($this->expandFolder)) {
989 $this->expandFolder = $cmpPath;
990 }
991 }
992 // Create upload/create folder forms, if a path is given
993 $selectedFolder = FALSE;
994 if ($this->expandFolder) {
995 $fileOrFolderObject = NULL;
996 try {
997 $fileOrFolderObject = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->retrieveFileOrFolderObject($this->expandFolder);
998 } catch (\Exception $e) {
999 }
1000
1001 if ($fileOrFolderObject instanceof Folder) {
1002 // It's a folder
1003 $selectedFolder = $fileOrFolderObject;
1004 } elseif ($fileOrFolderObject instanceof \TYPO3\CMS\Core\Resource\FileInterface) {
1005 // It's a file
1006 // @todo: find the parent folder, right now done a bit ugly, because the file does not
1007 // support finding the parent folder of a file on purpose
1008 $folderIdentifier = dirname($fileOrFolderObject->getIdentifier());
1009 $selectedFolder = $fileOrFolderObject->getStorage()->getFolder($folderIdentifier);
1010 }
1011 }
1012 // Or get the user's default upload folder
1013 if (!$selectedFolder) {
1014 $selectedFolder = $GLOBALS['BE_USER']->getDefaultUploadFolder();
1015 }
1016 // Build the file upload and folder creation form
1017 $uploadForm = '';
1018 $createFolder = '';
1019 if ($selectedFolder) {
1020 $uploadForm = ($this->act === 'file') ? $this->uploadForm($selectedFolder) : '';
1021 $createFolder = $this->createFolder($selectedFolder);
1022 }
1023 // Insert the upload form on top, if so configured
1024 if ($GLOBALS['BE_USER']->getTSConfigVal('options.uploadFieldsInTopOfEB')) {
1025 $content .= $uploadForm;
1026 }
1027
1028 // Render the filelist if there is a folder selected
1029 if ($selectedFolder) {
1030 $allowedExtensions = isset($this->P['params']['allowedExtensions']) ? $this->P['params']['allowedExtensions'] : '';
1031 $files = $this->expandFolder($selectedFolder, $allowedExtensions);
1032 }
1033 $this->doc->JScode .= $this->doc->wrapScriptTags('
1034 Tree.ajaxID = "SC_alt_file_navframe::expandCollapse";
1035 ');
1036 $content .= '
1037 <!--
1038 Wrapper table for folder tree / file/folder list:
1039 -->
1040 <table border="0" cellpadding="0" cellspacing="0" id="typo3-linkFiles">
1041 <tr>
1042 <td class="c-wCell" valign="top">'
1043 . $this->barheader(($GLOBALS['LANG']->getLL('folderTree') . ':')) . $tree . '</td>
1044 <td class="c-wCell" valign="top">' . $files . '</td>
1045 </tr>
1046 </table>
1047 <br />
1048 ';
1049 // Adding create folder + upload forms if applicable
1050 if (!$GLOBALS['BE_USER']->getTSConfigVal('options.uploadFieldsInTopOfEB')) {
1051 $content .= $uploadForm;
1052 }
1053 $content .= $createFolder . '<br />';
1054 break;
1055 case 'spec':
1056 if (is_array($this->thisConfig['userLinks.'])) {
1057 $subcats = array();
1058 $v = $this->thisConfig['userLinks.'];
1059 foreach ($v as $k2 => $value) {
1060 $k2i = (int)$k2;
1061 if (substr($k2, -1) == '.' && is_array($v[$k2i . '.'])) {
1062 // Title:
1063 $title = trim($v[$k2i]);
1064 if (!$title) {
1065 $title = $v[$k2i . '.']['url'];
1066 } else {
1067 $title = $GLOBALS['LANG']->sL($title);
1068 }
1069 // Description:
1070 $description = $v[$k2i . '.']['description']
1071 ? $GLOBALS['LANG']->sL($v[($k2i . '.')]['description'], TRUE) . '<br />'
1072 : '';
1073 // URL + onclick event:
1074 $onClickEvent = '';
1075 if (isset($v[$k2i . '.']['target'])) {
1076 $onClickEvent .= 'browse_links_setTarget(' . GeneralUtility::quoteJSvalue($v[($k2i . '.')]['target']) . ');';
1077 }
1078 $v[$k2i . '.']['url'] = str_replace('###_URL###', $this->siteURL, $v[$k2i . '.']['url']);
1079 if (substr($v[$k2i . '.']['url'], 0, 7) === 'http://' || substr($v[$k2i . '.']['url'], 0, 7) === 'mailto:') {
1080 $onClickEvent .= 'cur_href=' . GeneralUtility::quoteJSvalue($v[($k2i . '.')]['url']) . ';link_current();';
1081 } else {
1082 $onClickEvent .= 'link_spec(' . GeneralUtility::quoteJSvalue($this->siteURL . $v[($k2i . '.')]['url']) . ');';
1083 }
1084 // Link:
1085 $A = array('<a href="#" onclick="' . htmlspecialchars($onClickEvent) . 'return false;">', '</a>');
1086 // Adding link to menu of user defined links:
1087 $subcats[$k2i] = '
1088 <tr>
1089 <td class="bgColor4">' . $A[0] . '<strong>' . htmlspecialchars($title)
1090 . ($this->curUrlInfo['info'] == $v[$k2i . '.']['url']
1091 ? '<img' . IconUtility::skinImg(
1092 $GLOBALS['BACK_PATH'],
1093 'gfx/blinkarrow_right.gif',
1094 'width="5" height="9"'
1095 ) . ' class="c-blinkArrowR" alt="" />'
1096 : '')
1097 . '</strong><br />' . $description . $A[1] . '</td>
1098 </tr>';
1099 }
1100 }
1101 // Sort by keys:
1102 ksort($subcats);
1103 // Add menu to content:
1104 $content .= '
1105
1106 <!--
1107 Special userdefined menu:
1108 -->
1109 <table border="0" cellpadding="1" cellspacing="1" id="typo3-linkSpecial">
1110 <tr>
1111 <td class="bgColor5" class="c-wCell" valign="top"><strong>'
1112 . $GLOBALS['LANG']->getLL('special', TRUE) . '</strong></td>
1113 </tr>
1114 ' . implode('', $subcats) . '
1115 </table>
1116 ';
1117 }
1118 break;
1119 case 'page':
1120 $pageTree = GeneralUtility::makeInstance('localPageTree');
1121 $pageTree->thisScript = $this->thisScript;
1122 $pageTree->ext_showPageId = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showPageIdWithTitle');
1123 $pageTree->ext_showNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
1124 $pageTree->addField('nav_title');
1125 $tree = $pageTree->getBrowsableTree();
1126 $cElements = $this->expandPage();
1127
1128 $content .= '
1129
1130 <!--
1131 Wrapper table for page tree / record list:
1132 -->
1133 <table border="0" cellpadding="0" cellspacing="0" id="typo3-linkPages">
1134 <tr>
1135 <td class="c-wCell" valign="top">'
1136 . $this->barheader(($GLOBALS['LANG']->getLL('pageTree') . ':'))
1137 . $this->getTemporaryTreeMountCancelNotice()
1138 . $tree . '</td>
1139 <td class="c-wCell" valign="top">' . $cElements . '</td>
1140 </tr>
1141 </table>
1142 ';
1143 break;
1144 default:
1145 // Call hook
1146 foreach ($this->hookObjects as $hookObject) {
1147 $content .= $hookObject->getTab($this->act);
1148 }
1149 }
1150 if (in_array('params', $allowedFields, TRUE)) {
1151 $content .= '
1152 <!--
1153 Selecting params for link:
1154 -->
1155 <form action="" name="lparamsform" id="lparamsform">
1156 <table border="0" cellpadding="2" cellspacing="1" id="typo3-linkParams">
1157 <tr>
1158 <td style="width: 96px;">' . $GLOBALS['LANG']->getLL('params', TRUE) . '</td>
1159 <td><input type="text" name="lparams" class="typo3-link-input" onchange="'
1160 . 'browse_links_setParams(this.value);" value="' . htmlspecialchars($this->setParams)
1161 . '" /></td>
1162 </tr>
1163 </table>
1164 </form>
1165 ';
1166 }
1167 if (in_array('class', $allowedFields, TRUE)) {
1168 $content .= '
1169 <!--
1170 Selecting class for link:
1171 -->
1172 <form action="" name="lclassform" id="lclassform">
1173 <table border="0" cellpadding="2" cellspacing="1" id="typo3-linkClass">
1174 <tr>
1175 <td style="width: 96px;">' . $GLOBALS['LANG']->getLL('class', TRUE) . '</td>
1176 <td><input type="text" name="lclass" class="typo3-link-input" onchange="'
1177 . 'browse_links_setClass(this.value);" value="' . htmlspecialchars($this->setClass)
1178 . '" /></td>
1179 </tr>
1180 </table>
1181 </form>
1182 ';
1183 }
1184 if (in_array('title', $allowedFields, TRUE)) {
1185 $content .= '
1186 <!--
1187 Selecting title for link:
1188 -->
1189 <form action="" name="ltitleform" id="ltitleform">
1190 <table border="0" cellpadding="2" cellspacing="1" id="typo3-linkTitle">
1191 <tr>
1192 <td style="width: 96px;">' . $GLOBALS['LANG']->getLL('title', TRUE) . '</td>
1193 <td><input type="text" name="ltitle" class="typo3-link-input" onchange="'
1194 . 'browse_links_setTitle(this.value);" value="' . htmlspecialchars($this->setTitle)
1195 . '" /></td>
1196 </tr>
1197 </table>
1198 </form>
1199 ';
1200 }
1201 // additional fields for page links
1202 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.browse_links.php']['addFields_PageLink'])
1203 && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.browse_links.php']['addFields_PageLink'])
1204 ) {
1205 $conf = array();
1206 $_params = array(
1207 'conf' => &$conf
1208 );
1209 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.browse_links.php']['addFields_PageLink'] as $objRef) {
1210 $processor =& GeneralUtility::getUserObj($objRef);
1211 $content .= $processor->addFields($_params, $this);
1212 }
1213 }
1214 // Target:
1215 if ($this->act != 'mail' && in_array('target', $allowedFields, TRUE)) {
1216 $ltarget = '
1217
1218 <!--
1219 Selecting target for link:
1220 -->
1221 <form action="" name="ltargetform" id="ltargetform">
1222 <table border="0" cellpadding="2" cellspacing="1" id="typo3-linkTarget">
1223 <tr>
1224 <td>' . $GLOBALS['LANG']->getLL('target', TRUE) . ':</td>
1225 <td><input type="text" name="ltarget" onchange="browse_links_setTarget(this.value);" value="'
1226 . htmlspecialchars($this->setTarget) . '"' . $this->doc->formWidth(10) . ' /></td>
1227 <td>
1228 <select name="ltarget_type" onchange="browse_links_setTarget('
1229 . 'this.options[this.selectedIndex].value);document.ltargetform.ltarget.value='
1230 . 'this.options[this.selectedIndex].value;this.selectedIndex=0;">
1231 <option></option>
1232 <option value="_top">' . $GLOBALS['LANG']->getLL('top', TRUE) . '</option>
1233 <option value="_blank">' . $GLOBALS['LANG']->getLL('newWindow', TRUE) . '</option>
1234 </select>
1235 </td>
1236 <td>';
1237 if (($this->curUrlInfo['act'] == 'page' || $this->curUrlInfo['act'] == 'file' || $this->curUrlInfo['act'] == 'folder')
1238 && $this->curUrlArray['href'] && $this->curUrlInfo['act'] == $this->act
1239 ) {
1240 $ltarget .= '
1241 <input type="submit" value="' . $GLOBALS['LANG']->getLL('update', TRUE)
1242 . '" onclick="return link_current();" />';
1243 }
1244 $selectJS = '
1245 if (document.ltargetform.popup_width.options[document.ltargetform.popup_width.selectedIndex].value>0'
1246 . ' && document.ltargetform.popup_height.options[document.ltargetform.popup_height.selectedIndex].value>0) {
1247 document.ltargetform.ltarget.value = document.ltargetform.popup_width.options['
1248 . 'document.ltargetform.popup_width.selectedIndex].value+"x"'
1249 . '+document.ltargetformbrowse_links_setTarget.popup_height.options['
1250 . 'document.ltargetform.popup_height.selectedIndex].value;
1251 browse_links_setTarget(document.ltargetform.ltarget.value);
1252 browse_links_setClass(document.lclassform.lclass.value);
1253 browse_links_setTitle(document.ltitleform.ltitle.value);
1254 browse_links_setParams(document.lparamsform.lparams.value);
1255 document.ltargetform.popup_width.selectedIndex=0;
1256 document.ltargetform.popup_height.selectedIndex=0;
1257 }
1258 ';
1259 $ltarget .= ' </td>
1260 </tr>
1261 <tr>
1262 <td>' . $GLOBALS['LANG']->getLL('target_popUpWindow', TRUE) . ':</td>
1263 <td colspan="3">
1264 <select name="popup_width" onchange="' . htmlspecialchars($selectJS) . '">
1265 <option value="0">' . $GLOBALS['LANG']->getLL('target_popUpWindow_width', TRUE) . '</option>
1266 <option value="300">300</option>
1267 <option value="400">400</option>
1268 <option value="500">500</option>
1269 <option value="600">600</option>
1270 <option value="700">700</option>
1271 <option value="800">800</option>
1272 </select>
1273 x
1274 <select name="popup_height" onchange="' . htmlspecialchars($selectJS) . '">
1275 <option value="0">' . $GLOBALS['LANG']->getLL('target_popUpWindow_height', TRUE) . '</option>
1276 <option value="200">200</option>
1277 <option value="300">300</option>
1278 <option value="400">400</option>
1279 <option value="500">500</option>
1280 <option value="600">600</option>
1281 </select>
1282 </td>
1283 </tr>
1284 </table>
1285 </form>';
1286 // Add "target selector" box to content:
1287 $content .= $ltarget;
1288 // Add some space
1289 $content .= '<br /><br />';
1290 }
1291 // End page, return content:
1292 $content .= $this->doc->endPage();
1293 $content = $this->doc->insertStylesAndJS($content);
1294 return $content;
1295 }
1296
1297 /**
1298 * TYPO3 Element Browser: Showing a page tree and allows you to browse for records
1299 *
1300 * @return string HTML content for the module
1301 * @todo Define visibility
1302 */
1303 public function main_db() {
1304 // Starting content:
1305 $content = $this->doc->startPage('TBE record selector');
1306 // Init variable:
1307 $pArr = explode('|', $this->bparams);
1308 $tables = $pArr[3];
1309
1310 // Making the browsable pagetree:
1311 /** @var \TBE_PageTree $pagetree */
1312 $pagetree = GeneralUtility::makeInstance('TBE_PageTree');
1313 $pagetree->thisScript = $this->thisScript;
1314 $pagetree->ext_pArrPages = $tables === 'pages' ? 1 : 0;
1315 $pagetree->ext_showNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
1316 $pagetree->ext_showPageId = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showPageIdWithTitle');
1317 $pagetree->addField('nav_title');
1318
1319 $withTree = TRUE;
1320 if (($tables !== '') && ($tables !== '*')) {
1321 $tablesArr = GeneralUtility::trimExplode(',', $tables, TRUE);
1322 $onlyRootLevel = TRUE;
1323 foreach ($tablesArr as $currentTable) {
1324 $tableTca = $GLOBALS['TCA'][$currentTable];
1325 if (isset($tableTca)) {
1326 if (!isset($tableTca['ctrl']['rootLevel']) || ((int)$tableTca['ctrl']['rootLevel']) != 1) {
1327 $onlyRootLevel = FALSE;
1328 }
1329 }
1330 }
1331 if ($onlyRootLevel) {
1332 $withTree = FALSE;
1333 // page to work on will be root
1334 $this->expandPage = 0;
1335 }
1336 }
1337
1338 $tree = $pagetree->getBrowsableTree();
1339 // Making the list of elements, if applicable:
1340 $cElements = $this->TBE_expandPage($tables);
1341 // Putting the things together, side by side:
1342 $content .= '
1343
1344 <!--
1345 Wrapper table for page tree / record list:
1346 -->
1347 <table border="0" cellpadding="0" cellspacing="0" id="typo3-EBrecords">
1348 <tr>';
1349 if ($withTree) {
1350 $content .= '<td class="c-wCell" valign="top">'
1351 . $this->barheader(($GLOBALS['LANG']->getLL('pageTree') . ':'))
1352 . $this->getTemporaryTreeMountCancelNotice()
1353 . $tree . '</td>';
1354 }
1355 $content .= '<td class="c-wCell" valign="top">' . $cElements . '</td>
1356 </tr>
1357 </table>
1358 ';
1359 // Add some space
1360 $content .= '<br /><br />';
1361 // End page, return content:
1362 $content .= $this->doc->endPage();
1363 $content = $this->doc->insertStylesAndJS($content);
1364 return $content;
1365 }
1366
1367 /**
1368 * TYPO3 Element Browser: Showing a folder tree, allowing you to browse for files.
1369 *
1370 * @return string HTML content for the module
1371 * @todo Define visibility
1372 */
1373 public function main_file() {
1374 // include JS files and set prefs for foldertree
1375 $this->doc->getDragDropCode('folders');
1376 $this->doc->JScode .= $this->doc->wrapScriptTags('
1377 Tree.ajaxID = "SC_alt_file_navframe::expandCollapse";
1378 ');
1379 // Starting content:
1380 $content = $this->doc->startPage('TBE file selector');
1381 // Init variable:
1382 $pArr = explode('|', $this->bparams);
1383 // The key number 3 of the pArr contains the "allowed" string. Disallowed is not passed to
1384 // the element browser at all but only filtered out in TCEMain afterwards
1385 $allowed = $pArr[3];
1386 if ($allowed !== 'sys_file') {
1387 $allowedFileExtensions = $allowed;
1388 }
1389 $this->storages = $GLOBALS['BE_USER']->getFileStorages();
1390 if (isset($allowedFileExtensions)) {
1391 // Create new filter object
1392 $filterObject = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\Filter\\FileExtensionFilter');
1393 $filterObject->setAllowedFileExtensions($allowedFileExtensions);
1394 // Set file extension filters on all storages
1395 /** @var $storage \TYPO3\CMS\Core\Resource\ResourceStorage */
1396 foreach ($this->storages as $storage) {
1397 $storage->addFileAndFolderNameFilter(array($filterObject, 'filterFileList'));
1398 }
1399 }
1400 // Create upload/create folder forms, if a path is given
1401 if ($this->expandFolder) {
1402 $this->selectedFolder = FALSE;
1403 $fileOrFolderObject = NULL;
1404
1405 // Try to fetch the folder the user had open the last time he browsed files
1406 // Fallback to the default folder in case the last used folder is not existing
1407 try {
1408 $fileOrFolderObject = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->retrieveFileOrFolderObject($this->expandFolder);
1409 } catch (\TYPO3\CMS\Core\Resource\Exception $accessException) {
1410 // We're just catching the exception here, nothing to be done if folder does not exist or is not accessible.
1411 }
1412
1413 if ($fileOrFolderObject instanceof \TYPO3\CMS\Core\Resource\Folder) {
1414 // It's a folder
1415 $this->selectedFolder = $fileOrFolderObject;
1416 } elseif ($fileOrFolderObject instanceof \TYPO3\CMS\Core\Resource\FileInterface) {
1417 // It's a file
1418 // @todo: find the parent folder, right now done a bit ugly, because the file does not
1419 // support finding the parent folder of a file on purpose
1420 $folderIdentifier = dirname($fileOrFolderObject->getIdentifier());
1421 $this->selectedFolder = $fileOrFolderObject->getStorage()->getFolder($folderIdentifier);
1422 }
1423 }
1424 // Or get the user's default upload folder
1425 if (!$this->selectedFolder) {
1426 $this->selectedFolder = $GLOBALS['BE_USER']->getDefaultUploadFolder();
1427 }
1428 // Build the file upload and folder creation form
1429 $uploadForm = '';
1430 $createFolder = '';
1431 if ($this->selectedFolder) {
1432 $uploadForm = $this->uploadForm($this->selectedFolder);
1433 $createFolder = $this->createFolder($this->selectedFolder);
1434 }
1435 // Insert the upload form on top, if so configured
1436 if ($GLOBALS['BE_USER']->getTSConfigVal('options.uploadFieldsInTopOfEB')) {
1437 $content .= $uploadForm;
1438 }
1439 // Getting flag for showing/not showing thumbnails:
1440 $noThumbs = $GLOBALS['BE_USER']->getTSConfigVal('options.noThumbsInEB');
1441 $_MOD_SETTINGS = array();
1442 if (!$noThumbs) {
1443 // MENU-ITEMS, fetching the setting for thumbnails from File>List module:
1444 $_MOD_MENU = array('displayThumbs' => '');
1445 $_MCONF['name'] = 'file_list';
1446 $_MOD_SETTINGS = BackendUtility::getModuleData($_MOD_MENU, GeneralUtility::_GP('SET'), $_MCONF['name']);
1447 }
1448 $noThumbs = $noThumbs ?: !$_MOD_SETTINGS['displayThumbs'];
1449 // Create folder tree:
1450 $folderTree = GeneralUtility::makeInstance('TBE_FolderTree');
1451 $folderTree->thisScript = $this->thisScript;
1452 $folderTree->ext_noTempRecyclerDirs = $this->mode == 'filedrag';
1453 $tree = $folderTree->getBrowsableTree();
1454 list(, , $specUid) = explode('_', $this->PM);
1455 if ($this->selectedFolder) {
1456 if ($this->mode == 'filedrag') {
1457 $files = $this->TBE_dragNDrop($this->selectedFolder, $pArr[3]);
1458 } else {
1459 $files = $this->TBE_expandFolder($this->selectedFolder, $pArr[3], $noThumbs);
1460 }
1461 } else {
1462 $files = '';
1463 }
1464 // Add the FlashMessages if any
1465 $content .= $this->doc->getFlashMessages();
1466
1467 // Putting the parts together, side by side:
1468 $content .= '
1469
1470 <!--
1471 Wrapper table for folder tree / file list:
1472 -->
1473 <table border="0" cellpadding="0" cellspacing="0" id="typo3-EBfiles">
1474 <tr>
1475 <td class="c-wCell" valign="top">' . $this->barheader(($GLOBALS['LANG']->getLL('folderTree') . ':'))
1476 . $tree . '</td>
1477 <td class="c-wCell" valign="top">' . $files . '</td>
1478 </tr>
1479 </table>
1480 ';
1481 // Adding create folder + upload forms if applicable:
1482 if (!$GLOBALS['BE_USER']->getTSConfigVal('options.uploadFieldsInTopOfEB')) {
1483 $content .= $uploadForm;
1484 }
1485 $content .= $createFolder;
1486 // Add some space
1487 $content .= '<br /><br />';
1488 // Setup indexed elements:
1489 $this->doc->JScode .= $this->doc->wrapScriptTags('BrowseLinks.addElements(' . json_encode($this->elements) . ');');
1490 // Ending page, returning content:
1491 $content .= $this->doc->endPage();
1492 $content = $this->doc->insertStylesAndJS($content);
1493 return $content;
1494 }
1495
1496 /**
1497 * TYPO3 Element Browser: Showing a folder tree, allowing you to browse for folders.
1498 *
1499 * @return string HTML content for the module
1500 * @todo Define visibility
1501 */
1502 public function main_folder() {
1503 // include JS files
1504 $this->doc->getDragDropCode('folders');
1505 // Setting prefs for foldertree
1506 $this->doc->JScode .= $this->doc->wrapScriptTags('
1507 Tree.ajaxID = "SC_alt_file_navframe::expandCollapse";
1508 ');
1509 // Starting content:
1510 $content = $this->doc->startPage('TBE folder selector');
1511 // Init variable:
1512 $parameters = explode('|', $this->bparams);
1513 if ($this->expandFolder) {
1514 $this->selectedFolder = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->getFolderObjectFromCombinedIdentifier($this->expandFolder);
1515 }
1516 if ($this->selectedFolder) {
1517 $createFolder = $this->createFolder($this->selectedFolder);
1518 } else {
1519 $createFolder = '';
1520 }
1521 // Create folder tree:
1522 $folderTree = GeneralUtility::makeInstance('TBE_FolderTree');
1523 $folderTree->thisScript = $this->thisScript;
1524 $folderTree->ext_noTempRecyclerDirs = $this->mode == 'filedrag';
1525 $tree = $folderTree->getBrowsableTree(FALSE);
1526 list(, , $specUid) = explode('_', $this->PM);
1527 if ($this->mode == 'filedrag') {
1528 $folders = $this->TBE_dragNDrop($this->selectedFolder, $parameters[3]);
1529 } else {
1530 $folders = $this->TBE_expandSubFolders($this->selectedFolder);
1531 }
1532 // Putting the parts together, side by side:
1533 $content .= '
1534
1535 <!--
1536 Wrapper table for folder tree / folder list:
1537 -->
1538 <table border="0" cellpadding="0" cellspacing="0" id="typo3-EBfiles">
1539 <tr>
1540 <td class="c-wCell" valign="top">' . $this->barheader(($GLOBALS['LANG']->getLL('folderTree') . ':'))
1541 . $tree . '</td>
1542 <td class="c-wCell" valign="top">' . $folders . '</td>
1543 </tr>
1544 </table>
1545 ';
1546 // Adding create folder if applicable:
1547 $content .= $createFolder;
1548 // Add some space
1549 $content .= '<br /><br />';
1550 // Ending page, returning content:
1551 $content .= $this->doc->endPage();
1552 $content = $this->doc->insertStylesAndJS($content);
1553 return $content;
1554 }
1555
1556 /******************************************************************
1557 *
1558 * Record listing
1559 *
1560 ******************************************************************/
1561 /**
1562 * For RTE: This displays all content elements on a page and lets you create a link to the element.
1563 *
1564 * @return string HTML output. Returns content only if the ->expandPage value is set (pointing to a page uid to show tt_content records from ...)
1565 * @todo Define visibility
1566 */
1567 public function expandPage() {
1568 $out = '';
1569 // Set page id (if any) to expand
1570 $expPageId = $this->expandPage;
1571 // If there is an anchor value (content element reference) in the element reference, then force an ID to expand:
1572 if (!$this->expandPage && $this->curUrlInfo['cElement']) {
1573 // Set to the current link page id.
1574 $expPageId = $this->curUrlInfo['pageid'];
1575 }
1576 // Draw the record list IF there is a page id to expand:
1577 if ($expPageId
1578 && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($expPageId)
1579 && $GLOBALS['BE_USER']->isInWebMount($expPageId)
1580 ) {
1581 // Set header:
1582 $out .= $this->barheader($GLOBALS['LANG']->getLL('contentElements') . ':');
1583 // Create header for listing, showing the page title/icon:
1584 $mainPageRec = BackendUtility::getRecordWSOL('pages', $expPageId);
1585 $picon = IconUtility::getSpriteIconForRecord('pages', $mainPageRec);
1586 $picon .= BackendUtility::getRecordTitle('pages', $mainPageRec, TRUE);
1587 $out .= $picon . '<br />';
1588 // Look up tt_content elements from the expanded page:
1589 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
1590 'uid,header,hidden,starttime,endtime,fe_group,CType,colPos,bodytext',
1591 'tt_content',
1592 'pid=' . (int)$expPageId . BackendUtility::deleteClause('tt_content')
1593 . BackendUtility::versioningPlaceholderClause('tt_content'),
1594 '',
1595 'colPos,sorting'
1596 );
1597 $cc = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
1598 // Traverse list of records:
1599 $c = 0;
1600 while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1601 $c++;
1602 $icon = IconUtility::getSpriteIconForRecord('tt_content', $row);
1603 if ($this->curUrlInfo['act'] == 'page' && $this->curUrlInfo['cElement'] == $row['uid']) {
1604 $arrCol = '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/blinkarrow_left.gif', 'width="5" height="9"')
1605 . ' class="c-blinkArrowL" alt="" />';
1606 } else {
1607 $arrCol = '';
1608 }
1609 // Putting list element HTML together:
1610 $out .= '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'], ('gfx/ol/join' . ($c == $cc ? 'bottom' : '')
1611 . '.gif'), 'width="18" height="16"') . ' alt="" />' . $arrCol
1612 . '<a href="#" onclick="return link_typo3Page(\'' . $expPageId . '\',\'#' . $row['uid'] . '\');">'
1613 . $icon . BackendUtility::getRecordTitle('tt_content', $row, TRUE) . '</a><br />';
1614 // Finding internal anchor points:
1615 if (GeneralUtility::inList('text,textpic', $row['CType'])) {
1616 $split = preg_split('/(<a[^>]+name=[\'"]?([^"\'>[:space:]]+)[\'"]?[^>]*>)/i', $row['bodytext'], -1, PREG_SPLIT_DELIM_CAPTURE);
1617 foreach ($split as $skey => $sval) {
1618 if ($skey % 3 == 2) {
1619 // Putting list element HTML together:
1620 $sval = substr($sval, 0, 100);
1621 $out .= '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/ol/line.gif',
1622 'width="18" height="16"') . ' alt="" />'
1623 . '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'], ('gfx/ol/join'
1624 . ($skey + 3 > count($split) ? 'bottom' : '') . '.gif'), 'width="18" height="16"')
1625 . ' alt="" />' . '<a href="#" onclick="return link_typo3Page(' . GeneralUtility::quoteJSvalue($expPageId)
1626 . ',' . GeneralUtility::quoteJSvalue('#' . $sval) . ';">' . htmlspecialchars((' <A> ' . $sval))
1627 . '</a><br />';
1628 }
1629 }
1630 }
1631 }
1632 }
1633 return $out;
1634 }
1635
1636 /**
1637 * For TYPO3 Element Browser: This lists all content elements from the given list of tables
1638 *
1639 * @param string $tables Comma separated list of tables. Set to "*" if you want all tables.
1640 * @return string HTML output.
1641 * @todo Define visibility
1642 */
1643 public function TBE_expandPage($tables) {
1644 $out = '';
1645 if ($this->expandPage >= 0
1646 && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($this->expandPage)
1647 && $GLOBALS['BE_USER']->isInWebMount($this->expandPage)
1648 ) {
1649 // Set array with table names to list:
1650 if (trim($tables) === '*') {
1651 $tablesArr = array_keys($GLOBALS['TCA']);
1652 } else {
1653 $tablesArr = GeneralUtility::trimExplode(',', $tables, TRUE);
1654 }
1655 reset($tablesArr);
1656 // Headline for selecting records:
1657 $out .= $this->barheader($GLOBALS['LANG']->getLL('selectRecords') . ':');
1658 // Create the header, showing the current page for which the listing is.
1659 // Includes link to the page itself, if pages are amount allowed tables.
1660 $titleLen = (int)$GLOBALS['BE_USER']->uc['titleLen'];
1661 $mainPageRec = BackendUtility::getRecordWSOL('pages', $this->expandPage);
1662 $ATag = '';
1663 $ATag_e = '';
1664 $ATag2 = '';
1665 $picon = '';
1666 if (is_array($mainPageRec)) {
1667 $picon = IconUtility::getSpriteIconForRecord('pages', $mainPageRec);
1668 if (in_array('pages', $tablesArr)) {
1669 $ATag = '<a href="#" onclick="return insertElement(\'pages\', \'' . $mainPageRec['uid'] . '\', \'db\', '
1670 . GeneralUtility::quoteJSvalue($mainPageRec['title']) . ', \'\', \'\', \'\',\'\',1);">';
1671 $ATag2 = '<a href="#" onclick="return insertElement(\'pages\', \'' . $mainPageRec['uid'] . '\', \'db\', '
1672 . GeneralUtility::quoteJSvalue($mainPageRec['title']) . ', \'\', \'\', \'\',\'\',0);">';
1673 $ATag_e = '</a>';
1674 }
1675 }
1676 $pBicon = $ATag2 ? '<img'
1677 . IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/plusbullet2.gif', 'width="18" height="16"')
1678 . ' alt="" />' : '';
1679 $pText = htmlspecialchars(GeneralUtility::fixed_lgd_cs($mainPageRec['title'], $titleLen));
1680 $out .= $picon . $ATag2 . $pBicon . $ATag_e . $ATag . $pText . $ATag_e . '<br />';
1681 // Initialize the record listing:
1682 $id = $this->expandPage;
1683 $pointer = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->pointer, 0, 100000);
1684 $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1);
1685 $pageInfo = BackendUtility::readPageAccess($id, $perms_clause);
1686 // Generate the record list:
1687 /** @var $dbList \TYPO3\CMS\Backend\RecordList\ElementBrowserRecordList */
1688 if (is_object($this->recordList)) {
1689 $dbList = $this->recordList;
1690 } else {
1691 $dbList = GeneralUtility::makeInstance('TYPO3\\CMS\\Backend\\RecordList\\ElementBrowserRecordList');
1692 }
1693 $dbList->thisScript = $this->thisScript;
1694 $dbList->backPath = $GLOBALS['BACK_PATH'];
1695 $dbList->thumbs = 0;
1696 $dbList->calcPerms = $GLOBALS['BE_USER']->calcPerms($pageInfo);
1697 $dbList->noControlPanels = 1;
1698 $dbList->clickMenuEnabled = 0;
1699 $dbList->tableList = implode(',', $tablesArr);
1700 $pArr = explode('|', $this->bparams);
1701 // a string like "data[pages][79][storage_pid]"
1702 $fieldPointerString = $pArr[0];
1703 // parts like: data, pages], 79], storage_pid]
1704 $fieldPointerParts = explode('[', $fieldPointerString);
1705 $relatingTableName = substr($fieldPointerParts[1], 0, -1);
1706 $relatingFieldName = substr($fieldPointerParts[3], 0, -1);
1707 if ($relatingTableName && $relatingFieldName) {
1708 $dbList->setRelatingTableAndField($relatingTableName, $relatingFieldName);
1709 }
1710 $dbList->start($id, GeneralUtility::_GP('table'), $pointer, GeneralUtility::_GP('search_field'),
1711 GeneralUtility::_GP('search_levels'), GeneralUtility::_GP('showLimit')
1712 );
1713 $dbList->setDispFields();
1714 $dbList->generateList();
1715 // Add the HTML for the record list to output variable:
1716 $out .= $dbList->HTMLcode;
1717 // Add support for fieldselectbox in singleTableMode
1718 if ($dbList->table) {
1719 $out .= $dbList->fieldSelectBox($dbList->table);
1720 }
1721 $out .= $dbList->getSearchBox();
1722 }
1723 // Return accumulated content:
1724 return $out;
1725 }
1726
1727 /**
1728 * Render list of folders inside a folder.
1729 *
1730 * @param Folder $folder Folder
1731 * @return string HTML output
1732 * @todo Define visibility
1733 */
1734 public function TBE_expandSubFolders(Folder $folder) {
1735 $content = '';
1736 if ($folder->checkActionPermission('read')) {
1737 $content .= $this->folderList($folder);
1738 }
1739 // Return accumulated content for folderlisting:
1740 return $content;
1741 }
1742
1743 /******************************************************************
1744 *
1745 * File listing
1746 *
1747 ******************************************************************/
1748 /**
1749 * For RTE: This displays all files from folder. No thumbnails shown
1750 *
1751 * @param Folder $folder The folder path to expand
1752 * @param string $extensionList List of file extensions to show
1753 * @return string HTML output
1754 * @todo Define visibility
1755 */
1756 public function expandFolder(Folder $folder, $extensionList = '') {
1757 $out = '';
1758 $renderFolders = $this->act === 'folder';
1759 if ($folder->checkActionPermission('read')) {
1760 // Create header for file listing:
1761 $out .= $this->barheader($GLOBALS['LANG']->getLL('files') . ':');
1762 // Prepare current path value for comparison (showing red arrow)
1763 $currentIdentifier = '';
1764 if ($this->curUrlInfo['value']) {
1765 $currentIdentifier = $this->curUrlInfo['info'];
1766 }
1767 // Create header element; The folder from which files are listed.
1768 $titleLen = (int)$GLOBALS['BE_USER']->uc['titleLen'];
1769 $folderIcon = IconUtility::getSpriteIconForResource($folder);
1770 $folderIcon .= htmlspecialchars(GeneralUtility::fixed_lgd_cs($folder->getIdentifier(), $titleLen));
1771 $picon = '<a href="#" onclick="return link_folder(\'file:' . $folder->getCombinedIdentifier() . '\');">'
1772 . $folderIcon . '</a>';
1773 if ($this->curUrlInfo['act'] == 'folder' && $currentIdentifier == $folder->getCombinedIdentifier()) {
1774 $out .= '<img'
1775 . IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/blinkarrow_left.gif', 'width="5" height="9"')
1776 . ' class="c-blinkArrowL" alt="" />';
1777 }
1778 $out .= $picon . '<br />';
1779 // Get files from the folder:
1780 if ($renderFolders) {
1781 $items = $folder->getSubfolders();
1782 } else {
1783 $items = $this->getFilesInFolder($folder, $extensionList);
1784 }
1785 $c = 0;
1786 $totalItems = count($items);
1787 foreach ($items as $fileOrFolderObject) {
1788 $c++;
1789 if ($renderFolders) {
1790 $fileIdentifier = $fileOrFolderObject->getCombinedIdentifier();
1791 $overlays = array();
1792 if ($fileOrFolderObject instanceof \TYPO3\CMS\Core\Resource\InaccessibleFolder) {
1793 $overlays = array('status-overlay-locked' => array());
1794 }
1795 $icon = IconUtility::getSpriteIcon(
1796 IconUtility::mapFileExtensionToSpriteIconName('folder'),
1797 array('title' => $fileOrFolderObject->getName()),
1798 $overlays);
1799 $itemUid = 'file:' . $fileIdentifier;
1800 } else {
1801 $fileIdentifier = $fileOrFolderObject->getUid();
1802 // File icon:
1803 $fileExtension = $fileOrFolderObject->getExtension();
1804 // Get size and icon:
1805 $size = ' (' . GeneralUtility::formatSize($fileOrFolderObject->getSize()) . 'bytes)';
1806 $icon = IconUtility::getSpriteIconForResource($fileOrFolderObject, array('title' => $fileOrFolderObject->getName() . $size));
1807 $itemUid = 'file:' . $fileIdentifier;
1808 }
1809 // If the listed file turns out to be the CURRENT file, then show blinking arrow:
1810 if (($this->curUrlInfo['act'] == 'file' || $this->curUrlInfo['act'] == 'folder')
1811 && $currentIdentifier == $fileIdentifier
1812 ) {
1813 $arrCol = '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/blinkarrow_left.gif',
1814 'width="5" height="9"') . ' class="c-blinkArrowL" alt="" />';
1815 } else {
1816 $arrCol = '';
1817 }
1818 // Put it all together for the file element:
1819 $out .=
1820 '<img' .
1821 IconUtility::skinImg(
1822 $GLOBALS['BACK_PATH'],
1823 ('gfx/ol/join' . ($c == $totalItems ? 'bottom' : '') . '.gif'),
1824 'width="18" height="16"'
1825 ) . ' alt="" />' . $arrCol .
1826 '<a href="#" onclick="return link_folder(\'' . $itemUid . '\');">' .
1827 $icon .
1828 htmlspecialchars(GeneralUtility::fixed_lgd_cs($fileOrFolderObject->getName(), $titleLen)) .
1829 '</a><br />';
1830 }
1831 }
1832 return $out;
1833 }
1834
1835 /**
1836 * For TYPO3 Element Browser: Expand folder of files.
1837 *
1838 * @param Folder $folder The folder path to expand
1839 * @param string $extensionList List of fileextensions to show
1840 * @param boolean $noThumbs Whether to show thumbnails or not. If set, no thumbnails are shown.
1841 * @return string HTML output
1842 * @todo Define visibility
1843 */
1844 public function TBE_expandFolder(Folder $folder, $extensionList = '', $noThumbs = FALSE) {
1845 if (!$folder->checkActionPermission('read')) {
1846 return '';
1847 }
1848 $extensionList = $extensionList == '*' ? '' : $extensionList;
1849 $files = $this->getFilesInFolder($folder, $extensionList);
1850 return $this->fileList($files, $folder, $noThumbs);
1851 }
1852
1853 /**
1854 * Render list of files.
1855 *
1856 * @param File[] $files List of files
1857 * @param Folder $folder If set a header with a folder icon and folder name are shown
1858 * @param boolean $noThumbs Whether to show thumbnails or not. If set, no thumbnails are shown.
1859 * @return string HTML output
1860 */
1861 protected function fileList(array $files, Folder $folder = NULL, $noThumbs = FALSE) {
1862 $out = '';
1863
1864 $lines = array();
1865 // Create headline (showing number of files):
1866 $filesCount = count($files);
1867 $out .= $this->barheader(sprintf($GLOBALS['LANG']->getLL('files') . ' (%s):', $filesCount));
1868 $out .= '<div id="filelist">';
1869 $out .= $this->getBulkSelector($filesCount);
1870 $titleLen = (int)$GLOBALS['BE_USER']->uc['titleLen'];
1871 // Create the header of current folder:
1872 if ($folder) {
1873 $folderIcon = IconUtility::getSpriteIconForResource($folder);
1874 $lines[] = '<tr class="t3-row-header">
1875 <td colspan="4">' . $folderIcon
1876 . htmlspecialchars(GeneralUtility::fixed_lgd_cs($folder->getIdentifier(), $titleLen)) . '</td>
1877 </tr>';
1878 }
1879 if ($filesCount == 0) {
1880 $lines[] = '
1881 <tr class="file_list_normal">
1882 <td colspan="4">No files found.</td>
1883 </tr>';
1884 }
1885 // Init graphic object for reading file and image dimensions:
1886 /** @var $imgObj \TYPO3\CMS\Core\Imaging\GraphicalFunctions */
1887 $imgObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Imaging\\GraphicalFunctions');
1888 $imgObj->init();
1889 $imgObj->mayScaleUp = 0;
1890 $imgObj->tempPath = PATH_site . $imgObj->tempPath;
1891 // Traverse the file list:
1892 /** @var $fileObject \TYPO3\CMS\Core\Resource\File */
1893 foreach ($files as $fileObject) {
1894 $fileExtension = $fileObject->getExtension();
1895 // Thumbnail/size generation:
1896 $imgInfo = array();
1897 if (GeneralUtility::inList(strtolower($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']), strtolower($fileExtension)) && !$noThumbs) {
1898 $imageUrl = $fileObject->process(
1899 \TYPO3\CMS\Core\Resource\ProcessedFile::CONTEXT_IMAGEPREVIEW,
1900 array('width' => 64, 'height' => 64)
1901 )->getPublicUrl(TRUE);
1902 $imgInfo = $imgObj->getImageDimensions($fileObject->getForLocalProcessing(FALSE));
1903 $pDim = $imgInfo[0] . 'x' . $imgInfo[1] . ' pixels';
1904 $clickIcon = '<img src="' . $imageUrl . '" hspace="5" vspace="5" border="1" />';
1905 } else {
1906 $clickIcon = '';
1907 $pDim = '';
1908 }
1909 // Create file icon:
1910 $size = ' (' . GeneralUtility::formatSize($fileObject->getSize()) . 'bytes' . ($pDim ? ', ' . $pDim : '') . ')';
1911 $icon = IconUtility::getSpriteIconForResource($fileObject, array('title' => $fileObject->getName() . $size));
1912 // Create links for adding the file:
1913 $filesIndex = count($this->elements);
1914 $this->elements['file_' . $filesIndex] = array(
1915 'type' => 'file',
1916 'table' => 'sys_file',
1917 'uid' => $fileObject->getUid(),
1918 'fileName' => $fileObject->getName(),
1919 'filePath' => $fileObject->getUid(),
1920 'fileExt' => $fileExtension,
1921 'fileIcon' => $icon
1922 );
1923 if ($this->fileIsSelectableInFileList($fileObject, $imgInfo)) {
1924 $ATag = '<a href="#" onclick="return BrowseLinks.File.insertElement(\'file_' . $filesIndex . '\');">';
1925 $ATag_alt = substr($ATag, 0, -4) . ',1);">';
1926 $bulkCheckBox = '<input type="checkbox" class="typo3-bulk-item" name="file_' . $filesIndex . '" value="0" /> ';
1927 $ATag_e = '</a>';
1928 } else {
1929 $ATag = '';
1930 $ATag_alt = '';
1931 $ATag_e = '';
1932 $bulkCheckBox = '';
1933 }
1934 // Create link to showing details about the file in a window:
1935 $Ahref = $GLOBALS['BACK_PATH'] . 'show_item.php?type=file&table=_FILE&uid='
1936 . rawurlencode($fileObject->getCombinedIdentifier())
1937 . '&returnUrl=' . rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI'));
1938 $ATag2 = '<a href="' . htmlspecialchars($Ahref) . '">';
1939 $ATag2_e = '</a>';
1940 // Combine the stuff:
1941 $filenameAndIcon = $bulkCheckBox . $ATag_alt . $icon
1942 . htmlspecialchars(GeneralUtility::fixed_lgd_cs($fileObject->getName(), $titleLen)) . $ATag_e;
1943 // Show element:
1944 if ($pDim) {
1945 // Image...
1946 $lines[] = '
1947 <tr class="file_list_normal">
1948 <td nowrap="nowrap">' . $filenameAndIcon . '&nbsp;</td>
1949 <td>' . ($ATag . '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/plusbullet2.gif',
1950 'width="18" height="16"') . ' title="' . $GLOBALS['LANG']->getLL('addToList', TRUE)
1951 . '" alt="" />' . $ATag_e) . '</td>
1952 <td nowrap="nowrap">' . ($ATag2 . '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'],
1953 'gfx/zoom2.gif', 'width="12" height="12"') . ' title="'
1954 . $GLOBALS['LANG']->getLL('info', TRUE) . '" alt="" /> '
1955 . $GLOBALS['LANG']->getLL('info', TRUE) . $ATag2_e) . '</td>
1956 <td nowrap="nowrap">&nbsp;' . $pDim . '</td>
1957 </tr>';
1958 $lines[] = '
1959 <tr>
1960 <td class="filelistThumbnail" colspan="4">' . $ATag_alt . $clickIcon . $ATag_e . '</td>
1961 </tr>';
1962 } else {
1963 $lines[] = '
1964 <tr class="file_list_normal">
1965 <td nowrap="nowrap">' . $filenameAndIcon . '&nbsp;</td>
1966 <td>' . ($ATag . '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/plusbullet2.gif',
1967 'width="18" height="16"') . ' title="' . $GLOBALS['LANG']->getLL('addToList', TRUE)
1968 . '" alt="" />' . $ATag_e) . '</td>
1969 <td nowrap="nowrap">' . ($ATag2 . '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'],
1970 'gfx/zoom2.gif', 'width="12" height="12"') . ' title="'
1971 . $GLOBALS['LANG']->getLL('info', TRUE) . '" alt="" /> '
1972 . $GLOBALS['LANG']->getLL('info', TRUE) . $ATag2_e) . '</td>
1973 <td>&nbsp;</td>
1974 </tr>';
1975 }
1976 }
1977 // Wrap all the rows in table tags:
1978 $out .= '
1979
1980 <!--
1981 File listing
1982 -->
1983 <table cellpadding="0" cellspacing="0" id="typo3-filelist">
1984 ' . implode('', $lines) . '
1985 </table>';
1986 // Return accumulated content for file listing:
1987 $out .= '</div>';
1988 return $out;
1989 }
1990
1991 /**
1992 * Checks if the given file is selectable in the file list.
1993 *
1994 * By default all files are selectable. This method may be overwritten in child classes.
1995 *
1996 * @param \TYPO3\CMS\Core\Resource\FileInterface $file
1997 * @param array $imgInfo Image dimensions from \TYPO3\CMS\Core\Imaging\GraphicalFunctions::getImageDimensions()
1998 * @return bool TRUE if file is selectable.
1999 */
2000 protected function fileIsSelectableInFileList(\TYPO3\CMS\Core\Resource\FileInterface $file, array $imgInfo) {
2001 return TRUE;
2002 }
2003
2004 /**
2005 * Render list of folders.
2006 *
2007 * @param Folder $baseFolder
2008 * @return string HTML output
2009 * @todo Define visibility
2010 */
2011 public function folderList(Folder $baseFolder) {
2012 $content = '';
2013 $folders = $baseFolder->getSubfolders();
2014 $baseFolderPath = $baseFolder->getPublicUrl();
2015 // Create headline (showing number of folders):
2016 $content .= $this->barheader(sprintf($GLOBALS['LANG']->getLL('folders') . ' (%s):', count($folders)));
2017 $titleLength = (int)$GLOBALS['BE_USER']->uc['titleLen'];
2018 // Create the header of current folder:
2019 $aTag = '<a href="#" onclick="return insertElement(\'\',' . GeneralUtility::quoteJSvalue($baseFolderPath)
2020 . ', \'folder\', ' . GeneralUtility::quoteJSvalue($baseFolderPath) . ', ' . GeneralUtility::quoteJSvalue($baseFolderPath)
2021 . ', \'\', \'\',\'\',1);">';
2022 // Add the foder icon
2023 $folderIcon = $aTag;
2024 $folderIcon .= '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/i/_icon_webfolders.gif',
2025 'width="18" height="16"') . ' alt="" />';
2026 $folderIcon .= htmlspecialchars(GeneralUtility::fixed_lgd_cs(basename($baseFolder), $titleLength));
2027 $folderIcon .= '</a>';
2028 $content .= $folderIcon . '<br />';
2029
2030 $lines = array();
2031 // Traverse the folder list:
2032 foreach ($folders as $folderPath) {
2033 $pathInfo = pathinfo($folderPath);
2034 // Create folder icon:
2035 $icon = '<img src="clear.gif" width="16" height="16" alt="" /><img'
2036 . IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/i/_icon_webfolders.gif',
2037 'width="16" height="16"') . ' title="' . htmlspecialchars(($pathInfo['basename']))
2038 . '" class="absmiddle" alt="" />';
2039 // Create links for adding the folder:
2040 if ($this->P['itemName'] != '' && $this->P['formName'] != '') {
2041 $aTag = '<a href="#" onclick="return set_folderpath(' . GeneralUtility::quoteJSvalue($folderPath)
2042 . ');">';
2043 } else {
2044 $aTag = '<a href="#" onclick="return insertElement(\'\',' . GeneralUtility::quoteJSvalue($folderPath)
2045 . ', \'folder\', ' . GeneralUtility::quoteJSvalue($folderPath) . ', '
2046 . GeneralUtility::quoteJSvalue($folderPath) . ', \'' . $pathInfo['extension'] . '\', \'\');">';
2047 }
2048 if (strstr($folderPath, ',') || strstr($folderPath, '|')) {
2049 // In case an invalid character is in the filepath, display error message:
2050 $errorMessage = GeneralUtility::quoteJSvalue(sprintf($GLOBALS['LANG']->getLL('invalidChar'), ', |'));
2051 $aTag = ($aTag_alt = '<a href="#" onclick="alert(' . $errorMessage . ');return false;">');
2052 } else {
2053 // If foldername is OK, just add it:
2054 $aTag_alt = substr($aTag, 0, -4) . ',\'\',1);">';
2055 }
2056 $aTag_e = '</a>';
2057 // Combine icon and folderpath:
2058 $foldernameAndIcon = $aTag_alt . $icon
2059 . htmlspecialchars(GeneralUtility::fixed_lgd_cs(basename($folderPath), $titleLength)) . $aTag_e;
2060 if ($this->P['itemName'] != '') {
2061 $lines[] = '
2062 <tr class="bgColor4">
2063 <td nowrap="nowrap">' . $foldernameAndIcon . '&nbsp;</td>
2064 <td>&nbsp;</td>
2065 </tr>';
2066 } else {
2067 $lines[] = '
2068 <tr class="bgColor4">
2069 <td nowrap="nowrap">' . $foldernameAndIcon . '&nbsp;</td>
2070 <td>' . $aTag . '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/plusbullet2.gif',
2071 'width="18" height="16"') . ' title="' . $GLOBALS['LANG']->getLL('addToList', TRUE)
2072 . '" alt="" />' . $aTag_e . ' </td>
2073 <td>&nbsp;</td>
2074 </tr>';
2075 }
2076 $lines[] = '
2077 <tr>
2078 <td colspan="3"><img src="clear.gif" width="1" height="3" alt="" /></td>
2079 </tr>';
2080 }
2081 // Wrap all the rows in table tags:
2082 $content .= '
2083
2084 <!--
2085 Folder listing
2086 -->
2087 <table border="0" cellpadding="0" cellspacing="1" id="typo3-folderList">
2088 ' . implode('', $lines) . '
2089 </table>';
2090 // Return accumulated content for folderlisting:
2091 return $content;
2092 }
2093
2094 /**
2095 * For RTE: This displays all IMAGES (gif,png,jpg) (from extensionList) from folder. Thumbnails are shown for images.
2096 * This listing is of images located in the web-accessible paths ONLY - the listing is for drag-n-drop use in the RTE
2097 *
2098 * @param Folder $folder The folder path to expand
2099 * @param string $extensionList List of file extensions to show
2100 * @return string HTML output
2101 * @todo Define visibility
2102 */
2103 public function TBE_dragNDrop(Folder $folder, $extensionList = '') {
2104 if (!$folder) {
2105 return '';
2106 }
2107 if (!$folder->getStorage()->isPublic()) {
2108 // Print this warning if the folder is NOT a web folder
2109 return $this->barheader($GLOBALS['LANG']->getLL('files'))
2110 . $this->getMsgBox($GLOBALS['LANG']->getLL('noWebFolder'), 'icon_warning2');
2111 }
2112 $out = '';
2113
2114 // Read files from directory:
2115 $extensionList = $extensionList == '*' ? '' : $extensionList;
2116 $files = $this->getFilesInFolder($folder, $extensionList);
2117
2118 $out .= $this->barheader(sprintf($GLOBALS['LANG']->getLL('files') . ' (%s):', count($files)));
2119 $titleLen = (int)$GLOBALS['BE_USER']->uc['titleLen'];
2120 $picon = '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/i/_icon_webfolders.gif', 'width="18" height="16"') . ' alt="" />';
2121 $picon .= htmlspecialchars(GeneralUtility::fixed_lgd_cs(basename($folder->getName()), $titleLen));
2122 $out .= $picon . '<br />';
2123 // Init row-array:
2124 $lines = array();
2125 // Add "drag-n-drop" message:
2126 $lines[] = '
2127 <tr>
2128 <td colspan="2">' . $this->getMsgBox($GLOBALS['LANG']->getLL('findDragDrop')) . '</td>
2129 </tr>';
2130 // Traverse files:
2131 foreach ($files as $fileObject) {
2132 $fileInfo = $fileObject->getStorage()->getFileInfo($fileObject);
2133 // URL of image:
2134 $iUrl = GeneralUtility::rawurlencodeFP($fileObject->getPublicUrl(TRUE));
2135 // Show only web-images
2136 $fileExtension = strtolower($fileObject->getExtension());
2137 if (GeneralUtility::inList('gif,jpeg,jpg,png', $fileExtension)) {
2138 $imgInfo = @getimagesize($fileObject->getForLocalProcessing(FALSE));
2139 $pDim = $imgInfo[0] . 'x' . $imgInfo[1] . ' pixels';
2140 $size = ' (' . GeneralUtility::formatSize($fileObject->getSize()) . 'bytes' . ($pDim ? ', ' . $pDim : '') . ')';
2141 $filenameAndIcon = IconUtility::getSpriteIconForResource($fileObject, array('title' => $fileObject->getName() . $size));
2142 if (GeneralUtility::_GP('noLimit')) {
2143 $maxW = 10000;
2144 $maxH = 10000;
2145 } else {
2146 $maxW = 380;
2147 $maxH = 500;
2148 }
2149 $IW = $imgInfo[0];
2150 $IH = $imgInfo[1];
2151 if ($IW > $maxW) {
2152 $IH = ceil($IH / $IW * $maxW);
2153 $IW = $maxW;
2154 }
2155 if ($IH > $maxH) {
2156 $IW = ceil($IW / $IH * $maxH);
2157 $IH = $maxH;
2158 }
2159 // Make row:
2160 $lines[] = '
2161 <tr class="bgColor4">
2162 <td nowrap="nowrap">' . $filenameAndIcon . '&nbsp;</td>
2163 <td nowrap="nowrap">' . ($imgInfo[0] != $IW
2164 ? '<a href="' . htmlspecialchars(GeneralUtility::linkThisScript(array('noLimit' => '1')))
2165 . '">' . '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/icon_warning2.gif',
2166 'width="18" height="16"') . ' title="'
2167 . $GLOBALS['LANG']->getLL('clickToRedrawFullSize', TRUE) . '" alt="" />' . '</a>'
2168 : '')
2169 . $pDim . '&nbsp;</td>
2170 </tr>';
2171 $lines[] = '
2172 <tr>
2173 <td colspan="2"><img src="' . htmlspecialchars($iUrl) . '" data-htmlarea-file-uid="' . $fileObject->getUid()
2174 . '" width="' . htmlspecialchars($IW) . '" height="' . htmlspecialchars($IH) . '" border="1" alt="" /></td>
2175 </tr>';
2176 $lines[] = '
2177 <tr>
2178 <td colspan="2"><img src="clear.gif" width="1" height="3" alt="" /></td>
2179 </tr>';
2180 }
2181 }
2182 // Finally, wrap all rows in a table tag:
2183 $out .= '
2184
2185
2186 <!--
2187 File listing / Drag-n-drop
2188 -->
2189 <table border="0" cellpadding="0" cellspacing="1" id="typo3-dragBox">
2190 ' . implode('', $lines) . '
2191 </table>';
2192
2193 return $out;
2194 }
2195
2196 /******************************************************************
2197 *
2198 * Miscellaneous functions
2199 *
2200 ******************************************************************/
2201 /**
2202 * Verifies that a path is a web-folder:
2203 *
2204 * @param string $folder Absolute filepath
2205 * @return boolean If the input path is found in PATH_site then it returns TRUE.
2206 * @deprecated since 6.2 - will be removed two versions later without replacement
2207 */
2208 public function isWebFolder($folder) {
2209 GeneralUtility::logDeprecatedFunction();
2210 $folder = rtrim($folder, '/') . '/';
2211 return GeneralUtility::isFirstPartOfStr($folder, PATH_site) ? TRUE : FALSE;
2212 }
2213
2214 /**
2215 * Checks, if a path is within the mountpoints of the backend user
2216 *
2217 * @param string $folder Absolute filepath
2218 * @return boolean If the input path is found in the backend users filemounts, then return TRUE.
2219 * @deprecated since 6.2 - will be removed two versions later without replacement
2220 */
2221 public function checkFolder($folder) {
2222 GeneralUtility::logDeprecatedFunction();
2223 return $this->fileProcessor->checkPathAgainstMounts(rtrim($folder, '/') . '/') ? TRUE : FALSE;
2224 }
2225
2226 /**
2227 * Prints a 'header' where string is in a tablecell
2228 *
2229 * @param string $str The string to print in the header. The value is htmlspecialchars()'ed before output.
2230 * @return string The header HTML (wrapped in a table)
2231 * @todo Define visibility
2232 */
2233 public function barheader($str) {
2234 return '
2235 <!-- Bar header: -->
2236 <h3>' . htmlspecialchars($str) . '</h3>
2237 ';
2238 }
2239
2240 /**
2241 * Displays a message box with the input message
2242 *
2243 * @param string $in_msg Input message to show (will be htmlspecialchars()'ed inside of this function)
2244 * @param string $icon Icon filename body from gfx/ (default is "icon_note") - meant to allow change to warning type icons...
2245 * @return string HTML for the message (wrapped in a table).
2246 * @todo Define visibility
2247 */
2248 public function getMsgBox($in_msg, $icon = 'icon_note') {
2249 $msg = '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'], ('gfx/' . $icon . '.gif'), 'width="18" height="16"')
2250 . ' alt="" />' . htmlspecialchars($in_msg);
2251 $msg = '
2252
2253 <!--
2254 Message box:
2255 -->
2256 <table cellspacing="0" class="bgColor4" id="typo3-msgBox">
2257 <tr>
2258 <td>' . $msg . '</td>
2259 </tr>
2260 </table>
2261 ';
2262 return $msg;
2263 }
2264
2265 /**
2266 * For RTE/link: This prints the 'currentUrl'
2267 *
2268 * @param string $str URL value. The value is htmlspecialchars()'ed before output.
2269 * @return string HTML content, wrapped in a table.
2270 * @todo Define visibility
2271 */
2272 public function printCurrentUrl($str) {
2273 // Output the folder or file identifier, when working with files
2274 if (isset($str) && \TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($str)
2275 && ($this->act === 'file' || $this->act === 'folder')
2276 ) {
2277 try {
2278 $fileObject = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->retrieveFileOrFolderObject($str);
2279 } catch (\TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException $e) {
2280 $fileObject = NULL;
2281 }
2282 $str = is_object($fileObject) ? $fileObject->getIdentifier() : '';
2283 }
2284 if (strlen($str)) {
2285 return '
2286 <!-- Print current URL -->
2287 <table border="0" cellpadding="0" cellspacing="0" id="typo3-curUrl">
2288 <tr>
2289 <td>' . $GLOBALS['LANG']->getLL('currentLink', TRUE) . ': '
2290 . htmlspecialchars(rawurldecode($str)) . '</td>
2291 </tr>
2292 </table>';
2293 } else {
2294 return '';
2295 }
2296 }
2297
2298 /**
2299 * For RTE/link: Parses the incoming URL and determines if it's a page, file, external or mail address.
2300 *
2301 * @param string $href HREF value tp analyse
2302 * @param string $siteUrl The URL of the current website (frontend)
2303 * @return array Array with URL information stored in assoc. keys: value, act (page, file, spec, mail), pageid, cElement, info
2304 * @todo Define visibility
2305 */
2306 public function parseCurUrl($href, $siteUrl) {
2307 $href = trim($href);
2308 if ($href) {
2309 $info = array();
2310 // Default is "url":
2311 $info['value'] = $href;
2312 $info['act'] = 'url';
2313 $specialParts = explode('#_SPECIAL', $href);
2314 // Special kind (Something RTE specific: User configurable links through: "userLinks." from ->thisConfig)
2315 if (count($specialParts) == 2) {
2316 $info['value'] = '#_SPECIAL' . $specialParts[1];
2317 $info['act'] = 'spec';
2318 } elseif (strpos($href, 'file:') !== FALSE) {
2319 $rel = substr($href, strpos($href, 'file:') + 5);
2320 $rel = rawurldecode($rel);
2321 // resolve FAL-api "file:UID-of-sys_file-record" and "file:combined-identifier"
2322 $fileOrFolderObject = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->retrieveFileOrFolderObject($rel);
2323 if ($fileOrFolderObject instanceof Folder) {
2324 $info['act'] = 'folder';
2325 $info['value'] = $fileOrFolderObject->getCombinedIdentifier();
2326 } elseif ($fileOrFolderObject instanceof File) {
2327 $info['act'] = 'file';
2328 $info['value'] = $fileOrFolderObject->getUid();
2329 } else {
2330 $info['value'] = $rel;
2331 }
2332 } elseif (GeneralUtility::isFirstPartOfStr($href, $siteUrl)) {
2333 // If URL is on the current frontend website:
2334 // URL is a file, which exists:
2335 if (file_exists(PATH_site . rawurldecode($href))) {
2336 $info['value'] = rawurldecode($href);
2337 if (@is_dir((PATH_site . $info['value']))) {
2338 $info['act'] = 'folder';
2339 } else {
2340 $info['act'] = 'file';
2341 }
2342 } else {
2343 // URL is a page (id parameter)
2344 $uP = parse_url($href);
2345
2346 $pp = preg_split('/^id=/', $uP['query']);
2347 $pp[1] = preg_replace('/&id=[^&]*/', '', $pp[1]);
2348 $parameters = explode('&', $pp[1]);
2349 $id = array_shift($parameters);
2350 if ($id) {
2351 // Checking if the id-parameter is an alias.
2352 if (!\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($id)) {
2353 list($idPartR) = BackendUtility::getRecordsByField('pages', 'alias', $id);
2354 $id = (int)$idPartR['uid'];
2355 }
2356 $pageRow = BackendUtility::getRecordWSOL('pages', $id);
2357 $titleLen = (int)$GLOBALS['BE_USER']->uc['titleLen'];
2358 $info['value'] = ((((($GLOBALS['LANG']->getLL('page', TRUE) . ' \'')
2359 . htmlspecialchars(GeneralUtility::fixed_lgd_cs($pageRow['title'], $titleLen)))
2360 . '\' (ID:') . $id) . ($uP['fragment'] ? ', #' . $uP['fragment'] : '')) . ')';
2361 $info['pageid'] = $id;
2362 $info['cElement'] = $uP['fragment'];
2363 $info['act'] = 'page';
2364 $info['query'] = $parameters[0] ? '&' . implode('&', $parameters) : '';
2365 }
2366 }
2367 } else {
2368 // Email link:
2369 if (strtolower(substr($href, 0, 7)) == 'mailto:') {
2370 $info['value'] = trim(substr($href, 7));
2371 $info['act'] = 'mail';
2372 }
2373 }
2374 $info['info'] = $info['value'];
2375 } else {
2376 // NO value inputted:
2377 $info = array();
2378 $info['info'] = $GLOBALS['LANG']->getLL('none');
2379 $info['value'] = '';
2380 $info['act'] = 'page';
2381 }
2382 // let the hook have a look
2383 foreach ($this->hookObjects as $hookObject) {
2384 $info = $hookObject->parseCurrentUrl($href, $siteUrl, $info);
2385 }
2386 return $info;
2387 }
2388
2389 /**
2390 * Setter for the class that should be used by TBE_expandPage() to generate the record list.
2391 * This method is intended to be used by Extensions that implement their own browsing functionality.
2392 *
2393 * @param \TYPO3\CMS\Backend\RecordList\ElementBrowserRecordList $recordList
2394 * @throws \InvalidArgumentException
2395 * @return void
2396 * @api
2397 */
2398 public function setRecordList($recordList) {
2399 if (!$recordList instanceof \TYPO3\CMS\Backend\RecordList\ElementBrowserRecordList) {
2400 throw new \InvalidArgumentException('$recordList needs to be an instance of \\TYPO3\\CMS\\Backend\\RecordList\\ElementBrowserRecordList', 1370878522);
2401 }
2402 $this->recordList = $recordList;
2403 }
2404
2405 /**
2406 * For TBE: Makes an upload form for uploading files to the filemount the user is browsing.
2407 * The files are uploaded to the tce_file.php script in the core which will handle the upload.
2408 *
2409 * @param Folder $folderObject Absolute filepath on server to which to upload.
2410 * @return string HTML for an upload form.
2411 * @todo Define visibility
2412 */
2413 public function uploadForm(Folder $folderObject) {
2414 if (!$folderObject->checkActionPermission('write')) {
2415 return '';
2416 }
2417 // Read configuration of upload field count
2418 $userSetting = $GLOBALS['BE_USER']->getTSConfigVal('options.folderTree.uploadFieldsInLinkBrowser');
2419 $count = isset($userSetting) ? $userSetting : 3;
2420 if ($count === '0') {
2421 return '';
2422 }
2423 $count = (int)$count === 0 ? 3 : (int)$count;
2424 // Create header, showing upload path:
2425 $header = $folderObject->getIdentifier();
2426 $code = '
2427 <br />
2428 <!--
2429 Form, for uploading files:
2430 -->
2431 <form action="' . $GLOBALS['BACK_PATH'] . 'tce_file.php" method="post" name="editform"'
2432 . 'id="typo3-uplFilesForm" enctype="' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'] . '">
2433 <table border="0" cellpadding="0" cellspacing="0" id="typo3-uplFiles">
2434 <tr>
2435 <td>' . $this->barheader($GLOBALS['LANG']->sL(
2436 'LLL:EXT:lang/locallang_core.xlf:file_upload.php.pagetitle', TRUE) . ':') . '</td>
2437 </tr>
2438 <tr>
2439 <td class="c-wCell c-hCell"><strong>' . $GLOBALS['LANG']->getLL('path', TRUE) . ':</strong> '
2440 . htmlspecialchars($header) . '</td>
2441 </tr>
2442 <tr>
2443 <td class="c-wCell c-hCell">';
2444 // Traverse the number of upload fields (default is 3):
2445 for ($a = 1; $a <= $count; $a++) {
2446 $code .= '<input type="file" multiple="multiple" name="upload_' . $a . '[]"' . $this->doc->formWidth(35)
2447 . ' size="50" />
2448 <input type="hidden" name="file[upload][' . $a . '][target]" value="'
2449 . htmlspecialchars($folderObject->getCombinedIdentifier()) . '" />
2450 <input type="hidden" name="file[upload][' . $a . '][data]" value="' . $a . '" /><br />';
2451 }
2452 // Make footer of upload form, including the submit button:
2453 $redirectValue = $this->getThisScript() . 'act=' . $this->act . '&mode=' . $this->mode
2454 . '&expandFolder=' . rawurlencode($folderObject->getCombinedIdentifier())
2455 . '&bparams=' . rawurlencode($this->bparams);
2456 $code .= '<input type="hidden" name="redirect" value="' . htmlspecialchars($redirectValue) . '" />';
2457 $code .= \TYPO3\CMS\Backend\Form\FormEngine::getHiddenTokenField('tceAction');
2458 $code .= '
2459 <div id="c-override">
2460 <label><input type="checkbox" name="overwriteExistingFiles" id="overwriteExistingFiles" value="1" /> '
2461 . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.xlf:overwriteExistingFiles', TRUE) . '</label>
2462 </div>
2463 <input type="submit" name="submit" value="'
2464 . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:file_upload.php.submit', TRUE) . '" />
2465 ';
2466 $code .= '</td>
2467 </tr>
2468 </table>
2469 </form><br />';
2470 return $code;
2471 }
2472
2473 /**
2474 * For TBE: Makes a form for creating new folders in the filemount the user is browsing.
2475 * The folder creation request is sent to the tce_file.php script in the core which will handle the creation.
2476 *
2477 * @param Folder $folderObject Absolute filepath on server in which to create the new folder.
2478 * @return string HTML for the create folder form.
2479 * @todo Define visibility
2480 */
2481 public function createFolder(Folder $folderObject) {
2482 if (!$folderObject->checkActionPermission('write')) {
2483 return '';
2484 }
2485 if (!($GLOBALS['BE_USER']->isAdmin() || $GLOBALS['BE_USER']->getTSConfigVal('options.createFoldersInEB'))) {
2486 return '';
2487 }
2488 // Don't show Folder-create form if it's denied
2489 if ($GLOBALS['BE_USER']->getTSConfigVal('options.folderTree.hideCreateFolder')) {
2490 return '';
2491 }
2492 // Create header, showing upload path:
2493 $header = $folderObject->getIdentifier();
2494 $code = '
2495
2496 <!--
2497 Form, for creating new folders:
2498 -->
2499 <form action="' . $GLOBALS['BACK_PATH'] . 'tce_file.php" method="post" name="editform2" id="typo3-crFolderForm">
2500 <table border="0" cellpadding="0" cellspacing="0" id="typo3-crFolder">
2501 <tr>
2502 <td>' . $this->barheader($GLOBALS['LANG']->sL(
2503 'LLL:EXT:lang/locallang_core.xlf:file_newfolder.php.pagetitle') . ':') . '</td>
2504 </tr>
2505 <tr>
2506 <td class="c-wCell c-hCell"><strong>'
2507 . $GLOBALS['LANG']->getLL('path', TRUE) . ':</strong> ' . htmlspecialchars($header) . '</td>
2508 </tr>
2509 <tr>
2510 <td class="c-wCell c-hCell">';
2511 // Create the new-folder name field:
2512 $a = 1;
2513 $code .= '<input' . $this->doc->formWidth(20) . ' type="text" name="file[newfolder][' . $a . '][data]" />'
2514 . '<input type="hidden" name="file[newfolder][' . $a . '][target]" value="'
2515 . htmlspecialchars($folderObject->getCombinedIdentifier()) . '" />';
2516 // Make footer of upload form, including the submit button:
2517 $redirectValue = $this->getThisScript() . 'act=' . $this->act . '&mode=' . $this->mode
2518 . '&expandFolder=' . rawurlencode($folderObject->getCombinedIdentifier())
2519 . '&bparams=' . rawurlencode($this->bparams);
2520 $code .= '<input type="hidden" name="redirect" value="' . htmlspecialchars($redirectValue) . '" />'
2521 . \TYPO3\CMS\Backend\Form\FormEngine::getHiddenTokenField('tceAction')
2522 . '<input type="submit" name="submit" value="'
2523 . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:file_newfolder.php.submit', TRUE) . '" />';
2524 $code .= '</td>
2525 </tr>
2526 </table>
2527 </form>';
2528 return $code;
2529 }
2530
2531 /**
2532 * Get the HTML data required for a bulk selection of files of the TYPO3 Element Browser.
2533 *
2534 * @param integer $filesCount Number of files currently displayed
2535 * @return string HTML data required for a bulk selection of files - if $filesCount is 0, nothing is returned
2536 * @todo Define visibility
2537 */
2538 public function getBulkSelector($filesCount) {
2539 if (!$filesCount) {
2540 return '';
2541 }
2542
2543 $labelToggleSelection = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_browse_links.xlf:toggleSelection', TRUE);
2544 $labelImportSelection = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_browse_links.xlf:importSelection', TRUE);
2545 // Getting flag for showing/not showing thumbnails:
2546 $noThumbsInEB = $GLOBALS['BE_USER']->getTSConfigVal('options.noThumbsInEB');
2547 $out = $this->doc->spacer(10) . '<div>' . '<a href="#" onclick="BrowseLinks.Selector.handle()">'
2548 . '<img' . IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/import.gif', 'width="12" height="12"')
2549 . ' title="' . $labelImportSelection . '" alt="" /> ' . $labelImportSelection . '</a>&nbsp;&nbsp;&nbsp;'
2550 . '<a href="#" onclick="BrowseLinks.Selector.toggle()">' . '<img'
2551 . IconUtility::skinImg($GLOBALS['BACK_PATH'], 'gfx/clip_select.gif', 'width="12" height="12"')
2552 . ' title="' . $labelToggleSelection . '" alt="" /> ' . $labelToggleSelection . '</a>' . '</div>';
2553 $thumbNailCheck = '';
2554 if (!$noThumbsInEB && $this->selectedFolder) {
2555 // MENU-ITEMS, fetching the setting for thumbnails from File>List module:
2556 $_MOD_MENU = array('displayThumbs' => '');
2557 $_MCONF['name'] = 'file_list';
2558 $_MOD_SETTINGS = BackendUtility::getModuleData($_MOD_MENU, GeneralUtility::_GP('SET'), $_MCONF['name']);
2559 $addParams = '&act=' . $this->act . '&mode=' . $this->mode
2560 . '&expandFolder=' . rawurlencode($this->selectedFolder->getCombinedIdentifier())
2561 . '&bparams=' . rawurlencode($this->bparams);
2562 $thumbNailCheck = BackendUtility::getFuncCheck('', 'SET[displayThumbs]', $_MOD_SETTINGS['displayThumbs'],
2563 GeneralUtility::_GP('M') ? '' : $this->thisScript, $addParams, 'id="checkDisplayThumbs"')
2564 . ' <label for="checkDisplayThumbs">'
2565 . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_file_list.xlf:displayThumbs', TRUE) . '</label>';
2566 $out .= $this->doc->spacer(5) . $thumbNailCheck . $this->doc->spacer(15);
2567 } else {
2568 $out .= $this->doc->spacer(15);
2569 }
2570 return $out;
2571 }
2572
2573 /**
2574 * Determines whether submitted field change functions are valid
2575 * and are coming from the system and not from an external abuse.
2576 *
2577 * @param boolean $handleFlexformSections Whether to handle flexform sections differently
2578 * @return boolean Whether the submitted field change functions are valid
2579 */
2580 protected function areFieldChangeFunctionsValid($handleFlexformSections = FALSE) {
2581 $result = FALSE;
2582 if (isset($this->P['fieldChangeFunc']) && is_array($this->P['fieldChangeFunc']) && isset($this->P['fieldChangeFuncHash'])) {
2583 $matches = array();
2584 $pattern = '#\\[el\\]\\[(([^]-]+-[^]-]+-)(idx\\d+-)([^]]+))\\]#i';
2585 $fieldChangeFunctions = $this->P['fieldChangeFunc'];
2586 // Special handling of flexform sections:
2587 // Field change functions are modified in JavaScript, thus the hash is always invalid
2588 if ($handleFlexformSections && preg_match($pattern, $this->P['itemName'], $matches)) {
2589 $originalName = $matches[1];
2590 $cleanedName = $matches[2] . $matches[4];
2591 foreach ($fieldChangeFunctions as &$value) {
2592 $value = str_replace($originalName, $cleanedName, $value);
2593 }
2594 unset($value);
2595 }
2596 $result = $this->P['fieldChangeFuncHash'] === GeneralUtility::hmac(serialize($fieldChangeFunctions));
2597 }
2598 return $result;
2599 }
2600
2601 /**
2602 * Check if a temporary tree mount is set and return a cancel button
2603 *
2604 * @return string
2605 */
2606 protected function getTemporaryTreeMountCancelNotice() {
2607 if ((int)$GLOBALS['BE_USER']->getSessionData('pageTree_temporaryMountPoint') === 0) {
2608 return '';
2609 }
2610 $link = '<a href="' . htmlspecialchars(GeneralUtility::linkThisScript(array('setTempDBmount' => 0))) . '">'
2611 . $GLOBALS['LANG']->sl('LLL:EXT:lang/locallang_core.xlf:labels.temporaryDBmount', TRUE) . '</a>';
2612 /** @var \TYPO3\CMS\Core\Messaging\FlashMessage $flashMessage */
2613 $flashMessage = GeneralUtility::makeInstance(
2614 'TYPO3\\CMS\\Core\\Messaging\\FlashMessage',
2615 $link,
2616 '',
2617 \TYPO3\CMS\Core\Messaging\FlashMessage::INFO
2618 );
2619 return $flashMessage->render();
2620 }
2621
2622 /**
2623 * Get a list of Files in a folder filtered by extension
2624 *
2625 * @param \TYPO3\CMS\Core\Resource\Folder $folder
2626 * @param string $extensionList
2627 * @return \TYPO3\CMS\Core\Resource\File[]
2628 */
2629 protected function getFilesInFolder(\TYPO3\CMS\Core\Resource\Folder $folder, $extensionList) {
2630 if ($extensionList !== '') {
2631 /** @var \TYPO3\CMS\Core\Resource\Filter\FileExtensionFilter $filter */
2632 $filter = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\Filter\\FileExtensionFilter');
2633 $filter->setAllowedFileExtensions($extensionList);
2634 $folder->setFileAndFolderNameFilters(array(array($filter, 'filterFileList')));
2635 }
2636 return $folder->getFiles();
2637 }
2638 }