[!!!][TASK] Remove $TYPO3_CONF_VARS['FE']['pageOverlayFields'] 54/51954/5
authorOliver Hader <oliver@typo3.org>
Sun, 5 Mar 2017 10:25:16 +0000 (11:25 +0100)
committerChristian Kuhn <lolli@schwarzbu.ch>
Tue, 14 Mar 2017 21:57:48 +0000 (22:57 +0100)
The configuration $GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields']
is removed from the default configuration as well as from the overlay
handling in PageRepository and RootlineUtility. This setting has been
used to determine overlay fields in the table pages_language_overlay at
a time in the runtime processing when the complete TCA was not fully
available. Since the allowLanguageSynchronization possibility has been
integrated into TYPO3 CMS 8, l10n_mode was available already and the TCA
is loaded as well, the pageOverlayFields settings are superfluous.

Change-Id: I36198d7dec94204fc761048de705aa03a5e931c3
Resolves: #80149
Releases: master
Reviewed-on: https://review.typo3.org/51954
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Susanne Moog <susanne.moog@typo3.org>
Tested-by: Susanne Moog <susanne.moog@typo3.org>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/core/Classes/Migrations/TcaMigration.php
typo3/sysext/core/Classes/Utility/RootlineUtility.php
typo3/sysext/core/Configuration/DefaultConfiguration.php
typo3/sysext/core/Configuration/DefaultConfigurationDescription.php
typo3/sysext/core/Documentation/Changelog/master/Breaking-80149-RemoveGLOBALSTYPO3_CONF_VARSFEpageOverlayFields.rst [new file with mode: 0644]
typo3/sysext/core/Tests/Unit/Migrations/TcaMigrationTest.php
typo3/sysext/frontend/Classes/Page/PageRepository.php

index 84413f7..e199f98 100644 (file)
@@ -66,6 +66,7 @@ class TcaMigration
         $tca = $this->migrateWorkspacesOptions($tca);
         $tca = $this->migrateTranslationTable($tca);
         $tca = $this->migrateL10nModeDefinitions($tca);
+        $tca = $this->migratePageLocalizationDefinitions($tca);
         $tca = $this->migrateRequestUpdate($tca);
         $tca = $this->migrateInputDateTimeToRenderType($tca);
         $tca = $this->migrateWizardEnableByTypeConfigToColumnsOverrides($tca);
@@ -954,8 +955,8 @@ class TcaMigration
                     }
                     $this->messages[] = 'The TCA setting \'mergeIfNotBlank\' was removed '
                         . 'in TCA ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'l10n_mode\']'
-                        . ' and changed to ' . $table . '[\'columns\'][\'' . $fieldName . '\'][\'behaviour\']'
-                        . '[\'allowLanguageSynchronization\'] = true';
+                        . ' and changed to ' . $table . '[\'columns\'][\'' . $fieldName . '\']'
+                        . '[\'config\'][\'behaviour\'][\'allowLanguageSynchronization\'] = true';
                 }
             }
         }
