Fixed bug #11834: Field handling API in t3lib_extMgm does not check for duplicates...
authorOliver Hader <oliver.hader@typo3.org>
Sun, 20 Sep 2009 13:11:23 +0000 (13:11 +0000)
committerOliver Hader <oliver.hader@typo3.org>
Sun, 20 Sep 2009 13:11:23 +0000 (13:11 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@6012 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
t3lib/class.t3lib_extmgm.php

index ee99584..d97c0fe 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,7 @@
 
        * Cleanup: Set SVN properties
        * Follow-up to feature #10585: Fixed PHPdoc comments and field rendering
+       * Fixed bug #11834: Field handling API in t3lib_extMgm does not check for duplicates on insertion and runs superflouos insertions
 
 2009-09-20  Francois Suter  <francois@typo3.org>
 
index 8360bd3..42aff01 100644 (file)
@@ -308,6 +308,7 @@ final class t3lib_extMgm {
         */
        public static function addFieldsToAllPalettesOfField($table, $field, $addFields, $insertionPosition = '') {
                $generatedPalette = '';
+               $processedPalettes = array();
                t3lib_div::loadTCA($table);
 
                if (isset($GLOBALS['TCA'][$table]['columns'][$field])) {
@@ -320,7 +321,10 @@ final class t3lib_extMgm {
                                                        // If the field already has a palette, extend it:
                                                if ($items[$field]['details']['palette']) {
                                                        $palette = $items[$field]['details']['palette'];
-                                                       self::addFieldsToPalette($table, $palette, $addFields, $insertionPosition);
+                                                       if (!isset($processedPalettes[$palette])) {
+                                                               self::addFieldsToPalette($table, $palette, $addFields, $insertionPosition);
+                                                               $processedPalettes[$palette] = true;
+                                                       }
                                                        // If there's not palette yet, create one:
                                                } else {
                                                        if ($generatedPalette) {
@@ -366,7 +370,7 @@ final class t3lib_extMgm {
                                );
                                // If it's a new palette, just set the data:
                        } else {
-                               $paletteData['showitem'] = $addFields;
+                               $paletteData['showitem'] = self::removeDuplicatesForInsertion($addFields);
                        }
                }
        }
@@ -405,47 +409,49 @@ final class t3lib_extMgm {
         */
        protected static function executePositionedStringInsertion($list, $insertionList, $insertionPosition = '') {
                $list = trim($list);
-               $insertionList = self::removeDuplicatesForInsertion($list, $insertionList);
+               $insertionList = self::removeDuplicatesForInsertion($insertionList, $list);
 
-                       // Append data to the end (default):
-               if ($insertionPosition === '') {
-                       $list.= ($list ? ', ' : '') . $insertionList;
-                       // Insert data before or after insertion points:
-               } else {
-                       $positions = t3lib_div::trimExplode(',', $insertionPosition, true);
-                       $items = self::explodeItemList($list);
-                       $isInserted = false;
-                               // Iterate through all fields an check whether it's possible to inserte there:
-                       foreach ($items as $item => &$itemDetails) {
-                               $needles = self::getInsertionNeedles($item, $itemDetails['details']);
-                                       // Insert data before:
-                               foreach ($needles['before'] as $needle) {
-                                       if (in_array($needle, $positions)) {
-                                               $itemDetails['rawData'] = $insertionList . ', '  . $itemDetails['rawData'];
-                                               $isInserted = true;
-                                               break;
+               if ($insertionList) {
+                               // Append data to the end (default):
+                       if ($insertionPosition === '') {
+                               $list.= ($list ? ', ' : '') . $insertionList;
+                               // Insert data before or after insertion points:
+                       } else {
+                               $positions = t3lib_div::trimExplode(',', $insertionPosition, true);
+                               $items = self::explodeItemList($list);
+                               $isInserted = false;
+                                       // Iterate through all fields an check whether it's possible to inserte there:
+                               foreach ($items as $item => &$itemDetails) {
+                                       $needles = self::getInsertionNeedles($item, $itemDetails['details']);
+                                               // Insert data before:
+                                       foreach ($needles['before'] as $needle) {
+                                               if (in_array($needle, $positions)) {
+                                                       $itemDetails['rawData'] = $insertionList . ', '  . $itemDetails['rawData'];
+                                                       $isInserted = true;
+                                                       break;
+                                               }
                                        }
-                               }
-                                       // Insert data after:
-                               foreach ($needles['after'] as $needle) {
-                                       if (in_array($needle, $positions)) {
-                                               $itemDetails['rawData'] .= ', ' . $insertionList;
-                                               $isInserted = true;
+                                               // Insert data after:
+                                       foreach ($needles['after'] as $needle) {
+                                               if (in_array($needle, $positions)) {
+                                                       $itemDetails['rawData'] .= ', ' . $insertionList;
+                                                       $isInserted = true;
+                                                       break;
+                                               }
+                                       }
+                                               // Break if insertion was already done:
+                                       if ($isInserted) {
                                                break;
                                        }
                                }
-                                       // Break if insertion was already done:
-                               if ($isInserted) {
-                                       break;
+                                       // If insertion point could not be determined, append the data:
+                               if (!$isInserted) {
+                                       $list.= ($list ? ', ' : '') . $insertionList;
+                                       // If data was correctly inserted before or after existing items, recreate the list:
+                               } else {
+                                       $list = self::generateItemList($items, true);
                                }
                        }
-                               // If insertion point could not be determined, append the data:
-                       if (!$isInserted) {
-                               $list.= ($list ? ', ' : '') . $insertionList;
-                               // If data was correctly inserted before or after existing items, recreate the list:
-                       } else {
-                               $list = self::generateItemList($items, true);
-                       }
                }
 
                return $list;
@@ -460,27 +466,34 @@ final class t3lib_extMgm {
         *  + insertion: 'field_b, field_d, field_c;;;4-4-4'
         * -> new insertion: 'field_d'
         *
-        * @param       string          $list: The list of items to be extended
         * @param       string          $insertionList: The list of items to inserted
+        * @param       string          $list: The list of items to be extended (default: '')
         * @return      string          Duplicate-free list of items to be inserted
         */
-       protected static function removeDuplicatesForInsertion($list, $insertionList) {
+       protected static function removeDuplicatesForInsertion($insertionList, $list = '') {
                $pattern = '/(^|,)\s*\b([^;,]+)\b[^,]*/';
+               $listItems = array();
 
                if ($list && preg_match_all($pattern, $list, $listMatches)) {
-                       if ($insertionList && preg_match_all($pattern, $insertionList, $insertionListMatches)) {
-                               $duplicates = array_intersect($listMatches[2], $insertionListMatches[2]);
-                               if ($duplicates) {
-                                       foreach ($duplicates as &$duplicate) {
-                                               $duplicate = preg_quote($duplicate, '/');
-                                       }
-                                       $insertionList = preg_replace(
-                                               array('/(^|,)\s*\b(' . implode('|', $duplicates) . ')\b[^,]*(,|$)/', '/,$/'),
-                                               array('\3', ''),
-                                               $insertionList
-                                       );
+                       $listItems = $listMatches[2];
+               }
+
+               if ($insertionList && preg_match_all($pattern, $insertionList, $insertionListMatches)) {
+                       $insertionItems = array();
+                       $insertionDuplicates = false;
+
+                       foreach ($insertionListMatches[2] as $insertionIndex => $insertionItem) {
+                               if (!isset($insertionItems[$insertionItem]) && !in_array($insertionItem, $listItems)) {
+                                       $insertionItems[$insertionItem] = true;
+                               } else {
+                                       unset($insertionListMatches[0][$insertionIndex]);
+                                       $insertionDuplicates = true;
                                }
                        }
+
+                       if ($insertionDuplicates) {
+                               $insertionList = implode('', $insertionListMatches[0]);
+                       }
                }
 
                return $insertionList;