Updates mainly to import/export extension. Many smaller changes / additions. See...
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_clipboard.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2004 Kasper Skaarhoj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Contains class for TYPO3 clipboard for records and files
29 *
30 * $Id$
31 * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
32 * XHTML compliant
33 *
34 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
35 */
36 /**
37 * [CLASS/FUNCTION INDEX of SCRIPT]
38 *
39 *
40 *
41 * 90: class t3lib_clipboard
42 * 126: function initializeClipboard()
43 * 155: function lockToNormal()
44 * 172: function setCmd($cmd)
45 * 219: function setCurrentPad($padIdent)
46 * 234: function endClipboard()
47 * 247: function cleanUpCBC($CBarr,$table,$removeDeselected=0)
48 * 265: function isElements()
49 * 274: function printClipboard()
50 * 363: function printContentFromTab($pad)
51 * 437: function padTitleWrap($str,$pad)
52 * 454: function linkItemText($str,$rec,$table='')
53 * 479: function isSelected($table,$uid)
54 * 493: function getSelectedRecord($table='',$uid='')
55 * 516: function selUrlDB($table,$uid,$copy=0,$deselect=0,$baseArray=array())
56 * 532: function selUrlFile($path,$copy=0,$deselect=0,$baseArray=array())
57 * 549: function pasteUrl($table,$uid,$setRedirect=1)
58 * 566: function deleteUrl($setRedirect=1,$file=0)
59 * 583: function editUrl()
60 * 604: function removeUrl($table,$uid)
61 * 614: function cleanCurrent()
62 * 641: function elFromTable($matchTable='',$pad='')
63 * 673: function confirmMsg($table,$rec,$type,$clElements)
64 * 716: function removeElement($el)
65 * 728: function saveClipboard()
66 * 738: function currentMode()
67 * 749: function clLabel($key,$Akey='labels')
68 *
69 * SECTION: FOR USE IN tce_db.php:
70 * 790: function makePasteCmdArray($ref,$CMD)
71 * 819: function makeDeleteCmdArray($CMD)
72 *
73 * SECTION: FOR USE IN tce_file.php:
74 * 862: function makePasteCmdArray_file($ref,$FILE)
75 * 884: function makeDeleteCmdArray_file($FILE)
76 *
77 * TOTAL FUNCTIONS: 30
78 * (This index is automatically created/updated by the extension "extdeveval")
79 *
80 */
81
82
83 /**
84 * TYPO3 clipboard for records and files
85 *
86 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
87 * @package TYPO3
88 * @subpackage t3lib
89 */
90 class t3lib_clipboard {
91 var $numberTabs = 3;
92
93 /**
94 * Clipboard data kept here
95 *
96 * Keys:
97 * 'normal'
98 * 'tab_[x]' where x is >=1 and denotes the pad-number
99 * \ 'mode' : 'copy' means copy-mode, default = moving ('cut')
100 * \ 'el' : Array of elements:
101 * DB: keys = '[tablename]|[uid]' eg. 'tt_content:123'
102 * DB: values = 1 (basically insignificant)
103 * FILE: keys = '_FILE|[shortmd5 of path]' eg. '_FILE|9ebc7e5c74'
104 * FILE: values = The full filepath, eg. '/www/htdocs/typo3/32/dummy/fileadmin/sem1_3_examples/alternative_index.php' or 'C:/www/htdocs/typo3/32/dummy/fileadmin/sem1_3_examples/alternative_index.php'
105 *
106 * 'current' pointer to current tab (among the above...)
107 * '_setThumb' boolean: If set, file thumbnails are shown.
108 *
109 * The virtual tablename '_FILE' will always indicate files/folders. When checking for elements from eg. 'all tables' (by using an empty string) '_FILE' entries are excluded (so in effect only DB elements are counted)
110 *
111 */
112 var $clipData=array();
113
114 var $changed=0;
115 var $current='';
116 var $backPath='';
117 var $lockToNormal=0;
118 var $fileMode=0; // If set, clipboard is displaying files.
119
120
121
122
123
124
125
126
127
128
129
130
131
132 /*****************************************
133 *
134 * Initialize
135 *
136 ****************************************/
137
138 /**
139 * Initialize the clipboard from the be_user session
140 *
141 * @return void
142 */
143 function initializeClipboard() {
144 global $BE_USER;
145
146 // Get data
147 $clipData = $BE_USER->getModuleData('clipboard',$BE_USER->getTSConfigVal('options.saveClipboard')?'':'ses');
148
149 // NumberTabs
150 $clNP = $BE_USER->getTSConfigVal('options.clipboardNumberPads');
151 if (t3lib_div::testInt($clNP) && $clNP>=0) {
152 $this->numberTabs = t3lib_div::intInRange($clNP,0,20);
153 }
154
155 // Resets/reinstates the clipboard pads
156 $this->clipData['normal'] = is_array($clipData['normal']) ? $clipData['normal'] : array();
157 for ($a=1;$a<=$this->numberTabs;$a++) {
158 $this->clipData['tab_'.$a] = is_array($clipData['tab_'.$a]) ? $clipData['tab_'.$a] : array();
159 }
160
161 // Setting the current pad pointer ($this->current) and _setThumb (which determines whether or not do show file thumbnails)
162 $this->clipData['current'] = $this->current = isset($this->clipData[$clipData['current']]) ? $clipData['current'] : 'normal';
163 $this->clipData['_setThumb'] = $clipData['_setThumb'];
164 }
165
166 /**
167 * Call this method after initialization if you want to lock the clipboard to operate on the normal pad only. Trying to switch pad through ->setCmd will not work
168 * This is used by the clickmenu since it only allows operation on single elements at a time (that is the "normal" pad)
169 *
170 * @return void
171 */
172 function lockToNormal() {
173 $this->lockToNormal = 1;
174 $this->current = 'normal';
175 }
176
177 /**
178 * The array $cmd may hold various keys which notes some action to take.
179 * Normally perform only one action at a time.
180 * In scripts like db_list.php / file_list.php the GET-var CB is used to control the clipboard.
181 *
182 * Selecting / Deselecting elements
183 * Array $cmd['el'] has keys = element-ident, value = element value (see description of clipData array in header)
184 * Selecting elements for 'copy' should be done by simultaneously setting setCopyMode.
185 *
186 * @param array Array of actions, see function description
187 * @return void
188 */
189 function setCmd($cmd) {
190 if (is_array($cmd['el'])) {
191 reset($cmd['el']);
192 while(list($k,$v)=each($cmd['el'])) {
193 if ($this->current=='normal') {
194 unset($this->clipData['normal']);
195 }
196 if ($v) {
197 $this->clipData[$this->current]['el'][$k]=$v;
198 } else {
199 $this->removeElement($k);
200 }
201 $this->changed=1;
202 }
203 }
204 // Change clipboard pad (if not locked to normal)
205 if ($cmd['setP']) {
206 $this->setCurrentPad($cmd['setP']);
207 }
208 // Remove element (value = item ident: DB; '[tablename]|[uid]' FILE: '_FILE|[shortmd5 hash of path]'
209 if ($cmd['remove']) {
210 $this->removeElement($cmd['remove']);
211 $this->changed=1;
212 }
213 // Remove all on current pad (value = pad-ident)
214 if ($cmd['removeAll']) {
215 $this->clipData[$cmd['removeAll']]=array();
216 $this->changed=1;
217 }
218 // Set copy mode of the tab
219 if (isset($cmd['setCopyMode'])) {
220 $this->clipData[$this->current]['mode']=$this->isElements()?($cmd['setCopyMode']?'copy':''):'';
221 $this->changed=1;
222 }
223 // Toggle thumbnail display for files on/off
224 if (isset($cmd['setThumb'])) {
225 $this->clipData['_setThumb']=$cmd['setThumb'];
226 $this->changed=1;
227 }
228 }
229
230 /**
231 * Setting the current pad on clipboard
232 *
233 * @param string Key in the array $this->clipData
234 * @return void
235 */
236 function setCurrentPad($padIdent) {
237 // Change clipboard pad (if not locked to normal)
238 if (!$this->lockToNormal && $this->current!=$padIdent) {
239 if (isset($this->clipData[$padIdent])) $this->clipData['current'] = $this->current = $padIdent;
240 if ($this->current!='normal' || !$this->isElements()) $this->clipData[$this->current]['mode']=''; // Setting mode to default (move) if no items on it or if not 'normal'
241 $this->changed=1;
242 }
243 }
244
245 /**
246 * Call this after initialization and setCmd in order to save the clipboard to the user session.
247 * The function will check if the internal flag ->changed has been set and if so, save the clipboard. Else not.
248 *
249 * @return void
250 */
251 function endClipboard() {
252 if ($this->changed) $this->saveClipboard();
253 $this->changed=0;
254 }
255
256 /**
257 * Cleans up an incoming element array $CBarr (Array selecting/deselecting elements)
258 *
259 * @param array Element array from outside ("key" => "selected/deselected")
260 * @param string $table is the 'table which is allowed'. Must be set.
261 * @param boolean $removeDeselected can be set in order to remove entries which are marked for deselection.
262 * @return array Processed input $CBarr
263 */
264 function cleanUpCBC($CBarr,$table,$removeDeselected=0) {
265 if (is_array($CBarr)) {
266 reset($CBarr);
267 while(list($k,$v)=each($CBarr)) {
268 $p=explode('|',$k);
269 if ((string)$p[0]!=(string)$table || ($removeDeselected && !$v)) {
270 unset($CBarr[$k]);
271 }
272 }
273 }
274 return $CBarr;
275 }
276
277
278
279
280
281
282
283
284
285
286
287
288 /*****************************************
289 *
290 * Clipboard HTML renderings
291 *
292 ****************************************/
293
294 /**
295 * Prints the clipboard
296 *
297 * @return string HTML output
298 */
299 function printClipboard() {
300 global $TBE_TEMPLATE,$LANG;
301
302 $out=array();
303 $elCount = count($this->elFromTable($this->fileMode?'_FILE':''));
304
305 // Upper header
306 $out[]='
307 <tr class="bgColor2">
308 <td colspan="3" nowrap="nowrap" align="center"><span class="uppercase"><strong>'.$this->clLabel('clipboard','buttons').'</strong></span></td>
309 </tr>';
310
311 // Button/menu header:
312 $thumb_url = t3lib_div::linkThisScript(array('CB'=>array('setThumb'=>$this->clipData['_setThumb']?0:1)));
313 $copymode_url = t3lib_div::linkThisScript(array('CB'=>array('setCopyMode'=>($this->currentMode()=='copy'?'':'copy'))));
314 $rmall_url = t3lib_div::linkThisScript(array('CB'=>array('removeAll'=>$this->current)));
315
316 // Selector menu + clear button
317 $opt=array();
318 $opt[]='<option value="" selected="selected">'.$this->clLabel('menu','rm').'</option>';
319 // Import / Export link:
320 if ($elCount && t3lib_extMgm::isLoaded('impexp')) {
321 $opt[] = '<option value="'.htmlspecialchars("document.location='".$this->backPath.t3lib_extMgm::extRelPath('impexp').'app/index.php'.$this->exportClipElementParameters().'\';').'">'.$this->clLabel('export','rm').'</option>';
322 }
323 // Edit:
324 if (!$this->fileMode && $elCount) {
325 $opt[]='<option value="'.htmlspecialchars("document.location='".$this->editUrl()."&returnUrl='+top.rawurlencode(document.location);").'">'.$this->clLabel('edit','rm').'</option>';
326 }
327 // Delete:
328 if ($elCount) {
329 $opt[]='<option value="'.htmlspecialchars("
330 if(confirm(".$GLOBALS['LANG']->JScharCode(sprintf($LANG->sL('LLL:EXT:lang/locallang_core.php:mess.deleteClip'),$elCount)).")){
331 document.location='".$this->deleteUrl(0,$this->fileMode?1:0)."&redirect='+top.rawurlencode(document.location);
332 }
333 ").'">'.$this->clLabel('delete','rm').'</option>';
334 }
335 $selector_menu = '<select name="_clipMenu" onchange="eval(this.options[this.selectedIndex].value);this.selectedIndex=0;">'.implode('',$opt).'</select>';
336
337 $out[]='
338 <tr class="typo3-clipboard-head">
339 <td nowrap="nowrap">'.
340 '<a href="'.htmlspecialchars($thumb_url).'#clip_head">'.
341 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/thumb_'.($this->clipData['_setThumb']?'s':'n').'.gif','width="21" height="16"').' vspace="2" border="0" title="'.$this->clLabel('thumbmode_clip').'" alt="" />'.
342 '</a>'.
343 '<a href="'.htmlspecialchars($copymode_url).'#clip_head">'.
344 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/copymode_'.($this->currentMode()=='copy'?'s':'n').'.gif','width="21" height="16"').' vspace="2" border="0" title="'.$this->clLabel('copymode').'" alt="" />'.
345 '</a>'.
346 '</td>
347 <td width="95%">'.$selector_menu.'</td>
348 <td>'.
349 '<a href="'.htmlspecialchars($rmall_url).'#clip_head">'.
350 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/closedok_2.gif','width="21" height="16"').' vspace="2" border="0" title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:buttons.clear',1).'" alt="" />'.
351 '</a></td>
352 </tr>';
353
354
355 // Print header and content for the NORMAL tab:
356 $out[]='
357 <tr class="bgColor5">
358 <td colspan="3"><a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('CB'=>array('setP'=>'normal')))).'#clip_head">'.
359 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/ol/'.($this->current=='normal'?'minus':'plus').'bullet.gif','width="18" height="16"').' border="0" align="top" alt="" />'.
360 $this->padTitleWrap('Normal','normal').
361 '</a></td>
362 </tr>';
363 if ($this->current=='normal') $out=array_merge($out,$this->printContentFromTab('normal'));
364
365 // Print header and content for the NUMERIC tabs:
366 for ($a=1;$a<=$this->numberTabs;$a++) {
367 $out[]='
368 <tr class="bgColor5">
369 <td colspan="3"><a href="'.htmlspecialchars(t3lib_div::linkThisScript(array('CB'=>array('setP'=>'tab_'.$a)))).'#clip_head">'.
370 '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/ol/'.($this->current=='tab_'.$a?'minus':'plus').'bullet.gif','width="18" height="16"').' border="0" align="top" alt="" />'.
371 $this->padTitleWrap($this->clLabel('cliptabs').$a,'tab_'.$a).
372 '</a></td>
373 </tr>';
374 if ($this->current=='tab_'.$a) $out=array_merge($out,$this->printContentFromTab('tab_'.$a));
375 }
376
377 // Wrap accumulated rows in a table:
378 $output = '<a name="clip_head"></a>
379
380 <!--
381 TYPO3 Clipboard:
382 -->
383 <table cellpadding="0" cellspacing="1" border="0" width="290" id="typo3-clipboard">
384 '.implode('',$out).'
385 </table>';
386
387 // Wrap in form tag:
388 $output = '<form action="">'.$output.'</form>';
389
390 // Return the accumulated content:
391 return $output;
392 }
393
394 /**
395 * Print the content on a pad. Called from ->printClipboard()
396 *
397 * @param string Pad reference
398 * @return array Array with table rows for the clipboard.
399 * @access private
400 */
401 function printContentFromTab($pad) {
402 global $TBE_TEMPLATE;
403
404 $lines=array();
405 if (is_array($this->clipData[$pad]['el'])) {
406 reset($this->clipData[$pad]['el']);
407 while(list($k,$v)=each($this->clipData[$pad]['el'])) {
408 if ($v) {
409 list($table,$uid) = explode('|',$k);
410 $bgColClass = ($table=='_FILE'&&$this->fileMode)||($table!='_FILE'&&!$this->fileMode) ? 'bgColor4-20' : 'bgColor4';
411
412 if ($table=='_FILE') { // Rendering files/directories on the clipboard:
413 if (@file_exists($v) && t3lib_div::isAllowedAbsPath($v)) {
414 $fI = pathinfo($v);
415 $icon = is_dir($v) ? 'folder.gif' : t3lib_BEfunc::getFileIcon(strtolower($fI['extension']));
416 $size = ' ('.t3lib_div::formatSize(filesize($v)).'bytes)';
417 $icon = '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/fileicons/'.$icon,'width="18" height="16"').' border="0" hspace="20" class="absmiddle" title="'.htmlspecialchars($fI['basename'].$size).'" alt="" />';
418 $thumb = $this->clipData['_setThumb'] ? (t3lib_div::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],$fI['extension']) ? t3lib_BEfunc::getThumbNail($this->backPath.'thumbs.php',$v,' vspace="4"') : '') :'';
419
420 $lines[]='
421 <tr>
422 <td class="'.$bgColClass.'">'.$icon.'</td>
423 <td class="'.$bgColClass.'" nowrap="nowrap" width="95%">&nbsp;'.$this->linkItemText(htmlspecialchars(t3lib_div::fixed_lgd_cs(basename($v),$GLOBALS['BE_USER']->uc['titleLen'])),$v).
424 ($pad=='normal'?(' <strong>('.($this->clipData['normal']['mode']=='copy'?$this->clLabel('copy','cm'):$this->clLabel('cut','cm')).')</strong>'):'').'&nbsp;'.($thumb?'<br />'.$thumb:'').'</td>
425 <td class="'.$bgColClass.'" align="center" nowrap="nowrap">'.
426 '<a href="#" onclick="'.htmlspecialchars('top.launchView(\''.$v.'\', \'\'); return false;').'"><img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/zoom2.gif','width="12" height="12"').' hspace="2" border="0" title="'.$this->clLabel('info','cm').'" alt="" /></a>'.
427 '<a href="'.htmlspecialchars($this->removeUrl('_FILE',t3lib_div::shortmd5($v))).'#clip_head"><img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/close_12h.gif','width="11" height="12"').' border="0" title="'.$this->clLabel('removeItem').'" alt="" /></a>'.
428 '</td>
429 </tr>';
430 } else {
431 // If the file did not exist (or is illegal) then it is removed from the clipboard immediately:
432 unset($this->clipData[$pad]['el'][$k]);
433 $this->changed=1;
434 }
435 } else { // Rendering records:
436 $rec=t3lib_BEfunc::getRecord($table,$uid);
437 if (is_array($rec)) {
438 $lines[]='
439 <tr>
440 <td class="'.$bgColClass.'">'.$this->linkItemText(t3lib_iconWorks::getIconImage($table,$rec,$this->backPath,'hspace="20" title="'.htmlspecialchars(t3lib_BEfunc::getRecordIconAltText($rec,$table)).'"'),$rec,$table).'</td>
441 <td class="'.$bgColClass.'" nowrap="nowrap" width="95%">&nbsp;'.$this->linkItemText(htmlspecialchars(t3lib_div::fixed_lgd_cs(t3lib_BEfunc::getRecordTitle($table,$rec),$GLOBALS['BE_USER']->uc['titleLen'])),$rec,$table).
442 ($pad=='normal'?(' <strong>('.($this->clipData['normal']['mode']=='copy'?$this->clLabel('copy','cm'):$this->clLabel('cut','cm')).')</strong>'):'').'&nbsp;</td>
443 <td class="'.$bgColClass.'" align="center" nowrap="nowrap">'.
444 '<a href="#" onclick="'.htmlspecialchars('top.launchView(\''.$table.'\', \''.intval($uid).'\'); return false;').'"><img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/zoom2.gif','width="12" height="12"').' hspace="2" border="0" title="'.$this->clLabel('info','cm').'" alt="" /></a>'.
445 '<a href="'.htmlspecialchars($this->removeUrl($table,$uid)).'#clip_head"><img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/close_12h.gif','width="11" height="12"').' border="0" title="'.$this->clLabel('removeItem').'" alt="" /></a>'.
446 '</td>
447 </tr>';
448 } else {
449 unset($this->clipData[$pad]['el'][$k]);
450 $this->changed=1;
451 }
452 }
453 }
454 }
455 }
456 if (!count($lines)) {
457 $lines[]='
458 <tr>
459 <td class="bgColor4"><img src="clear.gif" width="56" height="1" alt="" /></td>
460 <td colspan="2" class="bgColor4" nowrap="nowrap" width="95%">&nbsp;<em>('.$this->clLabel('clipNoEl').')</em>&nbsp;</td>
461 </tr>';
462 }
463
464 $this->endClipboard();
465 return $lines;
466 }
467
468 /**
469 * Wraps title of pad in bold-tags and maybe the number of elements if any.
470 *
471 * @param string String (already htmlspecialchars()'ed)
472 * @param string Pad reference
473 * @return string HTML output (htmlspecialchar'ed content inside of tags.)
474 */
475 function padTitleWrap($str,$pad) {
476 $el = count($this->elFromTable($this->fileMode?'_FILE':'',$pad));
477 if ($el) {
478 return '<strong>'.$str.'</strong> ('.($pad=='normal'?($this->clipData['normal']['mode']=='copy'?$this->clLabel('copy','cm'):$this->clLabel('cut','cm')):htmlspecialchars($el)).')';
479 } else {
480 return $GLOBALS['TBE_TEMPLATE']->dfw($str);
481 }
482 }
483
484 /**
485 * Wraps the title of the items listed in link-tags. The items will link to the page/folder where they originate from
486 *
487 * @param string Title of element - must be htmlspecialchar'ed on beforehand.
488 * @param mixed If array, a record is expected. If string, its a path
489 * @param string Table name
490 * @return string
491 */
492 function linkItemText($str,$rec,$table='') {
493 if (is_array($rec) && $table) {
494 if ($this->fileMode) {
495 $str=$GLOBALS['TBE_TEMPLATE']->dfw($str);
496 } else {
497 $str='<a href="'.htmlspecialchars($this->backPath.'db_list.php?id='.$rec['pid']).'">'.$str.'</a>';
498 }
499 } elseif (@file_exists($rec)) {
500 if (!$this->fileMode) {
501 $str=$GLOBALS['TBE_TEMPLATE']->dfw($str);
502 } else {
503 $str='<a href="'.htmlspecialchars($this->backPath.'file_list.php?id='.dirname($rec)).'">'.$str.'</a>';
504 }
505 }
506 return $str;
507 }
508
509 /**
510 * Returns the select-url for database elements
511 *
512 * @param string Table name
513 * @param integer Uid of record
514 * @param boolean If set, copymode will be enabled
515 * @param boolean If set, the link will deselect, otherwise select.
516 * @param array The base array of GET vars to be sent in addition. Notice that current GET vars WILL automatically be included.
517 * @return string URL linking to the current script but with the CB array set to select the element with table/uid
518 */
519 function selUrlDB($table,$uid,$copy=0,$deselect=0,$baseArray=array()) {
520 $CB = array('el'=>array(rawurlencode($table.'|'.$uid)=>$deselect?0:1));
521 if ($copy) $CB['setCopyMode'] = 1;
522 $baseArray['CB'] = $CB;
523 return t3lib_div::linkThisScript($baseArray);
524 }
525
526 /**
527 * Returns the select-url for files
528 *
529 * @param string Filepath
530 * @param boolean If set, copymode will be enabled
531 * @param boolean If set, the link will deselect, otherwise select.
532 * @param array The base array of GET vars to be sent in addition. Notice that current GET vars WILL automatically be included.
533 * @return string URL linking to the current script but with the CB array set to select the path
534 */
535 function selUrlFile($path,$copy=0,$deselect=0,$baseArray=array()) {
536 $CB=array('el'=>array(rawurlencode('_FILE|'.t3lib_div::shortmd5($path))=>$deselect?'':$path));
537 if ($copy) $CB['setCopyMode']=1;
538 $baseArray['CB']=$CB;
539 return t3lib_div::linkThisScript($baseArray);
540 }
541
542 /**
543 * pasteUrl of the element (database and file)
544 * For the meaning of $table and $uid, please read from ->makePasteCmdArray!!!
545 * The URL will point to tce_file or tce_db depending in $table
546 *
547 * @param string Tablename (_FILE for files)
548 * @param mixed "destination": can be positive or negative indicating how the paste is done (paste into / paste after)
549 * @param boolean If set, then the redirect URL will point back to the current script, but with CB reset.
550 * @return string
551 */
552 function pasteUrl($table,$uid,$setRedirect=1) {
553 $rU = $this->backPath.($table=='_FILE'?'tce_file.php':'tce_db.php').'?'.
554 ($setRedirect ? 'redirect='.rawurlencode(t3lib_div::linkThisScript(array('CB'=>''))) : '').
555 '&vC='.$GLOBALS['BE_USER']->veriCode().
556 '&prErr=1&uPT=1'.
557 '&CB[paste]='.rawurlencode($table.'|'.$uid).
558 '&CB[pad]='.$this->current;
559 return $rU;
560 }
561
562 /**
563 * deleteUrl for current pad
564 *
565 * @param boolean If set, then the redirect URL will point back to the current script, but with CB reset.
566 * @param boolean If set, then the URL will link to the tce_file.php script in the typo3/ dir.
567 * @return string
568 */
569 function deleteUrl($setRedirect=1,$file=0) {
570 $rU = $this->backPath.($file?'tce_file.php':'tce_db.php').'?'.
571 ($setRedirect ? 'redirect='.rawurlencode(t3lib_div::linkThisScript(array('CB'=>''))) : '').
572 '&vC='.$GLOBALS['BE_USER']->veriCode().
573 '&prErr=1&uPT=1'.
574 '&CB[delete]=1'.
575 '&CB[pad]='.$this->current;
576 return $rU;
577 }
578
579 /**
580 * editUrl of all current elements
581 * ONLY database
582 * Links to alt_doc.php
583 *
584 * @return string The URL to alt_doc.php with parameters.
585 */
586 function editUrl() {
587 $elements = $this->elFromTable(''); // all records
588 reset($elements);
589 $editCMDArray=array();
590 while(list($tP)=each($elements)) {
591 list($table,$uid) = explode('|',$tP);
592 $editCMDArray[] = '&edit['.$table.']['.$uid.']=edit';
593 }
594
595 $rU = $this->backPath.'alt_doc.php?'.implode('',$editCMDArray);
596 return $rU;
597 }
598
599 /**
600 * Returns the remove-url (file and db)
601 * for file $table='_FILE' and $uid = shortmd5 hash of path
602 *
603 * @param string Tablename
604 * @param string uid integer/shortmd5 hash
605 * @return string URL
606 */
607 function removeUrl($table,$uid) {
608 return t3lib_div::linkThisScript(array('CB'=>array('remove'=>$table.'|'.$uid)));
609 }
610
611 /**
612 * Returns confirm JavaScript message
613 *
614 * @param string Table name
615 * @param mixed For records its an array, for files its a string (path)
616 * @param string Type-code
617 * @param array Array of selected elements
618 * @return string JavaScript "confirm" message
619 */
620 function confirmMsg($table,$rec,$type,$clElements) {
621 $labelKey = 'LLL:EXT:lang/locallang_core.php:mess.'.($this->currentMode()=='copy'?'copy':'move').($this->current=='normal'?'':'cb').'_'.$type;
622 $msg = $GLOBALS['LANG']->sL($labelKey);
623
624 if ($table=='_FILE') {
625 $thisRecTitle = basename($rec);
626 if ($this->current=='normal') {
627 reset($clElements);
628 $selItem = current($clElements);
629 $selRecTitle = basename($selItem);
630 } else {
631 $selRecTitle=count($clElements);
632 }
633 } else {
634 $thisRecTitle = (
635 $table=='pages' && !is_array($rec) ?
636 $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] :
637 t3lib_BEfunc::getRecordTitle($table,$rec)
638 );
639
640 if ($this->current=='normal') {
641 $selItem = $this->getSelectedRecord();
642 $selRecTitle=$selItem['_RECORD_TITLE'];
643 } else {
644 $selRecTitle=count($clElements);
645 }
646 }
647
648 // Message:
649 $conf='confirm('.$GLOBALS['LANG']->JScharCode(sprintf(
650 $msg,
651 t3lib_div::fixed_lgd_cs($selRecTitle,30),
652 t3lib_div::fixed_lgd_cs($thisRecTitle,30)
653 )).')';
654 return $conf;
655 }
656
657 /**
658 * Clipboard label - getting from "EXT:lang/locallang_core.php:"
659 *
660 * @param string Label Key
661 * @param string Alternative key to "labels"
662 * @return string
663 */
664 function clLabel($key,$Akey='labels') {
665 return htmlspecialchars($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:'.$Akey.'.'.$key));
666 }
667
668 /**
669 * Creates GET parameters for linking to the export module.
670 *
671 * @return string GET parameters for current clipboard content to be exported.
672 */
673 function exportClipElementParameters() {
674
675 // Init:
676 $pad = $this->current;
677 $params = array();
678 $params[] = 'tx_impexp[action]=export';
679
680 // Traverse items:
681 if (is_array($this->clipData[$pad]['el'])) {
682 reset($this->clipData[$pad]['el']);
683 while(list($k,$v)=each($this->clipData[$pad]['el'])) {
684 if ($v) {
685 list($table,$uid) = explode('|',$k);
686
687 if ($table=='_FILE') { // Rendering files/directories on the clipboard:
688 if (@file_exists($v) && t3lib_div::isAllowedAbsPath($v)) {
689 $params[] = 'tx_impexp['.(is_dir($v) ? 'dir' : 'file').'][]='.rawurlencode($v);
690 }
691 } else { // Rendering records:
692 $rec = t3lib_BEfunc::getRecord($table,$uid);
693 if (is_array($rec)) {
694 $params[] = 'tx_impexp[record][]='.rawurlencode($table.':'.$uid);
695 }
696 }
697 }
698 }
699 }
700
701 return '?'.implode('&', $params);
702 }
703
704
705
706
707
708
709
710
711 /*****************************************
712 *
713 * Helper functions
714 *
715 ****************************************/
716
717 /**
718 * Removes element on clipboard
719 *
720 * @param string Key of element in ->clipData array
721 * @return void
722 */
723 function removeElement($el) {
724 unset($this->clipData[$this->current]['el'][$el]);
725 $this->changed=1;
726 }
727
728 /**
729 * Saves the clipboard, no questions asked.
730 * Use ->endClipboard normally (as it checks if changes has been done so saving is necessary)
731 *
732 * @return void
733 * @access private
734 */
735 function saveClipboard() {
736 global $BE_USER;
737 $BE_USER->pushModuleData('clipboard',$this->clipData);
738 }
739
740 /**
741 * Returns the current mode, 'copy' or 'cut'
742 *
743 * @return string "copy" or "cut"
744 */
745 function currentMode() {
746 return $this->clipData[$this->current]['mode']=='copy' ? 'copy' : 'cut';
747 }
748
749 /**
750 * This traverses the elements on the current clipboard pane
751 * and unsets elements which does not exist anymore or are disabled.
752 *
753 * @return void
754 */
755 function cleanCurrent() {
756 if (is_array($this->clipData[$this->current]['el'])) {
757 reset($this->clipData[$this->current]['el']);
758 while(list($k,$v)=each($this->clipData[$this->current]['el'])) {
759 list($table,$uid) = explode('|',$k);
760 if ($table!='_FILE') {
761 if (!$v || !is_array(t3lib_BEfunc::getRecord($table,$uid,'uid'))) {
762 unset($this->clipData[$this->current]['el'][$k]);
763 $this->changed=1;
764 }
765 } else {
766 if (!$v || !@file_exists($v)) {
767 unset($this->clipData[$this->current]['el'][$k]);
768 $this->changed=1;
769 }
770 }
771 }
772 }
773 }
774
775 /**
776 * Counts the number of elements from the table $matchTable. If $matchTable is blank, all tables (except '_FILE' of course) is counted.
777 *
778 * @param string Table to match/count for.
779 * @param string $pad can optionally be used to set another pad than the current.
780 * @return array Array with keys from the CB.
781 */
782 function elFromTable($matchTable='',$pad='') {
783 $pad = $pad ? $pad : $this->current;
784 $list=array();
785 if (is_array($this->clipData[$pad]['el'])) {
786 reset($this->clipData[$pad]['el']);
787 while(list($k,$v)=each($this->clipData[$pad]['el'])) {
788 if ($v) {
789 list($table,$uid) = explode('|',$k);
790 if ($table!='_FILE') {
791 if ((!$matchTable || (string)$table==(string)$matchTable) && $GLOBALS['TCA'][$table]) {
792 $list[$k]= ($pad=='normal'?$v:$uid);
793 }
794 } else {
795 if ((string)$table==(string)$matchTable) {
796 $list[$k]=$v;
797 }
798 }
799 }
800 }
801 }
802 return $list;
803 }
804
805 /**
806 * Verifies if the item $table/$uid is on the current pad.
807 * If the pad is "normal", the mode value is returned if the element existed. Thus you'll know if the item was copy or cut moded...
808 *
809 * @param string Table name, (_FILE for files...)
810 * @param integer Element uid (path for files)
811 * @return string
812 */
813 function isSelected($table,$uid) {
814 $k=$table.'|'.$uid;
815 return $this->clipData[$this->current]['el'][$k] ? ($this->current=='normal'?$this->currentMode():1) : '';
816 }
817
818 /**
819 * Returns item record $table,$uid if selected on current clipboard
820 * If table and uid is blank, the first element is returned.
821 * Makes sense only for DB records - not files!
822 *
823 * @param string Table name
824 * @param integer Element uid
825 * @return array Element record with extra field _RECORD_TITLE set to the title of the record...
826 */
827 function getSelectedRecord($table='',$uid='') {
828 if (!$table && !$uid) {
829 $elArr = $this->elFromTable('');
830 reset($elArr);
831 list($table,$uid) = explode('|',key($elArr));
832 }
833 if ($this->isSelected($table,$uid)) {
834 $selRec = t3lib_BEfunc::getRecord($table,$uid);
835 $selRec['_RECORD_TITLE'] = t3lib_BEfunc::getRecordTitle($table,$selRec);
836 return $selRec;
837 }
838 }
839
840 /**
841 * Reports if the current pad has elements (does not check file/DB type OR if file/DBrecord exists or not. Only counting array)
842 *
843 * @return boolean True if elements exist.
844 */
845 function isElements() {
846 return is_array($this->clipData[$this->current]['el']) && count($this->clipData[$this->current]['el']);
847 }
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863 /*****************************************
864 *
865 * FOR USE IN tce_db.php:
866 *
867 ****************************************/
868
869 /**
870 * Applies the proper paste configuration in the $cmd array send to tce_db.php.
871 * $ref is the target, see description below.
872 * The current pad is pasted
873 *
874 * $ref: [tablename]:[paste-uid].
875 * tablename is the name of the table from which elements *on the current clipboard* is pasted with the 'pid' paste-uid.
876 * No tablename means that all items on the clipboard (non-files) are pasted. This requires paste-uid to be positive though.
877 * so 'tt_content:-3' means 'paste tt_content elements on the clipboard to AFTER tt_content:3 record
878 * 'tt_content:30' means 'paste tt_content elements on the clipboard into page with id 30
879 * ':30' means 'paste ALL database elements on the clipboard into page with id 30
880 * ':-30' not valid.
881 *
882 * @param string [tablename]:[paste-uid], see description
883 * @param array Command-array
884 * @return array Modified Command-array
885 */
886 function makePasteCmdArray($ref,$CMD) {
887 list($pTable,$pUid) = explode('|',$ref);
888 $pUid = intval($pUid);
889
890 if ($pTable || $pUid>=0) { // pUid must be set and if pTable is not set (that means paste ALL elements) the uid MUST be positive/zero (pointing to page id)
891 $elements = $this->elFromTable($pTable);
892
893 $elements = array_reverse($elements); // So the order is preserved.
894 $mode = $this->currentMode()=='copy' ? 'copy' : 'move';
895
896 // Traverse elements and make CMD array
897 reset($elements);
898 while(list($tP)=each($elements)) {
899 list($table,$uid) = explode('|',$tP);
900 if (!is_array($CMD[$table])) $CMD[$table]=array();
901 $CMD[$table][$uid][$mode]=$pUid;
902 if ($mode=='move') $this->removeElement($tP);
903 }
904 $this->endClipboard();
905 }
906 return $CMD;
907 }
908
909 /**
910 * Delete record entries in CMD array
911 *
912 * @param array Command-array
913 * @return array Modified Command-array
914 */
915 function makeDeleteCmdArray($CMD) {
916 $elements = $this->elFromTable(''); // all records
917 reset($elements);
918 while(list($tP)=each($elements)) {
919 list($table,$uid) = explode('|',$tP);
920 if (!is_array($CMD[$table])) $CMD[$table]=array();
921 $CMD[$table][$uid]['delete']=1;
922 $this->removeElement($tP);
923 }
924 $this->endClipboard();
925 return $CMD;
926 }
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944 /*****************************************
945 *
946 * FOR USE IN tce_file.php:
947 *
948 ****************************************/
949
950 /**
951 * Applies the proper paste configuration in the $file array send to tce_file.php.
952 * The current pad is pasted
953 *
954 * @param string Reference to element (splitted by "|")
955 * @param array Command-array
956 * @return array Modified Command-array
957 */
958 function makePasteCmdArray_file($ref,$FILE) {
959 list($pTable,$pUid) = explode('|',$ref);
960 $elements = $this->elFromTable('_FILE');
961 $mode = $this->currentMode()=='copy' ? 'copy' : 'move';
962
963 // Traverse elements and make CMD array
964 reset($elements);
965 while(list($tP,$path)=each($elements)) {
966 $FILE[$mode][]=array('data'=>$path,'target'=>$pUid);
967 if ($mode=='move') $this->removeElement($tP);
968 }
969 $this->endClipboard();
970
971 return $FILE;
972 }
973
974 /**
975 * Delete files in CMD array
976 *
977 * @param array Command-array
978 * @return array Modified Command-array
979 */
980 function makeDeleteCmdArray_file($FILE) {
981 $elements = $this->elFromTable('_FILE');
982 // Traverse elements and make CMD array
983 reset($elements);
984 while(list($tP,$path)=each($elements)) {
985 $FILE['delete'][]=array('data'=>$path);
986 $this->removeElement($tP);
987 }
988 $this->endClipboard();
989
990 return $FILE;
991 }
992 }
993
994
995
996 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_clipboard.php']) {
997 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_clipboard.php']);
998 }
999 ?>