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