@@ -963,6 +964,87 @@ class TcaMigration
     }
 
     /**
+     * Migrates localization definitions such as "allowLanguageSynchronization"
+     * or "l10n_mode" for tables pages and pages_language_overlay.
+     *
+     * @param array $tca
+     * @return array Migrated TCA
+     */
+    protected function migratePageLocalizationDefinitions(array $tca)
+    {
+        if (
+            empty($tca['pages']['columns'])
+            ||  empty($tca['pages_language_overlay']['columns'])
+        ) {
+            return $tca;
+        }
+
+        // ensure, that localization settings are defined for
+        // pages_language_overlay and not only for pages
+        foreach ($tca['pages']['columns'] as $fieldName => &$fieldConfig) {
+            $l10nMode = $fieldConfig['l10n_mode'] ?? null;
+            $allowLanguageSynchronization = $fieldConfig['config']['behaviour']['allowLanguageSynchronization'] ?? null;
+
+            $oppositeFieldConfig = $tca['pages_language_overlay']['columns'][$fieldName] ?? [];
+            $oppositeL10nMode = $oppositeFieldConfig['l10n_mode'] ?? null;
+            $oppositeAllowLanguageSynchronization = $oppositeFieldConfig['config']['behaviour']['allowLanguageSynchronization'] ?? null;
+
+            if ($l10nMode !== null) {
+                if (!empty($oppositeFieldConfig) && $oppositeL10nMode !== 'exclude') {
+                    $tca['pages_language_overlay']['columns'][$fieldName]['l10n_mode'] = $l10nMode;
+                    $this->messages[] = 'The TCA setting \'l10n_mode\' was migrated '
+                        . 'to TCA pages_language_overlay[\'columns\'][\'' . $fieldName . '\'][\'l10n_mode\'] '
+                        . 'from TCA pages[\'columns\'][\'' . $fieldName . '\'][\'l10n_mode\']';
+                }
+                unset($fieldConfig['l10n_mode']);
+                $this->messages[] = 'The TCA setting \'l10n_mode\' was removed '
+                    . 'in TCA pages[\'columns\'][\'' . $fieldName . '\'][\'l10n_mode\']';
+            }
+
+            if (!empty($allowLanguageSynchronization)) {
+                if (!empty($oppositeFieldConfig) && empty($oppositeAllowLanguageSynchronization)) {
+                    $tca['pages_language_overlay']['columns'][$fieldName]['config']['behaviour']['allowLanguageSynchronization'] = (bool)$allowLanguageSynchronization;
+                    $this->messages[] = 'The TCA setting \'allowLanguageSynchronization\' was migrated '
+                        . 'to TCA pages_language_overlay[\'columns\'][\'' . $fieldName . '\']'
+                        . '[\'config\'][\'behaviour\'][\'allowLanguageSynchronization\'] '
+                        . 'from TCA pages[\'columns\'][\'' . $fieldName . '\']'
+                        . '[\'config\'][\'behaviour\'][\'allowLanguageSynchronization\']';
+                }
+                unset($fieldConfig['config']['behaviour']['allowLanguageSynchronization']);
+                $this->messages[] = 'The TCA setting \'allowLanguageSynchronization\' was removed '
+                    . 'in TCA pages[\'columns\'][\'' . $fieldName . '\']'
+                    . '[\'config\'][\'behaviour\'][\'allowLanguageSynchronization\']';
+            }
+        }
+
+        // clean up localization settings in pages_language_overlay that cannot
+        // be used since the fields in pages are just not configured/available
+        foreach ($tca['pages_language_overlay']['columns'] as $fieldName => &$fieldConfig) {
+            $l10nMode = $fieldConfig['l10n_mode'] ?? null;
+            $allowLanguageSynchronization = $fieldConfig['config']['behaviour']['allowLanguageSynchronization'] ?? null;
+            $oppositeFieldConfig = $tca['pages']['columns'][$fieldName] ?? [];
+
+            if (!empty($oppositeFieldConfig)) {
+                continue;
+            }
+
+            if ($l10nMode !== null) {
+                unset($fieldConfig['l10n_mode']);
+                $this->messages[] = 'The TCA setting \'l10n_mode\' was removed '
+                    . 'in TCA pages_language_overlay[\'columns\'][\'' . $fieldName . '\'][\'l10n_mode\']';
+            }
+            if (!empty($allowLanguageSynchronization)) {
+                unset($fieldConfig['config']['behaviour']['allowLanguageSynchronization']);
+                $this->messages[] = 'The TCA setting \'allowLanguageSynchronization\' was removed '
+                    . 'in TCA pages[\'columns\'][\'' . $fieldName . '\']'
+                    . '[\'config\'][\'behaviour\'][\'allowLanguageSynchronization\']';
+            }
+        }
+
+        return $tca;
+    }
+
+    /**
      * Move ['ctrl']['requestUpdate'] to 'onChange => "reload"' of single fields
      *
      * @param array $tca Incoming TCA
index a05038b..3ef611c 100644 (file)
@@ -264,7 +264,7 @@ class RootlineUtility
                 if ($this->languageUid > 0) {
                     $row = $this->pageContext->getPageOverlay($row, $this->languageUid);
                 }
-                $row = $this->enrichWithRelationFields(isset($row['_PAGES_OVERLAY_UID']) ? $row['_PAGES_OVERLAY_UID'] : $uid, $row);
+                $row = $this->enrichWithRelationFields($row['_PAGES_OVERLAY_UID'] ??  $uid, $row);
                 self::$pageRecordCache[$currentCacheIdentifier] = $row;
             }
         }
@@ -277,16 +277,16 @@ class RootlineUtility
     /**
      * Resolve relations as defined in TCA and add them to the provided $pageRecord array.
      *
-     * @param int $uid Page id
-     * @param array $pageRecord Array with page data to add relation data to.
+     * @param int $uid Either pages.uid or pages_language_overlay.uid if localized
+     * @param array $pageRecord Page record (possibly overlaid) to be extended with relations
      * @throws \RuntimeException
      * @return array $pageRecord with additional relations
      */
     protected function enrichWithRelationFields($uid, array $pageRecord)
     {
-        $pageOverlayFields = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields']);
         $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
 
+        // @todo Remove this special interpretation of relations by consequently using RelationHandler
         foreach ($GLOBALS['TCA']['pages']['columns'] as $column => $configuration) {
             if ($this->columnHasRelationToResolve($configuration)) {
                 $configuration = $configuration['config'];
@@ -295,6 +295,7 @@ class RootlineUtility
                     $loadDBGroup = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\RelationHandler::class);
                     $loadDBGroup->start(
                         $pageRecord[$column],
+                        // @todo That depends on the type (group, select, inline)
                         isset($configuration['allowed']) ? $configuration['allowed'] : $configuration['foreign_table'],
                         $configuration['MM'],
                         $uid,
@@ -305,7 +306,7 @@ class RootlineUtility
                         ? $loadDBGroup->tableArray[$configuration['foreign_table']]
                         : [];
                 } else {
-                    $columnIsOverlaid = in_array($column, $pageOverlayFields, true);
+                    // @todo The assumption is wrong, since group can be used without "MM", but having "allowed"
                     $table = $configuration['foreign_table'];
 
                     $queryBuilder = $connectionPool->getQueryBuilderForTable($table);
@@ -318,7 +319,7 @@ class RootlineUtility
                             $queryBuilder->expr()->eq(
                                 $configuration['foreign_field'],
                                 $queryBuilder->createNamedParameter(
-                                    $columnIsOverlaid ? $uid : $pageRecord['uid'],
+                                    $uid,
                                     \PDO::PARAM_INT
                                 )
                             )
@@ -339,7 +340,7 @@ class RootlineUtility
                             $queryBuilder->expr()->eq(
                                 trim($configuration['foreign_table_field']),
                                 $queryBuilder->createNamedParameter(
-                                    (int)$this->languageUid > 0 && $columnIsOverlaid ? 'pages_language_overlay' : 'pages',
+                                    (int)$this->languageUid > 0 ? 'pages_language_overlay' : 'pages',
                                     \PDO::PARAM_STR
                                 )
                             )
index b840389..b71e695 100644 (file)
@@ -927,7 +927,6 @@ return [
         'get_url_id_token' => '#get_URL_ID_TOK#',
         'content_doktypes' => '1,2,5,7',
         'enable_mount_pids' => true,
-        'pageOverlayFields' => 'uid,doktype,title,subtitle,nav_title,media,keywords,description,abstract,author,author_email,url,urltype,shortcut,shortcut_mode',
         'hidePagesIfNotTranslatedByDefault' => false,
         'eID_include' => [], // Array of key/value pairs where key is "tx_[ext]_[optional suffix]" and value is relative filename of class to include. Key is used as "?eID=" for \TYPO3\CMS\Frontend\Http\RequestHandlerRequestHandler to include the code file which renders the page from that point. (Useful for functionality that requires a low initialization footprint, eg. frontend ajax applications)
         'disableNoCacheParameter' => false,
index 2fb9e41..a62f6e7 100644 (file)
@@ -156,7 +156,6 @@ return [
         'get_url_id_token' => 'This is the token, which is substituted in the output code in order to keep a GET-based session going. Normally the GET-session-id is 5 chars (\'&amp;ftu=\') + hash_length (norm. 10)',
         'content_doktypes' => 'List of pages.doktype values which can contain content (so shortcut pages and external url pages are excluded, but all pages below doktype 199 should be included. doktype=6 is not either (backend users only...).',
         'enable_mount_pids' => 'Boolean: If set to "1", the mount_pid feature allowing \'symlinks\' in the page tree (for frontend operation) is allowed.',
-        'pageOverlayFields' => 'List of fields from the table "pages_language_overlay" which should be overlaid on page records. See \\TYPO3\\CMS\\Frontend\\Page\\PageRepository::getPageOverlay()',
         'hidePagesIfNotTranslatedByDefault' => 'Boolean: If TRUE, pages that has no translation will be hidden by default. Basically this will inverse the effect of the page localization setting "Hide page if no translation for current language exists" to "Show page even if no translation exists"',
         'disableNoCacheParameter' => 'Boolean: If set, the no_cache request parameter will become ineffective. This is currently still an experimental feature and will require a website only with plugins that don\'t use this parameter. However, using "&amp;no_cache=1" should be avoided anyway because there are better ways to disable caching for a certain part of the website (see COA_INT/USER_INT documentation in TSref).',
         'cHashExcludedParameters' => 'String: The the given parameters will be ignored in the cHash calculation. Example: L,tx_search_pi1[query]',
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-80149-RemoveGLOBALSTYPO3_CONF_VARSFEpageOverlayFields.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-80149-RemoveGLOBALSTYPO3_CONF_VARSFEpageOverlayFields.rst
new file mode 100644 (file)
index 0000000..962ffff
--- /dev/null
@@ -0,0 +1,46 @@
+.. include:: ../../Includes.txt
+
+================================================================================
+Breaking: #80149 - Remove $GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields']
+================================================================================
+
+See :issue:`80149`
+
+Description
+===========
+
+The configuration `$GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields']` is
+removed from the default configuration as well as from the overlay handling in
+PageRepository and RootlineUtility.
+
+This setting has been used to determine overlay fields in the table
+`pages_language_overlay` at a time in the runtime processing when the
+complete TCA was not fully available. Since the `allowLanguageSynchronization`
+possibility has been integrated into TYPO3 CMS 8, `l10n_mode` was available
+already and the TCA is loaded as well, the `pageOverlayFields` settings
+are superfluous.
+
+
+Impact
+======
+
+Since `$GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields']` was used as a
+filter for field names to be taken from `pages_language_overlay` and merged
+onto those fields in `pages`, all fields are overlaid per default.
+
+
+Affected Installations
+======================
+
+All installations having custom fields in table `pages_language_overlay` and
+custom settings in `$GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields']`.
+
+
+Migration
+=========
+
+Check the TCA of `pages_language_overlay` and remove l10n_mode for those fields
+that previously were not defined in `$GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields']`
+ and thus should not be overlaid.
+
+.. index:: Frontend, TCA
\ No newline at end of file
index 4054a64..25b19ff 100644 (file)
@@ -2149,6 +2149,193 @@ class TcaMigrationTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
     /**
      * @return array
      */
+    public function migratePageLocalizationDefinitionsDataProvider()
+    {
+        return [
+            'missing l10n_mode' => [
+                [
+                    'pages' => [
+                        'columns' => [
+                            'aColumn' => [
+                                'config' => [
+                                    'type' => 'input',
+                                ],
+                                'l10n_mode' => 'any-possible-value',
+                            ],
+                        ],
+                    ],
+                    'pages_language_overlay' => [
+                        'columns' => [
+                            'aColumn' => [
+                                'config' => [
+                                    'type' => 'input',
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+                [
+                    'pages' => [
+                        'columns' => [
+                            'aColumn' => [
+                                'config' => [
+                                    'type' => 'input',
+                                ],
+                            ],
+                        ],
+                    ],
+                    'pages_language_overlay' => [
+                        'columns' => [
+                            'aColumn' => [
+                                'config' => [
+                                    'type' => 'input',
+                                ],
+                                'l10n_mode' => 'any-possible-value',
+                            ],
+                        ],
+                    ],
+                ]
+            ],
+            'missing allowLanguageSynchronization' => [
+                [
+                    'pages' => [
+                        'columns' => [
+                            'aColumn' => [
+                                'config' => [
+                                    'type' => 'input',
+                                    'behaviour' => [
+                                        'allowLanguageSynchronization' => true,
+                                    ]
+                                ],
+                            ],
+                        ],
+                    ],
+                    'pages_language_overlay' => [
+                        'columns' => [
+                            'aColumn' => [
+                                'config' => [
+                                    'type' => 'input',
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+                [
+                    'pages' => [
+                        'columns' => [
+                            'aColumn' => [
+                                'config' => [
+                                    'type' => 'input',
+                                    'behaviour' => []
+                                ],
+                            ],
+                        ],
+                    ],
+                    'pages_language_overlay' => [
+                        'columns' => [
+                            'aColumn' => [
+                                'config' => [
+                                    'type' => 'input',
+                                    'behaviour' => [
+                                        'allowLanguageSynchronization' => true,
+                                    ]
+                                ],
+                            ],
+                        ],
+                    ],
+                ]
+            ],
+            'superfluous l10n_mode' => [
+                [
+                    'pages' => [
+                        'columns' => [
+                            'aColumn' => [],
+                        ],
+                    ],
+                    'pages_language_overlay' => [
+                        'columns' => [
+                            'aColumn' => [
+                                'config' => [
+                                    'type' => 'input',
+                                ],
+                                'l10n_mode' => 'any-possible-value',
+                            ],
+                        ],
+                    ],
+                ],
+                [
+                    'pages' => [
+                        'columns' => [
+                            'aColumn' => [],
+                        ],
+                    ],
+                    'pages_language_overlay' => [
+                        'columns' => [
+                            'aColumn' => [
+                                'config' => [
+                                    'type' => 'input',
+                                ],
+                            ],
+                        ],
+                    ],
+                ]
+            ],
+            'superfluous allowLanguageSynchronization' => [
+                [
+                    'pages' => [
+                        'columns' => [
+                            'aColumn' => [],
+                        ],
+                    ],
+                    'pages_language_overlay' => [
+                        'columns' => [
+                            'aColumn' => [
+                                'config' => [
+                                    'type' => 'input',
+                                    'behaviour' => [
+                                        'allowLanguageSynchronization' => true,
+                                    ]
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+                [
+                    'pages' => [
+                        'columns' => [
+                            'aColumn' => [],
+                        ],
+                    ],
+                    'pages_language_overlay' => [
+                        'columns' => [
+                            'aColumn' => [
+                                'config' => [
+                                    'type' => 'input',
+                                    'behaviour' => []
+                                ],
+                            ],
+                        ],
+                    ],
+                ]
+            ],
+        ];
+    }
+
+    /**
+     * @param array $givenConfig
+     * @param array $expectedConfig
+     * @test
+     * @dataProvider migratePageLocalizationDefinitionsDataProvider
+     */
+    public function migratePageLocalizationDefinitions(array $givenConfig, array $expectedConfig)
+    {
+        $subject = new TcaMigration();
+        $this->assertEquals($expectedConfig, $subject->migrate($givenConfig));
+    }
+
+    /**
+     * @return array
+     */
     public function migrateMovesRequestUpdateCtrlFieldToColumnsDataProvider()
     {
         return [
index 40315bf..6ebdd8d 100644 (file)
@@ -436,14 +436,9 @@ class PageRepository
         }
         // If language UID is different from zero, do overlay:
         if ($lUid) {
-            $fieldArr = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['FE']['pageOverlayFields'], true);
             $page_ids = [];
 
             $origPage = reset($pagesInput);
-            if (is_array($origPage)) {
-                // Make sure that only fields which exist in the first incoming record are overlaid!
-                $fieldArr = array_intersect($fieldArr, array_keys($this->purgeComputedProperties($origPage)));
-            }
             foreach ($pagesInput as $origPage) {
                 if (is_array($origPage)) {
                     // Was the whole record
@@ -453,47 +448,42 @@ class PageRepository
                     $page_ids[] = $origPage;
                 }
             }
-            if (!empty($fieldArr)) {
-                if (!in_array('pid', $fieldArr, true)) {
-                    $fieldArr[] = 'pid';
-                }
-                // NOTE regarding the query restrictions
-                // Currently the showHiddenRecords of TSFE set will allow
-                // pages_language_overlay records to be selected as they are
-                // child-records of a page.
-                // However you may argue that the showHiddenField flag should
-                // determine this. But that's not how it's done right now.
-                // Selecting overlay record:
-                $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
-                    ->getQueryBuilderForTable('pages_language_overlay');
-                $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
-                $result = $queryBuilder->select(...$fieldArr)
-                    ->from('pages_language_overlay')
-                    ->where(
-                        $queryBuilder->expr()->in(
-                            'pid',
-                            $queryBuilder->createNamedParameter($page_ids, Connection::PARAM_INT_ARRAY)
-                        ),
-                        $queryBuilder->expr()->eq(
-                            'sys_language_uid',
-                            $queryBuilder->createNamedParameter($lUid, \PDO::PARAM_INT)
-                        )
+            // NOTE regarding the query restrictions
+            // Currently the showHiddenRecords of TSFE set will allow
+            // pages_language_overlay records to be selected as they are
+            // child-records of a page.
+            // However you may argue that the showHiddenField flag should
+            // determine this. But that's not how it's done right now.
+            // Selecting overlay record:
+            $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+                ->getQueryBuilderForTable('pages_language_overlay');
+            $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class));
+            $result = $queryBuilder->select('*')
+                ->from('pages_language_overlay')
+                ->where(
+                    $queryBuilder->expr()->in(
+                        'pid',
+                        $queryBuilder->createNamedParameter($page_ids, Connection::PARAM_INT_ARRAY)
+                    ),
+                    $queryBuilder->expr()->eq(
+                        'sys_language_uid',
+                        $queryBuilder->createNamedParameter($lUid, \PDO::PARAM_INT)
                     )
-                    ->execute();
-
-                $overlays = [];
-                while ($row = $result->fetch()) {
-                    $this->versionOL('pages_language_overlay', $row);
-                    if (is_array($row)) {
-                        $row['_PAGES_OVERLAY'] = true;
-                        $row['_PAGES_OVERLAY_UID'] = $row['uid'];
-                        $row['_PAGES_OVERLAY_LANGUAGE'] = $lUid;
-                        $origUid = $row['pid'];
-                        // Unset vital fields that are NOT allowed to be overlaid:
-                        unset($row['uid']);
-                        unset($row['pid']);
-                        $overlays[$origUid] = $row;
-                    }
+                )
+                ->execute();
+
+            $overlays = [];
+            while ($row = $result->fetch()) {
+                $this->versionOL('pages_language_overlay', $row);
+                if (is_array($row)) {
+                    $row['_PAGES_OVERLAY'] = true;
+                    $row['_PAGES_OVERLAY_UID'] = $row['uid'];
+                    $row['_PAGES_OVERLAY_LANGUAGE'] = $lUid;
+                    $origUid = $row['pid'];
+                    // Unset vital fields that are NOT allowed to be overlaid:
+                    unset($row['uid']);
+                    unset($row['pid']);
+                    $overlays[$origUid] = $row;
                 }
             }
         }