See changelog (2004-08-21). Localization features, Tab menus, few bugs fixed.
authorKasper Skårhøj <kasper@typo3.org>
Sat, 21 Aug 2004 17:55:41 +0000 (17:55 +0000)
committerKasper Skårhøj <kasper@typo3.org>
Sat, 21 Aug 2004 17:55:41 +0000 (17:55 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@437 709f56b5-9817-0410-a4d7-c38de5d9e867

28 files changed:
ChangeLog
t3lib/class.t3lib_befunc.php
t3lib/class.t3lib_beuserauth.php
t3lib/class.t3lib_install.php
t3lib/class.t3lib_stdgraphic.php
t3lib/class.t3lib_tceforms.php
t3lib/class.t3lib_tcemain.php
t3lib/class.t3lib_transferdata.php
t3lib/config_default.php
typo3/alt_doc.php
typo3/alt_main.php
typo3/class.show_rechis.inc
typo3/index.php
typo3/init.php
typo3/show_item.php
typo3/stylesheet.css
typo3/sysext/cms/ext_tables.php
typo3/sysext/cms/ext_tables.sql
typo3/sysext/cms/layout/class.tx_cms_layout.php
typo3/sysext/cms/layout/db_layout.php
typo3/sysext/cms/tbl_cms.php
typo3/sysext/cms/tbl_tt_content.php
typo3/sysext/cms/tslib/class.tslib_fe.php
typo3/sysext/cms/tslib/index_ts.php
typo3/sysext/install/mod/class.tx_install.php
typo3/sysext/lang/locallang_core.xml
typo3/tce_db.php
typo3/template.php

index 3e94bbf..d91a4ef 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2004-08-21  Kasper Skårhøj,,,  <kasper@typo3.com>
+
+       * Added support for backend initialization in PHP shell scripts. Interesting for deamons, cronjobs etc where you want a PHP script to run from shell but with a full backend environment. Documented in next version of Inside TYPO3.
+       * Configurable multiplication of DB field size (useful for resizing database for UTf-8 support)
+       * Fixed bug in show_item.php script / stdGraphic with abs/rel path prefix and typo3temp/ folder.
+       * TCEforms/TCEmain support for localization; You can exclude certain fields in localized versions, see diff. view if original changed, see the original records content with the localized version.
+       * TCEforms support for dynamic TAB menus (use the --div-- in types configuration and enable in [ctrl] section
+       * All TCEforms changes for localization and tab menus are documented in TYPO3 Core API
+       * Added support for localization-copies in Web>Page module; Now you can create copies of default language elements with a click on a button. There is even a new mode where all localizations must follow the default language 100% - but this still lacks frontend support. Enabled by "web.layout.defLangBinding=1" in Page TSconfig.
+       * Finally implemented dynamic (DHTML based) tab menus for flexforms using sheets!
+       * Added "select all" link for "checkbox" renderMode of "select" types in TCEforms
+       * New tcemain "cmd": "localize". Will make a localization-copy of a record, eg. content elements.
+       * Made "explicitDeny" mode for backend users configurable in TYPo3_CONF_VARS as requested on the dev-list.
+       * Added "sleep(5)" when a false login was detected in the login-screen. This makes trying lots of username/passwords in the login screen boooooring...
+       * Added new GUI type: Dynamic TAB menu which can switch between a number of sheets of content dynamically with tabs. Used in flexforms and also in TemplaVoila.
+       * Set-locale issue for USER_INT objects should be fixed. Please test this someone!!!
+       
+
 2004-08-20  Ingmar Schlecht  <ingmars@web.de>
 
  * Marginally changed the error message in t3lib_userauth appearing when the HTTP_REFERER mismatched.
index f2b055f..4820a30 100755 (executable)
@@ -1376,18 +1376,18 @@ class t3lib_BEfunc      {
         * @param       string          $labels should be something like ' min| hrs| days| yrs'. This value is typically delivered by this function call: $GLOBALS["LANG"]->sL("LLL:EXT:lang/locallang_core.php:labels.minutesHoursDaysYears")
         * @return      string          Formatted time
         */
-       function calcAge($seconds,$labels)      {
+       function calcAge($seconds,$labels = 'min|hrs|days|yrs') {
                $labelArr = explode('|',$labels);
                $prefix='';
                if ($seconds<0) {$prefix='-'; $seconds=abs($seconds);}
                if ($seconds<3600)      {
-                       $seconds = round ($seconds/60).$labelArr[0];
+                       $seconds = round ($seconds/60).' '.trim($labelArr[0]);
                } elseif ($seconds<24*3600)     {
-                       $seconds = round ($seconds/3600).$labelArr[1];
+                       $seconds = round ($seconds/3600).' '.trim($labelArr[1]);
                } elseif ($seconds<365*24*3600) {
-                       $seconds = round ($seconds/(24*3600)).$labelArr[2];
+                       $seconds = round ($seconds/(24*3600)).' '.trim($labelArr[2]);
                } else {
-                       $seconds = round ($seconds/(365*24*3600)).$labelArr[3];
+                       $seconds = round ($seconds/(365*24*3600)).' '.trim($labelArr[3]);
                }
                return $prefix.$seconds;
        }
@@ -2076,6 +2076,7 @@ class t3lib_BEfunc        {
         * @param       string          $backPath must point back to the TYPO3_mainDir directory (where alt_doc.php is)
         * @param       string          $requestUri is an optional returnUrl you can set - automatically set to REQUEST_URI.
         * @return      string
+        * @see template::issueCommand()
         */
        function editOnClick($params,$backPath='',$requestUri='')       {
                $retUrl = 'returnUrl='.($requestUri==-1?"'+T3_THIS_LOCATION+'":rawurlencode($requestUri?$requestUri:t3lib_div::getIndpEnv('REQUEST_URI')));
index 8e145ea..e08f80c 100644 (file)
@@ -209,6 +209,28 @@ class t3lib_beUserAuth extends t3lib_userAuthGroup {
        }
 
        /**
+        * If the backend script is in CLI mode, it will try to load a backend user named by the CLI module name (in lowercase)
+        *
+        * @return      boolean         Returns true if a CLI user was loaded, otherwise false!
+        */
+       function checkCLIuser() {
+                       // First, check if cliMode is enabled:
+               if (defined('TYPO3_cliMode') && TYPO3_cliMode)  {
+                       if (!$this->user['uid'])        {
+                               if (substr($GLOBALS['MCONF']['name'],0,5)=='_CLI_')     {
+                                       $userName = strtolower($GLOBALS['MCONF']['name']);
+                                       $this->setBeUserByName($userName);
+                                       if ($this->user['uid']) {
+                                               if (!$this->isAdmin())  {
+                                                       return TRUE;
+                                               } else die('ERROR: CLI backend user "'.$userName.'" was ADMIN which is not allowed!'.chr(10).chr(10));
+                                       } else die('ERROR: No backend user named "'.$userName.'" was found!'.chr(10).chr(10));
+                               } else die('ERROR: Module name, "'.$GLOBALS['MCONF']['name'].'", was not prefixed with "_CLI_"'.chr(10).chr(10));
+                       } else die('ERROR: Another user was already loaded which is impossible in CLI mode!'.chr(10).chr(10));
+               }
+       }
+
+       /**
         * Initialize the internal ->uc array for the backend user
         * Will make the overrides if necessary, and write the UC back to the be_users record if changes has happend
         *
index f17215e..7c7a1a0 100755 (executable)
@@ -101,6 +101,15 @@ class t3lib_install {
 
 
 
+       /**
+        * Constructor
+        */
+       function t3lib_install()        {
+               if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['multiplyDBfieldSize']>= 1 && $GLOBALS['TYPO3_CONF_VARS']['SYS']['multiplyDBfieldSize']<=5)      {
+                       $this->multiplySize = (double)$GLOBALS['TYPO3_CONF_VARS']['SYS']['multiplyDBfieldSize'];
+               }
+       }
+
 
 
        /**************************************
index 5d8948b..1f6e6d1 100644 (file)
@@ -178,7 +178,8 @@ class t3lib_stdGraphic      {
        var $workArea = Array();
 
                // Constants:
-       var $tempPath = 'typo3temp/';                                           // The temp-directory where to store the files. Relative to PATH_site.
+       var $tempPath = 'typo3temp/';                                           // The temp-directory where to store the files. Relative to PATH_site. MUST NOT be absolute!
+       var $absPrefix = '';                                                            // Prefix for relative paths. Used on "show_item.php" script
        var $scalecmd = '-geometry';                                            // ImageMagick scaling command; "-geometry" eller "-sample". Used in makeText() and imageMagickConvert()
        var $im5fx_blurSteps='1x2,2x2,3x2,4x3,5x3,5x4,6x4,7x5,8x5,9x5';                 // Used by v5_blur() to simulate 10 continuous steps of blurring
        var $im5fx_sharpenSteps='1x2,2x2,3x2,2x3,3x3,4x3,3x4,4x4,4x5,5x5';              // Used by v5_sharpen() to simulate 10 continuous steps of sharpening.
@@ -1812,7 +1813,7 @@ class t3lib_stdGraphic    {
 
                                        // Making the temporary filename:
                                $this->createTempSubDir('pics/');
-                               $output = $this->tempPath.'pics/'.$this->filenamePrefix.$theOutputName.'.'.$newExt;
+                               $output = $this->absPrefix.$this->tempPath.'pics/'.$this->filenamePrefix.$theOutputName.'.'.$newExt;
 
                                        // Register temporary filename:
                                $GLOBALS['TEMP_IMAGES_ON_PAGE'][] = $output;
@@ -2082,7 +2083,7 @@ class t3lib_stdGraphic    {
         * Returns an array where [0]/[1] is w/h, [2] is extension and [3] is the filename.
         * Using ImageMagick
         *
-        * @param       string          The absolute image filepath
+        * @param       string          The relative (to PATH_site) image filepath
         * @return      array
         */
        function imageMagickIdentify($imagefile)        {
@@ -2114,8 +2115,8 @@ class t3lib_stdGraphic    {
         * Executes a ImageMagick "convert" on two filenames, $input and $output using $params before them.
         * Can be used for many things, mostly scaling and effects.
         *
-        * @param       string          The absolute image filepath, input file (read from)
-        * @param       string          The absolute image filepath, output filename (written to)
+        * @param       string          The relative (to PATH_site) image filepath, input file (read from)
+        * @param       string          The relative (to PATH_site) image filepath, output filename (written to)
         * @param       string          ImageMagick parameters
         * @return      string          The result of a call to PHP function "exec()"
         */
@@ -2131,10 +2132,10 @@ class t3lib_stdGraphic  {
         * Executes a ImageMagick "combine" (or composite in newer times) on four filenames - $input, $overlay and $mask as input files and $output as the output filename (written to)
         * Can be used for many things, mostly scaling and effects.
         *
-        * @param       string          The absolute image filepath, bottom file
-        * @param       string          The absolute image filepath, overlay file (top)
-        * @param       string          The absolute image filepath, the mask file (grayscale)
-        * @param       string          The absolute image filepath, output filename (written to)
+        * @param       string          The relative (to PATH_site) image filepath, bottom file
+        * @param       string          The relative (to PATH_site) image filepath, overlay file (top)
+        * @param       string          The relative (to PATH_site) image filepath, the mask file (grayscale)
+        * @param       string          The relative (to PATH_site) image filepath, output filename (written to)
         * @return      void
         */
        function combineExec($input,$overlay,$mask,$output)     {
index 0b84b0d..22a972f 100755 (executable)
 
 
 
+require_once(PATH_t3lib.'class.t3lib_diff.php');
+
 
 
 /**
@@ -191,6 +193,8 @@ class t3lib_TCEforms        {
        var $prevBorderStyle='[nothing here...]';       // Something unique...
        var $allowUpload=0;                             // If set direct upload fields will be shown
        var $titleLen=15;                                       // $BE_USER->uc['titleLen'] but what is default??
+       var $defaultLanguageData = array();     // Array where records in the default language is stored. (processed by transferdata)
+       var $defaultLanguageData_diff = array();        // Array where records in the default language is stored (raw without any processing. used for making diff)
 
 
                // EXTERNAL, static
@@ -204,6 +208,7 @@ class t3lib_TCEforms        {
        var $doPrintPalette=1;                          // If set to false, palettes will NEVER be rendered.
        var $clipObj=FALSE;                                     // Set to initialized clipboard object; Then the element browser will offer a link to paste in records from clipboard.
        var $enableClickMenu=FALSE;                     // Enable click menu on reference icons.
+       var $enableTabMenu = FALSE;                     // Enable Tab Menus. If set to true, the JavaScript content from template::getDynTabMenuJScode() must be included in the document.
 
        var $form_rowsToStylewidth = 9.58;      // Form field width compensation: Factor from NN4 form field widths to style-aware browsers (like NN6+ and MSIE, with the $CLIENT[FORMSTYLE] value set)
        var $form_largeComp = 1.33;                     // Form field width compensation: Compensation for large documents, doc-tab (editing)
@@ -396,8 +401,13 @@ class t3lib_TCEforms       {
                $this->renderDepth=$depth;
 
                        // Init vars:
-               $out_array=array();
+               $out_array = array(array());
+               $out_array_meta = array(array(
+                       'title' => $this->getLL('l_generalTab')
+               ));
+
                $out_pointer=0;
+               $out_sheet=0;
                $this->palettesRendered=array();
                $this->palettesRendered[$this->renderDepth][$table]=array();
 
@@ -429,8 +439,8 @@ class t3lib_TCEforms        {
                                        $fields = $this->mergeFieldsWithAddedFields($fields,$this->getFieldsToAdd($table,$row,$typeNum));
 
                                                // Traverse the fields to render:
-                                       reset($fields);
-                                       while(list(,$fieldInfo)=each($fields))  {
+                                       $cc=0;
+                                       foreach($fields as $fieldInfo)  {
                                                        // Exploding subparts of the field configuration:
                                                $parts = explode(';',$fieldInfo);
 
@@ -444,7 +454,7 @@ class t3lib_TCEforms        {
                                                        if (!isset($this->fieldStyle))  $this->fieldStyle = $GLOBALS['TBE_STYLES']['styleschemes'][0];
                                                }
                                                if (strcmp($color_style_parts[2],''))   {
-                                                       $this->wrapBorder($out_array,$out_pointer);
+                                                       $this->wrapBorder($out_array[$out_sheet],$out_pointer);
                                                        $this->borderStyle = $GLOBALS['TBE_STYLES']['borderschemes'][intval($color_style_parts[2])];
                                                        if (!isset($this->borderStyle)) $this->borderStyle = $GLOBALS['TBE_STYLES']['borderschemes'][0];
                                                }
@@ -462,28 +472,41 @@ class t3lib_TCEforms      {
                                                                $sField = $this->getSingleField($table,$theField,$row,$parts[1],0,$parts[3],$parts[2]);
                                                                if ($sField)    $sField.=$sFieldPal;
 
-                                                               $out_array[$out_pointer].= $sField;
+                                                               $out_array[$out_sheet][$out_pointer].= $sField;
                                                        } elseif($theField=='--div--')  {
-                                                               $out_array[$out_pointer].=$this->getDivider();
+                                                               if ($cc>0) {
+                                                                       $out_array[$out_sheet][$out_pointer].=$this->getDivider();
+
+                                                                       if ($this->enableTabMenu && $TCA[$table]['ctrl']['dividers2tabs'])      {
+                                                                               $this->wrapBorder($out_array[$out_sheet],$out_pointer);
+                                                                               $out_sheet++;
+                                                                               $out_array[$out_sheet] = array();
+                                                                               $out_array_meta[$out_sheet]['title'] = $this->sL($parts[1]);
+                                                                       }
+                                                               } else {        // Setting alternative title for "General" tab if "--div--" is the very first element.
+                                                                       $out_array_meta[$out_sheet]['title'] = $this->sL($parts[1]);
+                                                               }
                                                        } elseif($theField=='--palette--')      {
                                                                if ($parts[2] && !isset($this->palettesRendered[$this->renderDepth][$table][$parts[2]]))        {
                                                                                // render a 'header' if not collapsed
                                                                        if ($TCA[$table]['palettes'][$parts[2]]['canNotCollapse'] AND $parts[1]) {
-                                                                               $out_array[$out_pointer].=$this->getPaletteFields($table,$row,$parts[2],$this->sL($parts[1]));
+                                                                               $out_array[$out_sheet][$out_pointer].=$this->getPaletteFields($table,$row,$parts[2],$this->sL($parts[1]));
                                                                        } else {
-                                                                               $out_array[$out_pointer].=$this->getPaletteFields($table,$row,$parts[2],'','',$this->sL($parts[1]));
+                                                                               $out_array[$out_sheet][$out_pointer].=$this->getPaletteFields($table,$row,$parts[2],'','',$this->sL($parts[1]));
                                                                        }
                                                                        $this->palettesRendered[$this->renderDepth][$table][$parts[2]] = 1;
                                                                }
                                                        }
                                                }
+
+                                               $cc++;
                                        }
                                }
                        }
                }
 
                        // Wrapping a border around it all:
-               $this->wrapBorder($out_array,$out_pointer);
+               $this->wrapBorder($out_array[$out_sheet],$out_pointer);
 
                        // Resetting styles:
                $this->resetSchemes();
@@ -493,18 +516,40 @@ class t3lib_TCEforms      {
                if ($mP && !isset($this->palettesRendered[$this->renderDepth][$table][$mP]))    {
                        $temp_palettesCollapsed=$this->palettesCollapsed;
                        $this->palettesCollapsed=0;
-                       $out_array[$out_pointer].=$this->getPaletteFields($table,$row,$mP,$this->getLL('l_generalOptions'));
+                       $out_array[$out_sheet][$out_pointer].=$this->getPaletteFields($table,$row,$mP,$this->getLL('l_generalOptions'));
                        $this->palettesCollapsed=$temp_palettesCollapsed;
                        $this->palettesRendered[$this->renderDepth][$table][$mP] = 1;
                }
-               $this->wrapBorder($out_array,$out_pointer);
+               $this->wrapBorder($out_array[$out_sheet],$out_pointer);
 
                if ($this->renderDepth) {
                        $this->renderDepth--;
                }
 
+
                        // Return the imploded $out_array:
-               return implode('',$out_array);
+               if ($out_sheet>0)       {       // There were --div-- dividers around...
+
+                               // Create parts array for the tab menu:
+                       $parts = array();
+                       foreach($out_array as $idx => $sheetContent)    {
+                               $parts[] = array(
+                                       'label' => $out_array_meta[$idx]['title'],
+                                       'content' => '<table border="0" cellspacing="0" cellpadding="0" width="100%">'.
+                                                       implode('',$sheetContent).
+                                               '</table>'
+                               );
+                       }
+
+                       return '
+                               <tr>
+                                       <td colspan="2">
+                                       '.$this->getDynTabMenu($parts, 'TCEforms:'.$table.':'.$row['uid']).'
+                                       </td>
+                               </tr>';
+               } else {        // Only one, so just implode:
+                       return implode('',$out_array[$out_sheet]);
+               }
        }
 
        /**
@@ -656,7 +701,8 @@ class t3lib_TCEforms        {
                                (!$PA['fieldConf']['exclude'] || $BE_USER->check('non_exclude_fields',$table.':'.$field)) &&
                                $PA['fieldConf']['config']['form_type']!='passthrough' &&
                                ($this->RTEenabled || !$PA['fieldConf']['config']['showIfRTE']) &&
-                               (!$PA['fieldConf']['displayCond'] || $this->isDisplayCondition($PA['fieldConf']['displayCond'],$row))
+                               (!$PA['fieldConf']['displayCond'] || $this->isDisplayCondition($PA['fieldConf']['displayCond'],$row)) &&
+                               (!$TCA[$table]['ctrl']['languageField'] || strcmp($PA['fieldConf']['l10n_mode'],'exclude') || $row[$TCA[$table]['ctrl']['languageField']]<=0)
                        )       {
 
                                // Fetching the TSconfig for the current table/field. This includes the $row which means that
@@ -707,6 +753,10 @@ class t3lib_TCEforms       {
                                                // Based on the type of the item, call a render function:
                                        $item = $this->getSingleField_SW($table,$field,$row,$PA);
 
+                                               // Add language + diff
+                                       $item = $this->renderDefaultLanguageContent($table,$field,$row,$item);
+                                       $item = $this->renderDefaultLanguageDiff($table,$field,$row,$item);
+
                                                // If the record has been saved and the "linkTitleToSelf" is set, we make the field name into a link, which will load ONLY this field in alt_doc.php
                                        $PA['label'] = t3lib_div::deHSCentities(htmlspecialchars($PA['label']));
                                        if (t3lib_div::testInt($row['uid']) && $PA['fieldTSConfig']['linkTitleToSelf']) {
@@ -1265,9 +1315,21 @@ class t3lib_TCEforms     {
                $tRows = array();
                $sOnChange = implode('',$PA['fieldChangeFunc']);
                $c=0;
+               $setAll = array();      // Used to accumulate the JS needed to restore the original selection.
                foreach($selItems as $p)        {
                                // Non-selectable element:
                        if (!strcmp($p[1],'--div--'))   {
+                               if (count($setAll))     {
+                                               $tRows[] = '
+                                                       <tr>
+                                                               <td colspan="2">'.
+                                                               '<a href="#" onclick="'.htmlspecialchars(implode('',$setAll).' return false;').'">'.
+                                                               htmlspecialchars($this->getLL('l_setAllCheckboxes')).
+                                                               '</a></td>
+                                                       </tr>';
+                                               $setAll = array();
+                               }
+
                                $tRows[] = '
                                        <tr class="c-header">
                                                <td colspan="2">'.htmlspecialchars($p[0]).'</td>
@@ -1289,6 +1351,7 @@ class t3lib_TCEforms      {
                                        // Compile row:
                                $onClickCell = $this->elName($PA['itemFormElName'].'['.$c.']').'.checked=!'.$this->elName($PA['itemFormElName'].'['.$c.']').'.checked;';
                                $onClick = 'this.attributes.getNamedItem("class").nodeValue = '.$this->elName($PA['itemFormElName'].'['.$c.']').'.checked ? "c-selectedItem" : "";';
+                               $setAll[] = $this->elName($PA['itemFormElName'].'['.$c.']').'.checked=1;';
                                $tRows[] = '
                                        <tr class="'.($sM ? 'c-selectedItem' : '').'" onclick="'.htmlspecialchars($onClick).'" style="cursor: pointer;">
                                                <td><input type="checkbox" name="'.htmlspecialchars($PA['itemFormElName'].'['.$c.']').'" value="'.htmlspecialchars($p[1]).'"'.$sM.' onclick="'.htmlspecialchars($sOnChange).'"'.$PA['onFocus'].' /></td>
@@ -1302,6 +1365,17 @@ class t3lib_TCEforms     {
                        }
                }
 
+                       // Remaining checkboxes will get their set-all link:
+               if (count($setAll))     {
+                               $tRows[] = '
+                                       <tr>
+                                               <td colspan="2">'.
+                                               '<a href="#" onclick="'.htmlspecialchars(implode('',$setAll).' return false;').'">'.
+                                               htmlspecialchars($this->getLL('l_setAllCheckboxes')).
+                                               '</a></td>
+                                       </tr>';
+               }
+
                        // Remaining values (invalid):
                if (count($itemArray) && !$PA['fieldTSConfig']['disableNoMatchingValueElement'] && !$config['disableNoMatchingValueElement'])   {
                        foreach($itemArray as $theNoMatchValue => $temp)        {
@@ -1324,7 +1398,8 @@ class t3lib_TCEforms      {
                $item.= '
                        <table border="0" cellpadding="0" cellspacing="0" class="typo3-TCEforms-select-checkbox">'.
                                implode('',$tRows).'
-                       </table>';
+                       </table>
+                       ';
 
                return $item;
        }
@@ -1790,11 +1865,11 @@ class t3lib_TCEforms    {
 
                                // Find the data structure if sheets are found:
                        $sheet = $editData['meta']['currentSheetId'] ? $editData['meta']['currentSheetId'] : 'sDEF';    // Sheet to display
-                       $item.= '<input type="hidden" name="'.$PA['itemFormElName'].'[meta][currentSheetId]" value="'.$sheet.'">';
+#                      $item.= '<input type="hidden" name="'.$PA['itemFormElName'].'[meta][currentSheetId]" value="'.$sheet.'">';
 
                                // Create sheet menu:
                        if (is_array($dataStructArray['sheets']))       {
-                               $item.=$this->getSingleField_typeFlex_sheetMenu($dataStructArray['sheets'], $PA['itemFormElName'].'[meta][currentSheetId]', $sheet).'<br />';
+                               #$item.=$this->getSingleField_typeFlex_sheetMenu($dataStructArray['sheets'], $PA['itemFormElName'].'[meta][currentSheetId]', $sheet).'<br />';
                        }
 #debug($editData);
 
@@ -1819,13 +1894,22 @@ class t3lib_TCEforms    {
                                $rotateLang = $editData['meta']['currentLangId'];
                        }
 
+                               // Tabs sheets
+                       if (is_array($dataStructArray['sheets']))       {
+                               $tabsToTraverse = array_keys($dataStructArray['sheets']);
+                       } else {
+                               $tabsToTraverse = array($sheet);
+                       }
+
                        foreach($rotateLang as $lKey)   {
                                if (!$langChildren && !$langDisabled)   {
                                        $item.= '<b>'.$lKey.':</b>';
                                }
-       #                       foreach($dataStructArray['sheets'] as $sheet => $_blabla)       {
+
+                               $tabParts = array();
+                               foreach($tabsToTraverse as $sheet)      {
+                                       $sheetCfg = $dataStructArray['sheets'][$sheet];
                                        list ($dataStruct, $sheet) = t3lib_div::resolveSheetDefInDS($dataStructArray,$sheet);
-               #debug(array($dataStruct, $sheet));
 
                                                // Render sheet:
                                        if (is_array($dataStruct['ROOT']) && is_array($dataStruct['ROOT']['el']))               {
@@ -1844,12 +1928,26 @@ class t3lib_TCEforms    {
                                                                        $PA,
                                                                        '[data]['.$sheet.']['.$lang.']'
                                                                );
-                                               $item.= '<table border="0" cellpadding="1" cellspacing="1" class="typo3-TCEforms-flexForm">'.implode('',$tRows).'</table>';
+                                               $sheetContent= '<table border="0" cellpadding="1" cellspacing="1" class="typo3-TCEforms-flexForm">'.implode('',$tRows).'</table>';
 
                        #                       $item = '<div style=" position:absolute;">'.$item.'</div>';
                                                //visibility:hidden;
-                                       } else $item.='Data Structure ERROR: No ROOT element found for sheet "'.$sheet.'".';
-       #                       }
+                                       } else $sheetContent='Data Structure ERROR: No ROOT element found for sheet "'.$sheet.'".';
+
+                                               // Add to tab:
+                                       $tabParts[] = array(
+                                               'label' => ($sheetCfg['ROOT']['TCEforms']['sheetTitle'] ? $this->sL($sheetCfg['ROOT']['TCEforms']['sheetTitle']) : $sKey),
+                                               'description' => ($sheetCfg['ROOT']['TCEforms']['sheetDescription'] ? $this->sL($sheetCfg['ROOT']['TCEforms']['sheetDescription']) : ''),
+                                               'linkTitle' => ($sheetCfg['ROOT']['TCEforms']['sheetShortDescr'] ? $this->sL($sheetCfg['ROOT']['TCEforms']['sheetShortDescr']) : ''),
+                                               'content' => $sheetContent
+                                       );
+                               }
+
+                               if (is_array($dataStructArray['sheets']))       {
+                                       $item.= $this->getDynTabMenu($tabParts,'TCEFORMS:flexform:'.$PA['itemFormElName']);
+                               } else {
+                                       $item.= $sheetContent;
+                               }
                        }
                } else $item='Data Structure ERROR: '.$dataStructArray;
 
@@ -1886,7 +1984,7 @@ class t3lib_TCEforms      {
         */
        function getSingleField_typeFlex_sheetMenu($sArr,$elName,$sheetKey)     {
 
-               $tCells=array();
+               $tCells =array();
                $pct = round(100/count($sArr));
                foreach($sArr as $sKey => $sheetCfg)    {
                        $onClick = 'if (confirm('.$GLOBALS['LANG']->JScharCode($this->getLL('m_onChangeAlert')).') && TBE_EDITOR_checkSubmit(-1)){'.$this->elName($elName).".value='".$sKey."'; TBE_EDITOR_submitForm()};";
@@ -2328,6 +2426,113 @@ class t3lib_TCEforms    {
 
 
 
+       /************************************************************
+        *
+        * Display of localized content etc.
+        *
+        ************************************************************/
+
+       /**
+        * Will register data from original language records if the current record is a translation of another.
+        * The original data is shown with the edited record in the form. The information also includes possibly diff-views of what changed in the original record.
+        * Function called from outside (see alt_doc.php + quick edit) before rendering a form for a record
+        *
+        * @param       string          Table name of the record being edited
+        * @param       array           Record array of the record being edited
+        * @return      void
+        */
+       function registerDefaultLanguageData($table,$rec)       {
+               global $TCA;
+
+                       // Add default language:
+               if ($TCA[$table]['ctrl']['languageField']
+                               && $rec[$TCA[$table]['ctrl']['languageField']] > 0
+                               && $TCA[$table]['ctrl']['transOrigPointerField']
+                               && intval($rec[$TCA[$table]['ctrl']['transOrigPointerField']]) > 0)     {
+
+                       $lookUpTable = $TCA[$table]['ctrl']['transOrigPointerTable'] ? $TCA[$table]['ctrl']['transOrigPointerTable'] : $table;
+
+                               // Get data formatted:
+                       $this->defaultLanguageData[$table.':'.$rec['uid']] = t3lib_BEfunc::getRecord($lookUpTable, intval($rec[$TCA[$table]['ctrl']['transOrigPointerField']]));
+
+                               // Get data for diff:
+                       if ($TCA[$table]['ctrl']['transOrigDiffSourceField'])   {
+                               $this->defaultLanguageData_diff[$table.':'.$rec['uid']] = unserialize($rec[$TCA[$table]['ctrl']['transOrigDiffSourceField']]);
+                       }
+               }
+       }
+
+       /**
+        * Renders the display of default language record content around current field.
+        * Will render content if any is found in the internal array, $this->defaultLanguageData, depending on registerDefaultLanguageData() being called prior to this.
+        *
+        * @param       string          Table name of the record being edited
+        * @param       string          Field name represented by $item
+        * @param       array           Record array of the record being edited
+        * @param       string          HTML of the form field. This is what we add the content to.
+        * @return      string          Item string returned again, possibly with the original value added to.
+        * @see getSingleField(), registerDefaultLanguageData()
+        */
+       function renderDefaultLanguageContent($table,$field,$row,$item) {
+               if (is_array($this->defaultLanguageData[$table.':'.$row['uid']]))       {
+                       $dLVal = t3lib_BEfunc::getProcessedValue($table,$field,$this->defaultLanguageData[$table.':'.$row['uid']][$field],0,1);
+
+                       if (strcmp($dLVal,''))  {
+                               $item.='<div class="typo3-TCEforms-originalLanguageValue">'.nl2br(htmlspecialchars($dLVal)).'&nbsp;</div>';
+                       }
+               }
+
+               return $item;
+       }
+
+       /**
+        * Renders the diff-view of default language record content compared with what the record was originally translated from.
+        * Will render content if any is found in the internal array, $this->defaultLanguageData, depending on registerDefaultLanguageData() being called prior to this.
+        *
+        * @param       string          Table name of the record being edited
+        * @param       string          Field name represented by $item
+        * @param       array           Record array of the record being edited
+        * @param       string          HTML of the form field. This is what we add the content to.
+        * @return      string          Item string returned again, possibly with the original value added to.
+        * @see getSingleField(), registerDefaultLanguageData()
+        */
+       function renderDefaultLanguageDiff($table,$field,$row,$item)    {
+               if (is_array($this->defaultLanguageData_diff[$table.':'.$row['uid']]))  {
+
+                               // Initialize:
+                       $dLVal = array(
+                               'old' => $this->defaultLanguageData_diff[$table.':'.$row['uid']],
+                               'new' => $this->defaultLanguageData[$table.':'.$row['uid']],
+                       );
+
+                       if (isset($dLVal['old'][$field]))       {       // There must be diff-data:
+                               if (strcmp($dLVal['old'][$field],$dLVal['new'][$field]))        {
+
+                                               // Create diff-result:
+                                       $t3lib_diff_Obj = t3lib_div::makeInstance('t3lib_diff');
+                                       $diffres = $t3lib_diff_Obj->makeDiffDisplay(
+                                               t3lib_BEfunc::getProcessedValue($table,$field,$dLVal['old'][$field],0,1),
+                                               t3lib_BEfunc::getProcessedValue($table,$field,$dLVal['new'][$field],0,1)
+                                       );
+
+                                       $item.='<div class="typo3-TCEforms-diffBox">'.
+                                               '<div class="typo3-TCEforms-diffBox-header">'.htmlspecialchars($this->getLL('l_changeInOrig')).':</div>'.
+                                               $diffres.
+                                       '</div>';
+                               }
+                       }
+               }
+
+               return $item;
+       }
+
+
+
+
+
+
+
+
 
        /************************************************************
         *
@@ -3019,6 +3224,28 @@ class t3lib_TCEforms     {
                return $out;
        }
 
+       /**
+        * Create tab menu
+        *
+        * @param       array   Parts for the tab menu, fed to template::getDynTabMenu()
+        * @param       string  ID string for the tab menu
+        * @return      string  HTML for the menu
+        */
+       function getDynTabMenu($parts, $idString) {
+               if (is_object($GLOBALS['TBE_TEMPLATE']))        {
+                       return $GLOBALS['TBE_TEMPLATE']->getDynTabMenu($parts, $idString);
+               } else {
+                       $output = '';
+                       foreach($parts as $singlePad)   {
+                               $output.='
+                               <h3>'.htmlspecialchars($singlePad['label']).'</h3>
+                               '.($singlePad['description'] ? '<p class="c-descr">'.nl2br(htmlspecialchars($singlePad['description'])).'</p>' : '').'
+                               '.$singlePad['content'];
+                       }
+
+                       return '<div class="typo3-dyntabmenu-divs">'.$output.'</div>';
+               }
+       }
 
 
 
index 44e25c2..e948f52 100755 (executable)
@@ -615,7 +615,11 @@ class t3lib_TCEmain        {
        function fillInFieldArray($table,$id,$fieldArray,$incomingFieldArray,$realPid,$status,$tscPID)  {
                global $TCA;
 
+                       // Initialize:
                t3lib_div::loadTCA($table);
+               unset($originalLanguageRecord);
+               unset($originalLanguage_diffStorage);
+               $diffStorageFlag = FALSE;
 
                        // Setting 'currentRecord' and 'checkValueRecord':
                if (strstr($id,'NEW'))  {
@@ -628,6 +632,19 @@ class t3lib_TCEmain        {
                        }
                } else {
                        $currentRecord = $checkValueRecord = $this->recordInfo($table,$id,'*'); // We must use the current values as basis for this!
+
+                               // Get original language record if available:
+                       if (is_array($currentRecord)
+                                       && $TCA[$table]['ctrl']['transOrigDiffSourceField']
+                                       && $TCA[$table]['ctrl']['languageField']
+                                       && $currentRecord[$TCA[$table]['ctrl']['languageField']] > 0
+                                       && $TCA[$table]['ctrl']['transOrigPointerField']
+                                       && intval($currentRecord[$TCA[$table]['ctrl']['transOrigPointerField']]) > 0)   {
+
+                               $lookUpTable = $TCA[$table]['ctrl']['transOrigPointerTable'] ? $TCA[$table]['ctrl']['transOrigPointerTable'] : $table;
+                               $originalLanguageRecord = $this->recordInfo($lookUpTable,$currentRecord[$TCA[$table]['ctrl']['transOrigPointerField']],'*');
+                               $originalLanguage_diffStorage = unserialize($currentRecord[$TCA[$table]['ctrl']['transOrigDiffSourceField']]);
+                       }
                }
                $this->checkValue_currentRecord = $checkValueRecord;
 
@@ -688,14 +705,27 @@ class t3lib_TCEmain       {
                                                                $res = $this->checkValue($table,$field,$fieldValue,$id,$status,$realPid,$tscPID);
                                                                if (isset($res['value']))       {
                                                                        $fieldArray[$field]=$res['value'];
+
+                                                                               // Add the value of the original record to the diff-storage content:
+                                                                       if ($TCA[$table]['ctrl']['transOrigDiffSourceField'])   {
+                                                                               $originalLanguage_diffStorage[$field] = $originalLanguageRecord[$field];
+                                                                               $diffStorageFlag = TRUE;
+                                                                       }
                                                                }
                                                        }
+
+
                                                break;
                                        }
                                }       // Checking language.
                        }       // Check exclude fields / disabled fields...
                }
 
+                       // Add diff-storage information:
+               if ($diffStorageFlag && !isset($fieldArray[$TCA[$table]['ctrl']['transOrigDiffSourceField']]))  {       // If the field is set it would probably be because of an undo-operation - in which case we should not update the field of course...
+                        $fieldArray[$TCA[$table]['ctrl']['transOrigDiffSourceField']] = serialize($originalLanguage_diffStorage);
+               }
+
                        // Checking for RTE-transformations of fields:
                $types_fieldConfig = t3lib_BEfunc::getTCAtypes($table,$currentRecord);
                $theTypeString = t3lib_BEfunc::getTCAtypeValue($table,$currentRecord);
@@ -2509,10 +2539,9 @@ class t3lib_TCEmain      {
                                $this->log($table,$id,2,0,1,"Attempt to modify table '%s' without permission",1,array($table));
                        }
                        if (isset($TCA[$table]) && !$this->tableReadOnly($table) && is_array($this->cmdmap[$table]) && $modifyAccessList)       {                       // Is table from $TCA and
-#debug();
-                               reset ($this->cmdmap[$table]);
-                               while (list($id,$incomingCmdArray) = each($this->cmdmap[$table]))       {                       // Har fundet en tabel
-                                       if (is_array($incomingCmdArray))        {       // Har fundet et ID-nummer
+
+                               foreach($this->cmdmap[$table] as $id => $incomingCmdArray)      {
+                                       if (is_array($incomingCmdArray))        {       // have found a command.
                                                reset($incomingCmdArray);
                                                $command = key($incomingCmdArray);
                                                $value = current($incomingCmdArray);
@@ -2526,11 +2555,14 @@ class t3lib_TCEmain     {
                                                                        $this->copyPages($id,$value);
                                                                } else {
                                                                        $this->copyRecord($table,$id,$value,1);
-#debug(array($table,$id,$value));
                                                                }
                                                                        // Merging the copy-array info together for remapping purposes.
                                                                $this->copyMappingArray_merged= t3lib_div::array_merge_recursive_overrule($this->copyMappingArray_merged,$this->copyMappingArray);
                                                        break;
+                                                       case 'localize':
+                                                               $this->copyMappingArray = Array();
+                                                               $this->copyRecord_localize($table,$id,$value);
+                                                       break;
                                                        case 'delete':
                                                                if ($table == 'pages')  {
                                                                        $this->deletePages($id);
@@ -2685,23 +2717,23 @@ class t3lib_TCEmain     {
        /**
         * Copying records
         *
-        * $destPid: >=0 then it points to a page-id on which to insert the record (as the first element). <0 then it points to a uid from its own table after which to insert it (works if
-        * $first is a flag set, if the record copied is NOT a 'slave' to another record copied. That is, if this record was asked to be copied in the cmd-array
-        *
-        * @param       [type]          $table: ...
-        * @param       [type]          $uid: ...
-        * @param       [type]          $destPid: ...
-        * @param       [type]          $first: ...
-        * @return      [type]          ...
+        * @param       string          Element table
+        * @param       integer         Element UID
+        * @param       integer         $destPid: >=0 then it points to a page-id on which to insert the record (as the first element). <0 then it points to a uid from its own table after which to insert it (works if
+        * @param       boolean         $first is a flag set, if the record copied is NOT a 'slave' to another record copied. That is, if this record was asked to be copied in the cmd-array
+        * @param       array           Associative array with field/value pairs to override directly. Notice; Fields must exist in the table record and NOT be among excluded fields!
+        * @param       string          Commalist of fields to exclude from the copy process (might get default values)
+        * @return      void
         */
-       function copyRecord($table,$uid,$destPid,$first=0)      {
+       function copyRecord($table,$uid,$destPid,$first=0,$overrideValues=array(),$excludeFields='')    {
                global $TCA;
+
                $uid = intval($uid);
                if ($TCA[$table] && $uid)       {
                        t3lib_div::loadTCA($table);
                        if ($this->doesRecordExist($table,$uid,'show')) {
                                $data = Array();
-                               $nonFields = explode(',','uid,perms_userid,perms_groupid,perms_user,perms_group,perms_everybody');
+                               $nonFields = array_unique(t3lib_div::trimExplode(',','uid,perms_userid,perms_groupid,perms_user,perms_group,perms_everybody,'.$excludeFields,1));
                                $row = $this->recordInfo($table,$uid,'*');
                                if (is_array($row))     {
                                        $theNewID = uniqid('NEW');
@@ -2710,21 +2742,21 @@ class t3lib_TCEmain     {
                                        $headerField = $TCA[$table]['ctrl']['label'];
                                        $defaultData = $this->newFieldArray($table);
 
-                                       $tscPID=t3lib_BEfunc::getTSconfig_pidValue($table,$uid,$destPid);       // NOT using t3lib_BEfunc::getTSCpid() because we need the real pid - not the id of a page, if the input is a page...
+                                       $tscPID = t3lib_BEfunc::getTSconfig_pidValue($table,$uid,$destPid);     // NOT using t3lib_BEfunc::getTSCpid() because we need the real pid - not the id of a page, if the input is a page...
                                        $TSConfig = $this->getTCEMAIN_TSconfig($tscPID);
                                        $tE = $this->getTableEntries($table,$TSConfig);
 //debug(array($table,$destPid,$TSConfig));
 
-                                       reset($row);
-                                       while (list($field,$value)=each($row))  {
+                                       foreach($row as $field => $value)       {
                                                if (!in_array($field,$nonFields))       {
                                                        $conf = $TCA[$table]['columns'][$field]['config'];
 
                                                        if ($field=='pid')      {
                                                                $value = $destPid;
                                                        }
-
-                                                       if ($TCA[$table]['ctrl']['setToDefaultOnCopy'] && t3lib_div::inList($TCA[$table]['ctrl']['setToDefaultOnCopy'],$field)) {
+                                                       if (isset($overrideValues[$field]))     {
+                                                               $value = $overrideValues[$field];
+                                                       } elseif ($TCA[$table]['ctrl']['setToDefaultOnCopy'] && t3lib_div::inList($TCA[$table]['ctrl']['setToDefaultOnCopy'],$field))   {
                                                                $value = $defaultData[$field];
                                                        } else {
                                                                if ($first && $field==$enableField && $TCA[$table]['ctrl']['hideAtCopy'] && !$this->neverHideAtCopy && !$tE['disableHideAtCopy'])       {
@@ -2782,6 +2814,14 @@ class t3lib_TCEmain      {
                                                // Added 02-05-02 to set the fields correctly for copied records...
                                        if ($destPid<0 && is_array($data[$table][$theNewID]))   {
                                                $copyAfterFields = $this->fixCopyAfterDuplFields($table,$uid,abs($destPid),0);
+
+                                                       // Remove all copy-after fields that should be overridden or simply excluded (important for the "localize" action:
+                                               foreach($copyAfterFields as $cAFN => $cAFV)     {
+                                                       if (in_array($cAFN,$nonFields) || isset($overrideValues[$cAFN]))        {
+                                                               unset($copyAfterFields[$cAFN]);
+                                                       }
+                                               }
+
                                                $data[$table][$theNewID] = array_merge($data[$table][$theNewID],$copyAfterFields);
 //debug($data[$table][$theNewID]);
                                        }       // origDestPid is retrieve before it may possibly be converted to resolvePid if the table is not sorted anyway. In this way, copying records to after another records which are not sorted still lets you use this function in order to copy fields from the one before.
@@ -2806,12 +2846,64 @@ class t3lib_TCEmain     {
                                        }
                                        $this->cachedTSconfig = $copyTCE->cachedTSconfig;       // Copy back the cached TSconfig
                                        unset($copyTCE);
-                               } else {
-                                       $this->log($table,$uid,3,0,1,'Attempt to copy record that did not exist!');
-                               }
-                       } else {
-                               $this->log($table,$uid,3,0,1,'Attempt to copy record without permission');
-                       }
+                               } else $this->log($table,$uid,3,0,1,'Attempt to copy record that did not exist!');
+                       } else $this->log($table,$uid,3,0,1,'Attempt to copy record without permission');
+               }
+       }
+
+       /**
+        * Localizes a record to another system language
+        *
+        * @param       string          Table name
+        * @param       integer         Record uid (to be localized)
+        * @param       integer         Language ID (from sys_language table)
+        * @return
+        */
+       function copyRecord_localize($table,$uid,$language)     {
+               global $TCA;
+
+               $uid = intval($uid);
+
+               if ($TCA[$table] && $uid)       {
+                       t3lib_div::loadTCA($table);
+
+                       if ($TCA[$table]['ctrl']['languageField'] && $TCA[$table]['ctrl']['transOrigPointerField'])     {
+                               if ($langRec = t3lib_BEfunc::getRecord('sys_language',intval($language),'uid,title'))   {
+                                       if ($this->doesRecordExist($table,$uid,'show')) {
+
+                                               $row = $this->recordInfo($table,$uid,'*');
+                                               if (is_array($row))     {
+                                                       if ($row[$TCA[$table]['ctrl']['languageField']] == 0)   {
+                                                               if ($row[$TCA[$table]['ctrl']['transOrigPointerField']] == 0)   {
+                                                                       if (!t3lib_BEfunc::getRecordsByField($table,$TCA[$table]['ctrl']['transOrigPointerField'],$uid,'AND pid='.intval($row['pid']).' AND '.$TCA[$table]['ctrl']['languageField'].'='.$langRec['uid']))       {
+
+                                                                                       // Initialize:
+                                                                               $overrideValues = array();
+                                                                               $excludeFields = array();
+
+                                                                                       // Set override values:
+                                                                               $overrideValues[$TCA[$table]['ctrl']['languageField']] = $langRec['uid'];
+                                                                               $overrideValues[$TCA[$table]['ctrl']['transOrigPointerField']] = $uid;
+
+                                                                                       // Set exclude Fields:
+                                                                               foreach($TCA[$table]['columns'] as $fN => $fCfg)        {
+                                                                                       if ($fCfg['l10n_mode']=='prefixLangTitle')      {       // Check if we are just prefixing:
+                                                                                               if ($fCfg['config']['type']=='text' || $fCfg['config']['type']=='input')        {
+                                                                                                       $overrideValues[$fN] = '[Translate to '.$langRec['title'].':] '.$row[$fN];
+                                                                                               }
+                                                                                       } elseif (t3lib_div::inList('exclude,noCopy,mergeIfNotBlank',$fCfg['l10n_mode']) && $fN!=$TCA[$table]['ctrl']['languageField'] && $fN!=$TCA[$table]['ctrl']['transOrigPointerField']) {  // Otherwise, do not copy field (unless it is the language field or pointer to the original language)
+                                                                                               $excludeFields[] = $fN;
+                                                                                       }
+                                                                               }
+                                                                                       // Execute the copy:
+                                                                               $this->copyRecord($table,$uid,-$uid,1,$overrideValues,implode(',',$excludeFields));
+                                                                       } else $this->log($table,$uid,3,0,1,'Localization failed; There already was a localization for this language of the record!');
+                                                               } else $this->log($table,$uid,3,0,1,'Localization failed; Source record contained a reference to an original default record (which is strange)!');
+                                                       } else $this->log($table,$uid,3,0,1,'Localization failed; Source record had another language than "default" defined!');
+                                               } else $this->log($table,$uid,3,0,1,'Attempt to localize record that did not exist!');
+                                       } else $this->log($table,$uid,3,0,1,'Attempt to localize record without permission');
+                               } else $this->log($table,$uid,3,0,1,'Sys language UID "'.$language.'" not found valid!');
+                       } else $this->log($table,$uid,3,0,1,'Localization failed; "languageField" and "transOrigPointerField" must be defined for the table!');
                }
        }
 
index 4b161c2..e4953b9 100755 (executable)
@@ -237,6 +237,11 @@ class t3lib_transferData {
                        if ($table == 'pages')  {$this->prevPageID = $id;}
 
                        $this->regTableItems_data[$uniqueItemRef] = $this->renderRecordRaw($table, $id, $pid, $row, $TSconfig, $tscPID);
+
+                               // Merges the processed array on-top of the raw one - this is done because some things in TCEforms may need access to other fields than those in the columns configuration!
+                       if (is_array($row) && is_array($this->regTableItems_data[$uniqueItemRef]))      {
+                               $this->regTableItems_data[$uniqueItemRef] = array_merge($row, $this->regTableItems_data[$uniqueItemRef]);
+                       }
                }
        }
 
@@ -282,7 +287,7 @@ class t3lib_transferData {
                        $data = $this->renderRecord_SW($data,$fieldConfig,$TSconfig,$table,$row,$field);
 
                                // Set the field in the accumulation array IF the $data variabel is set:
-                       $totalRecordContent[$field]=isset($data)?$data:'';
+                       $totalRecordContent[$field] = isset($data) ? $data : '';
                }
 
                        // Further processing may apply for each field in the record depending on the settings in the "types" configuration (the list of fields to currently display for a record in TCEforms).
index 0746e59..449ff0f 100755 (executable)
@@ -71,6 +71,7 @@ $TYPO3_CONF_VARS = Array(
                't3lib_cs_convMethod' => '',                    // String (values: "iconv", "recode", "mbstring", default is homemade PHP-code). Defines which of these PHP-features to use for various Charset conversing functions in t3lib_cs. Will speed up charset conversion radically.
                't3lib_cs_utils' => '',                                 // String (values: "iconv", "recode", "mbstring", default is homemade PHP-code). Defines which of these PHP-features to use for various Charset processing functions in t3lib_cs. Will speed up charset functions radically.
                '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. 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.
        ),
        'EXT' => Array (        // Options related to the Extension Management
                'noEdit' => 1,                                                  // Boolean: If set, the Extension Manager does NOT allow extension files to be edited! (Otherwise both local and global extensions can be edited.)
@@ -144,6 +145,7 @@ $TYPO3_CONF_VARS = Array(
                'XLLfile' => Array(),                                   // For extension/overriding of the arrays in 'locallang' files in the backend. See 'Inside TYPO3' for more information.
                'notificationPrefix' => '[TYPO3 Note]',
                'accessListRenderMode' => 'singlebox',  // Can be "singlebox", "checkbox" or blank. Refers to the "renderMode" for the selector boxes in be-groups configuration.
+               'explicitADmode' => 'explicitDeny',     // Sets the general allow/deny mode for selector box values. Value can be either "explicitAllow" or "explicitDeny", nothing else!
        ),
        'FE' => Array(                  // Configuration for the TypoScript frontend (FE). Nothing here relates to the administration backend!
                'png_to_gif' => 0,                                              // Boolean. Enables conversion back to gif of all png-files generated in the frontend libraries. Notice that this leaves an increased number of temporary files in typo3temp/
index e9148f9..32b077a 100755 (executable)
@@ -414,7 +414,7 @@ class SC_alt_doc {
                                return false;
                        }
                '.(isset($HTTP_POST_VARS['_savedokview_x']) && $this->popViewId ? t3lib_BEfunc::viewOnClick($this->popViewId,'',t3lib_BEfunc::BEgetRootLine($this->popViewId),'',$this->viewUrl) : '')
-               );
+               ).$this->doc->getDynTabMenuJScode();
 
                        // Setting up the context sensitive menu:
                $CMparts = $this->doc->getContextMenuCode();
@@ -446,6 +446,7 @@ class SC_alt_doc {
                        $this->tceforms->palettesCollapsed = !$this->MOD_SETTINGS['showPalettes'];
                        $this->tceforms->disableRTE = $this->MOD_SETTINGS['disableRTE'];
                        $this->tceforms->enableClickMenu = TRUE;
+                       $this->tceforms->enableTabMenu = TRUE;
 
                                // Clipboard is initialized:
                        $this->tceforms->clipObj = t3lib_div::makeInstance('t3lib_clipboard');          // Start clipboard
@@ -648,6 +649,9 @@ class SC_alt_doc {
                                                                                $this->tceforms->hiddenFieldListArr = array_keys($this->overrideVals[$table]);
                                                                        }
 
+                                                                               // Register default language labels, if any:
+                                                                       $this->tceforms->registerDefaultLanguageData($table,$rec);
+
                                                                                // Create form for the record (either specific list of fields or the whole record):
                                                                        $panel = '';
                                                                        if ($this->columnsOnly) {
index 36d9abe..86dc0dc 100755 (executable)
@@ -351,6 +351,9 @@ class SC_alt_main {
        var condensedMode = '.($BE_USER->uc['condensedMode']?1:0).';
        var currentSubScript = "";
        var currentSubNavScript = "";
+
+               // Used for tab-panels:
+       var DTM_currentTabs = new Array();
                ';
 
                        // Check editing of page:
index b785cc3..90b2840 100755 (executable)
@@ -704,7 +704,7 @@ class recordHistory {
         * @access private
         */
        function renderEntry($entry,$table)     {
-               global $SOBE, $LANG;
+               global $SOBE, $LANG, $TCA;
 
                $lines=array();
                if (is_array($entry['newRecord']))      {
@@ -713,42 +713,44 @@ class recordHistory {
 
                        $fieldsToDisplay = array_keys($entry['newRecord']);
                        foreach($fieldsToDisplay as $fN)        {
+                               if (is_array($TCA[$table]['columns'][$fN]) && $TCA[$table]['columns'][$fN]['config']['type']!='passthrough')    {
 
-                                       // Create diff-result:
-                               $diffres = $t3lib_diff_Obj->makeDiffDisplay(
-                                       t3lib_BEfunc::getProcessedValue($table,$fN,$entry['oldRecord'][$fN],0,1),
-                                       t3lib_BEfunc::getProcessedValue($table,$fN,$entry['newRecord'][$fN],0,1)
-                               );
+                                               // Create diff-result:
+                                       $diffres = $t3lib_diff_Obj->makeDiffDisplay(
+                                               t3lib_BEfunc::getProcessedValue($table,$fN,$entry['oldRecord'][$fN],0,1),
+                                               t3lib_BEfunc::getProcessedValue($table,$fN,$entry['newRecord'][$fN],0,1)
+                                       );
 
-                                       // Depending on list type, we make the row:
-                               switch($this->listType) {
-                                       case 1:
-                                               $lines[]='
-                                                       <tr class="bgColor4">
-                                                               <td><em>'.$LANG->sl(t3lib_BEfunc::getItemLabel($table,$fN),1).'</em></td>
-                                                               <td>'.nl2br($diffres).'</td>
-                                                               <td>&nbsp;</td>
-                                                       </tr>';
-                                       break;
-                                       case 2:
-                                               $lines[]='
-                                                       <tr class="bgColor4">
-                                                               <td><em>'.$LANG->sl(t3lib_BEfunc::getItemLabel($table,$fN)).'</em></td>
-                                                               <td>'.htmlspecialchars(t3lib_BEfunc::getProcessedValue($table,$fN,$entry['oldRecord'][$fN])).'</td>
-                                                               <td>'.$this->linkPage('<img'.t3lib_iconWorks::skinImg('','gfx/history.gif','width="13" height="12"').' title="'.$LANG->getLL('revertField',1).'" alt="" />', array('revert'=>'field:'.$fN)).'</td>
-                                                               <td>'.htmlspecialchars(t3lib_BEfunc::getProcessedValue($table,$fN,$entry['newRecord'][$fN])).'</td>
-                                                               <td>'.nl2br($diffres).'</td>
-                                                       </tr>';
-                                       break;
-                                       default:
-                                               $lines[]='
-                                                       <tr class="bgColor4">
-                                                               <td><em>'.$LANG->sl(t3lib_BEfunc::getItemLabel($table,$fN)).'</em></td>
-                                                               <td>'.htmlspecialchars(t3lib_BEfunc::getProcessedValue($table,$fN,$entry['oldRecord'][$fN])).'</td>
-                                                               <td>'.htmlspecialchars(t3lib_BEfunc::getProcessedValue($table,$fN,$entry['newRecord'][$fN])).'</td>
-                                                               <td>'.nl2br($diffres).'</td>
-                                                       </tr>';
-                                       break;
+                                               // Depending on list type, we make the row:
+                                       switch($this->listType) {
+                                               case 1:
+                                                       $lines[]='
+                                                               <tr class="bgColor4">
+                                                                       <td><em>'.$LANG->sl(t3lib_BEfunc::getItemLabel($table,$fN),1).'</em></td>
+                                                                       <td>'.nl2br($diffres).'</td>
+                                                                       <td>&nbsp;</td>
+                                                               </tr>';
+                                               break;
+                                               case 2:
+                                                       $lines[]='
+                                                               <tr class="bgColor4">
+                                                                       <td><em>'.$LANG->sl(t3lib_BEfunc::getItemLabel($table,$fN)).'</em></td>
+                                                                       <td>'.htmlspecialchars(t3lib_BEfunc::getProcessedValue($table,$fN,$entry['oldRecord'][$fN])).'</td>
+                                                                       <td>'.$this->linkPage('<img'.t3lib_iconWorks::skinImg('','gfx/history.gif','width="13" height="12"').' title="'.$LANG->getLL('revertField',1).'" alt="" />', array('revert'=>'field:'.$fN)).'</td>
+                                                                       <td>'.htmlspecialchars(t3lib_BEfunc::getProcessedValue($table,$fN,$entry['newRecord'][$fN])).'</td>
+                                                                       <td>'.nl2br($diffres).'</td>
+                                                               </tr>';
+                                               break;
+                                               default:
+                                                       $lines[]='
+                                                               <tr class="bgColor4">
+                                                                       <td><em>'.$LANG->sl(t3lib_BEfunc::getItemLabel($table,$fN)).'</em></td>
+                                                                       <td>'.htmlspecialchars(t3lib_BEfunc::getProcessedValue($table,$fN,$entry['oldRecord'][$fN])).'</td>
+                                                                       <td>'.htmlspecialchars(t3lib_BEfunc::getProcessedValue($table,$fN,$entry['newRecord'][$fN])).'</td>
+                                                                       <td>'.nl2br($diffres).'</td>
+                                                               </tr>';
+                                               break;
+                                       }
                                }
                        }
                }
index 87ab5cb..439603c 100755 (executable)
@@ -440,6 +440,8 @@ class SC_index {
                                        }
                                ');
                        }
+               } elseif(!$BE_USER->user['uid'] && $this->commandLI) {
+                       sleep(5);
                }
        }
 
index 20fa822..b55faef 100755 (executable)
@@ -240,7 +240,7 @@ if ($GLOBALS['TYPO3_DB']->sql_pconnect(TYPO3_db_host, TYPO3_db_username, TYPO3_d
 // *******************************
 // Checks for proper browser
 // *******************************
-if (!$CLIENT['BROWSER'])       {
+if (!$CLIENT['BROWSER'] && !(defined('TYPO3_cliMode') && TYPO3_cliMode))       {
        t3lib_BEfunc::typo3PrintError ('Browser error','You must use 4+ browsers with TYPO3!',0);
        exit;
 }
@@ -272,6 +272,7 @@ $BE_USER = t3lib_div::makeInstance('t3lib_beUserAuth');     // New backend user obje
 $BE_USER->warningEmail = $TYPO3_CONF_VARS['BE']['warning_email_addr'];
 $BE_USER->OS = TYPO3_OS;
 $BE_USER->start();                     // Object is initialized
+$BE_USER->checkCLIuser();
 $BE_USER->backendCheckLogin(); // Checking if there's a user logged in
 $BE_USER->trackBeUser($TYPO3_CONF_VARS['BE']['trackBeUser']);  // Tracking backend user script hits
 
@@ -279,6 +280,22 @@ $BE_USER->trackBeUser($TYPO3_CONF_VARS['BE']['trackBeUser']);      // Tracking backen
 $WEBMOUNTS = $BE_USER->returnWebmounts();              // ! WILL INCLUDE deleted mount pages as well!
 $FILEMOUNTS = $BE_USER->returnFilemounts();
 
+
+// ****************
+// CLI processing
+// ****************
+if (defined('TYPO3_cliMode') && TYPO3_cliMode) {
+               // Status output:
+       if (!strcmp($_SERVER['argv'][1],'status'))      {
+               echo "Status of TYPO3 CLI script:\n\n";
+               echo "Username [uid]: ".$BE_USER->user['username']." [".$BE_USER->user['uid']."]\n";
+               echo "Database: ".TYPO3_db."\n";
+               echo "PATH_site: ".PATH_site."\n";
+               echo "\n";
+               exit;
+       }
+}
+
 // ****************
 // compression
 // ****************
index d2cead9..af96b46 100755 (executable)
@@ -305,7 +305,7 @@ class SC_show_item {
                $imgObj = t3lib_div::makeInstance('t3lib_stdGraphic');
                $imgObj->init();
                $imgObj->mayScaleUp = 0;
-               $imgObj->tempPath = PATH_site.$imgObj->tempPath;
+               $imgObj->absPrefix = PATH_site;
 
                        // Read Image Dimensions (returns false if file was not an image type, otherwise dimensions in an array)
                $imgInfo = '';
@@ -336,6 +336,7 @@ class SC_show_item {
 
                        // If the file was an image...:
                if (is_array($imgInfo)) {
+
                        $imgInfo = $imgObj->imageMagickConvert($this->file,'web','346','200m','','','',1);
                        $imgInfo[3] = '../'.substr($imgInfo[3],strlen(PATH_site));
                        $code = '<br />
index 50f75b1..898906f 100755 (executable)
@@ -184,6 +184,23 @@ TABLE#typo3-tabmenu TD A { color:grey; text-decoration:none; display: block; wid
 TABLE#typo3-tabmenu TD.tabact A { color:#000; padding-left:10px; padding-right:10px; }
 TABLE#typo3-tabmenu TD A:hover { color:#000; background: #f6eab7; text-decoration:none; }
 
+/* Dynamic Tab menu (template.php) */
+DIV.typo3-dyntabmenu-tabs { margin-top: 5px; padding-right: 20px; }
+DIV.typo3-dyntabmenu-divs P.c-descr { font-style : italic; padding: 3px 10px 5px 10px; background: #e7dba8;  }
+TABLE.typo3-dyntabmenu TD.tabact { color: #000; border: solid black 1px; background: #e7dba8; }
+TABLE.typo3-dyntabmenu TD.tab { color:grey; border: solid #555 1px;  background: #c4d4cd; }
+TABLE.typo3-dyntabmenu TD.disabled { color:#999999; border: solid #555 1px;  background: #cccccc; padding-left: 5px; }
+TABLE.typo3-dyntabmenu TD.tab, TABLE.typo3-dyntabmenu TD.tabact, TABLE.typo3-dyntabmenu TD.disabled { border-radius: 3px; -moz-border-radius: 3px; border-bottom: 0px; }
+TABLE.typo3-dyntabmenu TD A { color:grey; text-decoration:none; display: block; width:100%; padding:2px; padding-left:5px; padding-right:5px; }
+TABLE.typo3-dyntabmenu TD.tabact A { color:#000; padding-left:10px; padding-right:10px; }
+TABLE.typo3-dyntabmenu TD A:hover { color:#000; background: #f6eab7; text-decoration:none; }
+DIV.typo3-dyntabmenu-divs-foldout DIV.c-tablayer {margin-left: 20px;}
+DIV.typo3-dyntabmenu-divs-foldout DIV.tab { background: #c4d4cd;  background-image: url(gfx/ol/plusonly.gif); background-repeat: no-repeat; border: solid black 1px; }
+DIV.typo3-dyntabmenu-divs-foldout DIV.tabact {  background: #e7dba8; background-image: url(gfx/ol/minusonly.gif); background-repeat: no-repeat; border: solid black 1px;  margin-top: 5px; }
+DIV.typo3-dyntabmenu-divs-foldout DIV.disabled { color:#999999; border: solid black 1px; background: #cccccc;  padding: 2px 2px 2px 22px; }
+DIV.typo3-dyntabmenu-divs-foldout DIV.tab A, DIV.typo3-dyntabmenu-divs-foldout DIV.tabact A { text-decoration:none; display: block; padding: 2px 2px 2px 22px; }
+
+
 /* Logo frame (alt_toplogo.php) */
 BODY#typo3-alt-toplogo-php {margin: 0px 0px 0px 0px;}
 
@@ -237,6 +254,9 @@ TABLE.typo3-TCEforms TABLE.typo3-TCEforms-select-checkbox TR TD.c-labelCell P.c-
 TABLE.typo3-TCEforms TABLE.typo3-TCEforms-select-checkbox TR.c-header TD { font-weight: bold; padding-top: 10px; border-bottom: none; }
 TABLE.typo3-TCEforms TABLE.typo3-TCEforms-select-checkbox { margin-top: 4px; margin-bottom: 10px; }
 TABLE.typo3-TCEforms TABLE.typo3-TCEforms-select-singlebox { margin-top: 4px; margin-bottom: 10px; }
+TABLE.typo3-TCEforms DIV.typo3-TCEforms-originalLanguageValue { background-color: #bbccbb; }
+TABLE.typo3-TCEforms DIV.typo3-TCEforms-diffBox { background-color: white; border: 1px solid black; }
+TABLE.typo3-TCEforms DIV.typo3-TCEforms-diffBox-header { background-color: red; font-weight: bold; }
 
 /* Element Browser / RTE link selection: */
 TABLE#typo3-curUrl { font-weight: bold; width: 100%; margin-bottom: 2px;}
@@ -447,6 +467,8 @@ TABLE.warningbox TD { padding: 20px 20px 20px 20px; font-weight: bold; }
 IMG.absmiddle { vertical-align: middle; }
 .smallCheckboxes { width:12px; height:12px; margin:0 0 0 0; }
 .uppercase { text-transform : uppercase; }
+.tableheader TD { font-weight: bold; padding-left: 2px; padding-right: 2px; }
+.lrPadding TD { padding-left: 2px; padding-right: 2px; }
 
 /* Permissions, green and red */
 .perm-allowed {color: green; font-weight: bold;}
index 885cd42..fd591c9 100755 (executable)
@@ -500,6 +500,7 @@ $TCA['tt_content'] = Array (
                'copyAfterDuplFields' => 'colPos,sys_language_uid',
                'useColumnsForDefaultValues' => 'colPos,sys_language_uid',
                'transOrigPointerField' => 'l18n_parent',
+               'transOrigDiffSourceField' => 'l18n_diffsource',
                'languageField' => 'sys_language_uid',
                'enablecolumns' => Array (
                        'disabled' => 'hidden',
@@ -609,6 +610,9 @@ $TCA['pages_language_overlay'] = Array (
                        'starttime' => 'starttime',
                        'endtime' => 'endtime'
                ),
+               'transOrigPointerField' => 'pid',
+               'transOrigPointerTable' => 'pages',
+               'transOrigDiffSourceField' => 'l18n_diffsource',
                'languageField' => 'sys_language_uid',
                'mainpalette' => 1,
                'dynamicConfigFile' => t3lib_extMgm::extPath($_EXTKEY).'tbl_cms.php'
index dfb9a1b..d3d4266 100755 (executable)
@@ -184,6 +184,8 @@ CREATE TABLE pages_language_overlay (
   author tinytext NOT NULL,
   author_email varchar(80) DEFAULT '' NOT NULL,
   tx_impexp_origuid int(11) DEFAULT '0' NOT NULL,
+  l18n_diffsource mediumblob NOT NULL,
+
   PRIMARY KEY (uid),
   KEY parent (pid)
 );
@@ -330,6 +332,7 @@ CREATE TABLE tt_content (
   tx_impexp_origuid int(11) DEFAULT '0' NOT NULL,
   pi_flexform mediumtext NOT NULL,
   l18n_parent int(11) DEFAULT '0' NOT NULL,
+  l18n_diffsource mediumblob NOT NULL,
 
   PRIMARY KEY (uid),
   KEY parent (pid)
index 9717b3d..762fb38 100755 (executable)
@@ -126,6 +126,7 @@ class tx_cms_layout extends recordList {
        var $agePrefixes = ' min| hrs| days| yrs';      // Age prefixes for displaying times. May be set externally to localized values.
        var $externalTables = array();                  // Array of tables which is configured to be listed by the Web > Page module in addition to the default tables.
        var $descrTable;                                                // "Pseudo" Description -table name
+       var $defLangBinding=FALSE;                              // If set true, the language mode of tt_content elements will be rendered with hard binding between default language content elements and their translations!
 
                // External, static: Configuration of tt_content element display:
        var $tt_contentConfig = Array (
@@ -400,10 +401,11 @@ class tx_cms_layout extends recordList {
                                } else {
                                        $langList=implode(',',array_keys($this->tt_contentConfig['languageCols']));
                                }
-                               $languageColumn=array();
+                               $languageColumn = array();
                        }
                        $langListArr = explode(',',$langList);
-
+                       $defLanguageCount = array();
+                       $defLangBinding = array();
 
                                // For EACH languages... :
                        foreach($langListArr as $lP)    {       // If NOT languageMode, then we'll only be through this once.
@@ -414,6 +416,7 @@ class tx_cms_layout extends recordList {
 
                                        // For EACH column, render the content into a variable:
                                foreach($cList as $key) {
+                                       if (!$lP) $defLanguageCount[$key] = array();
 
                                                // Select content elements from this column/language:
                                        $queryParts = $this->makeQueryArray('tt_content', $id, 'AND colPos='.intval($key).$showHidden.$showLanguage);
@@ -424,21 +427,26 @@ class tx_cms_layout extends recordList {
                                                $onClick = "document.location='db_new_content_el.php?id=".$id.'&colPos='.intval($key).'&sys_language_uid='.$lP.'&uid_pid='.$id.'&returnUrl='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI'))."';";
                                                $theNewButton = $GLOBALS['SOBE']->doc->t3Button($onClick,$GLOBALS['LANG']->getLL('newPageContent'));
                                                $content[$key].= '<img src="clear.gif" width="1" height="5" alt="" /><br />'.$theNewButton;
-
-                                                       // Copy for language:
-                                       #       $onClick = "alert(123);";
-                                       #       $theNewButton = $GLOBALS['SOBE']->doc->t3Button($onClick,$GLOBALS['LANG']->getLL('newPageContent_copyForLang'));
-                                       #       $content[$key].= '<img src="clear.gif" width="1" height="5" alt="" /><br />'.$theNewButton;
                                        }
 
                                                // Traverse any selected elements and render their display code:
                                        $rowArr = $this->getResult($result);
+
                                        foreach($rowArr as $row)        {
+                                               $singleElementHTML = '';
+                                               if (!$lP) $defLanguageCount[$key][] = $row['uid'];
+
                                                $editUidList.= $row['uid'].',';
-                                               $content[$key].= $this->tt_content_drawHeader($row,$this->tt_contentConfig['showInfo']?15:5);
+                                               $singleElementHTML.= $this->tt_content_drawHeader($row,$this->tt_contentConfig['showInfo']?15:5);
 
                                                $isRTE = $RTE && $this->isRTEforField('tt_content',$row,'bodytext');
-                                               $content[$key].= $this->tt_content_drawItem($row,$isRTE);
+                                               $singleElementHTML.= $this->tt_content_drawItem($row,$isRTE);
+
+                                               if ($this->defLangBinding && $this->tt_contentConfig['languageMode'])   {
+                                                       $defLangBinding[$key][$lP][$row[($lP ? 'l18n_parent' : 'uid')]] = $singleElementHTML;
+                                               } else {
+                                                       $content[$key].= $singleElementHTML;
+                                               }
                                        }
 
                                                // Add new-icon link, header:
@@ -447,7 +455,6 @@ class tx_cms_layout extends recordList {
                                        $editUidList = '';
                                }
 
-
                                        // For EACH column, fit the rendered content into a table cell:
                                $out='';
                                foreach($cList as $k => $key)   {
@@ -465,7 +472,10 @@ class tx_cms_layout extends recordList {
 
                                                // Storing content for use if languageMode is set:
                                        if ($this->tt_contentConfig['languageMode'])    {
-                                               $languageColumn[$key][$lP] = $head[$key].$content[$key].'<br /><br />';
+                                               $languageColumn[$key][$lP] = $head[$key].$content[$key];
+                                               if (!$this->defLangBinding)     {
+                                                       $languageColumn[$key][$lP].='<br /><br />'.$this->newLanguageButton($this->getNonTranslatedTTcontentUids($defLanguageCount[$key],$id,$lP),$lP);
+                                               }
                                        }
                                }
 
@@ -536,6 +546,33 @@ class tx_cms_layout extends recordList {
                                                <td valign="top">'.implode('</td>'.$midSep.'
                                                <td valign="top">',$cCont).'</td>
                                        </tr>';
+
+                                       if ($this->defLangBinding)      {
+                                                       // "defLangBinding" mode
+                                               foreach($defLanguageCount[$cKey] as $defUid)    {
+                                                       $cCont=array();
+                                                       foreach($langListArr as $lP)    {
+                                                               $cCont[] = $defLangBinding[$cKey][$lP][$defUid].
+                                                                               '<br/>'.$this->newLanguageButton($this->getNonTranslatedTTcontentUids(array($defUid),$id,$lP),$lP);
+                                                       }
+                                                       $out.='
+                                                       <tr>
+                                                               <td valign="top">'.implode('</td>'.$midSep.'
+                                                               <td valign="top">',$cCont).'</td>
+                                                       </tr>';
+                                               }
+
+                                                       // Create spacer:
+                                               $cCont=array();
+                                               foreach($langListArr as $lP)    {
+                                                       $cCont[] = '&nbsp;';
+                                               }
+                                               $out.='
+                                               <tr>
+                                                       <td valign="top">'.implode('</td>'.$midSep.'
+                                                       <td valign="top">',$cCont).'</td>
+                                               </tr>';
+                                       }
                                }
 
                                        // Finally, wrap it all in a table and add the language selector on top of it:
@@ -1707,6 +1744,60 @@ class tx_cms_layout extends recordList {
        }
 
        /**
+        * Filters out all tt_content uids which are already translated so only non-translated uids is left.
+        * Selects across columns, but within in the same PID. Columns are expect to be the same for translations and original but this may be a conceptual error (?)
+        *
+        * @param       array           Numeric array with uids of tt_content elements in the default language
+        * @param       integer         Page pid
+        * @param       integer         Sys language UID
+        * @return      array           Modified $defLanguageCount
+        */
+       function getNonTranslatedTTcontentUids($defLanguageCount,$id,$lP)       {
+               if ($lP && count($defLanguageCount))    {
+
+                               // Select all translations here:
+                       $queryParts = $this->makeQueryArray('tt_content', $id, 'AND sys_language_uid='.intval($lP).' AND l18n_parent IN ('.implode(',',$defLanguageCount).')');
+                       $result = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts);
+
+                               // Flip uids:
+                       $defLanguageCount = array_flip($defLanguageCount);
+
+                               // Traverse any selected elements and unset original UID if any:
+                       $rowArr = $this->getResult($result);
+                       foreach($rowArr as $row)        {
+                               unset($defLanguageCount[$row['l18n_parent']]);
+                       }
+
+                               // Flip again:
+                       $defLanguageCount = array_keys($defLanguageCount);
+               }
+
+               return $defLanguageCount;
+       }
+
+       /**
+        * Creates button which is used to create copies of records..
+        *
+        * @param       array           Numeric array with uids of tt_content elements in the default language
+        * @param       integer         Sys language UID
+        * @return      string          "Copy languages" button, if available.
+        */
+       function newLanguageButton($defLanguageCount,$lP)       {
+               if (count($defLanguageCount) && $lP)    {
+
+                       $params = '';
+                       foreach($defLanguageCount as $uidVal)   {
+                               $params.='&cmd[tt_content]['.$uidVal.'][localize]='.$lP;
+                       }
+
+                               // Copy for language:
+                       $onClick = "document.location='".$GLOBALS['SOBE']->doc->issueCommand($params)."'; return false;";
+                       $theNewButton = $GLOBALS['SOBE']->doc->t3Button($onClick,$GLOBALS['LANG']->getLL('newPageContent_copyForLang').' ['.count($defLanguageCount).']');
+                       return $theNewButton;
+               }
+       }
+
+       /**
         * Returns an icon, which has its title attribute set to a massive amount of information about the element.
         *
         * @param       array           Array where values are human readable output of field values (not htmlspecialchars()'ed though). The values are imploded by a linebreak.
index a7bdd70..1d82357 100755 (executable)
@@ -883,6 +883,7 @@ class SC_db_layout {
                $dblist->nextThree = t3lib_div::intInRange($this->modTSconfig['properties']['editFieldsAtATime'],0,10);
                $dblist->option_showBigButtons = $this->modTSconfig['properties']['disableBigButtons'] ? 0 : 1;
                $dblist->option_newWizard = $this->modTSconfig['properties']['disableNewContentElementWizard'] ? 0 : 1;
+               $dblist->defLangBinding = $this->modTSconfig['properties']['defLangBinding'] ? 1 : 0;
                if (!$dblist->nextThree)        $dblist->nextThree = 1;
 
                $dblist->externalTables = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['cms']['db_layout']['addTables'];
index 308a160..182420d 100755 (executable)
@@ -561,6 +561,7 @@ $TCA['pages_language_overlay'] = Array (
                        )
                ),
                'tx_impexp_origuid' => Array('config'=>array('type'=>'passthrough')),
+               'l18n_diffsource' => Array('config'=>array('type'=>'passthrough')),
        ),
        'types' => Array (
                '0' => Array('showitem' => 'hidden;;;;1-1-1, sys_language_uid, title;;;;2-2-2, subtitle, nav_title, --div--, abstract;;5;;3-3-3, keywords, description, media;;;;4-4-4')
index 84c6d65..9aef8cc 100755 (executable)
@@ -67,7 +67,7 @@ $TCA['tt_content'] = Array (
                                        Array('LLL:EXT:cms/locallang_ttc.php:CType.I.17', 'html')
                                ),
                                'default' => 'text',
-                               'authMode' => 'explicitDeny',
+                               'authMode' => $GLOBALS['TYPO3_CONF_VARS']['BE']['explicitADmode'],
                                'authMode_enforce' => 'strict',
                        )
                ),
@@ -187,6 +187,7 @@ $TCA['tt_content'] = Array (
                        )
                ),
                'header' => Array (
+                       'l10n_mode' => 'prefixLangTitle',
                        'label' => 'LLL:EXT:cms/locallang_ttc.php:header',
                        'config' => Array (
                                'type' => 'input',
@@ -253,6 +254,7 @@ $TCA['tt_content'] = Array (
                        )
                ),
                'bodytext' => Array (
+                       'l10n_mode' => 'prefixLangTitle',
                        'label' => 'LLL:EXT:lang/locallang_general.php:LGL.text',
                        'config' => Array (
                                'type' => 'text',
@@ -664,7 +666,7 @@ $TCA['tt_content'] = Array (
                                        Array('','')
                                ),
                                'default' => '',
-                               'authMode' => 'explicitAllow',
+                               'authMode' => $GLOBALS['TYPO3_CONF_VARS']['BE']['explicitADmode'],
                        )
                ),
                'select_key' => Array (
@@ -910,6 +912,7 @@ $TCA['tt_content'] = Array (
                        )
                ),
                'tx_impexp_origuid' => Array('config'=>array('type'=>'passthrough')),
+               'l18n_diffsource' => Array('config'=>array('type'=>'passthrough')),
        ),
        'types' => Array (
                '1' =>  Array('showitem' => 'CType'),
index 8a56c5e..56e7c6b 100755 (executable)
        }
 
        /**
+        * Setting locale
+        *
+        * @return      void
+        */
+       function settingLocale()        {
+
+                       // Setting locale
+               if ($this->config['config']['locale_all'])      {
+                       # Change by Rene Fritz, 22/10 2002
+                       # there`s the problem that PHP parses float values in scripts wrong if the locale LC_NUMERIC is set to something with a komma as decimal point
+                       # this does not work in php 4.2.3
+                       #setlocale('LC_ALL',$this->config['config']['locale_all']);
+                       #setlocale('LC_NUMERIC','en_US');
+
+                       # so we set all except LC_NUMERIC
+                       setlocale(LC_COLLATE,$this->config['config']['locale_all']);
+                       setlocale(LC_CTYPE,$this->config['config']['locale_all']);
+                       setlocale(LC_MONETARY,$this->config['config']['locale_all']);
+                       setlocale(LC_TIME,$this->config['config']['locale_all']);
+
+                       $this->localeCharset = $this->csConvObj->get_locale_charset($this->config['config']['locale_all']);
+               }
+       }
+
+       /**
         * Checks if any email-submissions or submission via the fe_tce
         *
         * @return      string          'email' if a formmail has been send, 'fe_tce' if front-end data submission (like forums, guestbooks) is send. '' if none.
                        // Here we put some temporary stuff in the cache in order to let the first hit generate the page. The temporary cache will expire after a few seconds (typ. 30) or will be cleared by the rendered page, which will also clear and rewrite the cache.
                $this->tempPageCacheContent();
 
-                       // Setting locale
-               if ($this->config['config']['locale_all'])      {
-                       # Change by Rene Fritz, 22/10 2002
-                       # there`s the problem that PHP parses float values in scripts wrong if the locale LC_NUMERIC is set to something with a komma as decimal point
-                       # this does not work in php 4.2.3
-                       #setlocale('LC_ALL',$this->config['config']['locale_all']);
-                       #setlocale('LC_NUMERIC','en_US');
-
-                       # so we set all except LC_NUMERIC
-                       setlocale(LC_COLLATE,$this->config['config']['locale_all']);
-                       setlocale(LC_CTYPE,$this->config['config']['locale_all']);
-                       setlocale(LC_MONETARY,$this->config['config']['locale_all']);
-                       setlocale(LC_TIME,$this->config['config']['locale_all']);
-
-                       $this->localeCharset = $this->csConvObj->get_locale_charset($this->config['config']['locale_all']);
-               }
 
                        // Setting cache_timeout_default. May be overridden by PHP include scritps.
                $this->cacheTimeOutDefault = intval($this->config['config']['cache_period']);
index e2f72e1..83cf54c 100755 (executable)
@@ -293,9 +293,10 @@ $TSFE->getCompressedTCarray();
 
 
 // *******************************************
-// Setting the internal var, sys_language_uid
+// Setting the internal var, sys_language_uid + locale settings
 // *******************************************
 $TSFE->settingLanguage();
+$TSFE->settingLocale();
 
 
 // ********************************
index 9e416ac..a169efb 100755 (executable)
@@ -225,6 +225,8 @@ class tx_install extends t3lib_install {
         * @return      [type]          ...
         */
        function tx_install()   {
+               parent::t3lib_install();
+
                if (!$GLOBALS["TYPO3_CONF_VARS"]["BE"]["installToolPassword"])  die("Install Tool deactivated.<BR>You must enable it by setting a password in typo3conf/localconf.php. If you insert the line below, the password will be 'joh316':<BR><BR>\$TYPO3_CONF_VARS[\"BE\"][\"installToolPassword\"] = \"bacb98acf97e0b6112b1d1b650b84971\";<BR><BR>See the document 'installing_upgrading_32b1.pdf' for more info.");
 
                if ($this->sendNoCacheHeaders)  {
index e0bd228..8534eda 100755 (executable)
@@ -55,6 +55,7 @@ Do you want to continue WITHOUT saving?</label>
                        <label index="labels.depth_3">3 levels</label>
                        <label index="labels.allow">Allow</label>
                        <label index="labels.deny">Deny</label>
+                       <label index="labels.generalTab">General</label>
                        <label index="labels.refresh">Reload the tree from server</label>
                        <label index="labels.temporaryDBmount">Cancel temporary DB mount</label>
                        <label index="labels.refreshList">Reload list from server</label>
@@ -79,6 +80,8 @@ Do you want to continue WITHOUT saving?</label>
                        <label index="labels.removeItem">Remove item</label>
                        <label index="labels.holdDownCTRL">Important: Hold down the CTRL key while toggling elements in this list!</label>
                        <label index="labels.revertSelection">Revert selection</label>
+                       <label index="labels.setAllCheckboxes">Select All Checkboxes</label>
+                       <label index="labels.changeInOrig">Change in original</label>
                        <label index="TYPO3_Element_Browser">TYPO3 Element Browser</label>
                        <label index="show_item.php.viewItem">View Item</label>
                        <label index="show_item.php.file">File</label>
index dc57828..16caece 100644 (file)
@@ -66,7 +66,6 @@ require_once (PATH_t3lib.'class.t3lib_tcemain.php');
 
 
 
-
 /**
  * Script Class, creating object of t3lib_TCEmain and sending the posted data to the object.
  * Used by many smaller forms/links in TYPO3, including the QuickEdit module.
index a1f18d5..86a1061 100755 (executable)
@@ -324,6 +324,7 @@ class template {
         * @param       string          $params is a set of GET params to send to tce_db.php. Example: "&cmd[tt_content][123][move]=456" or "&data[tt_content][123][hidden]=1&data[tt_content][123][title]=Hello%20World"
         * @param       string          Redirect URL if any other that t3lib_div::getIndpEnv('REQUEST_URI') is wished
         * @return      string          URL to tce_db.php + parameters (backpath is taken from $this->backPath)
+        * @see t3lib_BEfunc::editOnClick()
         */
        function issueCommand($params,$rUrl='') {
                $rUrl = $rUrl ? $rUrl : t3lib_div::getIndpEnv('REQUEST_URI');
@@ -966,9 +967,10 @@ $str.=$this->docBodyTagBegin().
         * 3:   Fatal error (Red stop sign)
         *
         * @param       integer         See description
+        * @param       string          Value for style attribute
         * @return      string          HTML image tag (if applicable)
         */
-       function icons($type)   {
+       function icons($type, $styleAttribValue='')     {
                switch($type)   {
                        case '3':
                                $icon = 'gfx/icon_fatalerror.gif';
@@ -986,7 +988,7 @@ $str.=$this->docBodyTagBegin().
                        break;
                }
                if ($icon)      {
-                       return '<img'.t3lib_iconWorks::skinImg($this->backPath,$icon,'width="18" height="16"').' class="absmiddle" alt="" />';
+                       return '<img'.t3lib_iconWorks::skinImg($this->backPath,$icon,'width="18" height="16"').' class="absmiddle"'.($styleAttribValue ? ' style="'.htmlspecialchars($styleAttribValue).'"' : '').' alt="" />';
                }
        }
 
@@ -1383,11 +1385,8 @@ $str.=$this->docBodyTagBegin().
                } else return array('','','');
        }
 
-
-
-
        /**
-        * creates a tab menu from an array definition
+        * Creates a tab menu from an array definition
         *
         * Returns a tab menu for a module
         * Requires the JS function jumpToUrl() to be available
@@ -1447,8 +1446,9 @@ $str.=$this->docBodyTagBegin().
                                $class = $isActive ? 'tabact' : 'tab';
                                $width = $isActive ? $widthAct : $widthNo;
 
+                                       // @rene: Here you should probably wrap $label and $url in htmlspecialchars() in order to make sure its XHTML compatible! I did it for $url already since that is VERY likely to break.
                                $label = $def['label'];
-                               $url = $def['url'];
+                               $url = htmlspecialchars($def['url']);
                                $params = $def['addParams'];
 
                                if($first) {
@@ -1478,6 +1478,182 @@ $str.=$this->docBodyTagBegin().
                return $content;
        }
 
+       /**
+        * Creates a DYNAMIC tab-menu where the tabs are switched between with DHTML.
+        *
+        * @param       array   Numeric array where each entry is an array in itself with associative keys: "label" contains the label for the TAB, "content" contains the HTML content that goes into the div-layer of the tabs content. "description" contains description text to be shown in the layer. "linkTitle" is short text for the title attribute of the tab-menu link (mouse-over text of tab). "stateIcon" indicates a standard status icon (see ->icon(), values: -1, 1, 2, 3). "icon" is an image tag placed before the text.
+        * @param       string  Identification string. This should be unique for every instance of a dynamic menu!
+        * @param       boolean         If set, then enabling one tab does not hide the others - they simply toggles each sheet on/off. This makes most sense together with the $foldout option
+        * @param       boolean         If set, the tabs are rendered as headers instead over each sheet. Effectively this means there is no tab menu, but rather a foldout/foldin menu. Make sure to set $toggle as well for this option.
+        * @param       integer         Character limit for a new row.
+        * @param       boolean         If set, tab table cells are not allowed to wrap their content
+        * @return      string  JavaScript section for the HTML header.
+        */
+       function getDynTabMenu($menuItems,$identString,$toggle=FALSE,$foldout=FALSE,$newRowCharLimit=50,$noWrap=1)      {
+               $content = '';
+
+               if (is_array($menuItems))       {
+
+                               // Init:
+                       $options = array(array());
+                       $divs = array();
+                       $JSinit = array();
+                       $id = 'DTM-'.t3lib_div::shortMD5($identString);
+                       $noWrap = $noWrap ? ' nowrap="nowrap"' : '';
+
+                               // Traverse menu items
+                       $c=0;
+                       $tabRows=0;
+                       $titleLenCount = 0;
+                       foreach($menuItems as $index => $def) {
+                                       // Switch to next tab row if needed
+                               if (!$foldout && $titleLenCount>$newRowCharLimit)       {       // 50 characters is probably a reasonable count of characters before switching to next row of tabs.
+                                       $titleLenCount=0;
+                                       $tabRows++;
+                                       $options[$tabRows] = array();
+                               }
+
+                               if ($toggle)    {
+                                       $onclick = 'this.blur(); DTM_toggle("'.$id.'","'.$index.'"); return false;';
+                               } else {
+                                       $onclick = 'this.blur(); DTM_activate("'.$id.'","'.$index.'"); return false;';
+                               }
+
+                               $isActive = strcmp($def['content'],'');
+
+                               if (!$foldout)  {
+                                               // Create TAB cell:
+                                       $options[$tabRows][] = '
+                                                       <td class="'.($isActive ? 'tab' : 'disabled').'" id="'.$id.'-'.$index.'-MENU"'.$noWrap.'>'.
+                                                       ($isActive ? '<a href="#" onclick="'.htmlspecialchars($onclick).'"'.($def['linkTitle'] ? ' title="'.htmlspecialchars($def['linkTitle']).'"':'').'>' : '').
+                                                       $def['icon'].
+                                                       ($def['label'] ? htmlspecialchars($def['label']) : '&nbsp;').
+                                                       $this->icons($def['stateIcon'],'margin-left: 10px;').
+                                                       ($isActive ? '</a>' :'').
+                                                       '</td>';
+                                       $titleLenCount+= strlen($def['label']);
+                               } else {
+                                               // Create DIV layer for content:
+                                       $divs[] = '
+                                               <div class="'.($isActive ? 'tab' : 'disabled').'" id="'.$id.'-'.$index.'-MENU">'.
+                                                       ($isActive ? '<a href="#" onclick="'.htmlspecialchars($onclick).'"'.($def['linkTitle'] ? ' title="'.htmlspecialchars($def['linkTitle']).'"':'').'>' : '').
+                                                       ($def['label'] ? htmlspecialchars($def['label']) : '&nbsp;').
+                                                       ($isActive ? '</a>' : '').
+                                                       '</div>';
+                               }
+
+                               if ($isActive)  {
+                                               // Create DIV layer for content:
+                                       $divs[] = '
+                                                       <div style="display: none;" id="'.$id.'-'.$index.'-DIV" class="c-tablayer">'.
+                                                               ($def['description'] ? '<p class="c-descr">'.nl2br(htmlspecialchars($def['description'])).'</p>' : '').
+                                                               $def['content'].
+                                                               '</div>';
+                                               // Create initialization string:
+                                       $JSinit[] = '
+                                                       DTM_array["'.$id.'"]['.$c.'] = "'.$id.'-'.$index.'";
+                                       ';
+                                       if ($toggle)    {
+                                               $JSinit[] = '
+                                                       if (top.DTM_currentTabs["'.$id.'-'.$index.'"]) { DTM_toggle("'.$id.'","'.$index.'"); }
+                                               ';
+                                       }
+
+                                       $c++;
+                               }
+                       }
+
+                               // Render menu:
+                       if (count($options))    {
+
+                                       // Tab menu is compiled:
+                               if (!$foldout)  {
+                                       $tabContent = '';
+                                       for($a=0;$a<=$tabRows;$a++)     {
+                                               $tabContent.= '
+
+                                       <!-- Tab menu -->
+                                       <table cellpadding="0" cellspacing="0" border="0" width="100%" class="typo3-dyntabmenu">
+                                               <tr>
+                                                               '.implode('',$options[$a]).'
+                                               </tr>
+                                       </table>';
+                                       }
+                                       $content.= '<div class="typo3-dyntabmenu-tabs">'.$tabContent.'</div>';
+                               }
+
+                                       // Div layers are added:
+                               $content.= '
+                               <!-- Div layers for tab menu: -->
+                               <div class="typo3-dyntabmenu-divs'.($foldout?'-foldout':'').'">
+                               '.implode('',$divs).'</div>';
+
+                                       // Java Script section added:
+                               $content.= '
+                               <!-- Initialization JavaScript for the menu -->
+                               <script type="text/javascript">
+                                       DTM_array["'.$id.'"] = new Array();
+                                       '.implode('',$JSinit).'
+
+                                       '.(!$toggle ? 'DTM_activate("'.$id.'",top.DTM_currentTabs["'.$id.'"]?top.DTM_currentTabs["'.$id.'"]:0);' : '').'
+                               </script>
+
+                               ';
+                       }
+
+               }
+               return $content;
+       }
+
+       /**
+        * Returns dynamic tab menu header JS code.
+        *
+        * @return      string  JavaScript section for the HTML header.
+        */
+       function getDynTabMenuJScode()  {
+               return '
+                       <script type="text/javascript">
+                       /*<![CDATA[*/
+                               var DTM_array = new Array();
+
+                               function DTM_activate(idBase,index)     {       //
+                                               // Hiding all:
+                                       if (DTM_array[idBase])  {
+                                               for(cnt = 0; cnt < DTM_array[idBase].length ; cnt++)    {
+                                                       if (DTM_array[idBase][cnt] != idBase+"-"+index) {
+                                                               document.getElementById(DTM_array[idBase][cnt]+"-DIV").style.display = "none";
+                                                               document.getElementById(DTM_array[idBase][cnt]+"-MENU").attributes.getNamedItem("class").nodeValue = "tab";
+                                                       }
+                                               }
+                                       }
+
+                                               // Showing one:
+                                       if (document.getElementById(idBase+"-"+index+"-DIV"))   {
+                                               document.getElementById(idBase+"-"+index+"-DIV").style.display = "block";
+                                               document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").nodeValue = "tabact";
+
+                                                       // Setting current tab index in top of browser.
+                                               top.DTM_currentTabs[idBase] = index;
+                                       }
+                               }
+                               function DTM_toggle(idBase,index)       {       //
+                                               // Showing one:
+                                       if (document.getElementById(idBase+"-"+index+"-DIV"))   {
+                                               if (document.getElementById(idBase+"-"+index+"-DIV").style.display == "block")  {
+                                                       document.getElementById(idBase+"-"+index+"-DIV").style.display = "none";
+                                                       document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").nodeValue = "tab";
+                                                       top.DTM_currentTabs[idBase+"-"+index] = 0;
+                                               } else {
+                                                       document.getElementById(idBase+"-"+index+"-DIV").style.display = "block";
+                                                       document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").nodeValue = "tabact";
+                                                       top.DTM_currentTabs[idBase+"-"+index] = 1;
+                                               }
+                                       }
+                               }
+                       /*]]>*/
+                       </script>
+               ';
+       }
 }