Updates mainly to import/export extension. Many smaller changes / additions. See...
authorKasper Skårhøj <kasper@typo3.org>
Fri, 17 Dec 2004 16:58:47 +0000 (16:58 +0000)
committerKasper Skårhøj <kasper@typo3.org>
Fri, 17 Dec 2004 16:58:47 +0000 (16:58 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@520 709f56b5-9817-0410-a4d7-c38de5d9e867

33 files changed:
ChangeLog
TODO.txt
t3lib/class.t3lib_basicfilefunc.php
t3lib/class.t3lib_befunc.php
t3lib/class.t3lib_clipboard.php
t3lib/class.t3lib_div.php
t3lib/class.t3lib_extfilefunc.php
t3lib/class.t3lib_parsehtml.php
t3lib/class.t3lib_softrefproc.php [new file with mode: 0755]
t3lib/class.t3lib_tceforms.php
t3lib/class.t3lib_tcemain.php
t3lib/config_default.php
t3lib/gfx/rel_softref.png [new file with mode: 0755]
t3lib/stddb/tables.php
t3lib/stddb/tbl_be.php
typo3/alt_shortcut.php
typo3/class.db_list_extra.inc
typo3/sysext/cms/ext_tables.php
typo3/sysext/cms/tbl_cms.php
typo3/sysext/cms/tbl_tt_content.php
typo3/sysext/cms/tslib/class.tslib_content.php
typo3/sysext/cms/tslib/class.tslib_fe.php
typo3/sysext/cms/tslib/class.tslib_gifbuilder.php
typo3/sysext/impexp/app/index.php
typo3/sysext/impexp/app/locallang.xml
typo3/sysext/impexp/class.tx_impexp.php
typo3/sysext/impexp/class.tx_impexp_clickmenu.php
typo3/sysext/impexp/doc/TODO.txt
typo3/sysext/impexp/ext_tables.php
typo3/sysext/impexp/ext_tables.sql [new file with mode: 0755]
typo3/sysext/impexp/modfunc1/class.tx_impexp_modfunc1.php [new file with mode: 0755]
typo3/sysext/lang/locallang_core.xml
typo3/sysext/lang/locallang_mod_web_list.xml

index fccaf94..2380526 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2004-12-17  Kasper Skårhøj,,,  <kasper@typo3.com>
+
+       * Mainly: Did tons of improvements on the import/export module (system extension "impexp").
+               Main features:
+                       Supports flexforms (hence TEmplaVoila).
+                       Supports RTE embedded images.
+                       Supports updates of existing records in various forms.
+                       Has optional XML format.
+                       Supports a new concept called "soft references" which are plain-text links/file references/markers and allows to track and include these in export. Examples are "fileadmin/..." references in TypoScript templates and <link> typolink tags.
+                       Can export from the page tree root.
+                       Character set dependant
+                       Extension dependencies can be set
+                       Embedding of HTML files and internal resources
+                       Export links directly from clipboard and Web>List
+                       Supports meta data including embedded thumbnail
+
+       * In shortcut frame I added possibility to enter  a table:uid pair in the "Edit page" box. For instance "tt_content:123" will launch the doc module for that element.
+       * Soft References; A parser-concept tied to TCA which allows to define parsers for certain fields that finds "soft references", eg. <link> tags, file-references etc. See import/export improvements above.
+       * Improvements to array2xml which allows detained mapping of array keys to XML-tags. As an example, study the import/export extensions T3RecordDocument configuration.
+       * Improved t3lib_parsehtml::prefixResourcePath() to access a suffix string to WRAP file references
+       * Improved t3lib_tcemain with support for forcing a UID for newly created records (used by import/export)
+       * t3lib_tcemain::checkValue_flex_procInData_travDS() now supports callback functions from external objects
+       * Changed "displayErrors" in config_default.php BACK to "-1" which corresponds to the default from before (notice this, stucki!)
+       * Ended the regime of the new be-usergroup selection box - back to the previous with ordering of backend groups since the first group was significant (being the default owner group)
+       * Added support for having temporary files in typo3temp/ prefixed with a meaningful prefix, typically coming from the menu title, original image name etc.
+
+
 2004-11-28  Kasper Skårhøj,,,  <kasper@typo3.com>
 
        * Main feature: Lots of updates on Indexed Search extension. The changes are mainly in the indexer, not the search plugin. The work is NOT FINISHED yet and don't update a production site with this work! One main thing to be aware of is that all indexing is done internally as utf-8. You should flush your old index tables before running the new one.
@@ -6,7 +33,7 @@
        * Fixed order of configuration forms in Extension Manager
        * Added timezone option in TYPO3_CONF_VARS array
        * Added right-click feature on context menus. Can be disabled with TYPO3_CONF_VARS if you don't like it. And a rightclick on the page/folder _title_ will also activate the menu! Theoretically it is not valid XHTML. Works in Mozilla and MSIE. Thanks Wolfgang!
-       * Added TS option "USERUID_substToken" 
+       * Added TS option "USERUID_substToken"
 
 2004-11-26  Michael Stucki  <michael@typo3.org>
 
index 05c8ff9..db68e22 100755 (executable)
--- a/TODO.txt
+++ b/TODO.txt
@@ -41,7 +41,7 @@ TCEmain:
        - Transformation API: Implement the possibility of custom to/from transformations for the "user" type (or any field?)
        - Selector box type:
                - MM support for strings
-       - Support for MM-records which does NOT get deleted, but is kept... and then support for having data in those!!
+       - Support for MM-records which does NOT get deleted, but is kept... and then support for having data in those!! NOTE 3/12 04: This will cause severe problems in the import/export interface and probably many other places where the MM relations are stored only as the uid of another table and nothing more. That makes it impossible to track the record in the middle....
        - Support that the content of a single field can be stored in an external file instead.
        - Support that a list of fields can be stored in an external XML file instead.
        - Record Reference tracking in a table in TCEmain; Used to:
index 8c1c223..17f3a4c 100644 (file)
@@ -332,6 +332,24 @@ class t3lib_basicFileFunctions     {
        }
 
        /**
+        * Find first web folder (relative to PATH_site.'fileadmin') in filemounts array
+        *
+        * @return      string          The key to the first mount inside PATH_site."fileadmin" found, otherwise nothing is returned.
+        */
+       function findFirstWebFolder()   {
+               global $TYPO3_CONF_VARS;
+
+               if (is_array($this->mounts))    {
+                       reset ($this->mounts);
+                       while(list($k,$val)=each($this->mounts))        {
+                               if (t3lib_div::isFirstPartOfStr($val['path'], PATH_site.$TYPO3_CONF_VARS['BE']['fileadminDir']))        {
+                                       return $k;
+                               }
+                       }
+               }
+       }
+
+       /**
         * Removes filemount part of a path, thus blinding the position.
         * Takes a path, $thePath, and removes the part of the path which equals the filemount.
         *
@@ -371,6 +389,11 @@ class t3lib_basicFileFunctions     {
 
 
 
+
+
+
+
+
        /*********************
         *
         * Cleaning functions
index 5906d3e..c07fec8 100755 (executable)
@@ -2804,16 +2804,17 @@ class t3lib_BEfunc      {
 
        /**
         * Returns first possible RTE object if available.
+        * Usage: $RTEobj = &t3lib_BEfunc::RTEgetObj();
         *
         * @return      mixed           If available, returns RTE object, otherwise an array of messages from possible RTEs
         */
        function &RTEgetObj()   {
 
                        // If no RTE object has been set previously, try to create it:
-               if (!isset($GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj']))    {
+               if (!isset($GLOBALS['T3_VAR']['RTEobj']))       {
 
                                // Set the object string to blank by default:
-                       $GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj'] = array();
+                       $GLOBALS['T3_VAR']['RTEobj'] = array();
 
                                // Traverse registered RTEs:
                        if (is_array($GLOBALS['TYPO3_CONF_VARS']['BE']['RTE_reg']))     {
@@ -2821,22 +2822,86 @@ class t3lib_BEfunc      {
                                        $rteObj = &t3lib_div::getUserObj($rteObjCfg['objRef']);
                                        if (is_object($rteObj)) {
                                                if ($rteObj->isAvailable())     {
-                                                       $GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj'] = &$rteObj;
+                                                       $GLOBALS['T3_VAR']['RTEobj'] = &$rteObj;
                                                        break;
                                                } else {
-                                                       $GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj'] = array_merge($GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj'], $rteObj->errorLog);
+                                                       $GLOBALS['T3_VAR']['RTEobj'] = array_merge($GLOBALS['T3_VAR']['RTEobj'], $rteObj->errorLog);
                                                }
                                        }
                                }
                        }
 
-                       if (!count($GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj']))    {
-                               $GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj'][] = 'No RTEs configured at all';
+                       if (!count($GLOBALS['T3_VAR']['RTEobj']))       {
+                               $GLOBALS['T3_VAR']['RTEobj'][] = 'No RTEs configured at all';
                        }
                }
 
                        // Return RTE object (if any!)
-               return $GLOBALS['TYPO3_CONF_VARS']['T3_VAR']['RTEobj'];
+               return $GLOBALS['T3_VAR']['RTEobj'];
+       }
+
+       /**
+        * Returns soft-reference parser for the softRef processing type
+        * Usage: $softRefObj = &t3lib_BEfunc::softRefParserObj('[parser key]');
+        *
+        * @param       string          softRef parser key
+        * @return      mixed           If available, returns Soft link parser object.
+        */
+       function &softRefParserObj($spKey)      {
+
+                       // If no softRef parser object has been set previously, try to create it:
+               if (!isset($GLOBALS['T3_VAR']['softRefParser'][$spKey]))        {
+
+                               // Set the object string to blank by default:
+                       $GLOBALS['T3_VAR']['softRefParser'][$spKey] = '';
+
+                               // Now, try to create parser object:
+                       $objRef = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['softRefParser'][$spKey] ?
+                                                       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['softRefParser'][$spKey] :
+                                                       $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['softRefParser_GL'][$spKey];
+                       if ($objRef)    {
+                               $softRefParserObj = &t3lib_div::getUserObj($objRef,'');
+                               if (is_object($softRefParserObj))       {
+                                       $GLOBALS['T3_VAR']['softRefParser'][$spKey] = &$softRefParserObj;
+                               }
+                       }
+               }
+
+                       // Return RTE object (if any!)
+               return $GLOBALS['T3_VAR']['softRefParser'][$spKey];
+       }
+
+       /**
+        * Returns array of soft parser references
+        *
+        * @param       string          softRef parser list
+        * @param       string          Table name
+        * @param       string          Field name
+        * @return      array           Array where the parser key is the key and the value is the parameter string
+        */
+       function explodeSoftRefParserList($parserList, $table, $field)  {
+
+                       // Looking for global parsers:
+               if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['softRefParser_GL']))  {
+                       $parserList = implode(',',array_keys($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['softRefParser_GL'])).','.$parserList;
+               }
+
+                       // Return immediately if list is blank:
+               if (!strlen($parserList))       return FALSE;
+
+                       // Otherwise parse the list:
+               $keyList = t3lib_div::trimExplode(',', $parserList, 1);
+               $output = array();
+
+               foreach($keyList as $val)       {
+                       $reg = array();
+                       if (ereg('^([[:alnum:]_-]+)\[(.*)\]$', $val, $reg))     {
+                               $output[$reg[1]] = t3lib_div::trimExplode(';', $reg[2], 1);
+                       } else {
+                               $output[$val] = '';
+                       }
+               }
+               return $output;
        }
 
        /**
index 5fb67a6..7d28403 100755 (executable)
@@ -118,6 +118,23 @@ class t3lib_clipboard {
        var $fileMode=0;                // If set, clipboard is displaying files.
 
 
+
+
+
+
+
+
+
+
+
+
+
+       /*****************************************
+        *
+        * Initialize
+        *
+        ****************************************/
+
        /**
         * Initialize the clipboard from the be_user session
         *
@@ -153,8 +170,8 @@ class t3lib_clipboard {
         * @return      void
         */
        function lockToNormal() {
-               $this->lockToNormal=1;
-               $this->current='normal';
+               $this->lockToNormal = 1;
+               $this->current = 'normal';
        }
 
        /**
@@ -257,14 +274,22 @@ class t3lib_clipboard {
                return $CBarr;
        }
 
-       /**
-        * Reports if the current pad has elements (does not check file/DB type OR if file/DBrecord exists or not. Only counting array)
+
+
+
+
+
+
+
+
+
+
+
+       /*****************************************
         *
-        * @return      boolean         True if elements exist.
-        */
-       function isElements()   {
-               return is_array($this->clipData[$this->current]['el']) && count($this->clipData[$this->current]['el']);
-       }
+        * Clipboard HTML renderings
+        *
+        ****************************************/
 
        /**
         * Prints the clipboard
@@ -291,17 +316,27 @@ class t3lib_clipboard {
                        // Selector menu + clear button
                $opt=array();
                $opt[]='<option value="" selected="selected">'.$this->clLabel('menu','rm').'</option>';
-               if (!$this->fileMode && $elCount)       $opt[]='<option value="'.htmlspecialchars("document.location='".$this->editUrl()."&returnUrl='+top.rawurlencode(document.location);").'">'.$this->clLabel('edit','rm').'</option>';
-               if ($elCount)   $opt[]='<option value="'.htmlspecialchars("
+                               // Import / Export link:
+               if ($elCount && t3lib_extMgm::isLoaded('impexp'))       {
+                       $opt[] = '<option value="'.htmlspecialchars("document.location='".$this->backPath.t3lib_extMgm::extRelPath('impexp').'app/index.php'.$this->exportClipElementParameters().'\';').'">'.$this->clLabel('export','rm').'</option>';
+               }
+                               // Edit:
+               if (!$this->fileMode && $elCount)       {
+                       $opt[]='<option value="'.htmlspecialchars("document.location='".$this->editUrl()."&returnUrl='+top.rawurlencode(document.location);").'">'.$this->clLabel('edit','rm').'</option>';
+               }
+                               // Delete:
+               if ($elCount)   {
+                       $opt[]='<option value="'.htmlspecialchars("
                        if(confirm(".$GLOBALS['LANG']->JScharCode(sprintf($LANG->sL('LLL:EXT:lang/locallang_core.php:mess.deleteClip'),$elCount)).")){
                                document.location='".$this->deleteUrl(0,$this->fileMode?1:0)."&redirect='+top.rawurlencode(document.location);
                        }
                        ").'">'.$this->clLabel('delete','rm').'</option>';
+               }
                $selector_menu = '<select name="_clipMenu" onchange="eval(this.options[this.selectedIndex].value);this.selectedIndex=0;">'.implode('',$opt).'</select>';
 
                $out[]='
                        <tr class="typo3-clipboard-head">
-                               <td>'.
+                               <td nowrap="nowrap">'.
                                '<a href="'.htmlspecialchars($thumb_url).'#clip_head">'.
                                        '<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="" />'.
                                        '</a>'.
@@ -310,7 +345,10 @@ class t3lib_clipboard {
                                        '</a>'.
                                '</td>
                                <td width="95%">'.$selector_menu.'</td>
-                               <td><a href="'.htmlspecialchars($rmall_url).'#clip_head">'.$LANG->sL('LLL:EXT:lang/locallang_core.php:buttons.clear',1).'</a></td>
+                               <td>'.
+                               '<a href="'.htmlspecialchars($rmall_url).'#clip_head">'.
+                                       '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/closedok_2.gif','width="21" height="16"').' vspace="2" border="0" title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:buttons.clear',1).'" alt="" />'.
+                                       '</a></td>
                        </tr>';
 
 
@@ -384,7 +422,7 @@ class t3lib_clipboard {
                                                                        <td class="'.$bgColClass.'">'.$icon.'</td>
                                                                        <td class="'.$bgColClass.'" nowrap="nowrap" width="95%">&nbsp;'.$this->linkItemText(htmlspecialchars(t3lib_div::fixed_lgd_cs(basename($v),$GLOBALS['BE_USER']->uc['titleLen'])),$v).
                                                                                ($pad=='normal'?(' <strong>('.($this->clipData['normal']['mode']=='copy'?$this->clLabel('copy','cm'):$this->clLabel('cut','cm')).')</strong>'):'').'&nbsp;'.($thumb?'<br />'.$thumb:'').'</td>
-                                                                       <td class="'.$bgColClass.'" align="center">'.
+                                                                       <td class="'.$bgColClass.'" align="center" nowrap="nowrap">'.
                                                                        '<a href="#" onclick="'.htmlspecialchars('top.launchView(\''.$v.'\', \'\'); return false;').'"><img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/zoom2.gif','width="12" height="12"').' hspace="2" border="0" title="'.$this->clLabel('info','cm').'" alt="" /></a>'.
                                                                        '<a href="'.htmlspecialchars($this->removeUrl('_FILE',t3lib_div::shortmd5($v))).'#clip_head"><img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/close_12h.gif','width="11" height="12"').' border="0" title="'.$this->clLabel('removeItem').'" alt="" /></a>'.
                                                                        '</td>
@@ -402,7 +440,7 @@ class t3lib_clipboard {
                                                                        <td class="'.$bgColClass.'">'.$this->linkItemText(t3lib_iconWorks::getIconImage($table,$rec,$this->backPath,'hspace="20" title="'.htmlspecialchars(t3lib_BEfunc::getRecordIconAltText($rec,$table)).'"'),$rec,$table).'</td>
                                                                        <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).
                                                                                ($pad=='normal'?(' <strong>('.($this->clipData['normal']['mode']=='copy'?$this->clLabel('copy','cm'):$this->clLabel('cut','cm')).')</strong>'):'').'&nbsp;</td>
-                                                                       <td class="'.$bgColClass.'" align="center">'.
+                                                                       <td class="'.$bgColClass.'" align="center" nowrap="nowrap">'.
                                                                        '<a href="#" onclick="'.htmlspecialchars('top.launchView(\''.$table.'\', \''.intval($uid).'\'); return false;').'"><img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/zoom2.gif','width="12" height="12"').' hspace="2" border="0" title="'.$this->clLabel('info','cm').'" alt="" /></a>'.
                                                                        '<a href="'.htmlspecialchars($this->removeUrl($table,$uid)).'#clip_head"><img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/close_12h.gif','width="11" height="12"').' border="0" title="'.$this->clLabel('removeItem').'" alt="" /></a>'.
                                                                        '</td>
@@ -469,41 +507,6 @@ class t3lib_clipboard {
        }
 
        /**
-        * Verifies if the item $table/$uid is on the current pad.
-        * 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...
-        *
-        * @param       string          Table name, (_FILE for files...)
-        * @param       integer         Element uid (path for files)
-        * @return      string
-        */
-       function isSelected($table,$uid)        {
-               $k=$table.'|'.$uid;
-               return $this->clipData[$this->current]['el'][$k] ? ($this->current=='normal'?$this->currentMode():1) : '';
-       }
-
-       /**
-        * Returns item record $table,$uid if selected on current clipboard
-        * If table and uid is blank, the first element is returned.
-        * Makes sense only for DB records - not files!
-        *
-        * @param       string          Table name
-        * @param       integer         Element uid
-        * @return      array           Element record with extra field _RECORD_TITLE set to the title of the record...
-        */
-       function getSelectedRecord($table='',$uid='')   {
-               if (!$table && !$uid)   {
-                       $elArr = $this->elFromTable('');
-                       reset($elArr);
-                       list($table,$uid) = explode('|',key($elArr));
-               }
-               if ($this->isSelected($table,$uid))     {
-                       $selRec = t3lib_BEfunc::getRecord($table,$uid);
-                       $selRec['_RECORD_TITLE'] = t3lib_BEfunc::getRecordTitle($table,$selRec);
-                       return $selRec;
-               }
-       }
-
-       /**
         * Returns the select-url for database elements
         *
         * @param       string          Table name
@@ -606,62 +609,6 @@ class t3lib_clipboard {
        }
 
        /**
-        * This traverses the elements on the current clipboard pane
-        * and unsets elements which does not exist anymore or are disabled.
-        *
-        * @return      void
-        */
-       function cleanCurrent() {
-               if (is_array($this->clipData[$this->current]['el']))    {
-                       reset($this->clipData[$this->current]['el']);
-                       while(list($k,$v)=each($this->clipData[$this->current]['el']))  {
-                               list($table,$uid) = explode('|',$k);
-                               if ($table!='_FILE')    {
-                                       if (!$v || !is_array(t3lib_BEfunc::getRecord($table,$uid,'uid')))       {
-                                               unset($this->clipData[$this->current]['el'][$k]);
-                                               $this->changed=1;
-                                       }
-                               } else {
-                                       if (!$v || !@file_exists($v))   {
-                                               unset($this->clipData[$this->current]['el'][$k]);
-                                               $this->changed=1;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Counts the number of elements from the table $matchTable. If $matchTable is blank, all tables (except '_FILE' of course) is counted.
-        *
-        * @param       string          Table to match/count for.
-        * @param       string          $pad can optionally be used to set another pad than the current.
-        * @return      array           Array with keys from the CB.
-        */
-       function elFromTable($matchTable='',$pad='')    {
-               $pad = $pad ? $pad : $this->current;
-               $list=array();
-               if (is_array($this->clipData[$pad]['el']))      {
-                       reset($this->clipData[$pad]['el']);
-                       while(list($k,$v)=each($this->clipData[$pad]['el']))    {
-                               if ($v) {
-                                       list($table,$uid) = explode('|',$k);
-                                       if ($table!='_FILE')    {
-                                               if ((!$matchTable || (string)$table==(string)$matchTable) && $GLOBALS['TCA'][$table])   {
-                                                       $list[$k]= ($pad=='normal'?$v:$uid);
-                                               }
-                                       } else {
-                                               if ((string)$table==(string)$matchTable)        {
-                                                       $list[$k]=$v;
-                                               }
-                                       }
-                               }
-                       }
-               }
-               return $list;
-       }
-
-       /**
         * Returns confirm JavaScript message
         *
         * @param       string          Table name
@@ -708,6 +655,66 @@ class t3lib_clipboard {
        }
 
        /**
+        * Clipboard label - getting from "EXT:lang/locallang_core.php:"
+        *
+        * @param       string          Label Key
+        * @param       string          Alternative key to "labels"
+        * @return      string
+        */
+       function clLabel($key,$Akey='labels')   {
+               return htmlspecialchars($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:'.$Akey.'.'.$key));
+       }
+
+       /**
+        * Creates GET parameters for linking to the export module.
+        *
+        * @return      string          GET parameters for current clipboard content to be exported.
+        */
+       function exportClipElementParameters()  {
+
+                       // Init:
+               $pad = $this->current;
+               $params = array();
+               $params[] = 'tx_impexp[action]=export';
+
+                       // Traverse items:
+               if (is_array($this->clipData[$pad]['el']))      {
+                       reset($this->clipData[$pad]['el']);
+                       while(list($k,$v)=each($this->clipData[$pad]['el']))    {
+                               if ($v) {
+                                       list($table,$uid) = explode('|',$k);
+
+                                       if ($table=='_FILE')    {       // Rendering files/directories on the clipboard:
+                                               if (@file_exists($v) && t3lib_div::isAllowedAbsPath($v))        {
+                                                       $params[] = 'tx_impexp['.(is_dir($v) ? 'dir' : 'file').'][]='.rawurlencode($v);
+                                               }
+                                       } else {        // Rendering records:
+                                               $rec = t3lib_BEfunc::getRecord($table,$uid);
+                                               if (is_array($rec))     {
+                                                       $params[] = 'tx_impexp[record][]='.rawurlencode($table.':'.$uid);
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               return '?'.implode('&', $params);
+       }
+
+
+
+
+
+
+
+
+       /*****************************************
+        *
+        * Helper functions
+        *
+        ****************************************/
+
+       /**
         * Removes element on clipboard
         *
         * @param       string          Key of element in ->clipData array
@@ -740,14 +747,103 @@ class t3lib_clipboard {
        }
 
        /**
-        * Clipboard label - getting from "EXT:lang/locallang_core.php:"
+        * This traverses the elements on the current clipboard pane
+        * and unsets elements which does not exist anymore or are disabled.
         *
-        * @param       string          Label Key
-        * @param       string          Alternative key to "labels"
+        * @return      void
+        */
+       function cleanCurrent() {
+               if (is_array($this->clipData[$this->current]['el']))    {
+                       reset($this->clipData[$this->current]['el']);
+                       while(list($k,$v)=each($this->clipData[$this->current]['el']))  {
+                               list($table,$uid) = explode('|',$k);
+                               if ($table!='_FILE')    {
+                                       if (!$v || !is_array(t3lib_BEfunc::getRecord($table,$uid,'uid')))       {
+                                               unset($this->clipData[$this->current]['el'][$k]);
+                                               $this->changed=1;
+                                       }
+                               } else {
+                                       if (!$v || !@file_exists($v))   {
+                                               unset($this->clipData[$this->current]['el'][$k]);
+                                               $this->changed=1;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Counts the number of elements from the table $matchTable. If $matchTable is blank, all tables (except '_FILE' of course) is counted.
+        *
+        * @param       string          Table to match/count for.
+        * @param       string          $pad can optionally be used to set another pad than the current.
+        * @return      array           Array with keys from the CB.
+        */
+       function elFromTable($matchTable='',$pad='')    {
+               $pad = $pad ? $pad : $this->current;
+               $list=array();
+               if (is_array($this->clipData[$pad]['el']))      {
+                       reset($this->clipData[$pad]['el']);
+                       while(list($k,$v)=each($this->clipData[$pad]['el']))    {
+                               if ($v) {
+                                       list($table,$uid) = explode('|',$k);
+                                       if ($table!='_FILE')    {
+                                               if ((!$matchTable || (string)$table==(string)$matchTable) && $GLOBALS['TCA'][$table])   {
+                                                       $list[$k]= ($pad=='normal'?$v:$uid);
+                                               }
+                                       } else {
+                                               if ((string)$table==(string)$matchTable)        {
+                                                       $list[$k]=$v;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               return $list;
+       }
+
+       /**
+        * Verifies if the item $table/$uid is on the current pad.
+        * 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...
+        *
+        * @param       string          Table name, (_FILE for files...)
+        * @param       integer         Element uid (path for files)
         * @return      string
         */
-       function clLabel($key,$Akey='labels')   {
-               return htmlspecialchars($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:'.$Akey.'.'.$key));
+       function isSelected($table,$uid)        {
+               $k=$table.'|'.$uid;
+               return $this->clipData[$this->current]['el'][$k] ? ($this->current=='normal'?$this->currentMode():1) : '';
+       }
+
+       /**
+        * Returns item record $table,$uid if selected on current clipboard
+        * If table and uid is blank, the first element is returned.
+        * Makes sense only for DB records - not files!
+        *
+        * @param       string          Table name
+        * @param       integer         Element uid
+        * @return      array           Element record with extra field _RECORD_TITLE set to the title of the record...
+        */
+       function getSelectedRecord($table='',$uid='')   {
+               if (!$table && !$uid)   {
+                       $elArr = $this->elFromTable('');
+                       reset($elArr);
+                       list($table,$uid) = explode('|',key($elArr));
+               }
+               if ($this->isSelected($table,$uid))     {
+                       $selRec = t3lib_BEfunc::getRecord($table,$uid);
+                       $selRec['_RECORD_TITLE'] = t3lib_BEfunc::getRecordTitle($table,$selRec);
+                       return $selRec;
+               }
+       }
+
+       /**
+        * Reports if the current pad has elements (does not check file/DB type OR if file/DBrecord exists or not. Only counting array)
+        *
+        * @return      boolean         True if elements exist.
+        */
+       function isElements()   {
+               return is_array($this->clipData[$this->current]['el']) && count($this->clipData[$this->current]['el']);
        }
 
 
index 5f1a815..0284466 100755 (executable)
@@ -1707,11 +1707,11 @@ class t3lib_div {
         * @param       string          Alternative document tag. Default is "phparray".
         * @param       integer         If set, the number of spaces corresponding to this number is used for indenting, otherwise a single chr(9) (TAB) is used
         * @param       array           Options for the compilation. Key "useNindex" => 0/1 (boolean: whether to use "n0, n1, n2" for num. indexes); Key "useIndexTagForNum" => "[tag for numerical indexes]"; Key "useIndexTagForAssoc" => "[tag for associative indexes"; Key "parentTagMap" => array('parentTag' => 'thisLevelTag')
-        * @param       string          Parent tag name. Don't touch.
+        * @param       string          Stack data. Don't touch.
         * @return      string          An XML string made from the input content in the array.
         * @see xml2array()
         */
-       function array2xml($array,$NSprefix='',$level=0,$docTag='phparray',$spaceInd=0, $options=array(),$parentTagName='')     {
+       function array2xml($array,$NSprefix='',$level=0,$docTag='phparray',$spaceInd=0, $options=array(),$stackData=array())    {
                        // The list of byte values which will trigger binary-safe storage. If any value has one of these char values in it, it will be encoded in base64
                $binaryChars = chr(0).chr(1).chr(2).chr(3).chr(4).chr(5).chr(6).chr(7).chr(8).
                                                chr(11).chr(12).chr(14).chr(15).chr(16).chr(17).chr(18).chr(19).
@@ -1731,7 +1731,16 @@ class t3lib_div {
                                $tagName = $k;
 
                                        // Construct the tag name.
-                               if (!strcmp(intval($tagName),$tagName)) {       // If integer...;
+                               if(isset($options['grandParentTagMap'][$stackData['grandParentTagName'].'/'.$stackData['parentTagName']])) {            // Use tag based on grand-parent + parent tag name
+                                       $attr.=' index="'.htmlspecialchars($tagName).'"';
+                                       $tagName = (string)$options['grandParentTagMap'][$stackData['grandParentTagName'].'/'.$stackData['parentTagName']];
+                               }elseif(isset($options['parentTagMap'][$stackData['parentTagName'].':'.$tagName])) {            // Use tag based on parent tag name + current tag
+                                       $attr.=' index="'.htmlspecialchars($tagName).'"';
+                                       $tagName = (string)$options['parentTagMap'][$stackData['parentTagName'].':'.$tagName];
+                               } elseif(isset($options['parentTagMap'][$stackData['parentTagName']])) {                // Use tag based on parent tag name:
+                                       $attr.=' index="'.htmlspecialchars($tagName).'"';
+                                       $tagName = (string)$options['parentTagMap'][$stackData['parentTagName']];
+                               } elseif (!strcmp(intval($tagName),$tagName))   {       // If integer...;
                                        if ($options['useNindex']) {    // If numeric key, prefix "n"
                                                $tagName = 'n'.$tagName;
                                        } else {        // Use special tag for num. keys:
@@ -1741,9 +1750,6 @@ class t3lib_div {
                                } elseif($options['useIndexTagForAssoc']) {             // Use tag for all associative keys:
                                        $attr.=' index="'.htmlspecialchars($tagName).'"';
                                        $tagName = $options['useIndexTagForAssoc'];
-                               } elseif(isset($options['parentTagMap'][$parentTagName])) {             // Use tag based on parent tag name:
-                                       $attr.=' index="'.htmlspecialchars($tagName).'"';
-                                       $tagName = (string)$options['parentTagMap'][$parentTagName];
                                }
 
                                        // The tag name is cleaned up so only alphanumeric chars (plus - and _) are in there and not longer than 100 chars either.
@@ -1751,8 +1757,30 @@ class t3lib_div {
 
                                        // If the value is an array then we will call this function recursively:
                                if (is_array($v))       {
-                                       // Sub elements:
-                                       $content = chr(10).t3lib_div::array2xml($v,$NSprefix,$level+1,'',$spaceInd,$options,$tagName).
+
+                                               // Sub elements:
+                                       if ($options['alt_options'][$stackData['path'].'/'.$tagName])   {
+                                               $subOptions = $options['alt_options'][$stackData['path'].'/'.$tagName];
+                                               $clearStackPath = $subOptions['clearStackPath'];
+                                       } else {
+                                               $subOptions = $options;
+                                               $clearStackPath = FALSE;
+                                       }
+
+                                       $content = chr(10).
+                                                               t3lib_div::array2xml(
+                                                                       $v,
+                                                                       $NSprefix,
+                                                                       $level+1,
+                                                                       '',
+                                                                       $spaceInd,
+                                                                       $subOptions,
+                                                                       array(
+                                                                               'parentTagName' => $tagName,
+                                                                               'grandParentTagName' => $stackData['parentTagName'],
+                                                                               'path' => $clearStackPath ? '' : $stackData['path'].'/'.$tagName,
+                                                                       )
+                                                               ).
                                                                str_pad('',($level+1)*$indentN,$indentChar);
                                        $attr.=' type="array"';
                                } else {        // Just a value:
@@ -1766,7 +1794,7 @@ class t3lib_div {
                                                        // Otherwise, just htmlspecialchar the stuff:
                                                $content = htmlspecialchars($v);
                                                $dType = gettype($v);
-                                               if ($dType!='string')   { $attr.=' type="'.$dType.'"'; }
+                                               if ($dType!='string' && !$options['disableTypeAttrib']) { $attr.=' type="'.$dType.'"'; }
                                        }
                                }
 
@@ -1793,10 +1821,11 @@ class t3lib_div {
         *
         * @param       string          XML content to convert into an array
         * @param       string          The tag-prefix resolve, eg. a namespace like "T3:"
+        * @param       boolean         If set, the document tag will be set in the key "_DOCUMENT_TAG" of the output array
         * @return      mixed           If the parsing had errors, a string with the error message is returned. Otherwise an array with the content.
         * @see array2xml()
         */
-       function xml2array($string,$NSprefix='') {
+       function xml2array($string,$NSprefix='',$reportDocTag=FALSE) {
                global $TYPO3_CONF_VARS;
 
                        // Create parser:
@@ -1809,7 +1838,7 @@ class t3lib_div {
 
                        // PHP5 fix of charset awareness:
                        // Problem is: PHP5 apparently detects the charset of the XML file (or defaults to utf-8) and will AUTOMATICALLY convert the content to either utf-8, iso-8859-1 or us-ascii. PHP4 just passed the content through without taking action regarding the charset.
-                       // In TYPO3 we expect that the charset of XML content is NOT handled in the parser but internally in TYPO3 instead. THerefore it would be very nice if PHP5 could be configured to NOT process the charset of the files. But this is not possible for now.
+                       // In TYPO3 we expect that the charset of XML content is NOT handled in the parser but internally in TYPO3 instead. Therefore it would be very nice if PHP5 could be configured to NOT process the charset of the files. But this is not possible for now.
                        // What we do here fixes the problem but ONLY if the charset is utf-8, iso-8859-1 or us-ascii. That should work for most TYPO3 installations, in particular if people use utf-8 which we highly recommend.
                if ((double)phpversion()>=5)    {
                        unset($ereg_result);
@@ -1822,20 +1851,24 @@ class t3lib_div {
                xml_parse_into_struct($parser, $string, $vals, $index);
 
                        // If error, return error message:
-               if (xml_get_error_code($parser))        return 'Line '.xml_get_current_line_number($parser).': '.xml_error_string(xml_get_error_code($parser));
+               if (xml_get_error_code($parser))        {
+                       return 'Line '.xml_get_current_line_number($parser).': '.xml_error_string(xml_get_error_code($parser));
+               }
                xml_parser_free($parser);
 
                        // Init vars:
                $stack = array(array());
                $stacktop = 0;
                $current=array();
-               $tagName='';
+               $tagName = '';
+               $documentTag = '';
 
                        // Traverse the parsed XML structure:
                foreach($vals as $key => $val) {
 
                                // First, process the tag-name (which is used in both cases, whether "complete" or "close")
                        $tagName = $val['tag'];
+                       if (!$documentTag)      $documentTag = $tagName;
 
                                // Test for name space:
                        $tagName = ($NSprefix && substr($tagName,0,strlen($NSprefix))==$NSprefix) ? substr($tagName,strlen($NSprefix)) : $tagName;
@@ -1887,6 +1920,10 @@ class t3lib_div {
                        }
                }
 
+               if ($reportDocTag)      {
+                       $current[$tagName]['_DOCUMENT_TAG'] = $documentTag;
+               }
+
                        // Finally return the content of the document tag.
                return $current[$tagName];
        }
@@ -2144,7 +2181,7 @@ class t3lib_div {
                                while($entry=$d->read()) {
                                        if (@is_file($path.'/'.$entry)) {
                                                $fI = pathinfo($entry);
-                                               $key = md5($path.'/'.$entry);
+                                               $key = md5($path.'/'.$entry);   // Don't change this ever - extensions may depend on the fact that the hash is an md5 of the path! (import/export extension)
                                                if (!$extensionList || t3lib_div::inList($extensionList,strtolower($fI['extension'])))  {
                                                    $filearray[$key]=($prependPath?$path.'/':'').$entry;
                                                        if ($order=='mtime') {$sortarray[$key]=filemtime($path.'/'.$entry);}
index 1fd7eab..0d5d954 100755 (executable)
@@ -136,6 +136,8 @@ class t3lib_extFileFunctions extends t3lib_basicFileFunctions       {
        var $PHPFileFunctions = 0;                      // If set, all fileoperations are done by the default PHP-functions. This is necessary under windows! On UNIX the system commands by exec() can be used unless safe_mode is enabled
        var $dont_use_exec_commands = 0;        // This is necessary under windows!
 
+               // Internal, dynamic:
+       var $internalUploadMap = array();       // Will contain map between upload ID and the final filename
 
 
 
@@ -793,6 +795,7 @@ class t3lib_extFileFunctions extends t3lib_basicFileFunctions       {
                                                                        t3lib_div::upload_copy_move($theFile,$theNewFile);
                                                                        clearstatcache();
                                                                        if (@is_file($theNewFile))      {
+                                                                               $this->internalUploadMap[$id] = $theNewFile;
                                                                                $this->writelog(1,0,1,'Uploading file "%s" to "%s"',Array($theName,$theNewFile, $id));
                                                                                return $theNewFile;
                                                                        } else $this->writelog(1,1,100,'Uploaded file could not be moved! Write-permission problem in "%s"?',Array($theTarget.'/'));
index 63f3228..9dea193 100644 (file)
@@ -813,11 +813,12 @@ class t3lib_parsehtml {
         * @param       string          Prefix string
         * @param       string          HTML content
         * @param       array           Array with alternative prefixes for certain of the tags. key=>value pairs where the keys are the tag element names in uppercase
+        * @param       string          Suffix string (put after the resource).
         * @return      string          Processed HTML content
         */
-       function prefixResourcePath($main_prefix,$content,$alternatives=array())        {
+       function prefixResourcePath($main_prefix,$content,$alternatives=array(),$suffix='')     {
 
-               $parts = $this->splitTags('td,table,body,img,input,form,link,script,a',$content);
+               $parts = $this->splitTags('embed,td,table,body,img,input,form,link,script,a',$content);
                foreach($parts as $k => $v)     {
                        if ($k%2)       {
                                $params = $this->get_tag_attributes($v,1);
@@ -832,7 +833,7 @@ class t3lib_parsehtml {
                                        case 'table':
                                                $src = $params[0]['background'];
                                                if ($src)       {
-                                                       $params[0]['background'] = $this->prefixRelPath($prefix,$params[0]['background']);
+                                                       $params[0]['background'] = $this->prefixRelPath($prefix,$params[0]['background'],$suffix);
                                                        $somethingDone=1;
                                                }
                                        break;
@@ -840,9 +841,10 @@ class t3lib_parsehtml {
                                        case 'img':
                                        case 'input':
                                        case 'script':
+                                       case 'embed':
                                                $src = $params[0]['src'];
                                                if ($src)       {
-                                                       $params[0]['src'] = $this->prefixRelPath($prefix,$params[0]['src']);
+                                                       $params[0]['src'] = $this->prefixRelPath($prefix,$params[0]['src'],$suffix);
                                                        $somethingDone=1;
                                                }
                                        break;
@@ -850,7 +852,7 @@ class t3lib_parsehtml {
                                        case 'a':
                                                $src = $params[0]['href'];
                                                if ($src)       {
-                                                       $params[0]['href'] = $this->prefixRelPath($prefix,$params[0]['href']);
+                                                       $params[0]['href'] = $this->prefixRelPath($prefix,$params[0]['href'],$suffix);
                                                        $somethingDone=1;
                                                }
                                        break;
@@ -858,7 +860,7 @@ class t3lib_parsehtml {
                                        case 'form':
                                                $src = $params[0]['action'];
                                                if ($src)       {
-                                                       $params[0]['action'] = $this->prefixRelPath($prefix,$params[0]['action']);
+                                                       $params[0]['action'] = $this->prefixRelPath($prefix,$params[0]['action'],$suffix);
                                                        $somethingDone=1;
                                                }
                                        break;
@@ -879,7 +881,7 @@ class t3lib_parsehtml {
                        $parts = $this->splitIntoBlock('style',$content);
                        foreach($parts as $k => $v)     {
                                if ($k%2)       {
-                                       $parts[$k] = eregi_replace('(url[[:space:]]*\([[:space:]]*["\']?)([^"\')]*)(["\']?[[:space:]]*\))','\1'.$prefix.'\2\3',$parts[$k]);
+                                       $parts[$k] = eregi_replace('(url[[:space:]]*\([[:space:]]*["\']?)([^"\')]*)(["\']?[[:space:]]*\))','\1'.$prefix.'\2'.$suffix.'\3',$parts[$k]);
                                }
                        }
                        $content = implode('',$parts);
@@ -893,13 +895,14 @@ class t3lib_parsehtml {
         *
         * @param       string          Prefix string
         * @param       string          Relative path/URL
+        * @param       string          Suffix
         * @return      string          Output path, prefixed if no scheme in input string
         * @access private
         */
-       function prefixRelPath($prefix,$srcVal) {
+       function prefixRelPath($prefix,$srcVal,$suffix='')      {
                $pU = parse_url($srcVal);
                if (!$pU['scheme'] && substr($srcVal, 0, 1)!='/')       { // If not an absolute URL.
-                       $srcVal = $prefix.$srcVal;
+                       $srcVal = $prefix.$srcVal.$suffix;
                }
                return $srcVal;
        }
diff --git a/t3lib/class.t3lib_softrefproc.php b/t3lib/class.t3lib_softrefproc.php
new file mode 100755 (executable)
index 0000000..8c7f15a
--- /dev/null
@@ -0,0 +1,846 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2003-2004 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  All rights reserved
+*
+*  This script is part of the Typo3 project. The Typo3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+/**
+ * Soft Reference processing class
+ * "Soft References" are references to database elements, files, email addresses, URls etc.
+ * which are found in-text in content. The <link [page_id]> tag from typical bodytext fields
+ * are an example of this.
+ * This class contains generic parsers for the most well-known types
+ * which are default for most TYPO3 installations. Soft References can also be userdefined.
+ * The Soft Reference parsers are used by the system to find these references and process them accordingly in import/export actions and copy operations.
+ *
+ * $Id$
+ *
+ * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ */
+/**
+ * [CLASS/FUNCTION INDEX of SCRIPT]
+ *
+ *
+ *
+ *  115: class t3lib_softrefproc
+ *  136:     function findRef($table, $field, $uid, $content, $spKey, $spParams, $structurePath='')
+ *  208:     function findRef_images($content, $spParams)
+ *  275:     function findRef_typolink($content, $spParams)
+ *  312:     function findRef_typolink_tag($content, $spParams)
+ *  347:     function findRef_TStemplate($content, $spParams)
+ *  429:     function findRef_TSconfig($content, $spParams)
+ *  452:     function findRef_email($content, $spParams)
+ *  490:     function findRef_url($content, $spParams)
+ *  532:     function findRef_extension_fileref($content, $spParams)
+ *
+ *              SECTION: Helper functions
+ *  584:     function fileadminReferences($content, &$elements)
+ *  627:     function getTypoLinkParts($typolinkValue)
+ *  711:     function setTypoLinkPartsElement($tLP, &$elements, $content, $idx)
+ *  822:     function getPageIdFromAlias($link_param)
+ *  834:     function makeTokenID($index='')
+ *
+ * TOTAL FUNCTIONS: 14
+ * (This index is automatically created/updated by the extension "extdeveval")
+ *
+ */
+
+
+/**
+ * Example of usage
+ *                             // Soft References:
+ *                     if ($conf['softref'] && strlen($value)) {       // Check if a TCA configured field has softreferences defined (see TYPO3 Core API document)
+ *                             $softRefs = t3lib_BEfunc::explodeSoftRefParserList($conf['softref']);           // Explode the list of softreferences/parameters
+ *                             foreach($softRefs as $spKey => $spParams)       {       // Traverse soft references
+ *                                     $softRefObj = &t3lib_BEfunc::softRefParserObj($spKey);  // create / get object
+ *                                     if (is_object($softRefObj))     {       // If there was an object returned...:
+ *                                             $resultArray = $softRefObj->findRef($table, $field, $uid, $softRefValue, $spKey, $spParams);    // Do processing
+ *
+ * Result Array:
+ * The Result array should contain two keys: "content" and "elements".
+ * "content" is a string containing the input content but possibly with tokens inside.
+ *             Tokens are strings like {softref:[tokenID]} which is a placeholder for a value extracted by a softref parser
+ *             For each token there MUST be an entry in the "elements" key which has a "subst" key defining the tokenID and the tokenValue. See below.
+ * "elements" is an array where the keys are insignificant, but the values are arrays with these keys:
+ *             "matchString" => The value of the match. This is only for informational purposes to show what was found.
+ *             "error" => An error message can be set here, like "file not found" etc.
+ *             "subst" => array(       // If this array is found there MUST be a token in the output content as well!
+ *                     "tokenID" => The tokenID string corresponding to the token in output content, {softref:[tokenID]}. This is typically an md5 hash of a string defining uniquely the position of the element.
+ *                     "tokenValue" => The value that the token substitutes in the text. Basically, if this value is inserted instead of the token the content should match what was inputted originally.
+ *                     "type" => file / db / string    = the type of substitution. "file" means it is a relative file [automatically mapped], "db" means a database record reference [automatically mapped], "string" means it is manually modified string content (eg. an email address)
+ *                     "relFileName" => (for "file" type): Relative filename. May not necessarily exist. This could be noticed in the error key.
+ *                     "recordRef" => (for "db" type) : Reference to DB record on the form [table]:[uid]. May not necessarily exist.
+ *                     "title" => Title of element (for backend information)
+ *                     "description" => Description of element (for backend information)
+ *             )
+ *
+ */
+
+
+require_once(PATH_t3lib.'class.t3lib_parsehtml.php');
+
+/**
+ * Class for processing of the default soft reference types for CMS:
+ *
+ * - 'substitute' : A full field value targeted for manual substitution (for import /export features)
+ * - 'notify' : Just report if a value is found, nothing more.
+ * - 'images' : HTML <img> tags for RTE images / images from fileadmin/
+ * - 'typolink' : references to page id or file, possibly with anchor/target, possibly commaseparated list.
+ * - 'typolink_tag' : As typolink, but searching for <link> tag to encapsulate it.
+ * - 'TSconfig' processing (filerefs? Domains? what do we know...)
+ * - 'TStemplate' : freetext references to "fileadmin/" files.
+ * - 'ext_fileref' : Relative file reference, prefixed "EXT:[extkey]/" - for finding extension dependencies
+ * - 'email' : Email highlight
+ * - 'url' : URL highlights (with a scheme)
+ *
+ * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class t3lib_softrefproc {
+
+               // external configuration
+       var $fileAdminDir = 'fileadmin';
+
+
+               // Internal:
+       var $tokenID_basePrefix = '';
+
+       /**
+        * Main function through which all processing happens
+        *
+        * @param       string          Database table name
+        * @param       string          Field name for which processing occurs
+        * @param       integer         UID of the record
+        * @param       string          The content/value of the field
+        * @param       string          The softlink parser key. This is only interesting if more than one parser is grouped in the same class. That is the case with this parser.
+        * @param       array           Parameters of the softlink parser. Basically this is the content inside optional []-brackets after the softref keys. Parameters are exploded by ";"
+        * @param       string          If running from inside a FlexForm structure, this is the path of the tag.
+        * @return      array           Result array on positive matches, see description above. Otherwise false
+        */
+       function findRef($table, $field, $uid, $content, $spKey, $spParams, $structurePath='')  {
+
+               $this->tokenID_basePrefix = $table.':'.$uid.':'.$field.':'.$structurePath.':'.$spKey;
+
+               switch($spKey)  {
+                       case 'notify':  // Simple notification
+                               $resultArray = array(
+                                       'elements' => array(
+                                               array(
+                                                       'matchString' => $content
+                                               )
+                                       )
+                               );
+                               return $resultArray;
+                       break;
+                       case 'substitute':
+                               $tokenID = $this->makeTokenID();
+                               $resultArray = array(
+                                       'content' => '{softref:'.$tokenID.'}',
+                                       'elements' => array(
+                                               array(
+                                                       'matchString' => $content,
+                                                       'subst' => array(
+                                                               'type' => 'string',
+                                                               'tokenID' => $tokenID,
+                                                               'tokenValue' => $content
+                                                       )
+                                               )
+                                       )
+                               );
+                               return $resultArray;
+                       break;
+                       case 'images':
+                               return $this->findRef_images($content, $spParams);
+                       break;
+                       case 'typolink':
+                               return $this->findRef_typolink($content, $spParams);
+                       break;
+                       case 'typolink_tag':
+                               return $this->findRef_typolink_tag($content, $spParams);
+                       break;
+                       case 'ext_fileref':
+                               return $this->findRef_extension_fileref($content, $spParams);
+                       break;
+                       case 'TStemplate':
+                               return $this->findRef_TStemplate($content, $spParams);
+                       break;
+                       case 'TSconfig':
+                               return $this->findRef_TSconfig($content, $spParams);
+                       break;
+                       case 'email':
+                               return $this->findRef_email($content, $spParams);
+                       break;
+                       case 'url':
+                               return $this->findRef_url($content, $spParams);
+                       break;
+                       default:
+                               return FALSE;
+                       break;
+               }
+       }
+
+       /**
+        * Finding image tags in the content.
+        * All images that are not from external URLs will be returned with an info text
+        * Will only return files in fileadmin/ and files in uploads/ folders which are prefixed with "RTEmagic[C|P]_" for substitution
+        * Any "clear.gif" images are ignored.
+        *
+        * @param       string          The input content to analyse
+        * @param       array           Parameters set for the softref parser key in TCA/columns
+        * @return      array           Result array on positive matches, see description above. Otherwise false
+        */
+       function findRef_images($content, $spParams)    {
+
+                       // Start HTML parser and split content by image tag:
+               $htmlParser = t3lib_div::makeInstance('t3lib_parsehtml');
+               $splitContent = $htmlParser->splitTags('img',$content);
+               $elements = array();
+
+                       // Traverse splitted parts:
+               foreach($splitContent as $k => $v)      {
+                       if ($k%2)       {
+
+                                       // Get file reference:
+                               $attribs = $htmlParser->get_tag_attributes($v);
+                               $srcRef = t3lib_div::htmlspecialchars_decode($attribs[0]['src']);
+                               $pI = pathinfo($srcRef);
+
+                                       // If it looks like a local image, continue. Otherwise ignore it.
+                               $absPath = t3lib_div::getFileAbsFileName(PATH_site.$srcRef);
+                               if (!$pI['scheme'] && !$pI['query'] && $absPath && $srcRef!=='clear.gif')       {
+
+                                               // Initialize the element entry with info text here:
+                                       $tokenID = $this->makeTokenID($k);
+                                       $elements[$k] = array();
+                                       $elements[$k]['matchString'] = $v;
+
+                                               // If the image seems to be from fileadmin/ folder or an RTE image, then proceed to set up substitution token:
+                                       if (t3lib_div::isFirstPartOfStr($srcRef,$this->fileAdminDir.'/') || (t3lib_div::isFirstPartOfStr($srcRef,'uploads/') && ereg('^RTEmagicC_',basename($srcRef)))) {
+                                                       // Token and substitute value:
+                                               if (strstr($splitContent[$k], $attribs[0]['src']))      {       // Make sure the value we work on is found and will get substituted in the content (Very important that the src-value is not DeHSC'ed)
+                                                       $splitContent[$k] = str_replace($attribs[0]['src'], '{softref:'.$tokenID.'}', $splitContent[$k]);       // Substitute value with token (this is not be an exact method if the value is in there twice, but we assume it will not)
+                                                       $elements[$k]['subst'] = array(
+                                                               'type' => 'file',
+                                                               'relFileName' => $srcRef,
+                                                               'tokenID' => $tokenID,
+                                                               'tokenValue' => $attribs[0]['src'],
+                                                       );
+                                                       if (!@is_file($absPath))        {       // Finally, notice if the file does not exist.
+                                                               $elements[$k]['error'] = 'File does not exist!';
+                                                       }
+                                               } else {
+                                                       $elements[$k]['error'] = 'Could not substitute image source with token!';
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+                       // Return result:
+               if (count($elements))   {
+                       $resultArray = array(
+                               'content' => implode('', $splitContent),
+                               'elements' => $elements
+                       );
+
+                       return $resultArray;
+               }
+       }
+
+       /**
+        * TypoLink value processing.
+        * Will process input value as a TypoLink value.
+        *
+        * @param       string          The input content to analyse
+        * @param       array           Parameters set for the softref parser key in TCA/columns. value "linkList" will split the string by comma before processing.
+        * @return      array           Result array on positive matches, see description above. Otherwise false
+        * @see tslib_content::typolink(), getTypoLinkParts()
+        */
+       function findRef_typolink($content, $spParams)  {
+
+                       // First, split the input string by a comma if the "linkList" parameter is set.
+                       // An example: the link field for images in content elements of type "textpic" or "image". This field CAN be configured to define a link per image, separated by comma.
+               if (is_array($spParams) && in_array('linkList',$spParams))      {
+                       $linkElement = explode(',', $content);  // Preserving whitespace on purpose.
+               } else {
+                       $linkElement = array($content); // If only one element, just set in this array to make it easy below.
+               }
+
+                       // Traverse the links now:
+               $elements = array();
+               foreach($linkElement as $k => $typolinkValue)   {
+                       $tLP = $this->getTypoLinkParts($typolinkValue);
+                       $linkElement[$k] = $this->setTypoLinkPartsElement($tLP, $elements, $typolinkValue, $k);
+               }
+
+                       // Return output:
+               if (count($elements))   {
+                       $resultArray = array(
+                               'content' => implode(',', $linkElement),
+                               'elements' => $elements
+                       );
+
+                       return $resultArray;
+               }
+       }
+
+       /**
+        * TypoLink tag processing.
+        * Will search for <link ...> tags in the content string and process any found.
+        *
+        * @param       string          The input content to analyse
+        * @param       array           Parameters set for the softref parser key in TCA/columns
+        * @return      array           Result array on positive matches, see description above. Otherwise false
+        * @see tslib_content::typolink(), getTypoLinkParts()
+        */
+       function findRef_typolink_tag($content, $spParams)      {
+
+                       // Parse string for special TYPO3 <link> tag:
+               $htmlParser = t3lib_div::makeInstance('t3lib_parsehtml');
+               $linkTags = $htmlParser->splitTags('link',$content);
+
+                       // Traverse result:
+               $elements = array();
+               foreach($linkTags as $k => $foundValue) {
+                       if ($k%2)       {
+                               $typolinkValue = eregi_replace('<link[[:space:]]+','',substr($foundValue,0,-1));
+                               $tLP = $this->getTypoLinkParts($typolinkValue);
+                               $linkTags[$k] = '<link '.$this->setTypoLinkPartsElement($tLP, $elements, $typolinkValue, $k).'>';
+                       }
+               }
+
+                       // Return output:
+               if (count($elements))   {
+                       $resultArray = array(
+                               'content' => implode('', $linkTags),
+                               'elements' => $elements
+                       );
+
+                       return $resultArray;
+               }
+       }
+
+       /**
+        * Processing the content expected from a TypoScript template
+        * This content includes references to files in fileadmin/ folders and file references in HTML tags like <img src="">, <a href=""> and <form action="">
+        *
+        * @param       string          The input content to analyse
+        * @param       array           Parameters set for the softref parser key in TCA/columns
+        * @return      array           Result array on positive matches, see description above. Otherwise false
+        */
+       function findRef_TStemplate($content, $spParams)        {
+               $elements = array();
+
+                       // First, try to find images and links:
+               $htmlParser = t3lib_div::makeInstance('t3lib_parsehtml');
+               $splitContent = $htmlParser->splitTags('img,a,form', $content);
+
+                       // Traverse splitted parts:
+               foreach($splitContent as $k => $v)      {
+                       if ($k%2)       {
+
+                               $attribs = $htmlParser->get_tag_attributes($v);
+
+                               $attributeName = '';
+                               switch($htmlParser->getFirstTagName($v))        {
+                                       case 'img':
+                                               $attributeName = 'src';
+                                       break;
+                                       case 'a':
+                                               $attributeName = 'href';
+                                       break;
+                                       case 'form':
+                                               $attributeName = 'action';
+                                       break;
+                               }
+
+                                       // Get file reference:
+                               if (isset($attribs[0][$attributeName])) {
+                                       $srcRef = t3lib_div::htmlspecialchars_decode($attribs[0][$attributeName]);
+
+                                               // Set entry:
+                                       $tokenID = $this->makeTokenID($k);
+                                       $elements[$k] = array();
+                                       $elements[$k]['matchString'] = $v;
+
+                                               // OK, if it looks like a local file from fileadmin/, include it:
+                                       $pI = pathinfo($srcRef);
+                                       $absPath = t3lib_div::getFileAbsFileName(PATH_site.$srcRef);
+                                       if (t3lib_div::isFirstPartOfStr($srcRef,$this->fileAdminDir.'/') && !$pI['query'] && $absPath)  {
+
+                                                       // Token and substitute value:
+                                               if (strstr($splitContent[$k], $attribs[0][$attributeName]))     {       // Very important that the src-value is not DeHSC'ed
+                                                       $splitContent[$k] = str_replace($attribs[0][$attributeName], '{softref:'.$tokenID.'}', $splitContent[$k]);
+                                                       $elements[$k]['subst'] = array(
+                                                               'type' => 'file',
+                                                               'relFileName' => $srcRef,
+                                                               'tokenID' => $tokenID,
+                                                               'tokenValue' => $attribs[0][$attributeName],
+                                                       );
+                                                       if (!@is_file($absPath))        {
+                                                               $elements[$k]['error'] = 'File does not exist!';
+                                                       }
+                                               } else {
+                                                       $elements[$k]['error'] = 'Could not substitute attribute ('.$attributeName.') value with token!';
+                                               }
+                                       }
+                               }
+                       }
+               }
+               $content = implode('', $splitContent);
+
+                       // Process free fileadmin/ references as well:
+               $content = $this->fileadminReferences($content, $elements);
+
+                       // Return output:
+               if (count($elements))   {
+                       $resultArray = array(
+                               'content' => $content,
+                               'elements' => $elements
+                       );
+                       return $resultArray;
+               }
+       }
+
+       /**
+        * Processes possible references inside of Page and User TSconfig fields.
+        * Currently this only includes file references to fileadmin/ but in fact there are currently no properties that supports such references.
+        *
+        * @param       string          The input content to analyse
+        * @param       array           Parameters set for the softref parser key in TCA/columns
+        * @return      array           Result array on positive matches, see description above. Otherwise false
+        */
+       function findRef_TSconfig($content, $spParams)  {
+               $elements = array();
+
+                       // Process free fileadmin/ references from TSconfig
+               $content = $this->fileadminReferences($content, $elements);
+
+                       // Return output:
+               if (count($elements))   {
+                       $resultArray = array(
+                               'content' => $content,
+                               'elements' => $elements
+                       );
+                       return $resultArray;
+               }
+       }
+
+       /**
+        * Finding email addresses in content and making them substitutable.
+        *
+        * @param       string          The input content to analyse
+        * @param       array           Parameters set for the softref parser key in TCA/columns
+        * @return      array           Result array on positive matches, see description above. Otherwise false
+        */
+       function findRef_email($content, $spParams)     {
+               $resultArray = array();
+
+                       // email:
+               $parts = preg_split("/([^[:alnum:]]+)([A-Za-z0-9\._-]+[@][A-Za-z0-9\._-]+[\.].[A-Za-z0-9]+)/", ' '.$content.' ',10000, PREG_SPLIT_DELIM_CAPTURE);
+               foreach($parts as $idx => $value)       {
+                       if ($idx%3 == 2)        {
+
+                               $tokenID = $this->makeTokenID($idx);
+                               $elements[$idx] = array();
+                               $elements[$idx]['matchString'] = $value;
+
+                               if (is_array($spParams) && in_array('subst',$spParams)) {
+                                       $parts[$idx] = '{softref:'.$tokenID.'}';
+                                       $elements[$idx]['subst'] = array(
+                                               'type' => 'string',
+                                               'tokenID' => $tokenID,
+                                               'tokenValue' => $value,
+                                       );
+                               }
+                       }
+               }
+
+                       // Return output:
+               if (count($elements))   {
+                       $resultArray = array(
+                               'content' => substr(implode('',$parts),1,-1),
+                               'elements' => $elements
+                       );
+                       return $resultArray;
+               }
+       }
+
+       /**
+        * Finding URLs in content, but only to notify about their existence. No substitution (could be done later via a parameter)
+        *
+        * @param       string          The input content to analyse
+        * @param       array           Parameters set for the softref parser key in TCA/columns
+        * @return      array           Result array on positive matches, see description above. Otherwise false
+        */
+       function findRef_url($content, $spParams)       {
+               $resultArray = array();
+
+                       // Fileadmin files:
+               $parts = preg_split("/([^[:alnum:]\"']+)((http|ftp):\/\/[^[:space:]\"'<>]*)([[:space:]])/", ' '.$content.' ',10000, PREG_SPLIT_DELIM_CAPTURE);
+
+               foreach($parts as $idx => $value)       {
+                       if ($idx%5 == 3)        { unset($parts[$idx]); }
+                       if ($idx%5 == 2)        {
+
+                               $tokenID = $this->makeTokenID($idx);
+                               $elements[$idx] = array();
+                               $elements[$idx]['matchString'] = $value;
+
+                               if (is_array($spParams) && in_array('subst',$spParams)) {
+                                       $parts[$idx] = '{softref:'.$tokenID.'}';
+                                       $elements[$idx]['subst'] = array(
+                                               'type' => 'string',
+                                               'tokenID' => $tokenID,
+                                               'tokenValue' => $value,
+                                       );
+                               }
+                       }
+               }
+
+                       // Return output:
+               if (count($elements))   {
+                       $resultArray = array(
+                               'content' => substr(implode('',$parts),1,-1),
+                               'elements' => $elements
+                       );
+                       return $resultArray;
+               }
+       }
+
+       /**
+        * Finding reference to files from extensions in content, but only to notify about their existence. No substitution
+        *
+        * @param       string          The input content to analyse
+        * @param       array           Parameters set for the softref parser key in TCA/columns
+        * @return      array           Result array on positive matches, see description above. Otherwise false
+        */
+       function findRef_extension_fileref($content, $spParams) {
+               $resultArray = array();
+
+                       // Fileadmin files:
+               $parts = preg_split("/([^[:alnum:]\"']+)(EXT:[[:alnum:]_]+\/[^[:space:]\"',]*)/", ' '.$content.' ',10000, PREG_SPLIT_DELIM_CAPTURE);
+
+               foreach($parts as $idx => $value)       {
+                       if ($idx%3 == 2)        {
+
+                               $tokenID = $this->makeTokenID($idx);
+                               $elements[$idx] = array();
+                               $elements[$idx]['matchString'] = $value;
+                       }
+               }
+
+                       // Return output:
+               if (count($elements))   {
+                       $resultArray = array(
+                               'content' => substr(implode('',$parts),1,-1),
+                               'elements' => $elements
+                       );
+                       return $resultArray;
+               }
+       }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+       /*************************
+        *
+        * Helper functions
+        *
+        *************************/
+
+       /**
+        * Searches the content for a reference to a file in "fileadmin/".
+        * When a match is found it will get substituted with a token.
+        *
+        * @param       string          Input content to analyse
+        * @param       array           Element array to be modified with new entries. Passed by reference.
+        * @return      string          Output content, possibly with tokens inserted.
+        */
+       function fileadminReferences($content, &$elements)      {
+
+                       // Fileadmin files are found
+               $parts = preg_split("/([^[:alnum:]]+)(".$this->fileAdminDir."\/[^[:space:]\"']*)/", ' '.$content.' ',10000, PREG_SPLIT_DELIM_CAPTURE);
+
+                       // Traverse files:
+               foreach($parts as $idx => $value)       {
+                       if ($idx%3 == 2)        {
+
+                                       // when file is found, set up an entry for the element:
+                               $tokenID = $this->makeTokenID('fileadminReferences:'.$idx);
+                               $elements['fileadminReferences.'.$idx] = array();
+                               $elements['fileadminReferences.'.$idx]['matchString'] = $value;
+                               $elements['fileadminReferences.'.$idx]['subst'] = array(
+                                       'type' => 'file',
+                                       'relFileName' => $value,
+                                       'tokenID' => $tokenID,
+                                       'tokenValue' => $value,
+                               );
+                               $parts[$idx] = '{softref:'.$tokenID.'}';
+
+                                       // Check if the file actually exists:
+                               $absPath = t3lib_div::getFileAbsFileName(PATH_site.$value);
+                               if (!@is_file($absPath))        {
+                                       $elements['fileadminReferences.'.$idx]['error'] = 'File does not exist!';
+                               }
+                       }
+               }
+#debug($parts);
+                       // Implode the content again, removing prefixed and trailing white space:
+               return substr(implode('',$parts),1,-1);
+       }
+
+       /**
+        * Analyse content as a TypoLink value and return an array with properties.
+        * TypoLinks format is: <link [typolink] [browser target] [css class]>. See tslib_content::typolink()
+        * The syntax of the [typolink] part is: [typolink] = [page id or alias][,[type value]][#[anchor, if integer = tt_content uid]]
+        * The extraction is based on how tslib_content::typolink() behaves.
+        *
+        * @param       string          TypoLink value.
+        * @return      array           Array with the properties of the input link specified. The key "LINK_TYPE" will reveal the type. If that is blank it could not be determined.
+        * @see tslib_content::typolink(), setTypoLinkPartsElement()
+        */
+       function getTypoLinkParts($typolinkValue)       {
+               $finalTagParts = array();
+
+                       // Split by space into link / target / class
+               list($link_param, $browserTarget, $cssClass) = t3lib_div::trimExplode(' ',$typolinkValue,1);
+               if (strlen($browserTarget))     $finalTagParts['target'] = $browserTarget;
+               if (strlen($cssClass))  $finalTagParts['class'] = $cssClass;
+
+                       // Parse URL:
+               $pU = parse_url($link_param);
+
+                       // Detecting the kind of reference:
+               if(strstr($link_param,'@') && !$pU['scheme'])   {               // If it's a mail address:
+                       $link_param = eregi_replace('^mailto:','',$link_param);
+
+                       $finalTagParts['LINK_TYPE'] = 'mailto';
+                       $finalTagParts['url'] = trim($link_param);
+               } else {
+                       $isLocalFile = 0;
+                       $fileChar = intval(strpos($link_param, '/'));
+                       $urlChar = intval(strpos($link_param, '.'));
+
+                               // Detects if a file is found in site-root (or is a 'virtual' simulateStaticDocument file!) and if so it will be treated like a normal file.
+                       list($rootFileDat) = explode('?',rawurldecode($link_param));
+                       $containsSlash = strstr($rootFileDat,'/');
+                       $rFD_fI = pathinfo($rootFileDat);
+                       if (trim($rootFileDat) && !$containsSlash && (@is_file(PATH_site.$rootFileDat) || t3lib_div::inList('php,html,htm',strtolower($rFD_fI['extension']))))  {
+                               $isLocalFile = 1;
+                       } elseif ($containsSlash)       {
+                               $isLocalFile = 2;               // Adding this so realurl directories are linked right (non-existing).
+                       }
+
+                       if($pU['scheme'] || ($isLocalFile!=1 && $urlChar && (!$containsSlash || $urlChar<$fileChar)))   {       // url (external): If doubleSlash or if a '.' comes before a '/'.
+                               $finalTagParts['LINK_TYPE'] = 'url';
+                               $finalTagParts['url'] = $link_param;
+                       } elseif ($containsSlash || $isLocalFile)       {       // file (internal)
+                               $splitLinkParam = explode('?', $link_param);
+                               if (@file_exists(rawurldecode($splitLinkParam[0])) || $isLocalFile)     {
+                                       $finalTagParts['LINK_TYPE'] = 'file';
+                                       $finalTagParts['filepath'] = rawurldecode($splitLinkParam[0]);
+                                       $finalTagParts['query'] = $splitLinkParam[1];
+                               }
+                       } else {        // integer or alias (alias is without slashes or periods or commas, that is 'nospace,alphanum_x,lower,unique' according to definition in $TCA!)
+                               $finalTagParts['LINK_TYPE'] = 'page';
+
+                               $link_params_parts = explode('#',$link_param);
+                               $link_param = trim($link_params_parts[0]);              // Link-data del
+
+                               if (strlen($link_params_parts[1]))      {
+                                       $finalTagParts['anchor'] = trim($link_params_parts[1]);
+                               }
+
+                                       // Splitting the parameter by ',' and if the array counts more than 1 element it's a id/type/? pair
+                               $pairParts = t3lib_div::trimExplode(',',$link_param);
+                               if (count($pairParts)>1)        {
+                                       $link_param = $pairParts[0];
+                                       $finalTagParts['type'] = $pairParts[1];         // Overruling 'type'
+                               }
+
+                                       // Checking if the id-parameter is an alias.
+                               if (strlen($link_param))        {
+                                       if (!t3lib_div::testInt($link_param))   {
+                                               $finalTagParts['alias'] = $link_param;
+                                               $link_param = $this->getPageIdFromAlias($link_param);
+                                       }
+
+                                       $finalTagParts['page_id'] = intval($link_param);
+                               }
+                       }
+               }
+
+               return $finalTagParts;
+       }
+
+       /**
+        * Recompile a TypoLink value from the array of properties made with getTypoLinkParts() into an elements array
+        *
+        * @param       array           TypoLink properties
+        * @param       array           Array of elements to be modified with substitution / information entries.
+        * @param       string          The content to process.
+        * @param       integer         Index value of the found element - user to make unique but stable tokenID
+        * @return      string          The input content, possibly containing tokens now according to the added substitution entries in $elements
+        * @see getTypoLinkParts()
+        */
+       function setTypoLinkPartsElement($tLP, &$elements, $content, $idx)      {
+
+                       // Initialize, set basic values. In any case a link will be shown
+               $tokenID = $this->makeTokenID('setTypoLinkPartsElement:'.$idx);
+               $elements[$tokenID.':'.$idx] = array();
+               $elements[$tokenID.':'.$idx]['matchString'] = $content;
+
+                       // Based on link type, maybe do more:
+               switch ((string)$tLP['LINK_TYPE'])      {
+                       case 'mailto':
+                                       // Mail addresses can be substituted manually:
+                               $elements[$tokenID.':'.$idx]['subst'] = array(
+                                       'type' => 'string',
+                                       'tokenID' => $tokenID,
+                                       'tokenValue' => $tLP['url'],
+                               );
+                                       // Output content will be the token instead:
+                               $content = '{softref:'.$tokenID.'}';
+                       break;
+                       case 'url':
+                                       // Nothing done, only for informational purposes. So return content right away:
+                               return $content;
+                       break;
+                       case 'file':
+                                       // Process files found in fileadmin directory:
+                               if (!$tLP['query'])     {       // We will not process files which has a query added to it. That will look like a script we don't want to move.
+                                       if (t3lib_div::isFirstPartOfStr($tLP['filepath'],$this->fileAdminDir.'/'))      {       // File must be inside fileadmin/
+
+                                                       // Set up the basic token and token value for the relative file:
+                                               $elements[$tokenID.':'.$idx]['subst'] = array(
+                                                       'type' => 'file',
+                                                       'relFileName' => $tLP['filepath'],
+                                                       'tokenID' => $tokenID,
+                                                       'tokenValue' => $tLP['filepath'],
+                                               );
+
+                                                       // Depending on whether the file exists or not we will set the
+                                               $absPath = t3lib_div::getFileAbsFileName(PATH_site.$tLP['filepath']);
+                                               if (!@is_file($absPath))        {
+                                                       $elements[$tokenID.':'.$idx]['error'] = 'File does not exist!';
+                                               }
+
+                                                       // Output content will be the token instead
+                                               $content = '{softref:'.$tokenID.'}';
+                                       } else return $content;
+                               } else return $content;
+                       break;
+                       case 'page':
+                                       // Rebuild page reference typolink part:
+                               $content = '';
+
+                                       // Set page id:
+                               if ($tLP['page_id'])    {
+                                       $content.= '{softref:'.$tokenID.'}';
+                                       $elements[$tokenID.':'.$idx]['subst'] = array(
+                                               'type' => 'db',
+                                               'recordRef' => 'pages:'.$tLP['page_id'],
+                                               'tokenID' => $tokenID,
+                                               'tokenValue' => $tLP['alias'] ? $tLP['alias'] : $tLP['page_id'],        // Set page alias if that was used.
+                                       );
+                               }
+
+                                       // Add type if applicable
+                               if (strlen($tLP['type']))       {
+                                       $content.= ','.$tLP['type'];
+                               }
+
+                                       // Add anchor if applicable
+                               if (strlen($tLP['anchor']))     {
+                                       if (t3lib_div::testInt($tLP['anchor'])) {       // Anchor is assumed to point to a content elements:
+                                                       // Initialize a new entry because we have a new relation:
+                                               $newTokenID = $this->makeTokenID('setTypoLinkPartsElement:anchor:'.$idx);
+                                               $elements[$newTokenID.':'.$idx] = array();
+                                               $elements[$newTokenID.':'.$idx]['matchString'] = 'Anchor Content Element: '.$tLP['anchor'];
+
+                                               $content.= '#{softref:'.$newTokenID.'}';
+                                               $elements[$newTokenID.':'.$idx]['subst'] = array(
+                                                       'type' => 'db',
+                                                       'recordRef' => 'tt_content:'.$tLP['anchor'],
+                                                       'tokenID' => $newTokenID,
+                                                       'tokenValue' => $tLP['anchor'],
+                                               );
+                                       } else {        // Anchor is a hardcoded string
+                                               $content.= '#'.$tLP['type'];
+                                       }
+                               }
+                       break;
+                       default:
+                               $elements[$tokenID.':'.$idx]['error'] = 'Couldn\t decide typolink mode.';
+                               return $content;
+                       break;
+               }
+
+                       // Finally, for all entries that was rebuild with tokens, add target and class in the end:
+               if (strlen($content) && strlen($tLP['target'])) {
+                       $content.= ' '.$tLP['target'];
+                       if (strlen($tLP['class']))      {
+                               $content.= ' '.$tLP['class'];
+                       }
+               }
+
+                       // Return rebuilt typolink value:
+               return $content;
+       }
+
+       /**
+        * Look up and return page uid for alias
+        *
+        * @param       integer         Page alias string value
+        * @return      integer         Page uid corresponding to alias value.
+        */
+       function getPageIdFromAlias($link_param)        {
+               $pRec = t3lib_BEfunc::getRecordsByField('pages','alias',$link_param);
+
+               return $pRec[0]['uid'];
+       }
+
+       /**
+        * Make Token ID for input index.
+        *
+        * @param       string          suffix value.
+        * @return      string          Token ID
+        */
+       function makeTokenID($index='') {
+               return md5($this->tokenID_basePrefix.':'.$index);
+       }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_softrefproc.php'])      {
+       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_softrefproc.php']);
+}
+?>
index 699b21a..b1b1002 100755 (executable)
@@ -1679,7 +1679,7 @@ class t3lib_TCEforms      {
 
                                                $fI = pathinfo($imgP[0]);
                                                $fileIcon = t3lib_BEfunc::getFileIcon(strtolower($fI['extension']));
-                                               $fileIcon = '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/fileicons/'.$fileIcon,'width="18" height="16"').' class="absmiddle" title="'.htmlspecialchars($fI['basename'].($absFilePath ? ' ('.t3lib_div::formatSize(filesize($absFilePath)).'bytes)' : ' - FILE NOT FOUND!')).'" alt="" />';
+                                               $fileIcon = '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/fileicons/'.$fileIcon,'width="18" height="16"').' class="absmiddle" title="'.htmlspecialchars($fI['basename'].($absFilePath && @is_file($absFilePath) ? ' ('.t3lib_div::formatSize(filesize($absFilePath)).'bytes)' : ' - FILE NOT FOUND!')).'" alt="" />';
 
                                                $imgs[] = '<span class="nobr">'.t3lib_BEfunc::thumbCode($rowCopy,$table,$field,$this->backPath,'thumbs.php',$config['uploadfolder'],0,' align="middle"').
                                                                        ($absFilePath ? $this->getClickMenu($fileIcon, $absFilePath) : $fileIcon).
index 546ccf2..62528f4 100755 (executable)
@@ -213,6 +213,8 @@ class t3lib_TCEmain {
        var $storeLogMessages=1;                // If set, the default log-messages will be stored. This should not be necessary if the locallang-file for the log-display is properly configured. So disabling this will just save some database-space as the default messages are not saved.
        var $enableLogging=1;                   // If set, actions are logged.
 
+       var $callBackObj;                               // Call back object for flex form traversation. Useful when external classes wants to use the iteration functions inside tcemain for traversing a FlexForm structure.
+
 //     var $history=1;                                 // Bit-array: Bit0: History on/off. DEPENDS on checkSimilar to be set!
        var $checkSimilar=1;                    // Boolean: If set, only fields which are different from the database values are saved! In fact, if a whole input array is similar, it's not saved then.
        var $dontProcessTransformations=0;      // Boolean: If set, then transformations are NOT performed on the input.
@@ -236,6 +238,7 @@ class t3lib_TCEmain {
        var $data_disableFields=array();                // If entries are set in this array corresponding to fields for update, they are ignored and thus NOT updated. You could set this array from a series of checkboxes with value=0 and hidden fields before the checkbox with 1. Then an empty checkbox will disable the field.
        var $defaultValues=array();                             // You can set this array on the form $defaultValues[$table][$field] = $value to override the default values fetched from TCA. You must set this externally.
        var $overrideValues=array();                    // You can set this array on the form $overrideValues[$table][$field] = $value to override the incoming data. You must set this externally. You must make sure the fields in this array are also found in the table, because it's not checked. All columns can be set by this array!
+       var $suggestedInsertUids=array();               // Use this array to validate suggested uids for tables by setting [table]:[uid]. This is a dangerous option since it will force the inserted record to have a certain UID. The value just have to be true, but if you set it to "DELETE" it will make sure any record with that UID will be deleted first (raw delete). The option is used for import of T3D files when synchronizing between two mirrored servers. As a security measure this feature is available only for Admin Users (for now)
 
                // *********
                // internal
@@ -595,7 +598,7 @@ class t3lib_TCEmain {
                                                        if (is_array($fieldArray)) {
                                                                if ($status=='new')     {
        //                                                              if ($pid_value<0)       {$fieldArray = $this->fixCopyAfterDuplFields($table,$id,abs($pid_value),0,$fieldArray);}        // Out-commented 02-05-02: I couldn't understand WHY this is needed for NEW records. Obviously to proces records being copied? Problem is that the fields are not set anyways and the copying function should basically take care of this!
-                                                                       $this->insertDB($table,$id,$fieldArray);
+                                                                       $this->insertDB($table,$id,$fieldArray,FALSE,$incomingFieldArray['uid']);
                                                                } else {
                                                                        $this->updateDB($table,$id,$fieldArray);
                                                                }
@@ -2020,7 +2023,8 @@ class t3lib_TCEmain       {
                                                        $uploadedFiles[$sKey][$lKey],
                                                        $dataStruct['ROOT']['el'],
                                                        $pParams,
-                                                       $callBackFunc
+                                                       $callBackFunc,
+                                                       $sKey.'/'.$lKey.'/'
                                                );
                                        }
                                }
@@ -2039,11 +2043,11 @@ class t3lib_TCEmain     {
         * @param       array           Uploaded files array for sheet/language. May be empty array() if not needed (for callBackFunctions)
         * @param       array           Data structure which fits the data array
         * @param       array           A set of parameters to pass through for the calling of the evaluation functions / call back function
-        * @param       string          Call back function, default is checkValue_SW().
+        * @param       string          Call back function, default is checkValue_SW(). If $this->callBackObj is set to an object, the callback function in that object is called instead.
         * @return      void
         * @see checkValue_flex_procInData()
         */
-       function checkValue_flex_procInData_travDS(&$dataValues,$dataValues_current,$uploadedFiles,$DSelements,$pParams,$callBackFunc='')       {
+       function checkValue_flex_procInData_travDS(&$dataValues,$dataValues_current,$uploadedFiles,$DSelements,$pParams,$callBackFunc,$structurePath)   {
                if (is_array($DSelements))      {
 
                                // For each DS element:
@@ -2062,7 +2066,8 @@ class t3lib_TCEmain       {
                                                                                        $uploadedFiles[$key]['el'][$ik][$theKey]['el'],
                                                                                        $DSelements[$key]['el'][$theKey]['el'],
                                                                                        $pParams,
-                                                                                       $callBackFunc
+                                                                                       $callBackFunc,
+                                                                                       $structurePath.$key.'/el/'.$ik.'/'.$theKey.'/el/'
                                                                                );
                                                                }
                                                        }
@@ -2074,7 +2079,8 @@ class t3lib_TCEmain       {
                                                                        $uploadedFiles[$key]['el'],
                                                                        $DSelements[$key]['el'],
                                                                        $pParams,
-                                                                       $callBackFunc
+                                                                       $callBackFunc,
+                                                                       $structurePath.$key.'/el/'
                                                                );
                                                }
                                        }
@@ -2083,13 +2089,24 @@ class t3lib_TCEmain     {
                                                foreach($dataValues[$key] as $vKey => $data)    {
 
                                                        if ($callBackFunc)      {
-                                                               $res = $this->$callBackFunc(
-                                                                                       $pParams,
-                                                                                       $dsConf['TCEforms']['config'],
-                                                                                       $dataValues[$key][$vKey],
-                                                                                       $dataValues_current[$key][$vKey],
-                                                                                       $uploadedFiles[$key][$vKey]
-                                                                               );
+                                                               if (is_object($this->callBackObj))      {
+                                                                       $res = $this->callBackObj->$callBackFunc(
+                                                                                               $pParams,
+                                                                                               $dsConf['TCEforms']['config'],
+                                                                                               $dataValues[$key][$vKey],
+                                                                                               $dataValues_current[$key][$vKey],
+                                                                                               $uploadedFiles[$key][$vKey],
+                                                                                               $structurePath.$key.'/'.$vKey.'/'
+                                                                                       );
+                                                               } else {
+                                                                       $res = $this->$callBackFunc(
+                                                                                               $pParams,
+                                                                                               $dsConf['TCEforms']['config'],
+                                                                                               $dataValues[$key][$vKey],
+                                                                                               $dataValues_current[$key][$vKey],
+                                                                                               $uploadedFiles[$key][$vKey]
+                                                                                       );
+                                                               }
                                                        } else {        // Default
                                                                list($CVtable,$CVid,$CVcurValue,$CVstatus,$CVrealPid,$CVrecFID,$CVtscPID) = $pParams;
 
@@ -2277,9 +2294,10 @@ class t3lib_TCEmain      {
         * @param       string          "NEW...." uid string
         * @param       array           Array of field=>value pairs to insert. FIELDS MUST MATCH the database FIELDS. No check is done. "pid" must point to the destination of the record!
         * @param       boolean         Set to true if new version is created.
+        * @param       integer         Suggested UID value for the inserted record. See the array $this->suggestedInsertUids; Admin-only feature
         * @return      void
         */
-       function insertDB($table,$id,$fieldArray,$newVersion=FALSE)     {
+       function insertDB($table,$id,$fieldArray,$newVersion=FALSE,$suggestedUid=0)     {
                global $TCA;
 
                if (is_array($fieldArray) && is_array($TCA[$table]) && isset($fieldArray['pid']))       {
@@ -2287,6 +2305,20 @@ class t3lib_TCEmain      {
 
                        if (count($fieldArray)) {
 
+                                       // Check for "suggestedUid".
+                                       // This feature is used by the import functionality to force a new record to have a certain UID value.
+                                       // This is only recommended for use when the destination server is a passive mirrow of another server.
+                                       // As a security measure this feature is available only for Admin Users (for now)
+                               $suggestedUid = intval($suggestedUid);
+                               if ($this->BE_USER->isAdmin() && $suggestedUid && $this->suggestedInsertUids[$table.':'.$suggestedUid]) {
+                                               // When the value of ->suggestedInsertUids[...] is "DELETE" it will try to remove the previous record
+                                       if ($this->suggestedInsertUids[$table.':'.$suggestedUid]==='DELETE')    {
+                                                       // DELETE:
+                                               $GLOBALS['TYPO3_DB']->exec_DELETEquery($table, 'uid='.intval($suggestedUid));
+                                       }
+                                       $fieldArray['uid'] = $suggestedUid;
+                               }
+
                                        // Execute the INSERT query:
                                $GLOBALS['TYPO3_DB']->exec_INSERTquery($table, $fieldArray);
 
@@ -2406,7 +2438,7 @@ class t3lib_TCEmain       {
         * @return      void
         */
        function clear_cache($table,$uid) {
-               global $TCA;
+               global $TCA, $TYPO3_CONF_VARS;
 
                $uid = intval($uid);
                if (is_array($TCA[$table]) && $uid > 0) {
@@ -2416,8 +2448,10 @@ class t3lib_TCEmain      {
                        $TSConfig = $this->getTCEMAIN_TSconfig($tscPID);
 
                        if (!$TSConfig['clearCache_disable'])   {
+
                                        // If table is "pages":
                                if (t3lib_extMgm::isLoaded('cms'))      {
+                                       $list_cache = array();
                                        if ($table=='pages')    {
 
                                                        // Builds list of pages on the SAME level as this page (siblings)
@@ -2427,7 +2461,6 @@ class t3lib_TCEmain       {
                                                                                'A.uid='.intval($uid).' AND B.pid=A.pid AND B.deleted=0'
                                                                        );
 
-                                               $list_cache = array();
                                                $pid_tmp = 0;
                                                while ($row_tmp = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res_tmp)) {
                                                        $list_cache[] = $row_tmp['uid'];
@@ -2460,16 +2493,23 @@ class t3lib_TCEmain     {
                                                                $list_cache[] = $row_tmp['pid'];
                                                        }
                                                }
+                                       } else {        // For other tables than "pages", delete cache for the records "parent page".
+                                               $list_cache[] = intval($this->getPID($table,$uid));
+                                       }
+
+                                               // Call pre-processing function for clearing of cache for page ids:
+                                       if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearPageCacheEval']))    {
+                                               foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearPageCacheEval'] as $funcName)     {
+                                                       $_params = array('pageIdArray' => &$list_cache, 'table' => $table, 'uid' => $uid, 'functionID' => 'clear_cache()');
+                                                               // Returns the array of ids to clear, false if nothing should be cleared! Never an empty array!
+                                                       t3lib_div::callUserFunction($funcName,$_params,$this);
+                                               }
+                                       }
 
-                                                       // Delete cache for selected pages:
+                                               // Delete cache for selected pages:
+                                       if (is_array($list_cache))      {
                                                $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages','page_id IN ('.implode(',',$GLOBALS['TYPO3_DB']->cleanIntArray($list_cache)).')');
                                                $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pagesection', 'page_id IN ('.implode(',',$GLOBALS['TYPO3_DB']->cleanIntArray($list_cache)).')');
-                                       } else {        // For other tables than "pages", delete cache for the records "parent page".
-                                               $uid_page = $this->getPID($table,$uid);
-                                               if ($uid_page>0)        {
-                                                       $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages', 'page_id='.intval($uid_page));
-                                                       $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pagesection', 'page_id='.intval($uid_page));
-                                               }
                                        }
                                }
                        }
@@ -4389,10 +4429,10 @@ class t3lib_TCEmain     {
        }
 
        /**
-        * [Describe function...]
+        * Returns true if the TCA/columns field type is a DB reference field
         *
-        * @param       [type]          $conf: ...
-        * @return      [type]          ...
+        * @param       array           config array for TCA/columns field
+        * @return      boolean         True if DB reference field (group/db or select with foreign-table)
         */
        function isReferenceField($conf)        {
                return ($conf['type']=='group' && $conf['internal_type']=='db') ||      ($conf['type']=='select' && $conf['foreign_table']);
@@ -4635,7 +4675,23 @@ class t3lib_TCEmain      {
                        // Clear cache for a page ID!
                if (t3lib_div::testInt($cacheCmd))      {
                        if (t3lib_extMgm::isLoaded('cms'))      {
-                               $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages', 'page_id='.intval($cacheCmd));
+
+                               $list_cache = array($cacheCmd);
+
+                                       // Call pre-processing function for clearing of cache for page ids:
+                               if (is_array($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearPageCacheEval']))    {
+                                       foreach($TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearPageCacheEval'] as $funcName)     {
+                                               $_params = array('pageIdArray' => &$list_cache, 'cacheCmd' => $cacheCmd, 'functionID' => 'clear_cacheCmd()');
+                                                       // Returns the array of ids to clear, false if nothing should be cleared! Never an empty array!
+                                               t3lib_div::callUserFunction($funcName,$_params,$this);
+                                       }
+                               }
+
+                                       // Delete cache for selected pages:
+                               if (is_array($list_cache))      {
+                                       $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pages','page_id IN ('.implode(',',$GLOBALS['TYPO3_DB']->cleanIntArray($list_cache)).')');
+                                       $GLOBALS['TYPO3_DB']->exec_DELETEquery('cache_pagesection', 'page_id IN ('.implode(',',$GLOBALS['TYPO3_DB']->cleanIntArray($list_cache)).')');  // Originally, cache_pagesection was not cleared with cache_pages!
+                               }
                        }
                }
 
index 8b1b4ba..a3302a3 100755 (executable)
@@ -74,7 +74,7 @@ $TYPO3_CONF_VARS = Array(
                'no_pconnect' => 0,                                             // Boolean: If true, "connect" is used instead of "pconnect" when connecting to the database!
                'multiplyDBfieldSize' => 1,                             // Double: 1-5: Amount used to multiply the DB field size when the install tool is evaluating the database size (eg. "2.5"). This is useful if you want to expand the size of fields for utf-8 etc. For western european sites using utf-8 the need should not be for more than twice the normal single-byte size (2) and for chinese / asian languages 3 should suffice.
                'setMemoryLimit' => 0,                                  // Integer, memory_limit in MB: If more than 16, TYPO3 will try to use ini_set() to set the memory limit of PHP to the value. This works only if the function ini_set() is not disabled by your sysadmin.
-               'displayErrors' => 0,                                   // Integer, -1,0,1. 0=Do not display any PHP error messages. 1=Display error messages. -1=Default setting. With this option, you can override the PHP setting "display_errors". It is suggested that you leave this unchanged but enable the "error_log" option in php.ini instead.
+               'displayErrors' => -1,                                  // Integer, -1,0,1. 0=Do not display any PHP error messages. 1=Display error messages. -1=Default setting. With this option, you can override the PHP setting "display_errors". It is suggested that you set this to "0" and enable the "error_log" option in php.ini instead.
                'serverTimeZone' => 1                                   // Integer, GMT offset of servers time (from time()). Default is "1" which is "GMT+1" (central european time). This value can be used in extensions that are GMT aware and wants to convert times to/from other timezones.
        ),
        'EXT' => Array (        // Options related to the Extension Management
@@ -197,7 +197,22 @@ $TYPO3_CONF_VARS = Array(
        ),
        'USER' => Array(                // Here you may define your own setup-vars for use in your include-scripts. (obsolete, make extension instead)
        ),
-       'SC_OPTIONS' => Array(          // Here you can more or less freely define additional configuration for scripts in TYPO3. Of course the features supported depends on the script. See documentation "Inside TYPO3" for examples. Keys in the array are the relative path of a script (for output scripts it should be the "script ID" as found in a comment in the HTML header ) and values can then be anything that scripts wants to define for itself.
+       'SC_OPTIONS' => Array(          // Here you can more or less freely define additional configuration for scripts in TYPO3. Of course the features supported depends on the script. See documentation "Inside TYPO3" for examples. Keys in the array are the relative path of a script (for output scripts it should be the "script ID" as found in a comment in the HTML header ) and values can then be anything that scripts wants to define for itself. The key "GLOBAL" is reserved.
+               'GLOBAL' => array(
+                       'softRefParser' => array(
+                               'substitute' => 't3lib/class.t3lib_softrefproc.php:&t3lib_softrefproc',
+                               'notify' => 't3lib/class.t3lib_softrefproc.php:&t3lib_softrefproc',
+                               'images' => 't3lib/class.t3lib_softrefproc.php:&t3lib_softrefproc',
+                               'typolink' => 't3lib/class.t3lib_softrefproc.php:&t3lib_softrefproc',
+                               'typolink_tag' => 't3lib/class.t3lib_softrefproc.php:&t3lib_softrefproc',
+                               'TSconfig' => 't3lib/class.t3lib_softrefproc.php:&t3lib_softrefproc',
+                               'TStemplate' => 't3lib/class.t3lib_softrefproc.php:&t3lib_softrefproc',
+                               'ext_fileref' => 't3lib/class.t3lib_softrefproc.php:&t3lib_softrefproc',
+                               'email' => 't3lib/class.t3lib_softrefproc.php:&t3lib_softrefproc',
+                               'url' => 't3lib/class.t3lib_softrefproc.php:&t3lib_softrefproc',
+                       ),
+                       'softRefParser_GL' => array()   // Global soft reference parsers
+               )
        ),
        'EXTCONF' => Array (            // Here you may add manually set configuration options for your extensions. Eg. $TYPO3_CONF_VARS['EXTCONF']['my_extension_key']['my_option'] = 'my_value';
 //             '--key--' => array()
diff --git a/t3lib/gfx/rel_softref.png b/t3lib/gfx/rel_softref.png
new file mode 100755 (executable)
index 0000000..c09d7ba
Binary files /dev/null and b/t3lib/gfx/rel_softref.png differ
index 3433fbd..89cd3c2 100755 (executable)
@@ -193,7 +193,8 @@ $TCA['pages'] = Array (
                                                'icon' => 'wizard_tsconfig.gif',
                                                'JSopenParams' => 'height=500,width=780,status=0,menubar=0,scrollbars=1',
                                        )
-                               )
+                               ),
+                               'softref' => 'TSconfig'
                        )
                ),
                'php_tree_stop' => Array (
index 7671839..84f09f6 100755 (executable)
@@ -74,7 +74,7 @@ $TCA['be_users'] = Array (
                                'foreign_table_where' => 'ORDER BY be_groups.title',
                                'size' => '5',
                                'maxitems' => '20',
-                               'renderMode' => $GLOBALS['TYPO3_CONF_VARS']['BE']['accessListRenderMode'],
+#                              'renderMode' => $GLOBALS['TYPO3_CONF_VARS']['BE']['accessListRenderMode'],
                                'iconsInOptionTags' => 1,
                                'wizards' => Array(
                                        '_PADDING' => 1,
@@ -118,7 +118,8 @@ $TCA['be_users'] = Array (
                                'size' => '20',
                                'eval' => 'trim',
                                'max' => '50',
-                               'checkbox' => ''
+                               'checkbox' => '',
+                               'softref' => 'substitute'
                        )
                ),
                'db_mountpoints' => Array (
@@ -185,7 +186,8 @@ $TCA['be_users'] = Array (
                                'type' => 'input',
                                'size' => '20',
                                'eval' => 'trim',
-                               'max' => '80'
+                               'max' => '80',
+                               'softref' => 'email[subst]'
                        )
                ),
                'realName' => Array (
@@ -351,7 +353,8 @@ $TCA['be_users'] = Array (
                                                'icon' => 'wizard_tsconfig.gif',
                                                'JSopenParams' => 'height=500,width=780,status=0,menubar=0,scrollbars=1',
                                        )
-                               )
+                               ),
+                               'softref' => 'TSconfig'
                        )
                ),
                'createdByAction' => Array('config'=>array('type'=>'passthrough'))
@@ -531,7 +534,8 @@ $TCA['be_groups'] = Array (
                                'size' => '20',
                                'eval' => 'trim',
                                'max' => '50',
-                               'checkbox' => ''
+                               'checkbox' => '',
+                               'softref' => 'substitute'
                        )
                ),
                'groupMods' => Array (
@@ -576,7 +580,8 @@ $TCA['be_groups'] = Array (
                                                'icon' => 'wizard_tsconfig.gif',
                                                'JSopenParams' => 'height=500,width=780,status=0,menubar=0,scrollbars=1',
                                        )
-                               )
+                               ),
+                               'softref' => 'TSconfig'
                        )
                ),
                'hide_in_lists' => Array (
@@ -632,7 +637,8 @@ $TCA['sys_filemounts'] = Array (
                                'type' => 'input',
                                'size' => '40',
                                'max' => '120',
-                               'eval' => 'required,trim'
+                               'eval' => 'required,trim',
+                               'softref' => 'substitute'
                        )
                ),
                'hidden' => Array (
index ca46d1c..eddd033 100755 (executable)
@@ -109,6 +109,9 @@ class SC_alt_shortcut {
        var $editPage;                  // Page alias or id to be edited
        var $selOpt;                    // Select options.
 
+       var $alternativeTableUid = array();     // Array with key 0/1 being table/uid of record to edit. Internally set.
+
+
 
        /**
         * Pre-initialization - setting input variables for storing shortcuts etc.
@@ -232,7 +235,7 @@ class SC_alt_shortcut {
         * @return      void
         */
        function main() {
-               global $BE_USER,$LANG;
+               global $BE_USER,$LANG,$TCA;
 
                        // Setting groups and globals
                $this->nGroups=4;
@@ -322,9 +325,16 @@ class SC_alt_shortcut {
 
                        ';
 
+                       // Launch Edit page:
                if ($this->theEditRec['uid'])   {
                        $this->content.=$this->doc->wrapScriptTags('top.loadEditId('.$this->theEditRec['uid'].');');
                }
+
+                       // Load alternative table/uid into editing form.
+               if (count($this->alternativeTableUid)==2 && isset($TCA[$this->alternativeTableUid[0]]) && t3lib_div::testInt($this->alternativeTableUid[1]))    {
+                       $JSaction = t3lib_BEfunc::editOnClick('&edit['.$this->alternativeTableUid[0].']['.$this->alternativeTableUid[1].']=edit','','dummy.php');
+                       $this->content.=$this->doc->wrapScriptTags('function editArbitraryElement() { top.content.'.$JSaction.'; } editArbitraryElement();');
+               }
        }
 
        /**
@@ -403,28 +413,34 @@ class SC_alt_shortcut {
                $this->editError = '';
                $this->theEditRec = '';
                if ($this->editPage)    {
-                       $where = ' AND ('.$BE_USER->getPagePermsClause(2).' OR '.$BE_USER->getPagePermsClause(16).')';
-                       if (t3lib_div::testInt($this->editPage))        {
-                               $this->theEditRec = t3lib_BEfunc::getRecord ('pages',$this->editPage,'*',$where);
-                       } else {
-                               $records = t3lib_BEfunc::getRecordsByField('pages','alias',$this->editPage,$where);
-                               if (is_array($records)) {
-                                       reset($records);
-                                       $this->theEditRec = current($records);
+
+                               // First, test alternative value consisting of [table]:[uid] and if not found, proceed with traditional page ID resolve:
+                       $this->alternativeTableUid = explode(':',$this->editPage);
+                       if (!(count($this->alternativeTableUid)==2 && $BE_USER->isAdmin()))     {       // We restrict it to admins only just because I'm not really sure if alt_doc.php properly checks permissions of passed records for editing. If alt_doc.php does that, then we can remove this.
+
+                               $where = ' AND ('.$BE_USER->getPagePermsClause(2).' OR '.$BE_USER->getPagePermsClause(16).')';
+                               if (t3lib_div::testInt($this->editPage))        {
+                                       $this->theEditRec = t3lib_BEfunc::getRecord ('pages',$this->editPage,'*',$where);
+                               } else {
+                                       $records = t3lib_BEfunc::getRecordsByField('pages','alias',$this->editPage,$where);
+                                       if (is_array($records)) {
+                                               reset($records);
+                                               $this->theEditRec = current($records);
+                                       }
                                }
-                       }
-                       if (!is_array($this->theEditRec) || !$BE_USER->isInWebMount($this->theEditRec['uid']))  {
-                               unset($this->theEditRec);
-                               $this->editError=$LANG->getLL('shortcut_notEditable');
-                       } else {
-                                       // Visual path set:
-                               $perms_clause = $BE_USER->getPagePermsClause(1);
-                               $this->editPath = t3lib_BEfunc::getRecordPath($this->theEditRec['pid'], $perms_clause, 30);
-
-                               if(!$BE_USER->getTSConfigVal('options.shortcut_onEditId_dontSetPageTree')) {
-
-                                               // Expanding page tree:
-                                       t3lib_BEfunc::openPageTree($this->theEditRec['pid'],!$BE_USER->getTSConfigVal('options.shortcut_onEditId_keepExistingExpanded'));
+                               if (!is_array($this->theEditRec) || !$BE_USER->isInWebMount($this->theEditRec['uid']))  {
+                                       unset($this->theEditRec);
+                                       $this->editError=$LANG->getLL('shortcut_notEditable');
+                               } else {
+                                               // Visual path set:
+                                       $perms_clause = $BE_USER->getPagePermsClause(1);
+                                       $this->editPath = t3lib_BEfunc::getRecordPath($this->theEditRec['pid'], $perms_clause, 30);
+
+                                       if(!$BE_USER->getTSConfigVal('options.shortcut_onEditId_dontSetPageTree')) {
+
+                                                       // Expanding page tree:
+                                               t3lib_BEfunc::openPageTree($this->theEditRec['pid'],!$BE_USER->getTSConfigVal('options.shortcut_onEditId_keepExistingExpanded'));
+                                       }
                                }
                        }
                }
index 21d0ac1..7fac467 100755 (executable)
@@ -228,6 +228,13 @@ class localRecordList extends recordList {
                                                        '</a>';
                }
 
+                       // Add "Export" link, if a specific table is shown:
+               if ($this->table && t3lib_extMgm::isLoaded('impexp'))   {
+                       $theData['up'][]='<a href="'.htmlspecialchars($this->backPath.t3lib_extMgm::extRelPath('impexp').'app/index.php?tx_impexp[action]=export&tx_impexp[list][]='.rawurlencode($this->table.':'.$this->id)).'">'.
+                                                       '<img'.t3lib_iconWorks::skinImg($this->backPath,t3lib_extMgm::extRelPath('impexp').'export.gif',' width="18" height="16"').' title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:rm.export',1).'" alt="" />'.
+                                                       '</a>';
+               }
+
                        // Add "refresh" link:
                $theData['up'][]='<a href="'.htmlspecialchars($this->listURL()).'">'.
                                                '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/refresh_n.gif','width="14" height="14"').' title="'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.reload',1).'" alt="" />'.
@@ -310,6 +317,7 @@ class localRecordList extends recordList {
                $this->fieldArray[] = $titleCol;        // Add title column
                if ($this->localizationView && $l10nEnabled)    {
                        $this->fieldArray[] = '_LOCALIZATION_';
+                       $this->fieldArray[] = '_LOCALIZATION_b';
                        $addWhere.=' AND '.$TCA[$table]['ctrl']['languageField'].'<=0';
                }
                if (!t3lib_div::inList($rowlist,'_CONTROL_'))   {
@@ -570,7 +578,11 @@ class localRecordList extends recordList {
                        } elseif ($fCol=='_CLIPBOARD_') {
                                $theData[$fCol]=$this->makeClip($table,$row);
                        } elseif ($fCol=='_LOCALIZATION_') {
-                               $theData[$fCol]=$this->makeLocalizationPanel($table,$row);
+                               list($lC1, $lC2) = $this->makeLocalizationPanel($table,$row);
+                               $theData[$fCol] = $lC1;
+                               $theData[$fCol.'b'] = $lC2;
+                       } elseif ($fCol=='_LOCALIZATION_b') {
+                               // Do nothing, has been done above.
                        } else {
                                $theData[$fCol]=htmlspecialchars(t3lib_BEfunc::getProcessedValueExtra($table,$fCol,$row[$fCol],100));
                        }
@@ -614,10 +626,13 @@ class localRecordList extends recordList {
 
                        switch((string)$fCol)   {
                                case '_PATH_':                  // Path
-                                       $theData[$fCol]='<i>['.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels._PATH_',1).']</i>';
+                                       $theData[$fCol] = '<i>['.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels._PATH_',1).']</i>';
                                break;
                                case '_LOCALIZATION_':                  // Path
-                                       $theData[$fCol]='<i>['.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels._LOCALIZATION_',1).']</i>';
+                                       $theData[$fCol] = '<i>['.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels._LOCALIZATION_',1).']</i>';
+                               break;
+                               case '_LOCALIZATION_b':                 // Path
+                                       $theData[$fCol] = $LANG->getLL('Localize',1);
                                break;
                                case '_CLIPBOARD_':             // Clipboard:
                                        $cells=array();
@@ -1001,16 +1016,19 @@ class localRecordList extends recordList {
         *
         * @param       string          The table
         * @param       array           The record for which to make the localization panel.
-        * @return      string          HTML table with the localization panel
+        * @return      array           Array with key 0/1 with content for column 1 and 2
         */
        function makeLocalizationPanel($table,$row)     {
                global $TCA,$LANG;
 
-               $out = '';
+               $out = array(
+                       0 => '',
+                       1 => '',
+               );
                if ($TCA[$table]['ctrl']['languageField'] && $TCA[$table]['ctrl']['transOrigPointerField'] && !$TCA[$table]['ctrl']['transOrigPointerTable'])   {
 
                                // Language title and icon:
-                       $out = $this->languageFlag($row[$TCA[$table]['ctrl']['languageField']]);
+                       $out[0] = $this->languageFlag($row[$TCA[$table]['ctrl']['languageField']]);
 
                                // Create new localizations links:
                        if ($row[$TCA[$table]['ctrl']['languageField']] <=0)    {
@@ -1042,9 +1060,9 @@ class localRecordList extends recordList {
                                        }
                                }
 
-                               if ($lNew)      $out.=' - '.$LANG->getLL('Localize',1).': '.$lNew;
+                               if ($lNew)      $out[1].= $lNew;
                        } else {
-                               $out = '&nbsp;&nbsp;&nbsp;&nbsp;'.$out;
+                               $out[0] = '&nbsp;&nbsp;&nbsp;&nbsp;'.$out[1];
                        }
                }
 
index e0c946c..b09fe53 100755 (executable)
@@ -206,7 +206,8 @@ if (TYPO3_MODE=='BE')       {
                                'type' => 'input',
                                'size' => '10',
                                'max' => '20',
-                               'eval' => 'nospace,alphanum_x,lower,unique'
+                               'eval' => 'nospace,alphanum_x,lower,unique',
+                               'softref' => 'notify'
                        )
                ),
                'url' => Array (
@@ -215,7 +216,8 @@ if (TYPO3_MODE=='BE')       {
                                'type' => 'input',
                                'size' => '25',
                                'max' => '256',
-                               'eval' => 'trim'
+                               'eval' => 'trim',
+                               'softref' => 'url'
                        )
                ),
                'urltype' => Array (
@@ -383,7 +385,8 @@ if (TYPO3_MODE=='BE')       {
                                'type' => 'input',
                                'size' => '20',
                                'eval' => 'trim',
-                               'max' => '80'
+                               'max' => '80',
+                               'softref' => 'email[subst]'
                        )
                ),
                'media' => Array (
index ca8205c..592117f 100755 (executable)
@@ -84,7 +84,8 @@ $TCA['fe_users'] = Array (
                                'size' => '20',
                                'eval' => 'trim',
                                'max' => '50',
-                               'checkbox' => ''
+                               'checkbox' => '',
+                               'softref' => 'substitute'
                        )
                ),
                'name' => Array (
@@ -262,7 +263,8 @@ $TCA['fe_users'] = Array (
                                                'icon' => 'wizard_tsconfig.gif',
                                                'JSopenParams' => 'height=500,width=780,status=0,menubar=0,scrollbars=1',
                                        )
-                               )
+                               ),
+                               'softref' => 'TSconfig'
                        )
                )
        ),
@@ -342,7 +344,8 @@ $TCA['fe_groups'] = Array (
                                                'icon' => 'wizard_tsconfig.gif',
                                                'JSopenParams' => 'height=500,width=780,status=0,menubar=0,scrollbars=1',
                                        )
-                               )
+                               ),
+                               'softref' => 'TSconfig'
                        )
                )
        ),
@@ -369,8 +372,9 @@ $TCA['sys_domain'] = Array (
                                'type' => 'input',
                                'size' => '35',
                                'max' => '80',
-                               'eval' => 'required,unique,lower,trim'
-                       )
+                               'eval' => 'required,unique,lower,trim',
+                               'softref' => 'substitute'
+                       ),
                ),
                'redirectTo' => Array (
                        'label' => 'LLL:EXT:cms/locallang_tca.php:sys_domain.redirectTo',
@@ -380,8 +384,9 @@ $TCA['sys_domain'] = Array (
                                'max' => '120',
                                'checkbox' => '',
                                'default' => '',
-                               'eval' => 'trim'
-                       )
+                               'eval' => 'trim',
+                               'softref' => 'substitute'
+                       ),
                ),
                'hidden' => Array (
                        'label' => 'LLL:EXT:lang/locallang_general.php:LGL.disable',
@@ -667,8 +672,9 @@ $TCA['sys_template'] = Array (
                                'type' => 'text',
                                'cols' => '48',
                                'rows' => '10',
-                               'wrap' => 'OFF'
-                       )
+                               'wrap' => 'OFF',
+                               'softref' => 'TStemplate,email[subst],url[subst]'
+                       ),
                ),
                'resources' => Array (
                        'label' => 'Resources:',
@@ -705,8 +711,8 @@ $TCA['sys_template'] = Array (
                                'foreign_table_where' => 'ORDER BY static_template.title DESC',
                                'size' => 10,
                                'maxitems' => 20,
-                               'default' => ''
-                       )
+                               'default' => '',
+                       ),
                ),
                'include_static_file' => Array(
                        'label' => 'Include static (from extensions):',
@@ -715,7 +721,8 @@ $TCA['sys_template'] = Array (
                                'size' => 10,
                                'maxitems' => 20,
                                'items' => Array (
-                               )
+                               ),
+                               'softref' => 'ext_fileref'
                        )
                ),
                'basedOn' => Array (
@@ -779,7 +786,8 @@ $TCA['sys_template'] = Array (
                                                'JSopenParams' => 'height=500,width=780,status=0,menubar=0,scrollbars=1',
                                        )
                                ),
-                               'wrap' => 'OFF'
+                               'wrap' => 'OFF',
+                               'softref' => 'TStemplate,email[subst],url[subst]'
                        )
                ),
                'editorcfg' => Array (
index d1632c6..ccbc857 100755 (executable)
@@ -224,7 +224,8 @@ $TCA['tt_content'] = Array (
                                                'script' => 'browse_links.php?mode=wizard',
                                                'JSopenParams' => 'height=300,width=500,status=0,menubar=0,scrollbars=1'
                                        )
-                               )
+                               ),
+                               'softref' => 'typolink'
                        )
                ),
                'header_layout' => Array (
@@ -250,7 +251,8 @@ $TCA['tt_content'] = Array (
                        'config' => Array (
                                'type' => 'input',
                                'size' => '30',
-                               'max' => '256'
+                               'max' => '256',
+                               'softref' => 'email[subst]'
                        )
                ),
                'bodytext' => Array (
@@ -289,7 +291,8 @@ $TCA['tt_content'] = Array (
                                                'script' => 'wizard_forms.php?special=formtype_mail',
                                                'params' => array('xmlOutput' => 0)
                                        )
-                               )
+                               ),
+                               'softref' => 'typolink_tag,images,email[subst],url'
                        )
                ),
                'text_align' => Array (
@@ -480,7 +483,8 @@ $TCA['tt_content'] = Array (
                                                'script' => 'browse_links.php?mode=wizard',
                                                'JSopenParams' => 'height=300,width=500,status=0,menubar=0,scrollbars=1'
                                        )
-                               )
+                               ),
+                               'softref' => 'typolink[linkList]'
                        )
                ),
                'image_zoom' => Array (
@@ -578,7 +582,8 @@ $TCA['tt_content'] = Array (
                        'config' => Array (
                                'type' => 'text',
                                'cols' => '30',
-                               'rows' => '3'
+                               'rows' => '3',
+                               'softref' => 'typolink_tag,images,email[subst],url'
                        )
                ),
                'imagecaption_position' => Array (
index 4bddf92..360b090 100755 (executable)
@@ -4420,6 +4420,11 @@ class tslib_cObj {
                                                if (!isset($GLOBALS['TSFE']->tmpl->fileCache[$hash]))   {
                                                        $gifCreator = t3lib_div::makeInstance('tslib_gifbuilder');
                                                        $gifCreator->init();
+
+                                                       if ($GLOBALS['TSFE']->config['config']['meaningfulTempFilePrefix'])     {
+                                                               $gifCreator->filenamePrefix = $GLOBALS['TSFE']->fileNameASCIIPrefix(ereg_replace('\.[[:alnum:]]+$','',basename($theImage)),intval($GLOBALS['TSFE']->config['config']['meaningfulTempFilePrefix']),'_');
+                                                       }
+
                                                        if ($fileArray['sample'])       {
                                                                $gifCreator->scalecmd = '-sample';
                                                                $GLOBALS['TT']->setTSlogMessage('Sample option: Images are scaled with -sample.');
@@ -4907,7 +4912,7 @@ class tslib_cObj {
                                                $GLOBALS['TT']->setTSlogMessage("typolink(): File '".$splitLinkParam[0]."' did not exist, so '".$linktxt."' was not linked.",1);
                                                return $linktxt;
                                        }
-                               } else {        // integer or alias (alias is without slashes or periods or commas, that is 'nospace,alphanum_x,lower,unique' according to tables.php!!)
+                               } else {        // integer or alias (alias is without slashes or periods or commas, that is 'nospace,alphanum_x,lower,unique' according to definition in $TCA!)
                                        if ($conf['no_cache.']) $conf['no_cache']=$this->stdWrap($conf['no_cache'], $conf['no_cache.']);
                                        $link_params_parts=explode('#',$link_param);
                                        $link_param = trim($link_params_parts[0]);              // Link-data del
index 1b43f45..dc432b0 100755 (executable)
@@ -2670,11 +2670,7 @@ if (version == "n3") {
                $titleChars = intval($this->config['config']['simulateStaticDocuments_addTitle']);
                $out = '';
                if ($titleChars)        {
-                       $out = $this->csConvObj->specCharsToASCII($this->renderCharset, $inTitle);
-                       $out= ereg_replace('[^[:alnum:]_-]','_',trim(substr($out,0,$titleChars)));
-                       $out= ereg_replace('_*$','',$out);
-                       $out= ereg_replace('^_*','',$out);
-                       if ($out)       $out.='.';
+                       $out = $this->fileNameASCIIPrefix($inTitle, $titleChars);
                }
                $enc = '';
                if (strcmp($addParams,'') && !$no_cache)        {
@@ -2749,6 +2745,25 @@ if (version == "n3") {
        }
 
        /**
+        * Converts input string to an ASCII based file name prefix
+        *
+        * @param       string          String to base output on
+        * @param       integer         Number of characters in the string
+        * @param       string          Character to put in the end of string to merge it with the next value.
+        * @return      string          String
+        */
+       function fileNameASCIIPrefix($inTitle,$titleChars,$mergeChar='.')       {
+               $out = $this->csConvObj->specCharsToASCII($this->renderCharset, $inTitle);
+               $out = ereg_replace('[^[:alnum:]_-]','_',trim(substr($out,0,$titleChars)));
+               $out = ereg_replace('[_-]*$','',$out);
+               $out = ereg_replace('^[_-]*','',$out);
+               $out = ereg_replace('([_-])[_-]*','\1',$out);
+               if (strlen($out))       $out.=$mergeChar;
+
+               return $out;
+       }
+
+       /**
         * Encryption of email addresses for <A>-tags See the spam protection setup in TS 'config.'
         *
         * @param       string          Input string to en/decode: "mailto:blabla@bla.com"
index 3fdde87..18ef7af 100755 (executable)
@@ -108,6 +108,8 @@ class tslib_gifBuilder extends t3lib_stdGraphic {
        var $map;                       // map-data
        var $workArea;
        var $setup = Array ();          // This holds the operational setup for gifbuilder. Basically this is a TypoScript array with properties.
+       var $combinedTextStrings = array();             // Contains all text strings used on this image
+       var $combinedFileNames = array();               // Contains all filenames (basename without extension) used on this image
        var $data = Array();            // This is the array from which data->field: [key] is fetched. So this is the current record!
        var $objBB = Array();
        var $myClassName = 'gifbuilder';
@@ -174,7 +176,7 @@ class tslib_gifBuilder extends t3lib_stdGraphic {
                                // Checking TEXT and IMAGE objects for files. If any errors the objects are cleared.
                                // The Bounding Box for the objects is stored in an array
                        foreach($sKeyArray as $theKey) {
-                               $theValue=$this->setup[$theKey];
+                               $theValue = $this->setup[$theKey];
 
                                if (intval($theKey) && $conf=$this->setup[$theKey.'.']) {
                                                // Swipes through TEXT and IMAGE-objects
@@ -189,21 +191,22 @@ class tslib_gifBuilder extends t3lib_stdGraphic {
 
                                                                        // Calculate bounding box:
                                                                $txtInfo=$this->calcBBox($this->setup[$theKey.'.']);
-                                                               $this->setup[$theKey.'.']['BBOX']=$txtInfo;
-                                                               $this->objBB[$theKey]=$txtInfo;
-                                                               $this->setup[$theKey.'.']['imgMap']=0;
+                                                               $this->setup[$theKey.'.']['BBOX'] = $txtInfo;
+                                                               $this->objBB[$theKey] = $txtInfo;
+                                                               $this->setup[$theKey.'.']['imgMap'] = 0;
                                                        }
                                                break;
                                                case 'IMAGE':
                                                        $fileInfo = $this->getResource($conf['file'],$conf['file.']);
                                                        if ($fileInfo)  {
-                                                               $this->setup[$theKey.'.']['file']=$fileInfo[3];
-                                                               $this->setup[$theKey.'.']['BBOX']=$fileInfo;
-                                                               $this->objBB[$theKey]=$fileInfo;
+                                                               $this->combinedFileNames[] = ereg_replace('\.[[:alnum:]]+$','',basename($fileInfo[3]));
+                                                               $this->setup[$theKey.'.']['file'] = $fileInfo[3];
+                                                               $this->setup[$theKey.'.']['BBOX'] = $fileInfo;
+                                                               $this->objBB[$theKey] = $fileInfo;
                                                                if ($conf['mask'])      {
                                                                        $maskInfo = $this->getResource($conf['mask'],$conf['mask.']);
                                                                        if ($maskInfo)  {
-                                                                               $this->setup[$theKey.'.']['mask']=$maskInfo[3];
+                                                                               $this->setup[$theKey.'.']['mask'] = $maskInfo[3];
                                                                        } else {
                                                                                $this->setup[$theKey.'.']['mask'] = '';
                                                                        }
@@ -489,6 +492,8 @@ class tslib_gifBuilder extends t3lib_stdGraphic {
                if (!$conf['doNotStripHTML'])   {
                        $conf['text'] = strip_tags($conf['text']);
                }
+               $this->combinedTextStrings[] = strip_tags($conf['text']);
+
                        // Max length = 100
                $tlen = intval($conf['textMaxLength']) ? intval($conf['textMaxLength']) : 100;
                $conf['text'] = substr($conf['text'],0,$tlen);
@@ -625,7 +630,13 @@ class tslib_gifBuilder extends t3lib_stdGraphic {
         * @access private
         */
        function fileName($pre) {
-               return $this->tempPath.$pre.t3lib_div::shortMD5(serialize($this->setup)).'.'.$this->extension();
+
+                       // WARNING: In PHP5 I discovered that rendering with freetype of Japanese letters was totally corrupt. Not only the wrong glyphs are printed but also some memory stack overflow resulted in strange additional chars - and finally the reason for this investigation: The Bounding box data was changing all the time resulting in new images being generated all the time. With PHP4 it works fine.
+               return $this->tempPath.
+                               $pre.
+                               ($GLOBALS['TSFE']->config['config']['meaningfulTempFilePrefix'] ? $GLOBALS['TSFE']->fileNameASCIIPrefix(implode('_',array_merge($this->combinedTextStrings,$this->combinedFileNames)),intval($GLOBALS['TSFE']->config['config']['meaningfulTempFilePrefix']),'_') : '').
+                               t3lib_div::shortMD5(serialize($this->setup)).
+                               '.'.$this->extension();
        }
 
        /**
index 9843976..b7dfd18 100755 (executable)
  *
  *
  *
- *   87: class localPageTree extends t3lib_browseTree
- *   92:     function localPageTree()
- *  103:     function wrapTitle($title,$v)
- *  116:     function PM_ATagWrap($icon,$cmd,$bMark='')
- *  127:     function wrapIcon($icon,$row)
- *  136:     function permsC()
- *  146:     function ext_tree($pid)
+ *  136: class localPageTree extends t3lib_browseTree
+ *  143:     function localPageTree()
+ *  154:     function wrapTitle($title,$v)
+ *  167:     function PM_ATagWrap($icon,$cmd,$bMark='')
+ *  178:     function wrapIcon($icon,$row)
+ *  187:     function permsC()
+ *  197:     function ext_tree($pid)
  *
  *
- *  227: class SC_mod_tools_log_index extends t3lib_SCbase
- *  233:     function main()
- *  366:     function printContent()
+ *  278: class SC_mod_tools_log_index extends t3lib_SCbase
+ *  287:     function main()
+ *  339:     function printContent()
  *
  *              SECTION: EXPORT FUNCTIONS
- *  388:     function exportData($inData)
- *  545:     function listQueryPid($table,$pid)
- *  558:     function makeConfigurationForm($inData)
+ *  367:     function exportData($inData)
+ *  641:     function addRecordsForPid($k, $tables, $maxNumber)
+ *  667:     function exec_listQueryPid($table,$pid,$limit)
+ *  695:     function makeConfigurationForm($inData, &$row)
+ *  859:     function makeAdvancedOptionsForm($inData, &$row)
+ *  906:     function makeSaveForm($inData, &$row)
  *
  *              SECTION: IMPORT FUNCTIONS
- *  651:     function importData($inData)
- *  748:     function tableSelector($prefix,$value,$excludeList="")
- *  781:     function renderSelectBox($prefix,$value,$optValues)
+ * 1036:     function importData($inData)
  *
- * TOTAL FUNCTIONS: 14
+ *              SECTION: Preset functions
+ * 1314:     function processPresets(&$inData)
+ * 1411:     function getPreset($uid)
+ *
+ *              SECTION: Helper functions
+ * 1437:     function userTempFolder()
+ * 1453:     function userSaveFolder()
+ * 1477:     function checkUploadOfThumbnail(&$inData)
+ * 1512:     function renderSelectBox($prefix,$value,$optValues)
+ * 1535:     function tableSelector($prefix,$value,$excludeList='')
+ * 1570:     function extensionSelector($prefix,$value)
+ *
+ * TOTAL FUNCTIONS: 23
  * (This index is automatically created/updated by the extension "extdeveval")
  *
  */
+/**
+ *     IMPORTING DATA:
+ *
+ *     Incoming array has syntax:
+ *             GETvar 'id' = import page id (must be readable)
+ *
+ *             file =  (pointing to filename relative to PATH_site)
+ *
+ *
+ *
+ *             [all relation fields are clear, but not files]
+ *             - page-tree is written first
+ *             - then remaining pages (to the root of import)
+ *             - then all other records are written either to related included pages or if not found to import-root (should be a sysFolder in most cases)
+ *             - then all internal relations are set and non-existing relations removed, relations to static tables preserved.
+ *
+ *     EXPORTING DATA:
+ *
+ *     Incoming array has syntax:
+ *
+ *             file[] = file
+ *             dir[] = dir
+ *             list[] = table:pid
+ *             record[] = table:uid
+ *
+ *             pagetree[id] = (single id)
+ *             pagetree[levels]=1,2,3, -1 = currently unpacked tree, -2 = only tables on page
+ *             pagetree[tables][]=table/_ALL
+ *
+ *             external_ref[tables][]=table/_ALL
+ */
+
 
 unset($MCONF);
 require ('conf.php');
@@ -72,13 +117,17 @@ require_once (t3lib_extMgm::extPath('impexp').'class.tx_impexp.php');
 require_once (PATH_t3lib.'class.t3lib_browsetree.php');
 require_once (PATH_t3lib.'class.t3lib_pagetree.php');
 
+require_once (PATH_t3lib.'class.t3lib_basicfilefunc.php');
+require_once (PATH_t3lib.'class.t3lib_extfilefunc.php');
+
 t3lib_extMgm::isLoaded('impexp',1);
 
 
 
 
+
 /**
- * Main script class
+ * Extension of the page tree class. Used to get the tree of pages to export.
  *
  * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
  * @package TYPO3
@@ -87,63 +136,67 @@ t3lib_extMgm::isLoaded('impexp',1);
 class localPageTree extends t3lib_browseTree {
 
        /**
-        * @return      [type]          ...
+        * Initialization
+        *
+        * @return      void
         */
        function localPageTree() {
                $this->init();
        }
 
        /**
-        * [Describe function...]
+        * Wrapping title from page tree.
         *
-        * @param       [type]          $title: ...
-        * @param       [type]          $v: ...
-        * @return      [type]          ...
+        * @param       string          Title to wrap
+        * @param       mixed           (See parent class)
+        * @return      string          Wrapped title
         */
        function wrapTitle($title,$v)   {
-               $title= (!strcmp(trim($title),'')) ? '<em>['.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.no_title',1).']</em>' : htmlspecialchars($title);
+               $title = (!strcmp(trim($title),'')) ? '<em>['.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.no_title',1).']</em>' : htmlspecialchars($title);
                return $title;
        }
 
        /**
-        * [Describe function...]
+        * Wrapping Plus/Minus icon
         *
-        * @param       [type]          $icon: ...
-        * @param       [type]          $cmd: ...
-        * @param       [type]          $bMark: ...
-        * @return      [type]          ...
+        * @param       string          Icon HTML
+        * @param       mixed           (See parent class)
+        * @param       mixed           (See parent class)
+        * @return      string          Icon HTML
         */
        function PM_ATagWrap($icon,$cmd,$bMark='')      {
                return $icon;
        }
 
        /**
-        * [Describe function...]
+        * Wrapping Icon
         *
-        * @param       [type]          $icon: ...
-        * @param       [type]          $row: ...
-        * @return      [type]          ...
+        * @param       string          Icon HTML
+        * @param       array           Record row (page)
+        * @return      string          Icon HTML
         */
        function wrapIcon($icon,$row)   {
                return $icon;
        }
 
        /**
-        * [Describe function...]
+        * Select permissions
         *
-        * @return      [type]          ...
+        * @return      string          SQL where clause
         */
        function permsC()       {
                return $this->BE_USER->getPagePermsClause(1);
        }
 
        /**
-        * [Describe function...]
+        * Tree rendering
         *
-        * @param       [type]          $pid: ...
-        * @return      [type]          ...
+        * @param       integer         PID value
+        * @return      array           Array of tree elements
         */
        function ext_tree($pid) {
+
+                       // Initialize:
                $this->init(' AND '.$this->permsC());
 
                        // Get stored tree structure:
@@ -153,15 +206,13 @@ class localPageTree extends t3lib_browseTree {
                $PM = t3lib_div::intExplode('_',t3lib_div::_GP('PM'));
 
                        // traverse mounts:
-               $titleLen=intval($this->BE_USER->uc['titleLen']);
-               $treeArr=array();
-
+               $titleLen = intval($this->BE_USER->uc['titleLen']);
+               $treeArr = array();
 
-               $idx=0;
-#              $pid=1;
+               $idx = 0;
 
                        // Set first:
-               $this->bank=$idx;
+               $this->bank = $idx;
                $isOpen = $this->stored[$idx][$pid] || $this->expandFirst;
 
                $curIds = $this->ids;   // save ids
@@ -169,36 +220,36 @@ class localPageTree extends t3lib_browseTree {
                $this->ids = $curIds;
 
                        // Set PM icon:
-               $cmd=$this->bank.'_'.($isOpen?'0_':'1_').$pid;
-               $icon='<img src="'.$this->backPath.'t3lib/gfx/ol/'.($isOpen?'minus':'plus').'only.gif" width="18" height="16" align="top" border="0" alt="" /></a>';
-               $firstHtml= $this->PM_ATagWrap($icon,$cmd);
+               $cmd = $this->bank.'_'.($isOpen?'0_':'1_').$pid;
+               $icon = '<img src="'.$this->backPath.'t3lib/gfx/ol/'.($isOpen?'minus':'plus').'only.gif" width="18" height="16" align="top" border="0" alt="" />';
+               $firstHtml = $this->PM_ATagWrap($icon,$cmd);
 
                if ($pid>0)     {
-                       $rootRec=t3lib_befunc::getRecord('pages',$pid);
-                       $firstHtml.=$this->wrapIcon('<img src="'.$this->backPath.t3lib_iconWorks::getIcon('pages',$rootRec).'" width="18" height="16" align="top" alt="" />',$rootRec);
+                       $rootRec = t3lib_befunc::getRecord('pages',$pid);
+                       $firstHtml.= $this->wrapIcon('<img src="'.$this->backPath.t3lib_iconWorks::getIcon('pages',$rootRec).'" width="18" height="16" align="top" alt="" />',$rootRec);
                } else {
-                       $rootRec=array(
-                               'title'=>$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'],
-                               'uid'=>0
+                       $rootRec = array(
+                               'title' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'],
+                               'uid' => 0
                        );
-                       $firstHtml.=$this->wrapIcon('<img src="'.$this->backPath.'gfx/i/_icon_website.gif" width="18" height="16" align="top" alt="" />',$rootRec);
+                       $firstHtml.= $this->wrapIcon('<img src="'.$this->backPath.'gfx/i/_icon_website.gif" width="18" height="16" align="top" alt="" />',$rootRec);
                }
-               $this->tree[]=array('HTML'=>$firstHtml,'row'=>$rootRec);
+               $this->tree[] = array('HTML'=>$firstHtml, 'row'=>$rootRec);
                if ($isOpen)    {
                                // Set depth:
-                       $depthD='<img src="'.$this->backPath.'t3lib/gfx/ol/blank.gif" width="18" height="16" align="top" alt="" />';
+                       $depthD = '<img src="'.$this->backPath.'t3lib/gfx/ol/blank.gif" width="18" height="16" align="top" alt="" />';
                        if ($this->addSelfId)   $this->ids[] = $pid;
                        $this->getTree($pid,999,$depthD);
 
-                       $idH=array();
-                       $idH[$pid]['uid']=$pid;
-                       if (count($this->buffer_idH))   $idH[$pid]['subrow']=$this->buffer_idH;
-                       $this->buffer_idH=$idH;
+                       $idH = array();
+                       $idH[$pid]['uid'] = $pid;
+                       if (count($this->buffer_idH))   $idH[$pid]['subrow'] = $this->buffer_idH;
+                       $this->buffer_idH = $idH;
 
                }
 
                        // Add tree:
-               $treeArr=array_merge($treeArr,$this->tree);
+               $treeArr = array_merge($treeArr,$this->tree);
 
                return $treeArr;
        }
@@ -229,15 +280,17 @@ class SC_mod_tools_log_index extends t3lib_SCbase {
        var $pageinfo;                  // array containing the current page.
 
        /**
-        * @return      [type]          ...
+        * Main module function
+        *
+        * @return      void
         */
        function main() {
-               global $BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
-
-               $this->checkExtObj();
+               global $BE_USER,$LANG,$BACK_PATH;
 
+                       // Start document template object:
                $this->doc = t3lib_div::makeInstance('mediumDoc');
                $this->doc->backPath = $BACK_PATH;
+               $this->doc->docType = 'xhtml_trans';
 
                                // JavaScript
                $this->doc->JScode = $this->doc->wrapScriptTags('
@@ -247,203 +300,214 @@ class SC_mod_tools_log_index extends t3lib_SCbase {
                        }
                ');
 
-               $this->doc->postCode=$this->doc->wrapScriptTags('
+                       // Set up JS for dynamic tab menu
+               $this->doc->JScode .= $this->doc->getDynTabMenuJScode();
+
+               $this->doc->postCode = $this->doc->wrapScriptTags('
                        script_ended = 1;
                        if (top.fsMod) top.fsMod.recentIds["web"] = '.intval($this->id).';
                ');
-               $this->doc->form='<form action="index.php" method="post"><input type="hidden" name="id" value="'.$this->id.'" />';
-
-               $this->content.=$this->doc->startPage($LANG->getLL('title'));
-               $this->content.=$this->doc->header($LANG->getLL('title'));
-               $this->content.=$this->doc->spacer(5);
+               $this->doc->form = '<form action="index.php" method="post" enctype="'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'].'"><input type="hidden" name="id" value="'.$this->id.'" />';
 
+               $this->content.= $this->doc->startPage($LANG->getLL('title'));
+               $this->content.= $this->doc->header($LANG->getLL('title'));
+               $this->content.= $this->doc->spacer(5);
 
+                       // Input data grabbed:
                $inData = t3lib_div::_GP('tx_impexp');
+
+               $this->checkUpload();
+
                switch((string)$inData['action'])       {
                        case 'export':
+
+                                       // Finally: If upload went well, set the new file as the thumbnail in the $inData array:
+                               if (is_object($this->fileProcessor) && $this->fileProcessor->internalUploadMap[1])      {
+                                       $inData['meta']['thumbnail'] = md5($this->fileProcessor->internalUploadMap[1]);
+                               }
+
+                                       // Call export interface
                                $this->exportData($inData);
                        break;
                        case 'import':
+
+                                       // Call import interface:
                                $this->importData($inData);
                        break;
                }
 
-               /**
-               IMPORTING DATA:
-
-               Incoming array has syntax:
-                       GETvar 'id' = import page id (must be readable)
-
-                       file =  (pointing to filename relative to PATH_site)
-
-
-
-                       [all relation fields are clear, but not files]
-                       - page-tree is written first
-                       - then remaining pages (to the root of import)
-                       - then all other records are written either to related included pages or if not found to import-root (should be a sysFolder in most cases)
-                       - then all internal relations are set and non-existing relations removed, relations to static tables preserved.
-               **/
-
-               /**
-               EXPORTING DATA:
-
-               Incoming array has syntax:
-
-                               record[]=table:uid,,,,
-
-                               FUTURE: list[]=table,,,,:pid,,,
-
-                               pagetree[id] = (single id)
-                               pagetree[levels]=1,2,3, -1=currently unpacked tree.
-                               pagetree[tables][]=table/_ALL
-
-                               external_ref[tables][]=table/_ALL
-
-
-               EXAMPLE for using the impexp-class for exporting stuff:
-
-                               // Create and initialize:
-                       $this->export = t3lib_div::makeInstance('tx_impexp');
-                       $this->export->init();
-                               // Set which tables relations we will allow:
-                       $this->export->relExclTables[]='tt_news';       // excludes
-                       $this->export->relOnlyTables[]="tt_news";       // exclusively includes. See comment in the class
-
-                               // Adding records:
-                       $this->export->export_addRecord("pages",$this->pageinfo);
-                       $this->export->export_addRecord("pages",t3lib_BEfunc::getRecord("pages",38));
-                       $this->export->export_addRecord("pages",t3lib_BEfunc::getRecord("pages",39));
-                       $this->export->export_addRecord("tt_content",t3lib_BEfunc::getRecord("tt_content",12));
-                       $this->export->export_addRecord("tt_content",t3lib_BEfunc::getRecord("tt_content",74));
-                       $this->export->export_addRecord("sys_template",t3lib_BEfunc::getRecord("sys_template",20));
-
-                               // Adding all the relations (recursively so relations has THEIR relations registered as well)
-                       for($a=0;$a<5;$a++)     {
-                               $addR = $this->export->export_addDBRelations($a);
-                               if (!count($addR)) break;
-       #                               debug("ADDED: ".count($addR),1);
-                       }
-
-                               // Finally load all the files.
-                       $this->export->export_addFilesFromRelations();  // MUST be after the DBrelations are set so that file from ALL added records are included!
-
-                               // Not the internal DAT array is ready to export:
-                       #debug($this->export->dat);
-
-                               // Write export
-                       $out = $this->export->compileMemoryToFileContent();
-                       #t3lib_div::writeFile(PATH_site."fileadmin/relations.trd",$out);
-                       #debug(strlen($out));
-               **/
-
-
-
-
-
-
-
-
-
-
-
-
-
-
                if ($BE_USER->mayMakeShortcut())        {
                        $this->content.=$this->doc->spacer(20).$this->doc->section('',$this->doc->makeShortcutIcon('tx_impexp','',$this->MCONF['name']));
                }
        }
 
        /**
-        * [Describe function...]
+        * Print the content
         *
-        * @return      [type]          ...
+        * @return      void
         */
        function printContent() {
 
-               $this->content.=$this->doc->spacer(20);
-               $this->content.=$this->doc->endPage();
+               $this->content.= $this->doc->spacer(20);
+               $this->content.= $this->doc->endPage();
                echo $this->content;
        }
 
 
 
 
-       /**
+
+
+
+
+
+
+       /**************************
         *
         * EXPORT FUNCTIONS
         *
-        */
+        **************************/
 
        /**
-        * @param       [type]          $inData: ...
-        * @return      [type]          ...
+        * Export part of module
+        *
+        * @param       array           Content of POST VAR tx_impexp[]..
+        * @return      void            Setting content in $this->content
         */
        function exportData($inData)    {
-               global $TCA;
+               global $TCA, $LANG;
+
+                       // BUILDING EXPORT DATA:
+
+                       // Processing of InData array values:
+               $inData['pagetree']['maxNumber'] = t3lib_div::intInRange($inData['pagetree']['maxNumber'],1,10000,100);
+               $inData['listCfg']['maxNumber'] = t3lib_div::intInRange($inData['listCfg']['maxNumber'],1,10000,100);
+               $inData['maxFileSize'] = t3lib_div::intInRange($inData['maxFileSize'],1,10000,1000);
+               $inData['filename'] = trim(ereg_replace('[^[:alnum:]./_-]*','',ereg_replace('\.(t3d|xml)$','',$inData['filename'])));
+               if (strlen($inData['filename']))        {
+                       $inData['filename'].= $inData['filetype']=='xml' ? '.xml' : '.t3d';
+               }
+
+                       // Set exclude fields in export object:
+               if (!is_array($inData['exclude']))      {
+                       $inData['exclude'] = array();
+               }
+
 
+                       // Saving/Loading/Deleting presets:
+               $this->processPresets($inData);
+
+                       // Create export object and configure it:
                $this->export = t3lib_div::makeInstance('tx_impexp');
-               $this->export->init($inData['dont_compress']);
-               $this->export->relExclTables=array();
-               $this->export->relOnlyTables=array();
+               $this->export->init(0,'export');
+               $this->export->setCharset($LANG->charSet);
+
+               $this->export->maxFileSize = $inData['maxFileSize']*1024;
+               $this->export->excludeMap = (array)$inData['exclude'];
+               $this->export->softrefCfg = (array)$inData['softrefCfg'];
+               $this->export->extensionDependencies = (array)$inData['extension_dep'];
+               $this->export->showStaticRelations = $inData['showStaticRelations'];
+
+               $this->export->includeHTMLfileResources = $inData['includeHTMLfileResources'];
+#debug($inData);
+                       // Static tables:
+               if (is_array($inData['external_static']['tables']))     {
+                       $this->export->relStaticTables = $inData['external_static']['tables'];
+               }
 
+                       // Configure which tables external relations are included for:
                if (is_array($inData['external_ref']['tables']))        {
-                       reset($TCA);
-                       while(list($table)=each($TCA))  {
-                               if (in_array($table,$inData['external_ref']['tables']) || in_array('_ALL',$inData['external_ref']['tables']))   {
-                                       if ($GLOBALS['BE_USER']->check('tables_select',$table)) {
-                                               $this->export->relOnlyTables[]=$table;
-                                       }
+                       $this->export->relOnlyTables = $inData['external_ref']['tables'];
+               }
+               $this->export->setHeaderBasics();
+
+                       // Meta data setting:
+               $this->export->setMetaData(
+                       $inData['meta']['title'],
+                       $inData['meta']['description'],
+                       $inData['meta']['notes'],
+                       $GLOBALS['BE_USER']->user['username'],
+                       $GLOBALS['BE_USER']->user['realName'],
+                       $GLOBALS['BE_USER']->user['email']
+               );
+               if ($inData['meta']['thumbnail'])       {
+                       $tempDir = $this->userTempFolder();
+                       if ($tempDir)   {
+                               $thumbnails = t3lib_div::getFilesInDir($tempDir,'png,gif,jpg',1);
+                               $theThumb = $thumbnails[$inData['meta']['thumbnail']];
+                               if ($theThumb)  {
+                                       $this->export->addThumbnail($theThumb);
                                }
                        }
                }
 
-                       // Records
+
+                       // Configure which records to export
                if (is_array($inData['record']))        {
-                       reset($inData['record']);
-                       while(list(,$ref)=each($inData['record']))      {
+                       foreach($inData['record'] as $ref)      {
+                               $rParts = explode(':',$ref);
+                               $this->export->export_addRecord($rParts[0],t3lib_BEfunc::getRecord($rParts[0],$rParts[1]));
+                       }
+               }
+
+                       // Configure which tables to export
+               if (is_array($inData['list']))  {
+                       foreach($inData['list'] as $ref)        {
                                $rParts = explode(':',$ref);
-                               $tName=$rParts[0];
-                               $uidList=t3lib_div::trimExplode(',',$rParts[1],1);
-                               reset($uidList);
-                               while(list(,$rUid)=each($uidList))      {
-                                       $this->export->export_addRecord($rParts[0],t3lib_BEfunc::getRecord($tName,$rUid));
+                               if ($GLOBALS['BE_USER']->check('tables_select',$rParts[0]))     {
+                                       $res = $this->exec_listQueryPid($rParts[0],$rParts[1],t3lib_div::intInRange($inData['listCfg']['maxNumber'],1));
+                                       while($subTrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))   {
+                                               $this->export->export_addRecord($rParts[0],$subTrow);
+                                       }
                                }
                        }
                }
 
                        // Pagetree
-               if (is_array($inData['pagetree']))      {
-                       if ($inData['pagetree']['levels']<0)    {       // Based on click-expandable tree
+               if (isset($inData['pagetree']['id']))   {
+                       if ($inData['pagetree']['levels']==-1)  {       // Based on click-expandable tree
                                $pagetree = t3lib_div::makeInstance('localPageTree');
                                $tree = $pagetree->ext_tree($inData['pagetree']['id']);
                                $this->treeHTML = $pagetree->printTree($tree);
 
-                               $idH=$pagetree->buffer_idH;
+                               $idH = $pagetree->buffer_idH;
 #                              debug($pagetree->buffer_idH);
+                       } elseif ($inData['pagetree']['levels']==-2)    {       // Only tables on page
+                               $this->addRecordsForPid($inData['pagetree']['id'],$inData['pagetree']['tables'],$inData['pagetree']['maxNumber']);
                        } else {        // Based on depth
                                        // Drawing tree:
-                               $sPage = t3lib_BEfunc::getRecord ('pages',$inData['pagetree']['id'],'*',' AND '.$this->perms_clause);
+                                       // If the ID is zero, export root
+                               if (!$inData['pagetree']['id'] && $GLOBALS['BE_USER']->isAdmin())       {
+                                       $sPage = array(
+                                               'uid' => 0,
+                                               'title' => 'ROOT'
+                                       );
+                               } else {
+                                       $sPage = t3lib_BEfunc::getRecord('pages',$inData['pagetree']['id'],'*',' AND '.$this->perms_clause);
+                               }
                                if (is_array($sPage))   {
                                        $pid = $inData['pagetree']['id'];
                                        $tree = t3lib_div::makeInstance('t3lib_pageTree');
                                        $tree->init('AND '.$this->perms_clause);
 
-                                       $HTML='<img src="'.$GLOBALS['BACK_PATH'].t3lib_iconWorks::getIcon('pages',$sPage).'" width="18" height="16" align="top" alt="" />';
-                                       $tree->tree[]=Array('row'=>$sPage,'HTML'=>$HTML);
-                                       $tree->buffer_idH=array();
-                                       if ($inData['pagetree']['levels']>0)    $tree->getTree($pid,$inData['pagetree']['levels'],'');
+                                       $HTML = '<img src="'.$GLOBALS['BACK_PATH'].t3lib_iconWorks::getIcon('pages',$sPage).'" width="18" height="16" align="top" alt="" />';
+                                       $tree->tree[] = Array('row'=>$sPage,'HTML'=>$HTML);
+                                       $tree->buffer_idH = array();
+                                       if ($inData['pagetree']['levels']>0)    {
+                                               $tree->getTree($pid,$inData['pagetree']['levels'],'');
+                                       }
 
-                                       $idH=array();
-                                       $idH[$pid]['uid']=$pid;
-                                       if (count($tree->buffer_idH))   $idH[$pid]['subrow']=$tree->buffer_idH;
+                                       $idH = array();
+                                       $idH[$pid]['uid'] = $pid;
+                                       if (count($tree->buffer_idH))   {
+                                               $idH[$pid]['subrow'] = $tree->buffer_idH;
+                                       }
 
 
                                        $pagetree = t3lib_div::makeInstance('localPageTree');
                                        $this->treeHTML = $pagetree->printTree($tree->tree);
 
-#                                      debug($idH);
+#debug($idH);
                                }
                        }
                                // In any case we should have a multi-level array, $idH, with the page structure here (and the HTML-code loaded into memory for nice display...)
@@ -452,120 +516,220 @@ class SC_mod_tools_log_index extends t3lib_SCbase {
                                reset($flatList);
                                while(list($k)=each($flatList)) {
                                        $this->export->export_addRecord('pages',t3lib_BEfunc::getRecord('pages',$k));
-
-                                       if (is_array($inData['pagetree']['tables']))    {
-                                               reset($TCA);
-                                               while(list($table)=each($TCA))  {
-                                                       if ($table!='pages' && (in_array($table,$inData['pagetree']['tables']) || in_array('_ALL',$inData['pagetree']['tables'])))      {
-                                                               if ($GLOBALS['BE_USER']->check('tables_select',$table)) {
-                                                                       $res = $this->exec_listQueryPid($table,$k);
-                                                                       while($subTrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))   {
-                                                                               $this->export->export_addRecord($table,$subTrow);
-                                                                       }
-                                                               }
-                                                       }
-                                               }
-                                       }
+                                       $this->addRecordsForPid($k,$inData['pagetree']['tables'],$inData['pagetree']['maxNumber']);
                                }
                        }
                }
 
-
                        // After adding ALL records we set relations:
 #              debug($this->export->relOnlyTables);
-               if (count($this->export->relOnlyTables))        {
+#              if (count($this->export->relOnlyTables))        {
                        for($a=0;$a<10;$a++)    {
                                $addR = $this->export->export_addDBRelations($a);
                                if (!count($addR)) break;
-       #                               debug("ADDED: ".count($addR),1);
                        }
-               }
+#              }
 
                        // Finally files are added:
                $this->export->export_addFilesFromRelations();  // MUST be after the DBrelations are set so that files from ALL added records are included!
+#debug($this->export->dat['header']);
+                       // If the download button is clicked, return file
+               if ($inData['download_export'] || $inData['save_export'])       {
+                       switch((string)$inData['filetype'])     {
+                               case 'xml':
+                                       $out = $this->export->compileMemoryToFileContent('xml');
+                                       $fExt = '.xml';
+                               break;
+                               case 't3d':
+                                       $this->export->dontCompress = 1;
+                               default:
+                                       $out = $this->export->compileMemoryToFileContent();
+                                       $fExt = ($this->export->doOutputCompress()?'-z':'').'.t3d';
+                               break;
+                       }
 
-// Now, what's next?
+                               // Filename:
+                       $dlFile = $inData['filename'] ? $inData['filename'] : 'T3D_'.substr(ereg_replace('[^[:alnum:]_]','-',$inData['download_export_name']),0,20).'_'.date('d-m-H-i-s').$fExt;
 
-               if ($inData['download_export']) {
-                       $out = $this->export->compileMemoryToFileContent();
-                       $dlFile='T3D_'.substr(ereg_replace('[^[:alnum:]_]','-',$inData['download_export_name']),0,20).'_'.date('d-m-H-i-s').($this->export->doOutputCompress()?'-z':'').'.t3d';
+                               // Export for download:
+                       if ($inData['download_export']) {
+                               $mimeType = 'application/octet-stream';
+                               Header('Content-Type: '.$mimeType);
+                               Header('Content-Disposition: attachment; filename='.basename($dlFile));
+                               echo $out;
+                               exit;
+                       }
 
-                       $mimeType = 'application/octet-stream';
-                       Header('Content-Type: '.$mimeType);
-                       Header('Content-Disposition: attachment; filename='.basename($dlFile));
-                       echo $out;
-                       exit;
+                               // Export by saving:
+                       if ($inData['save_export'])     {
+                               $savePath = $this->userSaveFolder();
+                               $fullName = $savePath.$dlFile;
 
-                       #debug(strlen($out));
+                               if (t3lib_div::isAllowedAbsPath($savePath) && @is_dir(dirname($fullName)) && t3lib_div::isAllowedAbsPath($fullName))    {
+                                       t3lib_div::writeFile($fullName, $out);
+                                       $this->content.= $this->doc->section('SAVED FILE','Saved in "'.substr($savePath.$dlFile,strlen(PATH_site)).'", bytes '.t3lib_div::formatSize(strlen($out)),0,1);
+                               } else {
+                                       $this->content.= $this->doc->section('Problems saving file','Bad path: "'.$fullName.'"',0,1,2);
+                               }
+                       }
                }
 
 
-
-
-               $this->makeConfigurationForm($inData);
-
-
-               $content=$this->export->displayContentOverview();
-               $this->content.=$this->doc->section('Structure to be exported:',$content,0,1);
-
-
+                       // OUTPUT to BROWSER:
+                       // Now, if we didn't make download file, show configuration form based on export:
+               $menuItems = array();
+
+                       // Export configuration
+               $row = array();
+               $this->makeConfigurationForm($inData, $row);
+               $menuItems[] = array(
+                       'label' => $LANG->getLL('tableselec_configuration','1'),
+                       'content' => '
+                               <table border="0" cellpadding="1" cellspacing="1">
+                                       '.implode('
+                                       ',$row).'
+                               </table>
+                       '
+               );
+
+                       // File options
+               $row = array();
+               $this->makeSaveForm($inData, $row);
+               $menuItems[] = array(
+                       'label' => 'File & Preset',
+                       'content' => '
+                               <table border="0" cellpadding="1" cellspacing="1">
+                                       '.implode('
+                                       ',$row).'
+                               </table>
+                       '
+               );
+
+                       // File options
+               $row = array();
+               $this->makeAdvancedOptionsForm($inData, $row);
+               $menuItems[] = array(
+                       'label' => 'Advanced Options',
+                       'content' => '
+                               <table border="0" cellpadding="1" cellspacing="1">
+                                       '.implode('
+                                       ',$row).'
+                               </table>
+                       '
+               );
+
+                       // Generate overview:
+               $overViewContent = $this->export->displayContentOverview();
+
+                       // Print errors that might be:
                $errors = $this->export->printErrorLog();
-               if ($errors)    $this->content.=$this->doc->section('Messages:',$errors,0,1);
+               $menuItems[] = array(
+                       'label' => 'Messages',
+                       'content' => $errors,
+                       'stateIcon' => $errors ? 2 : 0
+               );
 
+                       // Add hidden fields and create tabs:
+               $content = $this->doc->getDynTabMenu($menuItems,'tx_impexp_export',-1);
+               $content.= '<input type="hidden" name="tx_impexp[action]" value="export" />';
+               $this->content.= $this->doc->section('',$content,0,1);
 
-               /*
-               $this->export->setMetaData('My export of data','My description
-with linebreaks
+                       // Output Overview:
+               $this->content.= $this->doc->section('Structure to be exported:',$overViewContent,0,1);
 
-.. andmore ','This is a note',
-                       $GLOBALS["BE_USER"]->user["username"],
-                       $GLOBALS["BE_USER"]->user["realName"],
-                       $GLOBALS["BE_USER"]->user["email"]);
+       }
 
-               $this->export->addThumbnail(PATH_site."t3lib/gfx/typo3logo.gif");
-               */
+       /**
+        * Adds records to the export object for a specific page id.
+        *
+        * @param       integer         Page id for which to select records to add
+        * @param       array           Array of table names to select from
+        * @param       integer         Max amount of records to select
+        * @return      void
+        */
+       function addRecordsForPid($k, $tables, $maxNumber)      {
+               global $TCA;
+
+               if (is_array($tables))  {
+                       reset($TCA);
+                       while(list($table)=each($TCA))  {
+                               if ($table!='pages' && (in_array($table,$tables) || in_array('_ALL',$tables)))  {
+                                       if ($GLOBALS['BE_USER']->check('tables_select',$table) && !$TCA[$table]['ctrl']['is_static'])   {
+                                               $res = $this->exec_listQueryPid($table,$k,t3lib_div::intInRange($maxNumber,1));
+                                               while($subTrow = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))   {
+                                                       $this->export->export_addRecord($table,$subTrow);
+                                               }
+                                       }
+                               }
+                       }
+               }
        }
 
        /**
-        * [Describe function...]
+        * Selects records from table / pid
         *
-        * @param       [type]          $table: ...
-        * @param       [type]          $pid: ...
-        * @return      [type]          ...
+        * @param       string          Table to select from
+        * @param       integer         Page ID to select from
+        * @param       integer         Max number of records to select
+        * @return      pointer         SQL resource pointer
         */
-       function exec_listQueryPid($table,$pid) {
+       function exec_listQueryPid($table,$pid,$limit)  {
                global $TCA;
                $orderBy = $TCA[$table]['ctrl']['sortby'] ? 'ORDER BY '.$TCA[$table]['ctrl']['sortby'] : $TCA[$table]['ctrl']['default_sortby'];
-               return $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'pid='.intval($pid).t3lib_BEfunc::deleteClause($table), '', $GLOBALS['TYPO3_DB']->stripOrderBy($orderBy));
+               $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
+                               '*',
+                               $table,
+                               'pid='.intval($pid).
+                                       t3lib_BEfunc::deleteClause($table),
+                               '',
+                               $GLOBALS['TYPO3_DB']->stripOrderBy($orderBy),
+                               $limit
+                       );
+
+                       // Warning about hitting limit:
+               if ($GLOBALS['TYPO3_DB']->sql_num_rows($res) == $limit) {
+                       $this->content.= $this->doc->section('Max number limit!','An SQL query returned exactly the amount of records specified by the limit value ('.$limit.') - that could indicate an incomplete selection of records! Make sure this is on purpose.',0,1, 2);
+               }
+
+               return $res;
        }
 
        /**
-        * [Describe function...]
+        * Create configuration form
         *
-        * @param       [type]          $inData: ...
-        * @return      [type]          ...
+        * @param       array           Form configurat data
+        * @param       array           Table row accumulation variable. This is filled with table rows.
+        * @return      void            Sets content in $this->content
         */
-       function makeConfigurationForm($inData) {
-               $nameSuggestion ='';
-               if (is_array($inData['pagetree']) && $this->treeHTML)   {
-                       $row=array();
-
-                       $nameSuggestion.='tree_PID'.$inData['pagetree']['id'].'_L'.$inData['pagetree']['levels'];
-                       $row[]='<tr class="bgColor5">
-                                       <td colspan=2><strong>Export pagetree configuration:</strong></td>
+       function makeConfigurationForm($inData, &$row)  {
+
+               $nameSuggestion = '';
+
+                       // Page tree export options:
+               if (isset($inData['pagetree']['id']))   {
+
+                       $nameSuggestion.= 'tree_PID'.$inData['pagetree']['id'].'_L'.$inData['pagetree']['levels'];
+
+                       $row[] = '
+                               <tr class="tableheader bgColor5">
+                                       <td colspan="2">Export pagetree configuration:</td>
                                </tr>';
 
-                       $row[]='<tr class="bgColor4">
+                       $row[] = '
+                               <tr class="bgColor4">
                                        <td><strong>Page ID:</strong></td>
-                                       <td>'.htmlspecialchars($inData['pagetree']['id']).'<input type="hidden" value="'.htmlspecialchars($inData['pagetree']['id']).'" name="tx_impexp[pagetree][id]" /></td>
+                                       <td>'.htmlspecialchars($inData['pagetree']['id']).
+                                               '<input type="hidden" value="'.htmlspecialchars($inData['pagetree']['id']).'" name="tx_impexp[pagetree][id]" /></td>
                                </tr>';
 
-                       $row[]='<tr class="bgColor4">
-                               <td><strong>Tree:</strong></td>
-                               <td>'.$this->treeHTML.'</td>
+                       $row[] = '
+                               <tr class="bgColor4">
+                                       <td><strong>Tree:</strong></td>
+                                       <td>'.($this->treeHTML ? $this->treeHTML : 'No tree exported - only tables on the page.').'</td>
                                </tr>';
 
                        $opt = array(
+                               '-2' => 'Tables on this page',
                                '-1' => 'Expanded tree',
                                '0' => 'Only this page',
                                '1' => '1 level',
@@ -574,73 +738,312 @@ with linebreaks
                                '4' => '4 levels',
                                '999' => 'Infinite'
                        );
-                       $row[]='<tr class="bgColor4">
-                               <td><strong>Levels:</strong></td>
-                               <td>'.$this->renderSelectBox('tx_impexp[pagetree][levels]',$inData['pagetree']['levels'],$opt).'</td>
+                       $row[] = '
+                               <tr class="bgColor4">
+                                       <td><strong>Levels:</strong></td>
+                                       <td>'.$this->renderSelectBox('tx_impexp[pagetree][levels]',$inData['pagetree']['levels'],$opt).'</td>
                                </tr>';
 
-                       $row[]='<tr class="bgColor4">
-                               <td><strong>Include tables:</strong></td>
-                               <td>'.$this->tableSelector('tx_impexp[pagetree][tables]',$inData['pagetree']['tables'],'pages').'</td>
+                       $row[] = '
+                               <tr class="bgColor4">
+                                       <td><strong>Include tables:</strong></td>
+                                       <td>'.$this->tableSelector('tx_impexp[pagetree][tables]',$inData['pagetree']['tables'],'pages').'<br/>
+                                               Max number of records:<br/>
+                                               <input type="text" name="tx_impexp[pagetree][maxNumber]" value="'.htmlspecialchars($inData['pagetree']['maxNumber']).'"'.$this->doc->formWidth(10).' /><br/>
+                                       </td>
                                </tr>';
-                       $content.='<table border=0 cellpadding=1 cellspacing=1>'.implode('',$row).'</table>';
                }
 
-
-
+                       // Single record export:
                if (is_array($inData['record']))        {
-                       $row[]='<tr class="bgColor5">
-                                       <td colspan=2><strong>Export single record:</strong></td>
+                       $row[] = '
+                               <tr class="tableheader bgColor5">
+                                       <td colspan="2">Export single record:</td>
                                </tr>';
-                       reset($inData['record']);
-                       while(list(,$ref)=each($inData['record']))      {
-                               $rParts = explode(':',$ref);
-                               $tName=$rParts[0];
-                               $uidList=t3lib_div::trimExplode(',',$rParts[1],1);
-                               reset($uidList);
-                               while(list(,$rUid)=each($uidList))      {
-                                       $nameSuggestion.=$tName.'_'.$rUid;
-                                       $rec = t3lib_BEfunc::getRecord($tName,$rUid);
-
-                                       $row[]='<tr class="bgColor4">
-                                               <td><strong>Record:</strong></td>
-                                               <td>'.t3lib_iconworks::getIconImage($tName,$rec,$GLOBALS['BACK_PATH'],' align="top"').t3lib_BEfunc::getRecordTitle($tName,$rec,1).'<input type="hidden" name="tx_impexp[record][]" value="'.htmlspecialchars($tName.':'.$rUid).'" /></td>
-                                               </tr>';
+                       foreach($inData['record'] as $ref)      {
+                               $rParts = explode(':', $ref);
+                               $tName = $rParts[0];
+                               $rUid = $rParts[1];
+                               $nameSuggestion.= $tName.'_'.$rUid;
+                               $rec = t3lib_BEfunc::getRecord($tName,$rUid);
+
+                               $row[] = '
+                               <tr class="bgColor4">
+                                       <td><strong>Record:</strong></td>
+                                       <td>'.t3lib_iconworks::getIconImage($tName,$rec,$GLOBALS['BACK_PATH'],' align="top"').
+                                               t3lib_BEfunc::getRecordTitle($tName,$rec,1).
+                                               '<input type="hidden" name="tx_impexp[record][]" value="'.htmlspecialchars($tName.':'.$rUid).'" /></td>
+                               </tr>';
+                       }
+               }
+
+                       // Single tables/pids:
+               if (is_array($inData['list']))  {
+                       $row[] = '
+                               <tr class="tableheader bgColor5">
+                                       <td colspan="2">Export tables from pages:</td>
+                               </tr>';
+
+                       foreach($inData['list'] as $ref)        {
+                               $rParts = explode(':', $ref);
+                               $tName = $rParts[0];
+
+                               if ($GLOBALS['BE_USER']->check('tables_select',$tName)) {
+                                       $rec = t3lib_BEfunc::getRecord('pages', $rParts[1]);
+                                       $row[] = '
+                                       <tr class="bgColor4">
+                                               <td><strong>Table/Pids:</strong></td>
+                                               <td>Table "'.$tName.'" from '.t3lib_iconworks::getIconImage('pages',$rec,$GLOBALS['BACK_PATH'],' align="top"').
+                                                       t3lib_BEfunc::getRecordTitle('pages',$rec,1).
+                                                       '<input type="hidden" name="tx_impexp[list][]" value="'.htmlspecialchars($ref).'" /></td>
+                                       </tr>';
                                }
                        }
-                       $content.='<table border=0 cellpadding=1 cellspacing=1>'.implode('',$row).'</table>';
+                       $row[] = '
+                               <tr class="bgColor4">
+                                       <td>Max number of records:</td>
+                                       <td>
+                                               <input type="text" name="tx_impexp[listCfg][maxNumber]" value="'.htmlspecialchars($inData['listCfg']['maxNumber']).'"'.$this->doc->formWidth(10).' /><br/>
+                                       </td>
+                               </tr>';
                }
 
 
+               $row[] = '
+                       <tr class="tableheader bgColor5">
+                               <td colspan="2">Relations and Exclusions:</td>
+                       </tr>';
 
-               $content.='Include relations to tables:<br />'.$this->tableSelector('tx_impexp[external_ref][tables]',$inData['external_ref']['tables']);
-               $content.='<hr /><input type="submit" value="Update" /> - <input type="submit" value="Download export" name="tx_impexp[download_export]" />';
-               if ($this->export->compress) $content.='<input type="checkbox" name="tx_impexp[dont_compress]" value="1"'.($inData['dont_compress']?' checked="checked"':'').' />Don\'t compress';
-               $content.='<input type="hidden" name="tx_impexp[download_export_name]" value="'.$nameSuggestion.'" />';
+                       // Add relation selector:
+               $row[] = '
+                               <tr class="bgColor4">
+                                       <td><strong>Include relations to tables:</strong></td>
+                                       <td>'.$this->tableSelector('tx_impexp[external_ref][tables]',$inData['external_ref']['tables']).'</td>
+                               </tr>';
+
+                       // Add static relation selector:
+               $row[] = '
+                               <tr class="bgColor4">
+                                       <td><strong>Use static relations for tables:</strong></td>
+                                       <td>'.$this->tableSelector('tx_impexp[external_static][tables]',$inData['external_static']['tables']).'<br/>
+                                               Show static relations: <input type="checkbox" name="tx_impexp[showStaticRelations]" value="1"'.($inData['showStaticRelations'] ? ' checked="checked"' : '').' />
+                                               </td>
+                               </tr>';
+
+                       // Exclude:
+               $excludeHiddenFields = '';
+               if (is_array($inData['exclude']))       {
+                       foreach($inData['exclude'] as $key => $value)   {
+                               $excludeHiddenFields.= '<input type="hidden" name="tx_impexp[exclude]['.$key.']" value="1" />';
+                       }
+               }
+               $row[] = '
+                               <tr class="bgColor4">
+                                       <td><strong>Exclude elements:</strong></td>
+                                       <td>'.$excludeHiddenFields.'
+                                       '.(count($inData['exclude']) ? '<em>'.implode(', ',array_keys($inData['exclude'])).'</em><hr/>Clear all exclusions: <input type="checkbox" name="tx_impexp[exclude]" value="1" />' : 'No excluded elements yet. Exclude by setting checkboxes below in the element display.').'
+                                       </td>
+                               </tr>';
+
+
+                       // Add buttons:
+               $row[] = '
+                               <tr class="bgColor4">
+                                       <td>&nbsp;</td>
+                                       <td>
+                                               <input type="submit" value="Update" />
+                                               <input type="hidden" name="tx_impexp[download_export_name]" value="'.substr($nameSuggestion,0,30).'" />
+                                       </td>
+                               </tr>';
 
-               $content.='<input type="hidden" name="tx_impexp[action]" value="export" />';
-               $this->content.=$this->doc->section('Export to TYPO3 Document (.t3d)',$content,0,1);
        }
 
+       /**
+        * Create advanced options form
+        *
+        * @param       array           Form configurat data
+        * @param       array           Table row accumulation variable. This is filled with table rows.
+        * @return      void            Sets content in $this->content
+        */
+       function makeAdvancedOptionsForm($inData, &$row)        {
+
+                       // Soft references
+               $row[] = '
+                       <tr class="tableheader bgColor5">
+                               <td colspan="2">Soft References:</td>
+                       </tr>';
+               $row[] = '
+                               <tr class="bgColor4">
+                                       <td><strong>Include HTML file resources:</strong></td>
+                                       <td><input type="checkbox" name="tx_impexp[includeHTMLfileResources]" value="1"'.($inData['includeHTMLfileResources'] ? ' checked="checked"' : '').' /></td>
+                               </tr>';
+
+
+                       // Extensions
+               $row[] = '
+                       <tr class="tableheader bgColor5">
+                               <td colspan="2">Extension dependencies:</td>
+                       </tr>';
+               $row[] = '
+                               <tr class="bgColor4">
+                                       <td><strong>Select extensions that the exported content depends on:</strong></td>
+                                       <td>'.$this->extensionSelector('tx_impexp[extension_dep]',$inData['extension_dep']).'</td>
+                               </tr>';
 
 
 
+                       // Add buttons:
+               $row[] = '
+                               <tr class="bgColor4">
+                                       <td>&nbsp;</td>
+                                       <td>
+                                               <input type="submit" value="Update" />
+                                               <input type="hidden" name="tx_impexp[download_export_name]" value="'.substr($nameSuggestion,0,30).'" />
+                                       </td>
+                               </tr>';
 
 
+       }
 
        /**
+        * Create configuration form
+        *
+        * @param       array           Form configurat data
+        * @param       array           Table row accumulation variable. This is filled with table rows.
+        * @return      void            Sets content in $this->content
+        */
+       function makeSaveForm($inData, &$row)   {
+
+                       // Presets:
+               $row[] = '
+                       <tr class="tableheader bgColor5">
+                               <td colspan="2">Presets:</td>
+                       </tr>';
+
+               $opt = array('');
+               $presets = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
+                                               '*',
+                                               'tx_impexp_presets',
+                                               '(public>0 || user_uid='.intval($GLOBALS['BE_USER']->user['uid']).')'.
+                                                       ($inData['pagetree']['id'] ? ' AND item_uid='.intval($inData['pagetree']['id']) : '')
+
+                                       );
+               if (is_array($presets)) {
+                       foreach($presets as $presetCfg) {
+                               $opt[$presetCfg['uid']] = $presetCfg['title'].' ['.$presetCfg['uid'].']'.
+                                                                                       ($presetCfg['public'] ? ' [Public]' : '').
+                                                                                       ($presetCfg['user_uid']===$GLOBALS['BE_USER']->user['uid'] ? ' [Own]' : '');
+                       }
+               }
+
+               $row[] = '
+                               <tr class="bgColor4">
+                                       <td><strong>Presets:</strong></td>
+                                       <td>
+                                               Select preset:<br/>
+                                               '.$this->renderSelectBox('preset[select]','',$opt).'
+                                               <br/>
+                                               <input type="submit" value="Load" name="preset[load]" />
+                                               <input type="submit" value="Save" name="preset[save]" />
+                                               <input type="submit" value="Delete" name="preset[delete]" />
+                                               <input type="submit" value="Merge" name="preset[merge]" />
+                                               <br/>
+                                               Title of new preset:
+                                               <input type="text" name="tx_impexp[preset][title]" value="'.htmlspecialchars($inData['preset']['title']).'"'.$this->doc->formWidth(30).' /><br/>
+                                               Public:
+                                               <input type="checkbox" name="tx_impexp[preset][public]" value="1"'.($inData['preset']['public'] ? ' checked="checked"' : '').' /><br/>
+                                       </td>
+                               </tr>';
+
+                       // Output options:
+               $row[] = '
+                       <tr class="tableheader bgColor5">
+                               <td colspan="2">Output options:</td>
+                       </tr>';
+
+                       // Meta data:
+               $tempDir = $this->userTempFolder();
+               if ($tempDir)   {
+                       $thumbnails = t3lib_div::getFilesInDir($tempDir,'png,gif,jpg');
+                       array_unshift($thumbnails,'');
+               } else $thumbnails = FALSE;
+               $row[] = '
+                               <tr class="bgColor4">
+                                       <td><strong>Meta data:</strong></td>
+                                       <td>
+                                                       Title: <br/>
+                                                       <input type="text" name="tx_impexp[meta][title]" value="'.htmlspecialchars($inData['meta']['title']).'"'.$this->doc->formWidth(30).' /><br/>
+                                                       Description: <br/>
+                                                       <input type="text" name="tx_impexp[meta][description]" value="'.htmlspecialchars($inData['meta']['description']).'"'.$this->doc->formWidth(30).' /><br/>
+                                                       Notes: <br/>
+                                                       <textarea name="tx_impexp[meta][notes]"'.$this->doc->formWidth(30,1).'>'.t3lib_div::formatForTextarea($inData['meta']['notes']).'</textarea><br/>
+                                                       '.(is_array($thumbnails) ? '
+                                                       Thumbnail:<br/>
+                                                       '.$this->renderSelectBox('tx_impexp[meta][thumbnail]',$inData['meta']['thumbnail'],$thumbnails).'<br/>
+                                                       '.($inData['meta']['thumbnail'] ? '<img src="'.$this->doc->backPath.'../'.substr($tempDir,strlen(PATH_site)).$thumbnails[$inData['meta']['thumbnail']].'" vspace="5" style="border: solid black 1px;" alt="" /><br/>' : '').'
+                                                       Upload thumbnail:<br/>
+                                                       <input type="file" name="upload_1" '.$this->doc->formWidth(30).' size="30" /><br/>
+                                                               <input type="hidden" name="file[upload][1][target]" value="'.htmlspecialchars($tempDir).'" />
+                                                               <input type="hidden" name="file[upload][1][data]" value="1" /><br />
+                                                       ' : '').'
+                                               </td>
+                               </tr>';
+
+                       // Add file options:
+               $savePath = $this->userSaveFolder();
+               $opt = array();
+               if ($this->export->compress)    {
+                       $opt['t3d_compressed'] = 'T3D file / compressed';
+               }
+               $opt['t3d'] = 'T3D file';
+               $opt['xml'] = 'XML';
+               $row[] = '
+                               <tr class="bgColor4">
+                                       <td><strong>File format:</strong></td>
+                                       <td>'.$this->renderSelectBox('tx_impexp[filetype]',$inData['filetype'],$opt).'<br/>
+                                               Max size of files to include (kb):<br/>
+                                               <input type="text" name="tx_impexp[maxFileSize]" value="'.htmlspecialchars($inData['maxFileSize']).'"'.$this->doc->formWidth(10).' /><br/>
+                                               '.($savePath ? 'Filename (saved in "'.substr($savePath,strlen(PATH_site)).'"):<br/>
+                                               <input type="text" name="tx_impexp[filename]" value="'.htmlspecialchars($inData['filename']).'"'.$this->doc->formWidth(30).' /><br/>' : '').'
+                                       </td>
+                               </tr>';
+
+
+                       // Add buttons:
+               $row[] = '
+                               <tr class="bgColor4">
+                                       <td>&nbsp;</td>
+                                       <td><input type="submit" value="Update" /> - <input type="submit" value="Download export" name="tx_impexp[download_export]" />'.
+                                               ($savePath ? ' - <input type="submit" value="Save to filename" name="tx_impexp[save_export]" />' : '').'</td>
+                               </tr>';
+       }
+
+
+
+
+
+
+
+
+
+
+
+
+
+       /**************************
         *
         * IMPORT FUNCTIONS
         *
-        */
+        **************************/
 
        /**
-        * @param       [type]          $inData: ...
-        * @return      [type]          ...
+        * Import part of module
+        *
+        * @param       array           Content of POST VAR tx_impexp[]..
+        * @return      void            Setting content in $this->content
         */
        function importData($inData)    {
-               global $TCA,$LANG;
-
+               global $TCA,$LANG,$BE_USER;
 
                $this->pageinfo = t3lib_BEfunc::readPageAccess($this->id,$this->perms_clause);
                $access = is_array($this->pageinfo) ? 1 : 0;
@@ -651,190 +1054,541 @@ with linebreaks
                        }
 
                        $headerSection = $this->doc->getHeader('pages',$this->pageinfo,$this->pageinfo['_thePath']).'<br />'.$LANG->sL('LLL:EXT:lang/locallang_core.php:labels.path').': '.t3lib_div::fixed_lgd_cs($this->pageinfo['_thePath'],-50);
-                       $this->content.=$this->doc->section('',$headerSection);
+                       $this->content.= $this->doc->section('',$headerSection);
+
+                       if ($inData['new_import'])      {
+                               unset($inData['import_mode']);
+                       }
 
                        $import = t3lib_div::makeInstance('tx_impexp');
-                       $import->init();
+                       $import->init(0,'import');
+                       $import->update = $inData['do_update'];
+                       $import->import_mode = $inData['import_mode'];
+                       $import->enableLogging = $inData['enableLogging'];
+                       $import->global_ignore_pid = $inData['global_ignore_pid'];
+                       $import->showDiff = $inData['showDiff'];
+                       $import->allowPHPScripts = $inData['allowPHPScripts'];
+                       $import->softrefInputValues = $inData['softrefInputValues'];
 
-                       $row=array();
 
-                               // User temp files:
+                               // OUTPUT creation:
+                       $menuItems = array();
+
+
+                               // Make input selector:
+                       $path = 'fileadmin/';   // must have trailing slash.
+                       $filesInDir = t3lib_div::getFilesInDir(PATH_site.$path,'t3d,xml',1,1);
+                       if (is_dir(PATH_site.$path.'export/'))  {
+                               $filesInDir = array_merge($filesInDir, t3lib_div::getFilesInDir(PATH_site.$path.'export/','t3d,xml',1,1));
+                       }
                        $tempFolder = $this->userTempFolder();
                        if ($tempFolder)        {
-                               $row[]='<tr class="bgColor5">
-                                               <td colspan=2><strong>Upload file:</strong></td>
+                               $temp_filesInDir = t3lib_div::getFilesInDir($tempFolder,'t3d,xml',1,1);
+                               $filesInDir = array_merge($filesInDir, $temp_filesInDir);
+                       }
+
+                               // Configuration
+                       $row = array();
+                       $opt = array('');
+                       foreach($filesInDir as $file)   {
+                               $opt[$file] = substr($file,strlen(PATH_site));
+                       }
+
+                       $row[] = '<tr class="bgColor5">
+                                       <td colspan="2"><strong>Select file to import:</strong></td>
+                               </tr>';
+
+                       $row[] = '<tr class="bgColor4">
+                               <td><strong>File:</strong></td>
+                               <td>'.
+                                       $this->renderSelectBox('tx_impexp[file]',$inData['file'],$opt).'<br />(From path: '.$path.')'.
+                                       (!$import->compress ? '<br /><span class="typo3-red">NOTE: No decompressor available for compressed files!</span>':'').
+                               '</td>
+                               </tr>';
+
+                       $row[] = '<tr class="bgColor5">
+                                       <td colspan="2"><strong>Import Options:</strong></td>
+                               </tr>';
+
+                       $row[] = '<tr class="bgColor4">
+                               <td><strong>Update:</strong></td>
+                               <td>
+                                       <input type="checkbox" name="tx_impexp[do_update]" value="1"'.($inData['do_update'] ? ' checked="checked"' : '').' />
+                                       Update records<br/>
+                               <em>(This option requires that the structure you import already exists on this server and only needs to be updated with new content!)</em>'.
+                               ($inData['do_update'] ?
+                               '       <hr/>
+                                       <input type="checkbox" name="tx_impexp[global_ignore_pid]" value="1"'.($inData['global_ignore_pid'] ? ' checked="checked"' : '').' />
+                                       Ignore PID differences globally<br/>
+                                       <em>(If you set this option, the position of updated elements will not be updated to match the structure of the input file.)</em>
+
+                                       ' : ''
+                               ).'</td>
+                               </tr>';
+
+                       $row[] = '<tr class="bgColor4">
+                               <td><strong>Options:</strong></td>
+                               <td>
+                                       <input type="checkbox" name="tx_impexp[showDiff]" value="1"'.($inData['showDiff'] ? ' checked="checked"' : '').' />
+                                       Show differences in records<br/>
+                                       <em>(Green values are from the import file, red values from the current database record and black values are similar in both versions.)</em>
+                                       <br/><br/>
+
+                                       '.($GLOBALS['BE_USER']->isAdmin() ? '
+                                       <input type="checkbox" name="tx_impexp[allowPHPScripts]" value="1"'.($inData['allowPHPScripts'] ? ' checked="checked"' : '').' />
+                                       Allow to write banned file extensions (eg. PHP scripts), if any<br/>' : '').'
+                               </td>
+                               </tr>';
+
+                       $row[] = '<tr class="bgColor4">
+                               <td><strong>Action:</strong></td>
+                               <td>'.
+                                       (!$inData['import_file'] ? '<input type="submit" value="Preview" />'.($inData['file'] ? ' - <input type="submit" value="'.($inData['do_update']?'Update':'Import').'" name="tx_impexp[import_file]" onclick="return confirm(\'Are you sure?\');" />':''):'<input type="submit" name="tx_impexp[new_import]" value="New import" />').'
+                                       <input type="hidden" name="tx_impexp[action]" value="import" /></td>
+                               </tr>';
+
+                       $row[] = '<tr class="bgColor4">
+                               <td><strong>Enable logging:</strong></td>
+                               <td>
+                                       <input type="checkbox" name="tx_impexp[enableLogging]" value="1"'.($inData['enableLogging'] ? ' checked="checked"' : '').' />
+                                       Write individual DB actions during import to the log<br/>
+                                       <em>(This is disabled by default since there may be hundred of entries generated.)</em>
+                               </td>
+                               </tr>';
+
+                       $menuItems[] = array(
+                               'label' => 'Import',
+                               'content' => '
+                                       <table border="0" cellpadding="1" cellspacing="1">
+                                               '.implode('
+                                               ',$row).'
+                                       </table>
+                               '
+                       );
+
+                               // Upload file:
+                       $tempFolder = $this->userTempFolder();
+                       if ($tempFolder)        {
+                               $row = array();
+
+                               $row[] = '<tr class="bgColor5">
+                                               <td colspan="2"><strong>Upload file from local computer:</strong></td>
                                        </tr>';
-                               $row[]='<tr class="bgColor5">
-                                               <td colspan=2>
-
-                                                       <!--
-                                                               Form, for uploading files:
-                                                       -->
-                                                       </form>
-                                                       <form action="'.$GLOBALS['BACK_PATH'].'tce_file.php" method="post" name="editform" enctype="'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['form_enctype'].'">
-                                                               <input type="file" name="upload_1"'.$this->doc->formWidth(35).' size="50" />
+
+                               $row[] = '<tr class="bgColor4">
+                                               <td>Browse:</td>
+                                               <td>
+
+                                                               <input type="file" name="upload_1"'.$this->doc->formWidth(35).' size="40" />
                                                                <input type="hidden" name="file[upload][1][target]" value="'.htmlspecialchars($tempFolder).'" />
                                                                <input type="hidden" name="file[upload][1][data]" value="1" /><br />
 
-                                                               <input type="hidden" name="redirect" value="'.htmlspecialchars(t3lib_div::getIndpEnv('REQUEST_URI')).'" />
                                                                <input type="submit" name="submit" value="'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:file_upload.php.submit',1).'" />
                                                                <input type="checkbox" name="overwriteExistingFiles" value="1" checked="checked" /> '.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_misc.php:overwriteExistingFiles',1).'
-                                                       </form>
-                                                       '.$this->doc->form.'
                                                </td>
                                        </tr>';
 
-                               $temp_filesInDir = t3lib_div::getFilesInDir($tempFolder,'t3d',1,1);
+                               $menuItems[] = array(
+                                       'label' => 'Upload',
+                                       'content' => '
+                                               <table border="0" cellpadding="1" cellspacing="1">
+                                                       '.implode('
+                                                       ',$row).'
+                                               </table>
+                                       '
+                               );
                        }
 
 
-                               // Make input selector:
-                       $path = 'fileadmin/';   // must have trailing slash.
-                       $filesInDir = t3lib_div::getFilesInDir(PATH_site.$path,'t3d',1,1);
+                               // Perform import or preview depending:
+                       $overviewContent = '';
+                       $inFile = t3lib_div::getFileAbsFileName($inData['file']);
+                       if ($inFile && @is_file($inFile))       {
+                               $row = array();
+                               if ($import->loadFile($inFile,1))       {
 
-                       if (is_array($temp_filesInDir)) {
-                               if (is_array($filesInDir))      {
-                                       $filesInDir = array_merge($temp_filesInDir, $filesInDir);
-                               } else {
-                                       $filesInDir = $temp_filesInDir;
+                                       if ($inData['import_file'])     {
+                                               $import->importData($this->id);
+                                               t3lib_BEfunc::getSetUpdateSignal('updatePageTree');
+                                       }
+
+                                       $import->display_import_pid_record = $this->pageinfo;
+                                       $overviewContent = $import->displayContentOverview();
                                }
-                       }
 
-                       $row[]='<tr class="bgColor5">
-                                       <td colspan=2><strong>Import file:</strong></td>
-                               </tr>';
+                                       // Meta data output:
+                               $row[] = '<tr class="bgColor5">
+                                               <td colspan="2"><strong>Meta data:</strong></td>
+                                       </tr>';
 
-                       $opt = array('');
-                       if (is_array($filesInDir))      {
-                               while(list(,$file)=each($filesInDir))   {
-#                                      $file=$path.$file;
-                                       $opt[$file]= substr($file,strlen(PATH_site));
+                               $opt = array('');
+                               foreach($filesInDir as $file)   {
+                                       $opt[$file] = substr($file,strlen(PATH_site));
                                }
-                       }
 
-                       $row[]='<tr class="bgColor4">
-                               <td><strong>File:</strong></td>
-                               <td>'.$this->renderSelectBox('tx_impexp[file]',$inData['file'],$opt).'<br />(From path: '.$path.')'.
-                               (!$import->compress ? '<br /><span class="typo3-red">NOTE: No decompressor available for compressed files!</span>':'').
-                               '</td>
-                               </tr>';
+                               $row[] = '<tr class="bgColor4">
+                                       <td><strong>Title:</strong></td>
+                                       <td>'.nl2br(htmlspecialchars($import->dat['header']['meta']['title'])).'</td>
+                                       </tr>';
 
-/*                     if ($this->pageinfo['doktype']!=254)    {
-                               $row[]='<tr class="bgColor4">
-                                       <td><strong>Warning:</strong></td>
-                                       <td>'.$GLOBALS["TBE_TEMPLATE"]->rfw('If you import into a page which is not a sysFolder you may experience a partial import. If you are in doubt you should import into a sysFolder.').'</td>
+                               $row[] = '<tr class="bgColor4">
+                                       <td><strong>Description:</strong></td>
+                                       <td>'.nl2br(htmlspecialchars($import->dat['header']['meta']['description'])).'</td>
                                        </tr>';
+
+                               $row[] = '<tr class="bgColor4">
+                                       <td><strong>Notes:</strong></td>
+                                       <td>'.nl2br(htmlspecialchars($import->dat['header']['meta']['notes'])).'</td>
+                                       </tr>';
+
+                               $row[] = '<tr class="bgColor4">
+                                       <td><strong>Packager:</strong></td>
+                                       <td>'.nl2br(htmlspecialchars($import->dat['header']['meta']['packager_name'].' ('.$import->dat['header']['meta']['packager_username'].')')).'<br/>
+                                               Email: '.$import->dat['header']['meta']['packager_email'].'</td>
+                                       </tr>';
+
+                                       // Thumbnail icon:
+                               if (is_array($import->dat['header']['thumbnail']))      {
+                                       $pI = pathinfo($import->dat['header']['thumbnail']['filename']);
+                                       if (t3lib_div::inList('gif,jpg,png,jpeg',strtolower($pI['extension']))) {
+
+                                                       // Construct filename and write it:
+                                               $fileName = PATH_site.
+                                                                       'typo3temp/importthumb.'.$pI['extension'];
+                                               t3lib_div::writeFile($fileName, $import->dat['header']['thumbnail']['content']);
+
+                                                       // Check that the image really is an image and not a malicious PHP script...
+                                               if (getimagesize($fileName))    {
+                                                               // Create icon tag:
+                                                       $iconTag = '<img src="'.$this->doc->backPath.'../'.substr($fileName,strlen(PATH_site)).'" '.$import->dat['header']['thumbnail']['imgInfo'][3].' vspace="5" style="border: solid black 1px;" alt="" />';
+
+                                                       $row[] = '<tr class="bgColor4">
+                                                               <td><strong>Icon:</strong></td>
+                                                               <td>'.$iconTag.'</td>
+                                                               </tr>';
+                                               } else {
+                                                       t3lib_div::unlink_tempfile($fileName);
+                                               }
+                                       }
+                               }
+
+                               $menuItems[] = array(
+                                       'label' => 'Meta data',
+                                       'content' => '
+                                               <table border="0" cellpadding="1" cellspacing="1">
+                                                       '.implode('
+                                                       ',$row).'
+                                               </table>
+                                       '
+                               );
                        }
-       */
-/*                     $row[]='<tr class="bgColor4">
-                               <td><strong>Include tables:</strong></td>
-                               <td>'.$this->tableSelector("tx_impexp[pagetree][tables]",$inData["pagetree"]["tables"],"pages").'</td>
-                               </tr>';
-       */
-                       $content.='<table border=0 cellpadding=1 cellspacing=1>'.implode('',$row).'</table>';
 
-                       $content.='<hr /><input type="submit" value="Preview" />';
-                       if (!$inData['import_file'])    {
-                               $content.=' - <input type="submit" value="Import" name="tx_impexp[import_file]" />';
+
+                               // Output tabs:
+                       $content = $this->doc->getDynTabMenu($menuItems,'tx_impexp_import',-1);
+                       $this->content.= $this->doc->section('',$content,0,1);
+
+
+                               // Print overview:
+                       if ($overviewContent) {
+                               $this->content.= $this->doc->section($inData['import_file'] ? 'Structure has been imported:' : 'Structure to be imported:', $overviewContent, 0, 1);
+                       }
+                       $errors = $import->printErrorLog();
+                       if ($errors)    {
+                               $this->content.= $this->doc->section('Messages:', $errors, 0, 1);
                        }
-                       $content.='<input type="hidden" name="tx_impexp[action]" value="import" />';
+               }
+       }
 
-                       $this->content.=$this->doc->section('Import TYPO3 Document (.t3d)',$content,0,1);
 
 
 
-                       $inFile = t3lib_div::getFileAbsFileName($inData['file']);
-                       if ($inFile && @is_file($inFile))       {
-                               $import->loadFile($inFile,1);
 
-#                              debug($import->dat['header']);
-                               if ($inData['import_file'])     {
-                                       $import->importData($this->id);
-                                       t3lib_BEfunc::getSetUpdateSignal('updatePageTree');
+
+
+
+
+
+
+
+
+       /****************************
+        *
+        * Preset functions
+        *
+        ****************************/
+
+       /**
+        * Manipulate presets
+        *
+        * @param       array           In data array, passed by reference!
+        * @return      void
+        */
+       function processPresets(&$inData)       {
+
+               $presetData = t3lib_div::_GP('preset');
+               $err = FALSE;
+
+                       // Save preset
+               if (isset($presetData['save'])) {
+                       $preset = $this->getPreset($presetData['select']);
+                       if (is_array($preset))  {       // Update existing
+                               if ($GLOBALS['BE_USER']->isAdmin() || $preset['user_uid'] === $GLOBALS['BE_USER']->user['uid']) {
+                                       $fields_values = array(
+                                               'public' => $inData['preset']['public'],
+                                               'title' => $inData['preset']['title'],
+                                               'item_uid' => $inData['pagetree']['id'],
+                                               'preset_data' => serialize($inData)
+                                       );
+                                       $GLOBALS['TYPO3_DB']->exec_UPDATEquery('tx_impexp_presets','uid='.intval($preset['uid']),$fields_values);
+                                       $msg = 'Preset #'.$preset['uid'].' saved!';
+                               } else {
+                                       $msg = 'ERROR: The preset was not saved because you were not the owner of it!';
+                                       $err = TRUE;
                                }
+                       } else {        // Insert new:
+                               $fields_values = array(
+                                       'user_uid' => $GLOBALS['BE_USER']->user['uid'],
+                                       'public' => $inData['preset']['public'],
+                                       'title' => $inData['preset']['title'],
+                                       'item_uid' => $inData['pagetree']['id'],
+                                       'preset_data' => serialize($inData)
+                               );
+                               $GLOBALS['TYPO3_DB']->exec_INSERTquery('tx_impexp_presets',$fields_values);
+                               $msg = 'New preset "'.$inData['preset']['title'].'" is created';
+                       }
+               }
 
-                               $import->display_import_pid_record=$this->pageinfo;
-                               $content=$import->displayContentOverview(1);
-                               $this->content.=$this->doc->section($inData['import_file']?'Structure has been imported:':'Structure to be imported:',$content,0,1);
+                       // Delete preset:
+               if (isset($presetData['delete']))       {
+                       $preset = $this->getPreset($presetData['select']);
+                       if (is_array($preset))  {       // Update existing
+                               if ($GLOBALS['BE_USER']->isAdmin() || $preset['user_uid'] === $GLOBALS['BE_USER']->user['uid']) {
+                                       $GLOBALS['TYPO3_DB']->exec_DELETEquery('tx_impexp_presets','uid='.intval($preset['uid']));
+                                       $msg = 'Preset #'.$preset['uid'].' deleted!';
+                               } else {
+                                       $msg = 'ERROR: You were not the owner of the preset so you could not delete it.';
+                                       $err = TRUE;
+                               }
+                       } else {
+                               $msg = 'ERROR: No preset selected for deletion.';
+                               $err = TRUE;
+                       }
+               }
 
-                               $errors = $import->printErrorLog();
-                               if ($errors)    $this->content.=$this->doc->section('Messages:',$errors,0,1);
+                       // Load preset
+               if (isset($presetData['load']) || isset($presetData['merge']))  {
+                       $preset = $this->getPreset($presetData['select']);
+                       if (is_array($preset))  {       // Update existing
+                               $inData_temp = unserialize($preset['preset_data']);
+                               if (is_array($inData_temp))     {
+                                       if (isset($presetData['merge']))        {
+                                                       // Merge records in:
+                                               if (is_array($inData_temp['record']))   {
+                                                       $inData_temp['record'] = array_merge($inData_temp['record'], $inData['record']);
+                                               } else $inData_temp['record'] = $inData['record'];
+                                                       // Merge lists in:
+                                               if (is_array($inData_temp['list']))     {
+                                                       $inData_temp['list'] = array_merge($inData_temp['list'], $inData['list']);
+                                               } else $inData_temp['list'] = $inData['list'];
+                                               $inData_temp['listCfg'] = $inData['listCfg'];
+
+                                                       // Swap:
+                                               $inData = $inData_temp;
+                                       } else {
+                                               $msg = 'Preset #'.$preset['uid'].' loaded!';
+                                               $inData = $inData_temp;
+                                       }
+                               } else {
+                                       $msg = 'ERROR: No configuratio data found in preset record!';
+                                       $err = TRUE;
+                               }
+                       } else {
+                               $msg = 'ERROR: No preset selected for loading.';
+                               $err = TRUE;
                        }
                }
 
+                       // Show message:
+               if (strlen($msg))       {
+                       $this->content.= $this->doc->section('Presets',$msg,0,1,$err ? 3 : 1);
+               }
        }
 
        /**
-        * Returns a selector-box with tables
+        * Get single preset record
         *
-        * @param       [type]          $prefix: ...
-        * @param       [type]          $value: ...
-        * @param       [type]          $excludeList: ...
-        * @return      [type]          ...
+        * @param       integer         Preset record
+        * @return      array           Preset record, if any (otherwise false)
         */
-       function tableSelector($prefix,$value,$excludeList='')  {
-               global $TCA;
-               reset($TCA);
-               $optValues = array();
+       function getPreset($uid)        {
+               list($preset) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*','tx_impexp_presets','uid='.intval($uid));
+               return $preset;
+       }
 
-               if (!t3lib_div::inList($excludeList,'_ALL'))                                    $optValues['_ALL']='[ALL tables]';
 
-               while(list($table)=each($TCA))  {
-                       if ($GLOBALS['BE_USER']->check('tables_select',$table) && !t3lib_div::inList($excludeList,$table))      {
-                               $optValues[$table]=$table;
+
+
+
+
+
+
+
+
+
+       /****************************
+        *
+        * Helper functions
+        *
+        ****************************/
+
+       /**
+        * Returns first temporary folder of the user account (from $FILEMOUNTS)
+        *
+        * @return      string          Absolute path to first "_temp_" folder of the current user, otherwise blank.
+        */
+       function userTempFolder()       {
+               global $FILEMOUNTS;
+
+               foreach($FILEMOUNTS as $filePathInfo)   {
+                       $tempFolder = $filePathInfo['path'].'_temp_/';
+                       if (@is_dir($tempFolder))       {
+                               return $tempFolder;
                        }
                }
+       }
+
+       /**
+        * Returns folder where user can save export files.
+        *
+        * @return      string          Absolute path to folder where export files can be saved.
+        */
+       function userSaveFolder()       {
+               global $FILEMOUNTS;
 
+               reset($FILEMOUNTS);
+               $filePathInfo = current($FILEMOUNTS);
 
-                       // make box:
-               $opt=array();
-               $opt[]='<option value=""></option>';
-               reset($optValues);
-               while(list($k,$v)=each($optValues))     {
-                       if (is_array($value))   $sel = (in_array($k,$value)?' selected="selected"':'');
-                       $opt[]='<option value="'.htmlspecialchars($k).'"'.$sel.'>'.htmlspecialchars($v).'</option>';
+               if (is_array($filePathInfo))    {
+                       $tempFolder = $filePathInfo['path'].'export/';
+                       if (!@is_dir($tempFolder))      {
+                               $tempFolder = $filePathInfo['path'];
+                               if (!@is_dir($tempFolder))      {
+                                       return FALSE;
+                               }
+                       }
+                       return $tempFolder;
+               }
+       }
+
+       /**
+        * Check if a file has been uploaded
+        *
+        * @return      void
+        */
+       function checkUpload()  {
+               global $FILEMOUNTS,$TYPO3_CONF_VARS,$BE_USER;
+
+               $file = t3lib_div::_GP('file');
+
+                       // Initializing:
+               $this->fileProcessor = t3lib_div::makeInstance('t3lib_extFileFunctions');
+               $this->fileProcessor->init($FILEMOUNTS, $TYPO3_CONF_VARS['BE']['fileExtensions']);
+               $this->fileProcessor->init_actionPerms($BE_USER->user['fileoper_perms']);
+               $this->fileProcessor->dontCheckForUnique = t3lib_div::_GP('overwriteExistingFiles') ? 1 : 0;
+
+                       // Checking referer / executing:
+               $refInfo = parse_url(t3lib_div::getIndpEnv('HTTP_REFERER'));
+               $httpHost = t3lib_div::getIndpEnv('TYPO3_HOST_ONLY');
+               if ($httpHost!=$refInfo['host'] && $this->vC!=$BE_USER->veriCode() && !$TYPO3_CONF_VARS['SYS']['doNotCheckReferer'])    {
+                       $this->fileProcessor->writeLog(0,2,1,'Referer host "%s" and server host "%s" did not match!',array($refInfo['host'],$httpHost));
+               } else {
+                       $this->fileProcessor->start($file);
+                       $this->fileProcessor->processData();
                }
-               return '<select name="'.$prefix.'[]" multiple size="'.t3lib_d