[BUGFIX] CE "menu" subtype "keywords" generated wrong SQL 67/51067/4
authorSusanne Moog <susanne.moog@typo3.com>
Fri, 30 Dec 2016 08:50:39 +0000 (09:50 +0100)
committerMorton Jonuschat <m.jonuschat@mojocode.de>
Fri, 30 Dec 2016 16:02:51 +0000 (17:02 +0100)
When using the content element Menu with subtype "keywords"
the generated SQL contained non-replaced prepared statement
params resulting in a query error.

The whole query was rewritten to use the doctrine query builder directly.

Change-Id: I688a0f61eabf93c05e08841d57888be6f02226c7
Resolves: #79115
Releases: master
Reviewed-on: https://review.typo3.org/51067
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Benjamin Kott <benjamin.kott@outlook.com>
Tested-by: Benjamin Kott <benjamin.kott@outlook.com>
Reviewed-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Tested-by: Morton Jonuschat <m.jonuschat@mojocode.de>
typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php

index b393990..d564ea9 100644 (file)
@@ -960,10 +960,6 @@ abstract class AbstractMenuContentObject
         }
         // Max number of items
         $limit = MathUtility::forceIntegerInRange($this->conf['special.']['limit'], 0, 100);
-        $extraWhere = ' AND pages.uid<>' . $specialValue . ($this->conf['includeNotInMenu'] ? '' : ' AND pages.nav_hide=0') . $this->getDoktypeExcludeWhere();
-        if ($this->conf['special.']['excludeNoSearchPages']) {
-            $extraWhere .= ' AND pages.no_search=0';
-        }
         // Start point
         $eLevel = $this->parent_cObj->getKey(isset($this->conf['special.']['entryLevel.'])
             ? $this->parent_cObj->stdWrap($this->conf['special.']['entryLevel'], $this->conf['special.']['entryLevel.'])
@@ -991,15 +987,53 @@ abstract class AbstractMenuContentObject
                     )
                 );
             }
-            $where = empty($keyWordsWhereArr) ? '' : '(' . implode(' OR ', $keyWordsWhereArr) . ')';
-            $statement = $this->parent_cObj->exec_getQuery('pages', [
-                'pidInList' => '0',
-                'uidInList' => $id_list,
-                'where' => $where . $extraWhere,
-                'orderBy' => $sortingField ?: $sortField . ' desc',
-                'max' => $limit
-            ]);
-            while ($row = $statement->fetch()) {
+            $queryBuilder
+                ->select('*')
+                ->from('pages')
+                ->where(
+                    $queryBuilder->expr()->in(
+                        'uid',
+                        GeneralUtility::intExplode(',', $id_list, true)
+                    ),
+                    $queryBuilder->expr()->neq(
+                        'uid',
+                        $queryBuilder->createNamedParameter($specialValue, \PDO::PARAM_INT)
+                    )
+                );
+
+            if (count($keyWordsWhereArr) !== 0) {
+                $queryBuilder->andWhere($queryBuilder->expr()->orX(...$keyWordsWhereArr));
+            }
+
+            if ($this->doktypeExcludeList) {
+                $queryBuilder->andWhere(
+                    $queryBuilder->expr()->notIn(
+                        'pages.doktype',
+                        GeneralUtility::intExplode(',', $this->doktypeExcludeList, true)
+                    )
+                );
+            }
+
+            if (!$this->conf['includeNotInMenu']) {
+                $queryBuilder->andWhere($queryBuilder->expr()->eq('pages.nav_hide', 0));
+            }
+
+            if ($this->conf['special.']['excludeNoSearchPages']) {
+                $queryBuilder->andWhere($queryBuilder->expr()->eq('pages.no_search', 0));
+            }
+
+            if ($limit > 0) {
+                $queryBuilder->setMaxResults($limit);
+            }
+
+            if ($sortingField) {
+                $queryBuilder->orderBy($sortingField);
+            } else {
+                $queryBuilder->orderBy($sortField, 'desc');
+            }
+
+            $result = $queryBuilder->execute();
+            while ($row = $result->fetch()) {
                 $tsfe->sys_page->versionOL('pages', $row, true);
                 if (is_array($row)) {
                     $menuItems[$row['uid']] = $this->sys_page->getPageOverlay($row);