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