Fixed bug #14005: Moving a page with IRRE records misplaces IRRE records
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_install.php
old mode 100755 (executable)
new mode 100644 (file)
index 4332920..933f9bc
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  (c) 1999-2010 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
@@ -71,7 +71,6 @@
 
 
 
 
 
 
-require_once(PATH_t3lib.'class.t3lib_sqlparser.php');
 
 /**
  * Class to setup values in localconf.php and verify the TYPO3 DB tables/fields
 
 /**
  * Class to setup values in localconf.php and verify the TYPO3 DB tables/fields
@@ -141,6 +140,9 @@ class t3lib_install {
                $tokenSet = ($this->localconf_editPointToken && !$inArray);             // Flag is set if the token should be set but is not yet...
                $stopAtToken = ($this->localconf_editPointToken && $inArray);
                $comment = ' Modified or inserted by '.$this->updateIdentity.'.';
                $tokenSet = ($this->localconf_editPointToken && !$inArray);             // Flag is set if the token should be set but is not yet...
                $stopAtToken = ($this->localconf_editPointToken && $inArray);
                $comment = ' Modified or inserted by '.$this->updateIdentity.'.';
+               $replace = array('["', '"]');
+               $search = array('[\'', '\']');
+               $varDoubleQuotes = str_replace($search, $replace, $variable);
 
                        // Search for variable name:
                if (!$this->localconf_addLinesOnly && !$tokenSet)       {
 
                        // Search for variable name:
                if (!$this->localconf_addLinesOnly && !$tokenSet)       {
@@ -157,7 +159,21 @@ class t3lib_install {
                                                $found = 1;
                                                break;
                                        }
                                                $found = 1;
                                                break;
                                        }
-                               }
+                               } elseif (!strcmp(substr($v2, 0, strlen($varDoubleQuotes . ' ')), $varDoubleQuotes . ' ')) {
+                                               // Due to a bug in the update wizard (fixed in TYPO3 4.1.7) it is possible
+                                               // that $TYPO3_CONF_VARS['SYS']['compat_version'] was enclosed by "" (double
+                                               // quotes) instead of the expected '' (single quotes) when is was written to
+                                               // localconf.php. The following code was added to make sure that values with
+                                               // double quotes are updated, too.
+                                       $mainparts = explode($varDoubleQuotes, $v, 2);
+                                       if (count($mainparts) == 2) { // should ALWAYS be....
+                                               $subparts = explode('//', $mainparts[1], 2);
+                                               $line_array[$k] = $mainparts[0] . $variable . " = '" . $this->slashValueForSingleDashes($value) . "';   " . ('//' . $comment . str_replace($comment, '', $subparts[1]));
+                                               $this->touchedLine = count($line_array) - $k - 1;
+                                               $found = 1;
+                                               break;
+                                       }
+                               }
                        }
                        $line_array = array_reverse($line_array);
                }
                        }
                        $line_array = array_reverse($line_array);
                }
@@ -169,7 +185,11 @@ class t3lib_install {
                        $line_array[] = $variable." = '".$this->slashValueForSingleDashes($value)."';   // ".$comment;
                        $this->touchedLine = -1;
                }
                        $line_array[] = $variable." = '".$this->slashValueForSingleDashes($value)."';   // ".$comment;
                        $this->touchedLine = -1;
                }
-               $this->messages[] = $variable." = '".htmlspecialchars($value)."'";
+               if ($variable == '$typo_db_password') {
+                       $this->messages[] = 'Updated ' . $variable;
+               } else {
+                       $this->messages[] = $variable . " = '" . htmlspecialchars($value) . "'";
+               }
                $this->setLocalconf = 1;
        }
 
                $this->setLocalconf = 1;
        }
 
@@ -183,6 +203,7 @@ class t3lib_install {
         */
        function writeToLocalconf_control($inlines='',$absFullPath='')  {
                $tmpExt = '.TMP.php';
         */
        function writeToLocalconf_control($inlines='',$absFullPath='')  {
                $tmpExt = '.TMP.php';
+               $writeToLocalconf_dat = array();
                $writeToLocalconf_dat['file'] = $absFullPath ? $absFullPath : PATH_typo3conf.'localconf.php';
                $writeToLocalconf_dat['tmpfile'] = $writeToLocalconf_dat['file'].$tmpExt;
 
                $writeToLocalconf_dat['file'] = $absFullPath ? $absFullPath : PATH_typo3conf.'localconf.php';
                $writeToLocalconf_dat['tmpfile'] = $writeToLocalconf_dat['file'].$tmpExt;
 
@@ -303,8 +324,8 @@ class t3lib_install {
                        }
 
                        if (!strlen($table)) {
                        }
 
                        if (!strlen($table)) {
-                               $parts = explode(' ',$value);
-                               if ($parts[0]=='CREATE' && $parts[1]=='TABLE')  {
+                               $parts = t3lib_div::trimExplode(' ', $value, TRUE);
+                               if (strtoupper($parts[0]) === 'CREATE' && strtoupper($parts[1]) === 'TABLE') {
                                        $table = str_replace( '`', '', $parts[2]);
                                        if (TYPO3_OS=='WIN') {  // tablenames are always lowercase on windows!
                                                $table = strtolower($table);
                                        $table = str_replace( '`', '', $parts[2]);
                                        if (TYPO3_OS=='WIN') {  // tablenames are always lowercase on windows!
                                                $table = strtolower($table);
@@ -366,7 +387,14 @@ class t3lib_install {
 
                                                $newParts = explode(' ',$parts[1],2);
                                                $key = $parts[0]=='PRIMARY' ? $parts[0] : $newParts[0];
 
                                                $newParts = explode(' ',$parts[1],2);
                                                $key = $parts[0]=='PRIMARY' ? $parts[0] : $newParts[0];
+
                                                $total[$table]['keys'][$key] = $lineV;
                                                $total[$table]['keys'][$key] = $lineV;
+
+                                                       // This is a protection against doing something stupid: Only allow clearing of cache_* and index_* tables.
+                                               if (preg_match('/^(cache|index)_/',$table)) {
+                                                               // Suggest to truncate (clear) this table
+                                                       $total[$table]['extra']['CLEAR'] = 1;
+                                               }
                                        }
                                }
                        }
                                        }
                                }
                        }
@@ -426,7 +454,7 @@ class t3lib_install {
                                                                                                }
                                                                                                $keys[] = $kfN;
                                                                                        }
                                                                                                }
                                                                                                $keys[] = $kfN;
                                                                                        }
