Index: t3lib/stddb/tables.php =================================================================== --- t3lib/stddb/tables.php (Revision 9059) +++ t3lib/stddb/tables.php (Arbeitskopie) @@ -192,7 +192,7 @@ 'maxDBListItems' => 30, 'maxSingleDBListItems' => 50 ), - 'columns' => array( + 'columns' => array( 'doktype' => array( 'exclude' => 1, 'label' => 'LLL:EXT:lang/locallang_general.php:LGL.type', Index: t3lib/class.t3lib_page.php =================================================================== --- t3lib/class.t3lib_page.php (Revision 9059) +++ t3lib/class.t3lib_page.php (Arbeitskopie) @@ -1183,22 +1183,56 @@ * @return string AND sql-clause * @see enableFields() */ - function getMultipleGroupsWhereClause($field, $table) { + function getMultipleGroupsWhereClause($field, $table) { + $whereClause = ''; $memberGroups = t3lib_div::intExplode(',',$GLOBALS['TSFE']->gr_list); - $orChecks=array(); - $orChecks[]=$field.'=\'\''; // If the field is empty, then OK - $orChecks[]=$field.' IS NULL'; // If the field is NULL, then OK - $orChecks[]=$field.'=\'0\''; // If the field contsains zero, then OK - foreach($memberGroups as $value) { - $orChecks[] = $GLOBALS['TYPO3_DB']->listQuery($field, $value, $table); + $orChecks = array( + $field.'=\'\'', // If the field is empty, then OK + $field.' IS NULL', // If the field is NULL, then OK + $field.'=\'0\'', // If the field contsains zero, then OK + ); + + $plainFieldName = (strpos($field, '.') > 0 ? substr($field, strpos($field, '.') + 1) : $field); + $manyToManyRelationTable = $this->getManyToManyRelationTable($plainFieldName, $table); + + if ($manyToManyRelationTable !== FALSE) { + $orChecks[] = $table . '.uid IN (SELECT uid_local FROM ' . $manyToManyRelationTable . ' WHERE uid_foreign IN (' . implode(',', $memberGroups) . '))'; + } else { + foreach($memberGroups as $value) { + $orChecks[] = $GLOBALS['TYPO3_DB']->listQuery($field, $value, $table); + } } - return ' AND ('.implode(' OR ',$orChecks).')'; + $whereClause = ' AND ('.implode(' OR ',$orChecks).')'; + return $whereClause; } + /** + * Determines whether a table uses many-to-many relations for a given field. + * + * @param string $field Name of the field + * @param string $table Name of the table + * @return mixed Name of the relation table (string) or FALSE (boolean) otherwise + */ + protected function getManyToManyRelationTable($field, $table) { + $manyToManyRelationTable = FALSE; + // This check is explicitely added since e.g. pages has no dynamic config file + // in TCA that would allow to have the columns loaded afterwards: + if ($field == 'fe_group' && $table == 'pages') { + $manyToManyRelationTable = 'pages_fe_groups_rel_mm'; + } elseif ($field == 'fe_group' && $table == 'tt_content') { + $manyToManyRelationTable = 'tt_content_fe_groups_rel_mm'; + } elseif (isset($GLOBALS['TCA'][$table])) { + t3lib_div::loadTCA($table); + if (isset($GLOBALS['TCA'][$table]['columns'][$field]['config']['MM'])) { + $manyToManyRelationTable = $GLOBALS['TCA'][$table]['columns'][$field]['config']['MM']; + } + } + return $manyToManyRelationTable; + } @@ -1211,6 +1245,9 @@ + + + /********************************* * * Versioning Preview Index: typo3/sysext/cms/ext_tables.php =================================================================== --- typo3/sysext/cms/ext_tables.php (Revision 9059) +++ typo3/sysext/cms/ext_tables.php (Arbeitskopie) @@ -161,6 +161,7 @@ 'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.fe_group', 'config' => array ( 'type' => 'select', + 'MM' => 'pages_fe_groups_rel_mm', 'size' => 5, 'maxitems' => 20, 'items' => array ( Index: typo3/sysext/cms/ext_tables.sql =================================================================== --- typo3/sysext/cms/ext_tables.sql (Revision 9059) +++ typo3/sysext/cms/ext_tables.sql (Arbeitskopie) @@ -477,3 +477,33 @@ fe_login_mode tinyint(4) DEFAULT '0' NOT NULL, KEY alias (alias) ); + + +# +# Table structure for table 'tt_content_fe_groups_rel_mm' +# +CREATE TABLE tt_content_fe_groups_rel_mm ( + uid int(11) NOT NULL auto_increment, + uid_local int(11) DEFAULT '0' NOT NULL, + uid_foreign int(11) DEFAULT '0' NOT NULL, + sorting int(11) DEFAULT '0' NOT NULL, + + KEY uid_local (uid_local), + KEY uid_foreign (uid_foreign), + PRIMARY KEY (uid) +); + + +# +# Table structure for table 'pages_fe_groups_rel_mm' +# +CREATE TABLE pages_fe_groups_rel_mm ( + uid int(11) NOT NULL auto_increment, + uid_local int(11) DEFAULT '0' NOT NULL, + uid_foreign int(11) DEFAULT '0' NOT NULL, + sorting int(11) DEFAULT '0' NOT NULL, + + KEY uid_local (uid_local), + KEY uid_foreign (uid_foreign), + PRIMARY KEY (uid) +); Index: typo3/sysext/cms/tbl_tt_content.php =================================================================== --- typo3/sysext/cms/tbl_tt_content.php (Revision 9059) +++ typo3/sysext/cms/tbl_tt_content.php (Arbeitskopie) @@ -117,6 +117,7 @@ 'label' => 'LLL:EXT:lang/locallang_general.php:LGL.fe_group', 'config' => Array ( 'type' => 'select', + 'MM' => 'tt_content_fe_groups_rel_mm', 'size' => 5, 'maxitems' => 20, 'items' => Array ( Index: typo3/sysext/install/mod/class.tx_install.php =================================================================== --- typo3/sysext/install/mod/class.tx_install.php (Revision 9059) +++ typo3/sysext/install/mod/class.tx_install.php (Arbeitskopie) @@ -155,6 +155,7 @@ require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_statictemplates.php'); require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_t3skin.php'); require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_compressionlevel.php'); +require_once(t3lib_extMgm::extPath('install') . 'updates/class.tx_coreupdates_fegroups.php'); /** * Install Tool module Index: typo3/sysext/install/updates/class.tx_coreupdates_fegroups.php =================================================================== --- typo3/sysext/install/updates/class.tx_coreupdates_fegroups.php (Revision 0) +++ typo3/sysext/install/updates/class.tx_coreupdates_fegroups.php (Revision 0) @@ -0,0 +1,183 @@ + +* All rights reserved +* +* This script is part of the TYPO3 project. The TYPO3 project is +* free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* The GNU General Public License can be found at +* http://www.gnu.org/copyleft/gpl.html. +* A copy is found in the textfile GPL.txt and important notices to the license +* from the author is found in LICENSE.txt distributed with these scripts. +* +* +* This script is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* This copyright notice MUST APPEAR in all copies of the script! +***************************************************************/ + +/** + * Takes care of updating fe_group field of pages and tt_content table. + * The update wizard stores a "null row" in the accordant MM tables to keep + * the information that the table already was processed by this update wizard. + * + * @author Oliver Hader + */ +class tx_coreupdates_fegroups { + var $versionNumber; + + /** + * parent object + * + * @var tx_install + */ + var $pObj; + var $userInput; // user input + + /** + * Checks if an update is needed + * + * @param string &$description: The description for the update + * @return boolean whether an update is needed (true) or not (false) + */ + public function checkForUpdate(&$description) { + $result = false; + $description = 'Updates the fe_group field of the table pages and tt_content.'; + + $result = (!$this->hasNullRow('pages_fe_groups_rel_mm') && !$this->hasNullRow('tt_content_fe_groups_rel_mm')); + return $result; + } + + + /** + * Performs the database update. Changes the doktype from 2 (advanced) to 1 (standard) + * + * @param array &$dbQueries: queries done in this update + * @param mixed &$customMessages: custom messages + * @return boolean whether it worked (true) or not (false) + */ + public function performUpdate(&$dbQueries, &$customMessages) { + $result = false; + $query = ''; + + $query .= $this->executTableUpdate('pages', 'pages_fe_groups_rel_mm'); + $query .= $this->executTableUpdate('tt_content', 'tt_content_fe_groups_rel_mm'); + + $query .= $this->insertNullRow('pages_fe_groups_rel_mm'); + $query .= $this->insertNullRow('tt_content_fe_groups_rel_mm'); + + $result = ($this->hasNullRow('pages_fe_groups_rel_mm') && $this->hasNullRow('tt_content_fe_groups_rel_mm')); + + $dbQueries .= $query; + + return $result; + } + + /** + * Executes the updates for a table. + * + * @param string $table + * @param string $relationTable + * @return string + */ + protected function executTableUpdate($table, $relationTable) { + $query = ''; + $rows = $this->getAffectedRows($table); + + if (is_array($rows)) { + foreach ($rows as $row) { + $feGroups = t3lib_div::trimExplode(',', $row['fe_group'], TRUE); + $count = 0; + foreach ($feGroups as $feGroup) { + if ($feGroup) { + $query .= $this->persistNewRelation($relationTable, $row['uid'], $feGroup, ++$count); + } + } + $query .= $this->updateRelationCount($table, $row['uid'], $count); + } + } + + return $query; + } + + /** + * Updates the relation count. + * + * @param string $table + * @param integer $uid + * @param integer $count + * @return string + */ + protected function updateRelationCount($table, $uid, $count) { + $fields = array( + 'fe_group' => $count, + ); + $query = $GLOBALS['TYPO3_DB']->UPDATEquery($table, 'uid=' . intval($uid), $fields); + $GLOBALS['TYPO3_DB']->sql_query($query); + + return $query; + } + + /** + * Persists a new MM relation. + * + * @param table $table + * @param integer $uidLocal + * @param integer $uidForeign + * @param integer $sorting + * @return string + */ + protected function persistNewRelation($table, $uidLocal, $uidForeign, $sorting = 0) { + $fields = array( + 'uid_local' => $uidLocal, + 'uid_foreign' => $uidForeign, + 'sorting' => $sorting, + ); + $query = $GLOBALS['TYPO3_DB']->INSERTquery($table, $fields); + $GLOBALS['TYPO3_DB']->sql_query($query); + + return $query; + } + + /** + * Gets the affected rows that need to be processed. + * + * @param string $table + * @return array + */ + protected function getAffectedRows($table) { + $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid, fe_group', $table, 'fe_group != ""'); + return $rows; + } + + /** + * @param string $table + * @return string + */ + protected function insertNullRow($table) { + return $this->persistNewRelation($table, 0, 0); + } + + /** + * Determines whether a table has a "null row" that + * indicates that this update wizard was already executed + * for that table. + * + * @param string $table + * @returnb boolean + */ + protected function hasNullRow($table) { + $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid', $table, 'uid_local=0 AND uid_foreign=0'); + return count($rows); + } +} +?> \ No newline at end of file Index: typo3/sysext/install/ext_localconf.php =================================================================== --- typo3/sysext/install/ext_localconf.php (Revision 9059) +++ typo3/sysext/install/ext_localconf.php (Arbeitskopie) @@ -6,6 +6,9 @@ // manage split includes of css_styled_contents since TYPO3 4.3 $TYPO3_CONF_VARS['SC_OPTIONS']['ext/install']['update']['splitCscToMultipleTemplates'] = 'tx_coreupdates_cscsplit'; + // modifies fe_group field of tables pages and tt_content: +$TYPO3_CONF_VARS['SC_OPTIONS']['ext/install']['update']['updateFeGroup'] = 'tx_coreupdates_fegroups'; + // remove pagetype "not in menu" since TYPO3 4.2 // as there is an option in every pagetype $TYPO3_CONF_VARS['SC_OPTIONS']['ext/install']['update']['removeNotInMenuDoktypeConversion'] = 'tx_coreupdates_notinmenu';