[TASK] Reduce PageLayoutController and PageLayoutView dependencies 38/42838/2
authorOliver Hader <oliver@typo3.org>
Sat, 22 Aug 2015 11:48:15 +0000 (13:48 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Thu, 17 Sep 2015 21:16:52 +0000 (23:16 +0200)
This is a follow-up to #68395 to reduce complexity and exposed
public API of that change.

Even if class components have the names "controller" and "view",
which implies an underlying MVC-stack, the PageLayout components
are far from using the pattern. That's why it's quite fine to put
processing logic to the place where it makes most sense and where
dependencies and cross-calls to other objects are kept low.

This change is only about refactoring and reducing the public API
in terms of information hiding and encapsulation. Besides that
the $languagesInColumnCache class variable was defined but never
use - which is changed now as well. Further flaws concerning
proper record selection are part of another change.

Related: #68395
Resolves: #69261
Releases: master
Change-Id: I8bb7737d154a5d2c7a584dbe11fd0a5abfabafba
Reviewed-on: http://review.typo3.org/42838
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/backend/Classes/Controller/PageLayoutController.php
typo3/sysext/backend/Classes/View/PageLayoutView.php
typo3/sysext/core/Classes/DataHandling/DataHandler.php

index c39aa50..78f6e7a 100755 (executable)
@@ -289,21 +289,6 @@ class PageLayoutController {
        protected $closeUrl;
 
        /**
-        * Caches the available languages in a colPos
-        *
-        * @var array
-        */
-       protected $languagesInColumnCache = array();
-
-       /**
-        * Caches the amount of content elements as a matrix
-        *
-        * @var array
-        * @internal
-        */
-       public $contentElementCache = array();
-
-       /**
         * @var IconFactory
         */
        protected $iconFactory;
@@ -1289,92 +1274,6 @@ class PageLayoutController {
        }
 
        /**
-        * Get used languages in a colPos of a page
-        *
-        * @param int $pageId
-        * @param int $colPos
-        * @return bool|\mysqli_result|object
-        */
-       public function getUsedLanguagesInPageAndColumn($pageId, $colPos) {
-               if (!isset($languagesInColumnCache[$pageId])) {
-                       $languagesInColumnCache[$pageId] = array();
-               }
-               if (!isset($languagesInColumnCache[$pageId][$colPos])) {
-                       $languagesInColumnCache[$pageId][$colPos] = array();
-               }
-
-               if (empty($languagesInColumnCache[$pageId][$colPos])) {
-                       $exQ = BackendUtility::deleteClause('tt_content') .
-                               ($this->getBackendUser()->isAdmin() ? '' : ' AND sys_language.hidden=0');
-
-                       $databaseConnection = $this->getDatabaseConnection();
-                       $res = $databaseConnection->exec_SELECTquery(
-                               'sys_language.*',
-                               'tt_content,sys_language',
-                               'tt_content.sys_language_uid=sys_language.uid AND tt_content.colPos = ' . (int)$colPos . ' AND tt_content.pid=' . (int)$pageId . $exQ .
-                               BackendUtility::versioningPlaceholderClause('tt_content'),
-                               'tt_content.sys_language_uid,sys_language.uid,sys_language.pid,sys_language.tstamp,sys_language.hidden,sys_language.title,sys_language.language_isocode,sys_language.static_lang_isocode,sys_language.flag',
-                               'sys_language.title'
-                       );
-                       while ($row = $databaseConnection->sql_fetch_assoc($res)) {
-                               $languagesInColumnCache[$pageId][$colPos][$row['uid']] = $row;
-                       }
-                       $databaseConnection->sql_free_result($res);
-               }
-
-               return $languagesInColumnCache[$pageId][$colPos];
-       }
-
-       /**
-        * Check if a column of a page for a language is empty. Translation records are ignored here!
-        *
-        * @param int $colPos
-        * @param int $languageId
-        * @return bool
-        */
-       public function isColumnEmpty($colPos, $languageId) {
-               foreach ($this->contentElementCache[$languageId][$colPos] as $uid => $row) {
-                       if ((int)$row['l18n_parent'] === 0) {
-                               return FALSE;
-                       }
-               }
-               return TRUE;
-       }
-
-       /**
-        * Get elements for a column and a language
-        *
-        * @param int $pageId
-        * @param int $colPos
-        * @param int $languageId
-        * @return array
-        */
-       public function getElementsFromColumnAndLanguage($pageId, $colPos, $languageId) {
-               if (!isset($this->contentElementCache[$languageId][$colPos])) {
-                       $languageId = (int)$languageId;
-                       $whereClause = 'tt_content.pid=' . (int)$pageId . ' AND tt_content.colPos=' . (int)$colPos . ' AND tt_content.sys_language_uid=' . $languageId . BackendUtility::deleteClause('tt_content');
-                       if ($languageId > 0) {
-                               $whereClause .= ' AND tt_content.l18n_parent=0 AND sys_language.uid=' . $languageId . ($this->getBackendUser()->isAdmin() ? '' : ' AND sys_language.hidden=0');
-                       }
-
-                       $databaseConnection = $this->getDatabaseConnection();
-                       $res = $databaseConnection->exec_SELECTquery(
-                               'tt_content.uid',
-                               'tt_content,sys_language',
-                               $whereClause
-                       );
-                       while ($row = $databaseConnection->sql_fetch_assoc($res)) {
-                               $this->contentElementCache[$languageId][$colPos][$row['uid']] = $row;
-                       }
-                       $databaseConnection->sql_free_result($res);
-               }
-               if (is_array($this->contentElementCache[$languageId][$colPos])) {
-                       return array_keys($this->contentElementCache[$languageId][$colPos]);
-               }
-               return array();
-       }
-
-       /**
         * Check the editlock access
         *
         * @return bool
index bea9bcd..86fe9cd 100644 (file)
@@ -183,6 +183,21 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
        protected $pageinfo;
 
        /**
+        * Caches the available languages in a colPos
+        *
+        * @var array
+        */
+       protected $languagesInColumnCache = array();
+
+       /**
+        * Caches the amount of content elements as a matrix
+        *
+        * @var array
+        * @internal
+        */
+       protected $contentElementCache = array();
+
+       /**
         * @var IconFactory
         */
        protected $iconFactory;
@@ -445,8 +460,8 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
                foreach ($langListArr as $lP) {
                        $lP = (int)$lP;
 
-                       if (!isset($this->getPageLayoutController()->contentElementCache[$lP])) {
-                               $this->getPageLayoutController()->contentElementCache[$lP] = array();
+                       if (!isset($this->contentElementCache[$lP])) {
+                               $this->contentElementCache[$lP] = array();
                        }
 
                        if (count($langListArr) === 1 || $lP === 0) {
@@ -462,8 +477,8 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
                        $contentRecordsPerColumn = $this->getContentRecordsPerColumn('table', $id, array_values($cList), $showLanguage);
                        // For each column, render the content into a variable:
                        foreach ($cList as $key) {
-                               if (!isset($this->getPageLayoutController()->contentElementCache[$lP][$key])) {
-                                       $this->getPageLayoutController()->contentElementCache[$lP][$key] = array();
+                               if (!isset($this->contentElementCache[$lP][$key])) {
+                                       $this->contentElementCache[$lP][$key] = array();
                                }
 
                                if (!$lP) {
@@ -497,7 +512,7 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
                                $this->generateTtContentDataArray($rowArr);
 
                                foreach ((array)$rowArr as $rKey => $row) {
-                                       $this->getPageLayoutController()->contentElementCache[$lP][$key][$row['uid']] = $row;
+                                       $this->contentElementCache[$lP][$key][$row['uid']] = $row;
                                        if ($this->tt_contentConfig['languageMode']) {
                                                $languageColumn[$key][$lP] = $head[$key] . $content[$key];
                                                if (!$this->defLangBinding) {
@@ -1580,7 +1595,7 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
 
                $copyFromLanguageMenu = '';
                foreach ($this->getLanguagesToCopyFrom(GeneralUtility::_GP('id'), $lP, $colPos) as $languageId => $label) {
-                       $elementsInColumn = $languageId === 0 ? $defLanguageCount : $this->getPageLayoutController()->getElementsFromColumnAndLanguage(GeneralUtility::_GP('id'), $colPos, $languageId);
+                       $elementsInColumn = $languageId === 0 ? $defLanguageCount : $this->getElementsFromColumnAndLanguage(GeneralUtility::_GP('id'), $colPos, $languageId);
                        if (!empty($elementsInColumn)) {
                                $onClick = 'window.location.href=' . GeneralUtility::quoteJSvalue($this->getPageLayoutController()->doc->issueCommand('&cmd[tt_content][' . implode(',', $elementsInColumn) . '][copyFromLanguage]=' . GeneralUtility::_GP('id') . ',' . $lP)) . '; return false;';
                                $copyFromLanguageMenu .= '<li><a href="#" onclick="' . htmlspecialchars($onClick) . '">' . $this->languageFlag($languageId, FALSE) . ' ' . htmlspecialchars($label) . '</a></li>' . LF;
@@ -1607,7 +1622,7 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
                                                $onClick,
                                                $this->getLanguageService()->getLL('newPageContent_copyForLang', TRUE) . ' [' . count($defLanguageCount) . ']'
                                        );
-                       if ($copyFromLanguageMenu !== '' && $this->getPageLayoutController()->isColumnEmpty($colPos, $lP)) {
+                       if ($copyFromLanguageMenu !== '' && $this->isColumnEmpty($colPos, $lP)) {
                                $theNewButton .= '<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">'
                                        . '<span class="caret"></span>'
                                        . '<span class="sr-only">Toggle Dropdown</span>'
@@ -1616,7 +1631,7 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
                        }
                        $theNewButton .= '</div>';
                } else {
-                       if ($copyFromLanguageMenu !== '' && $this->getPageLayoutController()->isColumnEmpty($colPos, $lP)) {
+                       if ($copyFromLanguageMenu !== '' && $this->isColumnEmpty($colPos, $lP)) {
                                $theNewButton =
                                        '<div class="btn-group">'
                                        . '<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">'
@@ -1731,11 +1746,11 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
         */
        protected function getLanguagesToCopyFrom($pageId, $excludeLanguage = NULL, $colPos = 0) {
                $langSelItems = array();
-               if (!$this->getPageLayoutController()->isColumnEmpty($colPos, 0)) {
+               if (!$this->isColumnEmpty($colPos, 0)) {
                        $langSelItems[0] = $this->getLanguageService()->getLL('newPageContent_translateFromDefault', TRUE);
                }
 
-               $languages = $this->getPageLayoutController()->getUsedLanguagesInPageAndColumn($pageId, $colPos);
+               $languages = $this->getUsedLanguagesInPageAndColumn($pageId, $colPos);
                foreach ($languages as $uid => $language) {
                        $langSelItems[$uid] = sprintf($this->getLanguageService()->getLL('newPageContent_copyFromAnotherLang'), htmlspecialchars($language['title']));
                }
@@ -1748,6 +1763,92 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
        }
 
        /**
+        * Get used languages in a colPos of a page
+        *
+        * @param int $pageId
+        * @param int $colPos
+        * @return bool|\mysqli_result|object
+        */
+       protected function getUsedLanguagesInPageAndColumn($pageId, $colPos) {
+               if (!isset($this->languagesInColumnCache[$pageId])) {
+                       $this->languagesInColumnCache[$pageId] = array();
+               }
+               if (!isset($this->languagesInColumnCache[$pageId][$colPos])) {
+                       $this->languagesInColumnCache[$pageId][$colPos] = array();
+               }
+
+               if (empty($this->languagesInColumnCache[$pageId][$colPos])) {
+                       $exQ = BackendUtility::deleteClause('tt_content') .
+                               ($this->getBackendUser()->isAdmin() ? '' : ' AND sys_language.hidden=0');
+
+                       $databaseConnection = $this->getDatabaseConnection();
+                       $res = $databaseConnection->exec_SELECTquery(
+                               'sys_language.*',
+                               'tt_content,sys_language',
+                               'tt_content.sys_language_uid=sys_language.uid AND tt_content.colPos = ' . (int)$colPos . ' AND tt_content.pid=' . (int)$pageId . $exQ .
+                               BackendUtility::versioningPlaceholderClause('tt_content'),
+                               'tt_content.sys_language_uid,sys_language.uid,sys_language.pid,sys_language.tstamp,sys_language.hidden,sys_language.title,sys_language.language_isocode,sys_language.static_lang_isocode,sys_language.flag',
+                               'sys_language.title'
+                       );
+                       while ($row = $databaseConnection->sql_fetch_assoc($res)) {
+                               $this->languagesInColumnCache[$pageId][$colPos][$row['uid']] = $row;
+                       }
+                       $databaseConnection->sql_free_result($res);
+               }
+
+               return $this->languagesInColumnCache[$pageId][$colPos];
+       }
+
+       /**
+        * Check if a column of a page for a language is empty. Translation records are ignored here!
+        *
+        * @param int $colPos
+        * @param int $languageId
+        * @return bool
+        */
+       protected function isColumnEmpty($colPos, $languageId) {
+               foreach ($this->contentElementCache[$languageId][$colPos] as $uid => $row) {
+                       if ((int)$row['l18n_parent'] === 0) {
+                               return FALSE;
+                       }
+               }
+               return TRUE;
+       }
+
+       /**
+        * Get elements for a column and a language
+        *
+        * @param int $pageId
+        * @param int $colPos
+        * @param int $languageId
+        * @return array
+        */
+       protected function getElementsFromColumnAndLanguage($pageId, $colPos, $languageId) {
+               if (!isset($this->contentElementCache[$languageId][$colPos])) {
+                       $languageId = (int)$languageId;
+                       $whereClause = 'tt_content.pid=' . (int)$pageId . ' AND tt_content.colPos=' . (int)$colPos . ' AND tt_content.sys_language_uid=' . $languageId . BackendUtility::deleteClause('tt_content');
+                       if ($languageId > 0) {
+                               $whereClause .= ' AND tt_content.l18n_parent=0 AND sys_language.uid=' . $languageId . ($this->getBackendUser()->isAdmin() ? '' : ' AND sys_language.hidden=0');
+                       }
+
+                       $databaseConnection = $this->getDatabaseConnection();
+                       $res = $databaseConnection->exec_SELECTquery(
+                               'tt_content.uid',
+                               'tt_content,sys_language',
+                               $whereClause
+                       );
+                       while ($row = $databaseConnection->sql_fetch_assoc($res)) {
+                               $this->contentElementCache[$languageId][$colPos][$row['uid']] = $row;
+                       }
+                       $databaseConnection->sql_free_result($res);
+               }
+               if (is_array($this->contentElementCache[$languageId][$colPos])) {
+                       return array_keys($this->contentElementCache[$languageId][$colPos]);
+               }
+               return array();
+       }
+
+       /**
         * Make selector box for creating new translation in a language
         * Displays only languages which are not yet present for the current page and
         * that are not disabled with page TS.
index 909ca96..6ce96a6 100644 (file)
@@ -4657,7 +4657,7 @@ class DataHandler {
         * @param string $value Comma separated list of the destination and the target language
         * @return void
         */
-       public function copyRecordFromLanguage($table, $id, $value) {
+       protected function copyRecordFromLanguage($table, $id, $value) {
                list($destination, $language) = GeneralUtility::intExplode(',', $value);
 
                // array_reverse is required to keep the order of elements