-                                                                                       $total[$table]['keys'][$kN] = $match[1].'('.join(',',$keys).')'.$match[3];
+                                                                                       $total[$table]['keys'][$kN] = $match[1].'('.implode(',',$keys).')'.$match[3];
                                                                                }
                                                                        }
                                                                }
                                                                                }
                                                                        }
                                                                }
@@ -453,9 +481,14 @@ class t3lib_install {
        function getCollationForCharset($charset)       {
                        // Load character sets, if not cached already
                if (!count($this->character_sets)) {
        function getCollationForCharset($charset)       {
                        // Load character sets, if not cached already
                if (!count($this->character_sets)) {
-                       $this->character_sets = $GLOBALS['TYPO3_DB']->admin_get_charsets();
+                       if (method_exists($GLOBALS['TYPO3_DB'],'admin_get_charsets')) {
+                               $this->character_sets = $GLOBALS['TYPO3_DB']->admin_get_charsets();
+                       } else {
+                               $this->character_sets[$charset] = array();      // Add empty element to avoid that the check will be repeated
+                       }
                }
 
                }
 
+               $collation = '';
                if (isset($this->character_sets[$charset]['Default collation'])) {
                        $collation = $this->character_sets[$charset]['Default collation'];
                }
                if (isset($this->character_sets[$charset]['Default collation'])) {
                        $collation = $this->character_sets[$charset]['Default collation'];
                }
@@ -623,6 +656,18 @@ class t3lib_install {
                                                        if ($info['whole_table']) {
                                                                $whole_table[]=$fN.' '.$fV;
                                                        } else {
                                                        if ($info['whole_table']) {
                                                                $whole_table[]=$fN.' '.$fV;
                                                        } else {
+                                                                       // Special case to work around MySQL problems when adding auto_increment fields:
+                                                               if (stristr($fV, 'auto_increment')) {
+                                                                               // The field can only be set "auto_increment" if there exists a PRIMARY key of that field already.
+                                                                               // The check does not look up which field is primary but just assumes it must be the field with the auto_increment value...
+                                                                       if (isset($diffArr['extra'][$table]['keys']['PRIMARY'])) {
+                                                                                       // Remove "auto_increment" from the statement - it will be suggested in a 2nd step after the primary key was created
+                                                                               $fV = str_replace(' auto_increment', '', $fV);
+                                                                       } else {
+                                                                                       // In the next step, attempt to clear the table once again (2 = force)
+                                                                               $info['extra']['CLEAR'] = 2;
+                                                                       }
+                                                               }
                                                                if ($theKey=='extra') {
                                                                        if ($remove) {
                                                                                if (substr($fN,0,strlen($deletedPrefixKey))!=$deletedPrefixKey) {
                                                                if ($theKey=='extra') {
                                                                        if ($remove) {
                                                                                if (substr($fN,0,strlen($deletedPrefixKey))!=$deletedPrefixKey) {
@@ -669,16 +714,31 @@ class t3lib_install {
                                        if (is_array($info['extra'])) {
                                                $extras = array();
                                                $extras_currentValue = array();
                                        if (is_array($info['extra'])) {
                                                $extras = array();
                                                $extras_currentValue = array();
+                                               $clear_table = false;
+
                                                foreach ($info['extra'] as $fN => $fV) {
 
                                                                // Only consider statements which are missing in the database but don't remove existing properties
                                                        if (!$remove) {
                                                                if (!$info['whole_table']) {    // If the whole table is created at once, we take care of this later by imploding all elements of $info['extra']
                                                foreach ($info['extra'] as $fN => $fV) {
 
                                                                // Only consider statements which are missing in the database but don't remove existing properties
                                                        if (!$remove) {
                                                                if (!$info['whole_table']) {    // If the whole table is created at once, we take care of this later by imploding all elements of $info['extra']
-                                                                       $extras[] = $fN.'='.$fV;
-                                                                       $extras_currentValue[] = $fN.'='.$diffArr['diff_currentValues'][$table]['extra'][$fN];
+                                                                       if ($fN=='CLEAR') {
+                                                                                       // Truncate table must happen later, not now
+                                                                                       // Valid values for CLEAR: 1=only clear if keys are missing, 2=clear anyway (force)
+                                                                               if (count($info['keys']) || $fV==2) {
+                                                                                       $clear_table = true;
+                                                                               }
+                                                                               continue;
+                                                                       } else {
+                                                                               $extras[] = $fN.'='.$fV;
+                                                                               $extras_currentValue[] = $fN.'='.$diffArr['diff_currentValues'][$table]['extra'][$fN];
+                                                                       }
                                                                }
                                                        }
                                                }
                                                                }
                                                        }
                                                }
+                                               if ($clear_table) {
+                                                       $statement = 'TRUNCATE TABLE '.$table.';';
+                                                       $statements['clear_table'][md5($statement)] = $statement;
+                                               }
                                                if (count($extras)) {
                                                        $statement = 'ALTER TABLE '.$table.' '.implode(' ',$extras).';';
                                                        $statements['change'][md5($statement)] = $statement;
                                                if (count($extras)) {
                                                        $statement = 'ALTER TABLE '.$table.' '.implode(' ',$extras).';';
                                                        $statements['change'][md5($statement)] = $statement;
@@ -695,13 +755,15 @@ class t3lib_install {
                                                                $statements['drop_table'][md5($statement)] = $statement;
                                                        }
                                                                // count:
                                                                $statements['drop_table'][md5($statement)] = $statement;
                                                        }
                                                                // count:
-                                                       $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('count(*)', $table, '');
-                                                       list($count) = $GLOBALS['TYPO3_DB']->sql_fetch_row($res);
+                                                       $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', $table);
                                                        $statements['tables_count'][md5($statement)] = $count?'Records in table: '.$count:'';
                                                } else {
                                                        $statement = 'CREATE TABLE '.$table." (\n".implode(",\n",$whole_table)."\n)";
                                                        if ($info['extra']) {
                                                                foreach ($info['extra'] as $k=>$v) {
                                                        $statements['tables_count'][md5($statement)] = $count?'Records in table: '.$count:'';
                                                } else {
                                                        $statement = 'CREATE TABLE '.$table." (\n".implode(",\n",$whole_table)."\n)";
                                                        if ($info['extra']) {
                                                                foreach ($info['extra'] as $k=>$v) {
+                                                                       if ($k=='COLLATE' || $k=='CLEAR') {
+                                                                               continue;       // Skip these special statements. TODO: collation support is currently disabled (needs more testing)
+                                                                       }
                                                                        $statement.= ' '.$k.'='.$v;     // Add extra attributes like ENGINE, CHARSET, etc.
                                                                }
                                                        }
                                                                        $statement.= ' '.$k.'='.$v;     // Add extra attributes like ENGINE, CHARSET, etc.
                                                                }
                                                        }
@@ -770,7 +832,7 @@ class t3lib_install {
                        }
                        if (substr(trim($lineContent),-1)==';') {
                                if (isset($statementArray[$statementArrayPointer])) {
                        }
                        if (substr(trim($lineContent),-1)==';') {
                                if (isset($statementArray[$statementArrayPointer])) {
-                                       if (!trim($statementArray[$statementArrayPointer]) || ($query_regex && !eregi($query_regex,trim($statementArray[$statementArrayPointer])))) {
+                                       if (!trim($statementArray[$statementArrayPointer]) || ($query_regex && !preg_match('/'.$query_regex.'/i',trim($statementArray[$statementArrayPointer])))) {
                                                unset($statementArray[$statementArrayPointer]);
                                        }
                                }
                                                unset($statementArray[$statementArrayPointer]);
                                        }
                                }
@@ -796,7 +858,7 @@ class t3lib_install {
                $insertCount = array();
                foreach ($statements as $line => $lineContent) {
                        $reg = array();
                $insertCount = array();
                foreach ($statements as $line => $lineContent) {
                        $reg = array();
-                       if (eregi('^create[[:space:]]*table[[:space:]]*[`]?([[:alnum:]_]*)[`]?',substr($lineContent,0,100),$reg)) {
+                       if (preg_match('/^create[[:space:]]*table[[:space:]]*[`]?([[:alnum:]_]*)[`]?/i',substr($lineContent,0,100),$reg)) {
                                $table = trim($reg[1]);
                                if ($table)     {
                                                // table names are always lowercase on Windows!
                                $table = trim($reg[1]);
                                if ($table)     {
                                                // table names are always lowercase on Windows!
@@ -812,7 +874,7 @@ class t3lib_install {
                                        $lineContent = implode(chr(10), $sqlLines);
                                        $crTables[$table] = $lineContent;
                                }
                                        $lineContent = implode(chr(10), $sqlLines);
                                        $crTables[$table] = $lineContent;
                                }
-                       } elseif ($insertCountFlag && eregi('^insert[[:space:]]*into[[:space:]]*[`]?([[:alnum:]_]*)[`]?',substr($lineContent,0,100),$reg)) {
+                       } elseif ($insertCountFlag && preg_match('/^insert[[:space:]]*into[[:space:]]*[`]?([[:alnum:]_]*)[`]?/i',substr($lineContent,0,100),$reg)) {
                                $nTable = trim($reg[1]);
                                $insertCount[$nTable]++;
                        }
                                $nTable = trim($reg[1]);
                                $insertCount[$nTable]++;
                        }
@@ -878,7 +940,10 @@ class t3lib_install {
         */
        function getListOfTables()      {
                $whichTables = $GLOBALS['TYPO3_DB']->admin_get_tables(TYPO3_db);
         */
        function getListOfTables()      {
                $whichTables = $GLOBALS['TYPO3_DB']->admin_get_tables(TYPO3_db);
-               return array_keys($whichTables);
+               foreach ($whichTables as $key=>&$value) {
+                       $value = $key;
+               }
+               return $whichTables;
        }
 
        /**
        }
 
        /**
@@ -895,16 +960,30 @@ class t3lib_install {
        function generateUpdateDatabaseForm_checkboxes($arr,$label,$checked=1,$iconDis=0,$currentValue=array(),$cVfullMsg=0)    {
                $out = array();
                if (is_array($arr))     {
        function generateUpdateDatabaseForm_checkboxes($arr,$label,$checked=1,$iconDis=0,$currentValue=array(),$cVfullMsg=0)    {
                $out = array();
                if (is_array($arr))     {
+                       $tableId = uniqid('table');
+                       if (count($arr) > 1) {
+                               $out[] = '
+                                       <tr class="update-db-fields-batch">
+                                               <td valign="top">
+                                                       <input type="checkbox" id="' . $tableId . '-checkbox"' . ($checked ? ' checked="checked"' : '') . '
+                                                        onclick="$(\'' . $tableId . '\').select(\'input[type=checkbox]\').invoke(\'setValue\', $(this).checked);" />
+                                               </td>
+                                               <td nowrap="nowrap"><label for="' . $tableId . '-checkbox" style="cursor:pointer"><strong>select/deselect all</strong></label></td>
+                                       </tr>';
+                       }
                        foreach($arr as $key => $string)        {
                                $ico = '';
                        foreach($arr as $key => $string)        {
                                $ico = '';
+                               $warnings = array();
+
                                if ($iconDis)   {
                                if ($iconDis)   {
-                                       if (stristr($string,' user_'))  {
+                                       if (preg_match('/^TRUNCATE/i',$string)) {
+                                               $ico.= '<img src="'.$this->backPath.'gfx/icon_warning.gif" width="18" height="16" align="top" alt="" /><strong> </strong>';
+                                               $warnings['clear_table_info'] = 'Clearing the table is sometimes neccessary when adding new keys. In case of cache_* tables this should not hurt at all. However, use it with care.';
+                                       } elseif (stristr($string,' user_'))    {
                                                $ico.= '<img src="'.$this->backPath.'gfx/icon_warning.gif" width="18" height="16" align="top" alt="" /><strong>(USER) </strong>';
                                                $ico.= '<img src="'.$this->backPath.'gfx/icon_warning.gif" width="18" height="16" align="top" alt="" /><strong>(USER) </strong>';
-                                       }
-                                       if (stristr($string,' app_'))   {
+                                       } elseif (stristr($string,' app_'))     {
                                                $ico.= '<img src="'.$this->backPath.'gfx/icon_warning.gif" width="18" height="16" align="top" alt="" /><strong>(APP) </strong>';
                                                $ico.= '<img src="'.$this->backPath.'gfx/icon_warning.gif" width="18" height="16" align="top" alt="" /><strong>(APP) </strong>';
-                                       }
-                                       if (stristr($string,' ttx_') || stristr($string,' tx_'))        {
+                                       } elseif (stristr($string,' ttx_') || stristr($string,' tx_'))  {
                                                $ico.= '<img src="'.$this->backPath.'gfx/icon_warning.gif" width="18" height="16" align="top" alt="" /><strong>(EXT) </strong>';
                                        }
                                }
                                                $ico.= '<img src="'.$this->backPath.'gfx/icon_warning.gif" width="18" height="16" align="top" alt="" /><strong>(EXT) </strong>';
                                        }
                                }
@@ -917,16 +996,23 @@ class t3lib_install {
                                        $out[]='
                                        <tr>
                                                <td valign="top"></td>
                                        $out[]='
                                        <tr>
                                                <td valign="top"></td>
-                                               <td nowrap="nowrap" style="color : #666666;">'.nl2br((!$cVfullMsg?"Current value: ":"").'<em>'.$currentValue[$key].'</em>').'</td>
+                                               <td nowrap="nowrap" style="color:#666666;">'.nl2br((!$cVfullMsg?"Current value: ":"").'<em>'.$currentValue[$key].'</em>').'</td>
                                        </tr>';
                                }
                        }
                                        </tr>';
                                }
                        }
+                       if (count($warnings)) {
+                               $out[] = '
+                                       <tr>
+                                               <td valign="top"></td>
+                                               <td style="color:#666666;"><em>' . implode('<br />',$warnings) . '</em></td>
+                                       </tr>';
+                       }
 
                        // Compile rows:
                        $content = '
                                <!-- Update database fields / tables -->
                                <h3>'.$label.'</h3>
 
                        // Compile rows:
                        $content = '
                                <!-- Update database fields / tables -->
                                <h3>'.$label.'</h3>
-                               <table border="0" cellpadding="2" cellspacing="2" class="update-db-fields">'.implode('',$out).'
+                               <table border="0" cellpadding="2" cellspacing="2" id="' . $tableId . '" class="update-db-fields">' . implode('', $out) . '
                                </table>';
                }
 
                                </table>';
                }
 
@@ -938,9 +1024,11 @@ class t3lib_install {
         *
         * @param       string          Should be a string read from an SQL-file made with 'mysqldump [database_name] -d'
         * @return      array           Array with information about table.
         *
         * @param       string          Should be a string read from an SQL-file made with 'mysqldump [database_name] -d'
         * @return      array           Array with information about table.
-        * @deprecated  since TYPO3 4.2 Use ->getFieldDefinitions_fileContent() instead!
+        * @deprecated  since TYPO3 4.2, this function will be removed in TYPO3 4.5, use ->getFieldDefinitions_fileContent() instead!
         */
        function getFieldDefinitions_sqlContent($fileContent)   {
         */
        function getFieldDefinitions_sqlContent($fileContent)   {
+               t3lib_div::logDeprecatedFunction();
+
                return $this->getFieldDefinitions_fileContent($fileContent);
        }
 }
                return $this->getFieldDefinitions_fileContent($fileContent);
        }
 }
@@ -948,4 +1036,5 @@ class t3lib_install {
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_install.php'])  {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_install.php']);
 }
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_install.php'])  {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_install.php']);
 }
-?>
+
+?>
\ No newline at end of file