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