TYPO3 API  SVNRelease
class.t3lib_clipboard.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003  *  Copyright notice
00004  *
00005  *  (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
00006  *  All rights reserved
00007  *
00008  *  This script is part of the TYPO3 project. The TYPO3 project is
00009  *  free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  The GNU General Public License can be found at
00015  *  http://www.gnu.org/copyleft/gpl.html.
00016  *  A copy is found in the textfile GPL.txt and important notices to the license
00017  *  from the author is found in LICENSE.txt distributed with these scripts.
00018  *
00019  *
00020  *  This script is distributed in the hope that it will be useful,
00021  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023  *  GNU General Public License for more details.
00024  *
00025  *  This copyright notice MUST APPEAR in all copies of the script!
00026  ***************************************************************/
00027 /**
00028  * Contains class for TYPO3 clipboard for records and files
00029  *
00030  * $Id: class.t3lib_clipboard.php 10172 2011-01-20 22:23:37Z steffenk $
00031  * Revised for TYPO3 3.6 July/2003 by Kasper Skårhøj
00032  * XHTML compliant
00033  *
00034  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00035  */
00036 /**
00037  * [CLASS/FUNCTION INDEX of SCRIPT]
00038  *
00039  *
00040  *
00041  *   97: class t3lib_clipboard
00042  *
00043  *            SECTION: Initialize
00044  *  150:     function initializeClipboard()
00045  *  179:     function lockToNormal()
00046  *  196:     function setCmd($cmd)
00047  *  243:     function setCurrentPad($padIdent)
00048  *  258:     function endClipboard()
00049  *  271:     function cleanUpCBC($CBarr,$table,$removeDeselected=0)
00050  *
00051  *            SECTION: Clipboard HTML renderings
00052  *  306:     function printClipboard()
00053  *  413:     function printContentFromTab($pad)
00054  *  487:     function padTitleWrap($str,$pad)
00055  *  504:     function linkItemText($str,$rec,$table='')
00056  *  531:     function selUrlDB($table,$uid,$copy=0,$deselect=0,$baseArray=array())
00057  *  547:     function selUrlFile($path,$copy=0,$deselect=0,$baseArray=array())
00058  *  564:     function pasteUrl($table,$uid,$setRedirect=1)
00059  *  581:     function deleteUrl($setRedirect=1,$file=0)
00060  *  598:     function editUrl()
00061  *  619:     function removeUrl($table,$uid)
00062  *  632:     function confirmMsg($table,$rec,$type,$clElements)
00063  *  680:     function clLabel($key,$Akey='labels')
00064  *  689:     function exportClipElementParameters()
00065  *
00066  *            SECTION: Helper functions
00067  *  739:     function removeElement($el)
00068  *  751:     function saveClipboard()
00069  *  761:     function currentMode()
00070  *  771:     function cleanCurrent()
00071  *  798:     function elFromTable($matchTable='',$pad='')
00072  *  829:     function isSelected($table,$uid)
00073  *  843:     function getSelectedRecord($table='',$uid='')
00074  *  861:     function isElements()
00075  *
00076  *            SECTION: FOR USE IN tce_db.php:
00077  *  902:     function makePasteCmdArray($ref,$CMD)
00078  *  931:     function makeDeleteCmdArray($CMD)
00079  *
00080  *            SECTION: FOR USE IN tce_file.php:
00081  *  974:     function makePasteCmdArray_file($ref,$FILE)
00082  *  996:     function makeDeleteCmdArray_file($FILE)
00083  *
00084  * TOTAL FUNCTIONS: 31
00085  * (This index is automatically created/updated by the extension "extdeveval")
00086  *
00087  */
00088 
00089 
00090 /**
00091  * TYPO3 clipboard for records and files
00092  *
00093  * @author  Kasper Skårhøj <kasperYYYY@typo3.com>
00094  * @package TYPO3
00095  * @subpackage t3lib
00096  */
00097 class t3lib_clipboard {
00098     var $numberTabs = 3;
00099 
00100     /**
00101      * Clipboard data kept here
00102      *
00103      * Keys:
00104      *   'normal'
00105      *   'tab_[x]' where x is >=1 and denotes the pad-number
00106      *   \  'mode'  :   'copy' means copy-mode, default = moving ('cut')
00107      *   \  'el'    :   Array of elements:
00108      *       DB: keys = '[tablename]|[uid]' eg. 'tt_content:123'
00109      *       DB: values = 1 (basically insignificant)
00110      *       FILE: keys = '_FILE|[shortmd5 of path]'    eg. '_FILE|9ebc7e5c74'
00111      *       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'
00112      *
00113      *           'current' pointer to current tab (among the above...)
00114      *           '_setThumb'    boolean: If set, file thumbnails are shown.
00115      *
00116      *       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)
00117      *
00118      */
00119     var $clipData = array();
00120 
00121     var $changed = 0;
00122     var $current = '';
00123     var $backPath = '';
00124     var $lockToNormal = 0;
00125     var $fileMode = 0; // If set, clipboard is displaying files.
00126 
00127 
00128     /*****************************************
00129      *
00130      * Initialize
00131      *
00132      ****************************************/
00133 
00134     /**
00135      * Initialize the clipboard from the be_user session
00136      *
00137      * @return  void
00138      */
00139     function initializeClipboard() {
00140         global $BE_USER;
00141 
00142         $this->backPath = $GLOBALS['BACK_PATH'];
00143 
00144             // Get data
00145         $clipData = $BE_USER->getModuleData('clipboard', $BE_USER->getTSConfigVal('options.saveClipboard') ? '' : 'ses');
00146 
00147             // NumberTabs
00148         $clNP = $BE_USER->getTSConfigVal('options.clipboardNumberPads');
00149         if (t3lib_div::testInt($clNP) && $clNP >= 0) {
00150             $this->numberTabs = t3lib_div::intInRange($clNP, 0, 20);
00151         }
00152 
00153             // Resets/reinstates the clipboard pads
00154         $this->clipData['normal'] = is_array($clipData['normal']) ? $clipData['normal'] : array();
00155         for ($a = 1; $a <= $this->numberTabs; $a++) {
00156             $this->clipData['tab_' . $a] = is_array($clipData['tab_' . $a]) ? $clipData['tab_' . $a] : array();
00157         }
00158 
00159             // Setting the current pad pointer ($this->current) and _setThumb (which determines whether or not do show file thumbnails)
00160         $this->clipData['current'] = $this->current = isset($this->clipData[$clipData['current']]) ? $clipData['current'] : 'normal';
00161         $this->clipData['_setThumb'] = $clipData['_setThumb'];
00162     }
00163 
00164     /**
00165      * 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
00166      * This is used by the clickmenu since it only allows operation on single elements at a time (that is the "normal" pad)
00167      *
00168      * @return  void
00169      */
00170     function lockToNormal() {
00171         $this->lockToNormal = 1;
00172         $this->current = 'normal';
00173     }
00174 
00175     /**
00176      * The array $cmd may hold various keys which notes some action to take.
00177      * Normally perform only one action at a time.
00178      * In scripts like db_list.php / file_list.php the GET-var CB is used to control the clipboard.
00179      *
00180      *       Selecting / Deselecting elements
00181      *       Array $cmd['el'] has keys = element-ident, value = element value (see description of clipData array in header)
00182      *       Selecting elements for 'copy' should be done by simultaneously setting setCopyMode.
00183      *
00184      * @param   array       Array of actions, see function description
00185      * @return  void
00186      */
00187     function setCmd($cmd) {
00188         if (is_array($cmd['el'])) {
00189             foreach ($cmd['el'] as $k => $v) {
00190                 if ($this->current == 'normal') {
00191                     unset($this->clipData['normal']);
00192                 }
00193                 if ($v) {
00194                     $this->clipData[$this->current]['el'][$k] = $v;
00195                 } else {
00196                     $this->removeElement($k);
00197                 }
00198                 $this->changed = 1;
00199             }
00200         }
00201             // Change clipboard pad (if not locked to normal)
00202         if ($cmd['setP']) {
00203             $this->setCurrentPad($cmd['setP']);
00204         }
00205             // Remove element   (value = item ident: DB; '[tablename]|[uid]'    FILE: '_FILE|[shortmd5 hash of path]'
00206         if ($cmd['remove']) {
00207             $this->removeElement($cmd['remove']);
00208             $this->changed = 1;
00209         }
00210             // Remove all on current pad (value = pad-ident)
00211         if ($cmd['removeAll']) {
00212             $this->clipData[$cmd['removeAll']] = array();
00213             $this->changed = 1;
00214         }
00215             // Set copy mode of the tab
00216         if (isset($cmd['setCopyMode'])) {
00217             $this->clipData[$this->current]['mode'] = $this->isElements() ? ($cmd['setCopyMode'] ? 'copy' : '') : '';
00218             $this->changed = 1;
00219         }
00220             // Toggle thumbnail display for files on/off
00221         if (isset($cmd['setThumb'])) {
00222             $this->clipData['_setThumb'] = $cmd['setThumb'];
00223             $this->changed = 1;
00224         }
00225     }
00226 
00227     /**
00228      * Setting the current pad on clipboard
00229      *
00230      * @param   string      Key in the array $this->clipData
00231      * @return  void
00232      */
00233     function setCurrentPad($padIdent) {
00234             // Change clipboard pad (if not locked to normal)
00235         if (!$this->lockToNormal && $this->current != $padIdent) {
00236             if (isset($this->clipData[$padIdent])) {
00237                 $this->clipData['current'] = $this->current = $padIdent;
00238             }
00239             if ($this->current != 'normal' || !$this->isElements()) {
00240                 $this->clipData[$this->current]['mode'] = '';
00241             } // Setting mode to default (move) if no items on it or if not 'normal'
00242             $this->changed = 1;
00243         }
00244     }
00245 
00246     /**
00247      * Call this after initialization and setCmd in order to save the clipboard to the user session.
00248      * The function will check if the internal flag ->changed has been set and if so, save the clipboard. Else not.
00249      *
00250      * @return  void
00251      */
00252     function endClipboard() {
00253         if ($this->changed) {
00254             $this->saveClipboard();
00255         }
00256         $this->changed = 0;
00257     }
00258 
00259     /**
00260      * Cleans up an incoming element array $CBarr (Array selecting/deselecting elements)
00261      *
00262      * @param   array       Element array from outside ("key" => "selected/deselected")
00263      * @param   string      $table is the 'table which is allowed'. Must be set.
00264      * @param   boolean     $removeDeselected can be set in order to remove entries which are marked for deselection.
00265      * @return  array       Processed input $CBarr
00266      */
00267     function cleanUpCBC($CBarr, $table, $removeDeselected = 0) {
00268         if (is_array($CBarr)) {
00269             foreach ($CBarr as $k => $v) {
00270                 $p = explode('|', $k);
00271                 if ((string) $p[0] != (string) $table || ($removeDeselected && !$v)) {
00272                     unset($CBarr[$k]);
00273                 }
00274             }
00275         }
00276         return $CBarr;
00277     }
00278 
00279 
00280     /*****************************************
00281      *
00282      * Clipboard HTML renderings
00283      *
00284      ****************************************/
00285 
00286     /**
00287      * Prints the clipboard
00288      *
00289      * @return  string      HTML output
00290      */
00291     function printClipboard() {
00292         global $TBE_TEMPLATE, $LANG;
00293 
00294         $out = array();
00295         $elCount = count($this->elFromTable($this->fileMode ? '_FILE' : ''));
00296 
00297             // Upper header
00298         $out[] = '
00299             <tr class="t3-row-header">
00300                 <td colspan="3">' . t3lib_BEfunc::wrapInHelp('xMOD_csh_corebe', 'list_clipboard', $this->clLabel('clipboard', 'buttons')) . '</td>
00301             </tr>';
00302 
00303             // Button/menu header:
00304         $thumb_url = t3lib_div::linkThisScript(array('CB' => array('setThumb' => $this->clipData['_setThumb'] ? 0 : 1)));
00305         $rmall_url = t3lib_div::linkThisScript(array('CB' => array('removeAll' => $this->current)));
00306 
00307             // Copymode Selector menu
00308         $copymode_url = t3lib_div::linkThisScript();
00309         $moveLabel = htmlspecialchars($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.php:moveElements'));
00310         $copyLabel = htmlspecialchars($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.php:copyElements'));
00311         $opt = array();
00312         $opt[] = '<option style="padding-left: 20px; background-image: url(\'' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/clip_cut.gif', '', 1) . '\'); background-repeat: no-repeat;" value="" ' . (($this->currentMode() == 'copy') ? '' : 'selected="selected"') . '>' . $moveLabel . '</option>';
00313         $opt[] = '<option style="padding-left: 20px; background-image: url(\'' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/clip_copy.gif', '', 1) . '\'); background-repeat: no-repeat;" value="1" ' . (($this->currentMode() == 'copy') ? 'selected="selected"' : '') . '>' . $copyLabel . '</option>';
00314 
00315         $copymode_selector = ' <select name="CB[setCopyMode]" onchange="this.form.method=\'POST\'; this.form.action=\'' . htmlspecialchars($copymode_url . '&CB[setCopyMode]=') . '\'+(this.options[this.selectedIndex].value); this.form.submit(); return true;" >' . implode('', $opt) . '</select>';
00316 
00317             // Selector menu + clear button
00318         $opt = array();
00319         $opt[] = '<option value="" selected="selected">' . $this->clLabel('menu', 'rm') . '</option>';
00320             // Import / Export link:
00321         if ($elCount && t3lib_extMgm::isLoaded('impexp')) {
00322             $opt[] = '<option value="' . htmlspecialchars("window.location.href='" . $this->backPath . t3lib_extMgm::extRelPath('impexp') . 'app/index.php' . $this->exportClipElementParameters() . '\';') . '">' . $this->clLabel('export', 'rm') . '</option>';
00323         }
00324             // Edit:
00325         if (!$this->fileMode && $elCount) {
00326             $opt[] = '<option value="' . htmlspecialchars("window.location.href='" . $this->editUrl() . "&returnUrl='+top.rawurlencode(window.location.href);") . '">' . $this->clLabel('edit', 'rm') . '</option>';
00327         }
00328             // Delete:
00329         if ($elCount) {
00330             if ($GLOBALS['BE_USER']->jsConfirmation(4)) {
00331                 $js = "
00332             if(confirm(" . $GLOBALS['LANG']->JScharCode(sprintf($LANG->sL('LLL:EXT:lang/locallang_core.php:mess.deleteClip'), $elCount)) . ")){
00333                 window.location.href='" . $this->deleteUrl(0, $this->fileMode ? 1 : 0) . "&redirect='+top.rawurlencode(window.location.href);
00334             }
00335                     ";
00336             } else {
00337                 $js = " window.location.href='" . $this->deleteUrl(0, $this->fileMode ? 1 : 0) . "&redirect='+top.rawurlencode(window.location.href); ";
00338             }
00339             $opt[] = '<option value="' . htmlspecialchars($js) . '">' . $this->clLabel('delete', 'rm') . '</option>';
00340         }
00341         $selector_menu = '<select name="_clipMenu" onchange="eval(this.options[this.selectedIndex].value);this.selectedIndex=0;">' . implode('', $opt) . '</select>';
00342 
00343         $out[] = '
00344             <tr class="typo3-clipboard-head">
00345                 <td nowrap="nowrap">' .
00346                 '<a href="' . htmlspecialchars($thumb_url) . '#clip_head">' .
00347                 '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/thumb_' . ($this->clipData['_setThumb'] ? 's' : 'n') . '.gif', 'width="21" height="16"') . ' vspace="2" border="0" title="' . $this->clLabel('thumbmode_clip') . '" alt="" />' .
00348                 '</a>' .
00349                 '</td>
00350                 <td width="95%" nowrap="nowrap">' .
00351                 $copymode_selector . ' ' .
00352                 $selector_menu .
00353                 '</td>
00354                 <td>' .
00355                 '<a href="' . htmlspecialchars($rmall_url) . '#clip_head">' .
00356                 t3lib_iconWorks::getSpriteIcon('actions-document-close', array('title' => $LANG->sL('LLL:EXT:lang/locallang_core.php:buttons.clear', TRUE))) .
00357                 '</a></td>
00358             </tr>';
00359 
00360 
00361             // Print header and content for the NORMAL tab:
00362         $out[] = '
00363             <tr class="bgColor5">
00364                 <td colspan="3"><a href="' . htmlspecialchars(t3lib_div::linkThisScript(array('CB' => array('setP' => 'normal')))) . '#clip_head">' .
00365                 t3lib_iconWorks::getSpriteIcon('actions-view-table-' . (($this->current == 'normal') ? 'collapse' : 'expand')) .
00366                 $this->padTitleWrap('Normal', 'normal') .
00367                 '</a></td>
00368             </tr>';
00369         if ($this->current == 'normal') {
00370             $out = array_merge($out, $this->printContentFromTab('normal'));
00371         }
00372 
00373             // Print header and content for the NUMERIC tabs:
00374         for ($a = 1; $a <= $this->numberTabs; $a++) {
00375             $out[] = '
00376                 <tr class="bgColor5">
00377                     <td colspan="3"><a href="' . htmlspecialchars(t3lib_div::linkThisScript(array('CB' => array('setP' => 'tab_' . $a)))) . '#clip_head">' .
00378                     t3lib_iconWorks::getSpriteIcon('actions-view-table-' . (($this->current == 'tab_' . $a) ? 'collapse' : 'expand')) .
00379                     $this->padTitleWrap($this->clLabel('cliptabs') . $a, 'tab_' . $a) .
00380                     '</a></td>
00381                 </tr>';
00382             if ($this->current == 'tab_' . $a) {
00383                 $out = array_merge($out, $this->printContentFromTab('tab_' . $a));
00384             }
00385         }
00386 
00387             // Wrap accumulated rows in a table:
00388         $output = '<a name="clip_head"></a>
00389 
00390             <!--
00391                 TYPO3 Clipboard:
00392             -->
00393             <table cellpadding="0" cellspacing="1" border="0" width="290" id="typo3-clipboard">
00394                 ' . implode('', $out) . '
00395             </table>';
00396 
00397             // Wrap in form tag:
00398         $output = '<form action="">' . $output . '</form>';
00399 
00400             // Return the accumulated content:
00401         return $output;
00402     }
00403 
00404     /**
00405      * Print the content on a pad. Called from ->printClipboard()
00406      *
00407      * @param   string      Pad reference
00408      * @return  array       Array with table rows for the clipboard.
00409      * @access private
00410      */
00411     function printContentFromTab($pad) {
00412         global $TBE_TEMPLATE;
00413 
00414         $lines = array();
00415         if (is_array($this->clipData[$pad]['el'])) {
00416             foreach ($this->clipData[$pad]['el'] as $k => $v) {
00417                 if ($v) {
00418                     list($table, $uid) = explode('|', $k);
00419                     $bgColClass = ($table == '_FILE' && $this->fileMode) || ($table != '_FILE' && !$this->fileMode) ? 'bgColor4-20' : 'bgColor4';
00420 
00421                     if ($table == '_FILE') { // Rendering files/directories on the clipboard:
00422                         if (file_exists($v) && t3lib_div::isAllowedAbsPath($v)) {
00423                             $fI = pathinfo($v);
00424                             $icon = is_dir($v) ? 'folder.gif' : t3lib_BEfunc::getFileIcon(strtolower($fI['extension']));
00425                             $size = ' (' . t3lib_div::formatSize(filesize($v)) . 'bytes)';
00426                             $icon = t3lib_iconWorks::getSpriteIconForFile(is_dir($v) ? 'folder' : strtolower($fI['extension']), array('style' => 'margin: 0 20px;', 'title' => htmlspecialchars($fI['basename'] . $size)));
00427                             $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"') : '') : '';
00428 
00429                             $lines[] = '
00430                                 <tr>
00431                                     <td class="' . $bgColClass . '">' . $icon . '</td>
00432                                     <td class="' . $bgColClass . '" nowrap="nowrap" width="95%">&nbsp;' . $this->linkItemText(htmlspecialchars(t3lib_div::fixed_lgd_cs(basename($v), $GLOBALS['BE_USER']->uc['titleLen'])), $v) .
00433                                     ($pad == 'normal' ? (' <strong>(' . ($this->clipData['normal']['mode'] == 'copy' ? $this->clLabel('copy', 'cm') : $this->clLabel('cut', 'cm')) . ')</strong>') : '') . '&nbsp;' . ($thumb ? '<br />' . $thumb : '') . '</td>
00434                                     <td class="' . $bgColClass . '" align="center" nowrap="nowrap">' .
00435                                     '<a href="#" onclick="' . htmlspecialchars('top.launchView(\'' . $v . '\', \'\'); return false;') . '">' . t3lib_iconWorks::getSpriteIcon('actions-document-info', array('title' => $this->clLabel('info', 'cm'))) . '</a>' .
00436                                     '<a href="' . htmlspecialchars($this->removeUrl('_FILE', t3lib_div::shortmd5($v))) . '#clip_head">' . t3lib_iconWorks::getSpriteIcon('actions-selection-delete', array('title' => $this->clLabel('removeItem'))) . '</a>' .
00437                                     '</td>
00438                                 </tr>';
00439                         } else {
00440                                 // If the file did not exist (or is illegal) then it is removed from the clipboard immediately:
00441                             unset($this->clipData[$pad]['el'][$k]);
00442                             $this->changed = 1;
00443                         }
00444                     } else { // Rendering records:
00445                         $rec = t3lib_BEfunc::getRecordWSOL($table, $uid);
00446                         if (is_array($rec)) {
00447                             $lines[] = '
00448                                 <tr>
00449                                     <td class="' . $bgColClass . '">' . $this->linkItemText(t3lib_iconWorks::getSpriteIconForRecord($table, $rec, array('style' => 'margin: 0 20px;', 'title' => htmlspecialchars(t3lib_BEfunc::getRecordIconAltText($rec, $table)))), $rec, $table) . '</td>
00450                                     <td class="' . $bgColClass . '" nowrap="nowrap" width="95%">&nbsp;' . $this->linkItemText(htmlspecialchars(t3lib_div::fixed_lgd_cs(t3lib_BEfunc::getRecordTitle($table, $rec), $GLOBALS['BE_USER']->uc['titleLen'])), $rec, $table) .
00451                                     ($pad == 'normal' ? (' <strong>(' . ($this->clipData['normal']['mode'] == 'copy' ? $this->clLabel('copy', 'cm') : $this->clLabel('cut', 'cm')) . ')</strong>') : '') . '&nbsp;</td>
00452                                     <td class="' . $bgColClass . '" align="center" nowrap="nowrap">' .
00453                                     '<a href="#" onclick="' . htmlspecialchars('top.launchView(\'' . $table . '\', \'' . intval($uid) . '\'); return false;') . '">' . t3lib_iconWorks::getSpriteIcon('actions-document-info', array('title' => $this->clLabel('info', 'cm'))) . '</a>' .
00454                                     '<a href="' . htmlspecialchars($this->removeUrl($table, $uid)) . '#clip_head">' . t3lib_iconWorks::getSpriteIcon('actions-selection-delete', array('title' => $this->clLabel('removeItem'))) . '</a>' .
00455                                     '</td>
00456                                 </tr>';
00457 
00458                             $localizationData = $this->getLocalizations($table, $rec, $bgColClass, $pad);
00459                             if ($localizationData) {
00460                                 $lines[] = $localizationData;
00461                             }
00462 
00463                         } else {
00464                             unset($this->clipData[$pad]['el'][$k]);
00465                             $this->changed = 1;
00466                         }
00467                     }
00468                 }
00469             }
00470         }
00471         if (!count($lines)) {
00472             $lines[] = '
00473                                 <tr>
00474                                     <td class="bgColor4"><img src="clear.gif" width="56" height="1" alt="" /></td>
00475                                     <td colspan="2" class="bgColor4" nowrap="nowrap" width="95%">&nbsp;<em>(' . $this->clLabel('clipNoEl') . ')</em>&nbsp;</td>
00476                                 </tr>';
00477         }
00478 
00479         $this->endClipboard();
00480         return $lines;
00481     }
00482 
00483 
00484     /**
00485      * Gets all localizations of the current record.
00486      *
00487      * @param   string      the table
00488      * @param   array       the current record
00489      * @return  string      HTML table rows
00490      */
00491     function getLocalizations($table, $parentRec, $bgColClass, $pad) {
00492         $lines = array();
00493         $tcaCtrl = $GLOBALS['TCA'][$table]['ctrl'];
00494 
00495         if ($table != 'pages' && t3lib_BEfunc::isTableLocalizable($table) && !$tcaCtrl['transOrigPointerTable']) {
00496             $where = array();
00497             $where[] = $tcaCtrl['transOrigPointerField'] . '=' . intval($parentRec['uid']);
00498             $where[] = $tcaCtrl['languageField'] . '!=0';
00499 
00500             if (isset($tcaCtrl['delete']) && $tcaCtrl['delete']) {
00501                 $where[] = $tcaCtrl['delete'] . '=0';
00502             }
00503 
00504             if (isset($tcaCtrl['versioningWS']) && $tcaCtrl['versioningWS']) {
00505                 $where[] = 't3ver_wsid=' . $parentRec['t3ver_wsid'];
00506             }
00507 
00508             $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', $table, implode(' AND ', $where));
00509 
00510             if (is_array($rows)) {
00511                 $modeData = '';
00512                 if ($pad == 'normal') {
00513                     $mode = ($this->clipData['normal']['mode'] == 'copy' ? 'copy' : 'cut');
00514                     $modeData = ' <strong>(' . $this->clLabel($mode, 'cm') . ')</strong>';
00515                 }
00516 
00517                 foreach ($rows as $rec) {
00518                     $lines[] = '
00519                     <tr>
00520                         <td class="' . $bgColClass . '">' .
00521                             t3lib_iconWorks::getSpriteIconForRecord($table, $rec, array('style' => "margin-left: 38px;")) . '</td>
00522                         <td class="' . $bgColClass . '" nowrap="nowrap" width="95%">&nbsp;' . htmlspecialchars(
00523                         t3lib_div::fixed_lgd_cs(t3lib_BEfunc::getRecordTitle($table, $rec), $GLOBALS['BE_USER']->uc['titleLen'])) .
00524                             $modeData . '&nbsp;</td>
00525                         <td class="' . $bgColClass . '" align="center" nowrap="nowrap">&nbsp;</td>
00526                     </tr>';
00527                 }
00528             }
00529         }
00530         return implode('', $lines);
00531     }
00532 
00533 
00534     /**
00535      * Wraps title of pad in bold-tags and maybe the number of elements if any.
00536      *
00537      * @param   string      String (already htmlspecialchars()'ed)
00538      * @param   string      Pad reference
00539      * @return  string      HTML output (htmlspecialchar'ed content inside of tags.)
00540      */
00541     function padTitleWrap($str, $pad) {
00542         $el = count($this->elFromTable($this->fileMode ? '_FILE' : '', $pad));
00543         if ($el) {
00544             return '<strong>' . $str . '</strong> (' . ($pad == 'normal' ? ($this->clipData['normal']['mode'] == 'copy' ? $this->clLabel('copy', 'cm') : $this->clLabel('cut', 'cm')) : htmlspecialchars($el)) . ')';
00545         } else {
00546             return $GLOBALS['TBE_TEMPLATE']->dfw($str);
00547         }
00548     }
00549 
00550     /**
00551      * Wraps the title of the items listed in link-tags. The items will link to the page/folder where they originate from
00552      *
00553      * @param   string      Title of element - must be htmlspecialchar'ed on beforehand.
00554      * @param   mixed       If array, a record is expected. If string, its a path
00555      * @param   string      Table name
00556      * @return  string
00557      */
00558     function linkItemText($str, $rec, $table = '') {
00559         if (is_array($rec) && $table) {
00560             if ($this->fileMode) {
00561                 $str = $GLOBALS['TBE_TEMPLATE']->dfw($str);
00562             } else {
00563                 if (t3lib_extMgm::isLoaded('recordlist')) {
00564                     $str = '<a href="' . htmlspecialchars(
00565                         t3lib_BEfunc::getModuleUrl(
00566                             'web_list',
00567                             array('id' => $rec['pid']),
00568                             $this->backPath)
00569                     ) . '">' . $str . '</a>';
00570                 }
00571             }
00572         } elseif (file_exists($rec)) {
00573             if (!$this->fileMode) {
00574                 $str = $GLOBALS['TBE_TEMPLATE']->dfw($str);
00575             } else {
00576                 if (t3lib_extMgm::isLoaded('filelist')) {
00577                     $str = '<a href="' . htmlspecialchars(
00578                         $this->backPath . t3lib_extMgm::extRelPath('filelist') . 'mod1/file_list.php?id=' . dirname($rec)
00579                     ) . '">' . $str . '</a>';
00580                 }
00581             }
00582         }
00583         return $str;
00584     }
00585 
00586     /**
00587      * Returns the select-url for database elements
00588      *
00589      * @param   string      Table name
00590      * @param   integer     Uid of record
00591      * @param   boolean     If set, copymode will be enabled
00592      * @param   boolean     If set, the link will deselect, otherwise select.
00593      * @param   array       The base array of GET vars to be sent in addition. Notice that current GET vars WILL automatically be included.
00594      * @return  string      URL linking to the current script but with the CB array set to select the element with table/uid
00595      */
00596     function selUrlDB($table, $uid, $copy = 0, $deselect = 0, $baseArray = array()) {
00597         $CB = array('el' => array(rawurlencode($table . '|' . $uid) => $deselect ? 0 : 1));
00598         if ($copy) {
00599             $CB['setCopyMode'] = 1;
00600         }
00601         $baseArray['CB'] = $CB;
00602         return t3lib_div::linkThisScript($baseArray);
00603     }
00604 
00605     /**
00606      * Returns the select-url for files
00607      *
00608      * @param   string      Filepath
00609      * @param   boolean     If set, copymode will be enabled
00610      * @param   boolean     If set, the link will deselect, otherwise select.
00611      * @param   array       The base array of GET vars to be sent in addition. Notice that current GET vars WILL automatically be included.
00612      * @return  string      URL linking to the current script but with the CB array set to select the path
00613      */
00614     function selUrlFile($path, $copy = 0, $deselect = 0, $baseArray = array()) {
00615         $CB = array('el' => array(rawurlencode('_FILE|' . t3lib_div::shortmd5($path)) => $deselect ? '' : $path));
00616         if ($copy) {
00617             $CB['setCopyMode'] = 1;
00618         }
00619         $baseArray['CB'] = $CB;
00620         return t3lib_div::linkThisScript($baseArray);
00621     }
00622 
00623     /**
00624      * pasteUrl of the element (database and file)
00625      * For the meaning of $table and $uid, please read from ->makePasteCmdArray!!!
00626      * The URL will point to tce_file or tce_db depending in $table
00627      *
00628      * @param   string      Tablename (_FILE for files)
00629      * @param   mixed       "destination": can be positive or negative indicating how the paste is done (paste into / paste after)
00630      * @param   boolean     If set, then the redirect URL will point back to the current script, but with CB reset.
00631      * @return  string
00632      */
00633     function pasteUrl($table, $uid, $setRedirect = 1) {
00634         $rU = $this->backPath . ($table == '_FILE' ? 'tce_file.php' : 'tce_db.php') . '?' .
00635                 ($setRedirect ? 'redirect=' . rawurlencode(t3lib_div::linkThisScript(array('CB' => ''))) : '') .
00636                 '&vC=' . $GLOBALS['BE_USER']->veriCode() .
00637                 '&prErr=1&uPT=1' .
00638                 '&CB[paste]=' . rawurlencode($table . '|' . $uid) .
00639                 '&CB[pad]=' . $this->current .
00640                 t3lib_BEfunc::getUrlToken('tceAction');
00641         return $rU;
00642     }
00643 
00644     /**
00645      * deleteUrl for current pad
00646      *
00647      * @param   boolean     If set, then the redirect URL will point back to the current script, but with CB reset.
00648      * @param   boolean     If set, then the URL will link to the tce_file.php script in the typo3/ dir.
00649      * @return  string
00650      */
00651     function deleteUrl($setRedirect = 1, $file = 0) {
00652         $rU = $this->backPath . ($file ? 'tce_file.php' : 'tce_db.php') . '?' .
00653                 ($setRedirect ? 'redirect=' . rawurlencode(t3lib_div::linkThisScript(array('CB' => ''))) : '') .
00654                 '&vC=' . $GLOBALS['BE_USER']->veriCode() .
00655                 '&prErr=1&uPT=1' .
00656                 '&CB[delete]=1' .
00657                 '&CB[pad]=' . $this->current .
00658                 t3lib_BEfunc::getUrlToken('tceAction');
00659         return $rU;
00660     }
00661 
00662     /**
00663      * editUrl of all current elements
00664      * ONLY database
00665      * Links to alt_doc.php
00666      *
00667      * @return  string      The URL to alt_doc.php with parameters.
00668      */
00669     function editUrl() {
00670         $elements = $this->elFromTable(''); // all records
00671         $editCMDArray = array();
00672         foreach ($elements as $tP => $value) {
00673             list($table, $uid) = explode('|', $tP);
00674             $editCMDArray[] = '&edit[' . $table . '][' . $uid . ']=edit';
00675         }
00676 
00677         $rU = $this->backPath . 'alt_doc.php?' . implode('', $editCMDArray);
00678         return $rU;
00679     }
00680 
00681     /**
00682      * Returns the remove-url (file and db)
00683      * for file $table='_FILE' and $uid = shortmd5 hash of path
00684      *
00685      * @param   string      Tablename
00686      * @param   string      uid integer/shortmd5 hash
00687      * @return  string      URL
00688      */
00689     function removeUrl($table, $uid) {
00690         return t3lib_div::linkThisScript(array('CB' => array('remove' => $table . '|' . $uid)));
00691     }
00692 
00693     /**
00694      * Returns confirm JavaScript message
00695      *
00696      * @param   string      Table name
00697      * @param   mixed       For records its an array, for files its a string (path)
00698      * @param   string      Type-code
00699      * @param   array       Array of selected elements
00700      * @return  string      JavaScript "confirm" message
00701      */
00702     function confirmMsg($table, $rec, $type, $clElements) {
00703         if ($GLOBALS['BE_USER']->jsConfirmation(2)) {
00704             $labelKey = 'LLL:EXT:lang/locallang_core.php:mess.' . ($this->currentMode() == 'copy' ? 'copy' : 'move') . ($this->current == 'normal' ? '' : 'cb') . '_' . $type;
00705             $msg = $GLOBALS['LANG']->sL($labelKey);
00706 
00707             if ($table == '_FILE') {
00708                 $thisRecTitle = basename($rec);
00709                 if ($this->current == 'normal') {
00710                     reset($clElements);
00711                     $selItem = current($clElements);
00712                     $selRecTitle = basename($selItem);
00713                 } else {
00714                     $selRecTitle = count($clElements);
00715                 }
00716             } else {
00717                 $thisRecTitle = (
00718                 $table == 'pages' && !is_array($rec) ?
00719                         $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] :
00720                         t3lib_BEfunc::getRecordTitle($table, $rec)
00721                 );
00722 
00723                 if ($this->current == 'normal') {
00724                     $selItem = $this->getSelectedRecord();
00725                     $selRecTitle = $selItem['_RECORD_TITLE'];
00726                 } else {
00727                     $selRecTitle = count($clElements);
00728                 }
00729             }
00730 
00731                 // Message:
00732             $conf = 'confirm(' . $GLOBALS['LANG']->JScharCode(sprintf(
00733                 $msg,
00734                 t3lib_div::fixed_lgd_cs($selRecTitle, 30),
00735                 t3lib_div::fixed_lgd_cs($thisRecTitle, 30)
00736             )) . ')';
00737         } else {
00738             $conf = '';
00739         }
00740         return $conf;
00741     }
00742 
00743     /**
00744      * Clipboard label - getting from "EXT:lang/locallang_core.php:"
00745      *
00746      * @param   string      Label Key
00747      * @param   string      Alternative key to "labels"
00748      * @return  string
00749      */
00750     function clLabel($key, $Akey = 'labels') {
00751         return htmlspecialchars($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:' . $Akey . '.' . $key));
00752     }
00753 
00754     /**
00755      * Creates GET parameters for linking to the export module.
00756      *
00757      * @return  string      GET parameters for current clipboard content to be exported.
00758      */
00759     function exportClipElementParameters() {
00760 
00761             // Init:
00762         $pad = $this->current;
00763         $params = array();
00764         $params[] = 'tx_impexp[action]=export';
00765 
00766             // Traverse items:
00767         if (is_array($this->clipData[$pad]['el'])) {
00768             foreach ($this->clipData[$pad]['el'] as $k => $v) {
00769                 if ($v) {
00770                     list($table, $uid) = explode('|', $k);
00771 
00772                     if ($table == '_FILE') { // Rendering files/directories on the clipboard:
00773                         if (file_exists($v) && t3lib_div::isAllowedAbsPath($v)) {
00774                             $params[] = 'tx_impexp[' . (is_dir($v) ? 'dir' : 'file') . '][]=' . rawurlencode($v);
00775                         }
00776                     } else { // Rendering records:
00777                         $rec = t3lib_BEfunc::getRecord($table, $uid);
00778                         if (is_array($rec)) {
00779                             $params[] = 'tx_impexp[record][]=' . rawurlencode($table . ':' . $uid);
00780                         }
00781                     }
00782                 }
00783             }
00784         }
00785 
00786         return '?' . implode('&', $params);
00787     }
00788 
00789 
00790     /*****************************************
00791      *
00792      * Helper functions
00793      *
00794      ****************************************/
00795 
00796     /**
00797      * Removes element on clipboard
00798      *
00799      * @param   string      Key of element in ->clipData array
00800      * @return  void
00801      */
00802     function removeElement($el) {
00803         unset($this->clipData[$this->current]['el'][$el]);
00804         $this->changed = 1;
00805     }
00806 
00807     /**
00808      * Saves the clipboard, no questions asked.
00809      * Use ->endClipboard normally (as it checks if changes has been done so saving is necessary)
00810      *
00811      * @return  void
00812      * @access private
00813      */
00814     function saveClipboard() {
00815         global $BE_USER;
00816         $BE_USER->pushModuleData('clipboard', $this->clipData);
00817     }
00818 
00819     /**
00820      * Returns the current mode, 'copy' or 'cut'
00821      *
00822      * @return  string      "copy" or "cut"
00823      */
00824     function currentMode() {
00825         return $this->clipData[$this->current]['mode'] == 'copy' ? 'copy' : 'cut';
00826     }
00827 
00828     /**
00829      * This traverses the elements on the current clipboard pane
00830      * and unsets elements which does not exist anymore or are disabled.
00831      *
00832      * @return  void
00833      */
00834     function cleanCurrent() {
00835         if (is_array($this->clipData[$this->current]['el'])) {
00836             foreach ($this->clipData[$this->current]['el'] as $k => $v) {
00837                 list($table, $uid) = explode('|', $k);
00838                 if ($table != '_FILE') {
00839                     if (!$v || !is_array(t3lib_BEfunc::getRecord($table, $uid, 'uid'))) {
00840                         unset($this->clipData[$this->current]['el'][$k]);
00841                         $this->changed = 1;
00842                     }
00843                 } else {
00844                     if (!$v || !file_exists($v)) {
00845                         unset($this->clipData[$this->current]['el'][$k]);
00846                         $this->changed = 1;
00847                     }
00848                 }
00849             }
00850         }
00851     }
00852 
00853     /**
00854      * Counts the number of elements from the table $matchTable. If $matchTable is blank, all tables (except '_FILE' of course) is counted.
00855      *
00856      * @param   string      Table to match/count for.
00857      * @param   string      $pad can optionally be used to set another pad than the current.
00858      * @return  array       Array with keys from the CB.
00859      */
00860     function elFromTable($matchTable = '', $pad = '') {
00861         $pad = $pad ? $pad : $this->current;
00862         $list = array();
00863         if (is_array($this->clipData[$pad]['el'])) {
00864             foreach ($this->clipData[$pad]['el'] as $k => $v) {
00865                 if ($v) {
00866                     list($table, $uid) = explode('|', $k);
00867                     if ($table != '_FILE') {
00868                         if ((!$matchTable || (string) $table == (string) $matchTable) && $GLOBALS['TCA'][$table]) {
00869                             $list[$k] = ($pad == 'normal' ? $v : $uid);
00870                         }
00871                     } else {
00872                         if ((string) $table == (string) $matchTable) {
00873                             $list[$k] = $v;
00874                         }
00875                     }
00876                 }
00877             }
00878         }
00879         return $list;
00880     }
00881 
00882     /**
00883      * Verifies if the item $table/$uid is on the current pad.
00884      * 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...
00885      *
00886      * @param   string      Table name, (_FILE for files...)
00887      * @param   integer     Element uid (path for files)
00888      * @return  string
00889      */
00890     function isSelected($table, $uid) {
00891         $k = $table . '|' . $uid;
00892         return $this->clipData[$this->current]['el'][$k] ? ($this->current == 'normal' ? $this->currentMode() : 1) : '';
00893     }
00894 
00895     /**
00896      * Returns item record $table,$uid if selected on current clipboard
00897      * If table and uid is blank, the first element is returned.
00898      * Makes sense only for DB records - not files!
00899      *
00900      * @param   string      Table name
00901      * @param   integer     Element uid
00902      * @return  array       Element record with extra field _RECORD_TITLE set to the title of the record...
00903      */
00904     function getSelectedRecord($table = '', $uid = '') {
00905         if (!$table && !$uid) {
00906             $elArr = $this->elFromTable('');
00907             reset($elArr);
00908             list($table, $uid) = explode('|', key($elArr));
00909         }
00910         if ($this->isSelected($table, $uid)) {
00911             $selRec = t3lib_BEfunc::getRecordWSOL($table, $uid);
00912             $selRec['_RECORD_TITLE'] = t3lib_BEfunc::getRecordTitle($table, $selRec);
00913             return $selRec;
00914         }
00915     }
00916 
00917     /**
00918      * Reports if the current pad has elements (does not check file/DB type OR if file/DBrecord exists or not. Only counting array)
00919      *
00920      * @return  boolean     True if elements exist.
00921      */
00922     function isElements() {
00923         return is_array($this->clipData[$this->current]['el']) && count($this->clipData[$this->current]['el']);
00924     }
00925 
00926 
00927     /*****************************************
00928      *
00929      * FOR USE IN tce_db.php:
00930      *
00931      ****************************************/
00932 
00933     /**
00934      * Applies the proper paste configuration in the $cmd array send to tce_db.php.
00935      * $ref is the target, see description below.
00936      * The current pad is pasted
00937      *
00938      *       $ref: [tablename]:[paste-uid].
00939      *       tablename is the name of the table from which elements *on the current clipboard* is pasted with the 'pid' paste-uid.
00940      *       No tablename means that all items on the clipboard (non-files) are pasted. This requires paste-uid to be positive though.
00941      *       so 'tt_content:-3' means 'paste tt_content elements on the clipboard to AFTER tt_content:3 record
00942      *       'tt_content:30'    means 'paste tt_content elements on the clipboard into page with id 30
00943      *       ':30'  means 'paste ALL database elements on the clipboard into page with id 30
00944      *       ':-30' not valid.
00945      *
00946      * @param   string      [tablename]:[paste-uid], see description
00947      * @param   array       Command-array
00948      * @return  array       Modified Command-array
00949      */
00950     function makePasteCmdArray($ref, $CMD) {
00951         list($pTable, $pUid) = explode('|', $ref);
00952         $pUid = intval($pUid);
00953 
00954         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)
00955             $elements = $this->elFromTable($pTable);
00956 
00957             $elements = array_reverse($elements); // So the order is preserved.
00958             $mode = $this->currentMode() == 'copy' ? 'copy' : 'move';
00959 
00960                 // Traverse elements and make CMD array
00961             foreach ($elements as $tP => $value) {
00962                 list($table, $uid) = explode('|', $tP);
00963                 if (!is_array($CMD[$table])) {
00964                     $CMD[$table] = array();
00965                 }
00966                 $CMD[$table][$uid][$mode] = $pUid;
00967                 if ($mode == 'move') {
00968                     $this->removeElement($tP);
00969                 }
00970             }
00971             $this->endClipboard();
00972         }
00973         return $CMD;
00974     }
00975 
00976     /**
00977      * Delete record entries in CMD array
00978      *
00979      * @param   array       Command-array
00980      * @return  array       Modified Command-array
00981      */
00982     function makeDeleteCmdArray($CMD) {
00983         $elements = $this->elFromTable(''); // all records
00984         foreach ($elements as $tP => $value) {
00985             list($table, $uid) = explode('|', $tP);
00986             if (!is_array($CMD[$table])) {
00987                 $CMD[$table] = array();
00988             }
00989             $CMD[$table][$uid]['delete'] = 1;
00990             $this->removeElement($tP);
00991         }
00992         $this->endClipboard();
00993         return $CMD;
00994     }
00995 
00996 
00997     /*****************************************
00998      *
00999      * FOR USE IN tce_file.php:
01000      *
01001      ****************************************/
01002 
01003     /**
01004      * Applies the proper paste configuration in the $file array send to tce_file.php.
01005      * The current pad is pasted
01006      *
01007      * @param   string      Reference to element (splitted by "|")
01008      * @param   array       Command-array
01009      * @return  array       Modified Command-array
01010      */
01011     function makePasteCmdArray_file($ref, $FILE) {
01012         list($pTable, $pUid) = explode('|', $ref);
01013         $elements = $this->elFromTable('_FILE');
01014         $mode = $this->currentMode() == 'copy' ? 'copy' : 'move';
01015 
01016             // Traverse elements and make CMD array
01017         foreach ($elements as $tP => $path) {
01018             $FILE[$mode][] = array('data' => $path, 'target' => $pUid, 'altName' => 1);
01019             if ($mode == 'move') {
01020                 $this->removeElement($tP);
01021             }
01022         }
01023         $this->endClipboard();
01024 
01025         return $FILE;
01026     }
01027 
01028     /**
01029      * Delete files in CMD array
01030      *
01031      * @param   array       Command-array
01032      * @return  array       Modified Command-array
01033      */
01034     function makeDeleteCmdArray_file($FILE) {
01035         $elements = $this->elFromTable('_FILE');
01036             // Traverse elements and make CMD array
01037         foreach ($elements as $tP => $path) {
01038             $FILE['delete'][] = array('data' => $path);
01039             $this->removeElement($tP);
01040         }
01041         $this->endClipboard();
01042 
01043         return $FILE;
01044     }
01045 }
01046 
01047 
01048 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_clipboard.php'])) {
01049     include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_clipboard.php']);
01050 }
01051 
01052 ?>