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