[BUGFIX] Shortcut list (top right) is filled by duplicated entries 79/42279/8
authorJan Runte <jan.runte@hmmh.de>
Wed, 5 Aug 2015 14:10:17 +0000 (16:10 +0200)
committerFrank Nägler <frank.naegler@typo3.org>
Wed, 5 Aug 2015 20:08:16 +0000 (22:08 +0200)
The AjaxShortcut function has no validation of an already existing entry in the
shortcut list before it create a new one. At this case you have multiple
duplicated entries in your shortcut list and that is simply not expected and
makes no sense.

Additional behaviour for "Delete" buttons in the shortcut list:
After clicking a "Delete" action of a shortcut list entry you get a
modal window to confirm. But the gui blocker for the modal window cannot
completely disallow the shortcut buttons outside the modal context. In this case
the zIndex for the "modal" class (with gui blocker) is simply wrong here
(too small).

Resolves: #68297
Releases: master
Change-Id: I3d10e25a90055d935e33c005274de87d6de098ef
Reviewed-on: http://review.typo3.org/42279
Reviewed-by: Daniel Goerz <ervaude@gmail.com>
Tested-by: Daniel Goerz <ervaude@gmail.com>
Reviewed-by: Frank Nägler <frank.naegler@typo3.org>
Tested-by: Frank Nägler <frank.naegler@typo3.org>
Build/Resources/Public/Less/_variables.less
typo3/sysext/backend/Classes/Backend/ToolbarItems/ShortcutToolbarItem.php
typo3/sysext/t3skin/Resources/Public/Css/backend.css

index acc54f7..882b668 100644 (file)
 @headings-small-color:        @gray;
 @dl-horizontal-offset:        90px;
 @hr-border:                   #7a7a7a;
+
+// Modal
+@zindex-modal: 5000;
\ No newline at end of file
index 034a450..2425d4f 100644 (file)
@@ -18,6 +18,7 @@ use TYPO3\CMS\Backend\Module\ModuleLoader;
 use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Backend\Utility\IconUtility;
+use TYPO3\CMS\Core\Database\PreparedStatement;
 use TYPO3\CMS\Core\Http\AjaxRequestHandler;
 use TYPO3\CMS\Core\Page\PageRenderer;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -481,23 +482,23 @@ class ShortcutToolbarItem implements ToolbarItemInterface {
         * Creates a shortcut through an AJAX call
         *
         * @param array $params Array of parameters from the AJAX interface, currently unused
-        * @param \TYPO3\CMS\Core\Http\AjaxRequestHandler $ajaxObj Oject of type AjaxRequestHandler
+        * @param AjaxRequestHandler $ajaxObj Oject of type AjaxRequestHandler
+        *
         * @return void
         */
        public function createAjaxShortcut($params = array(), AjaxRequestHandler $ajaxObj = NULL) {
-               $databaseConnection = $this->getDatabaseConnection();
                $languageService = $this->getLanguageService();
-               $shortcutCreated = 'failed';
+
                // Default name
                $shortcutName = 'Shortcut';
                $shortcutNamePrepend = '';
                $url = GeneralUtility::_POST('url');
-               $module = GeneralUtility::_POST('module');
-               $motherModule = GeneralUtility::_POST('motherModName');
+
                // Determine shortcut type
                $url = rawurldecode($url);
                $queryParts = parse_url($url);
                $queryParameters = GeneralUtility::explodeUrl2Array($queryParts['query'], TRUE);
+
                // Proceed only if no scheme is defined, as URL is expected to be relative
                if (empty($queryParts['scheme'])) {
                        if (is_array($queryParameters['edit'])) {
@@ -516,11 +517,12 @@ class ShortcutToolbarItem implements ToolbarItemInterface {
                                $shortcut['table'] = '';
                                $shortcut['recordid'] = 0;
                        }
-                       // Lookup the title of this page and use it as default description
 
+                       // Lookup the title of this page and use it as default description
                        $pageId = (int)($shortcut['pid'] ?: ($shortcut['recordid'] ?: $this->getLinkedPageId($url)));
                        if ($pageId) {
                                $page = BackendUtility::getRecord('pages', $pageId);
+
                                if (!empty($page)) {
                                        // Set the name to the title of the page
                                        if ($shortcut['type'] === 'other') {
@@ -531,6 +533,7 @@ class ShortcutToolbarItem implements ToolbarItemInterface {
                                }
                        } else {
                                $dirName = urldecode($pageId);
+
                                if (preg_match('/\\/$/', $dirName)) {
                                        // If $pageId is a string and ends with a slash,
                                        // assume it is a fileadmin reference and set
@@ -538,25 +541,96 @@ class ShortcutToolbarItem implements ToolbarItemInterface {
                                        $shortcutName .= ' ' . basename($dirName);
                                }
                        }
-                       // adding the shortcut
-                       if ($module && $url) {
-                               if ($shortcutName === 'Shortcut' && !empty($languageService->moduleLabels['labels'][$module . '_tablabel'])) {
-                                       $shortcutName = $languageService->moduleLabels['labels'][$module . '_tablabel'];
-                               }
-                               $fieldValues = array(
-                                       'userid' => $this->getBackendUser()->user['uid'],
-                                       'module_name' => $module . '|' . $motherModule,
-                                       'url' => $url,
-                                       'description' => $shortcutName,
-                                       'sorting' => $GLOBALS['EXEC_TIME']
-                               );
-                               $databaseConnection->exec_INSERTquery('sys_be_shortcuts', $fieldValues);
-                               if ($databaseConnection->sql_affected_rows() == 1) {
-                                       $shortcutCreated = 'success';
-                               }
+
+                       $this->tryAddingTheShortcut($ajaxObj, $url, $shortcutName);
+               }
+       }
+
+       /**
+        * Try to adding a shortcut
+        *
+        * @param AjaxRequestHandler $ajaxObj Oject of type AjaxRequestHandler
+        * @param string $url
+        * @param string $shortcutName
+        *
+        * @return void
+        */
+       protected function tryAddingTheShortcut(AjaxRequestHandler $ajaxObj, $url, $shortcutName) {
+               $module = GeneralUtility::_POST('module');
+               $shortcutCreated = 'failed';
+
+               if (!empty($module) && !empty($url)) {
+                       $shortcutCreated = 'alreadyExists';
+
+                       if (!$this->shortcutExists($url)) {
+                               $shortcutCreated = $this->addShortcut($url, $shortcutName, $module);
                        }
-                       $ajaxObj->addContent('create', $shortcutCreated);
                }
+
+               $ajaxObj->addContent('create', $shortcutCreated);
+       }
+
+       /**
+        * Add a shortcut now with some user stuffs
+        *
+        * @param string $url
+        * @param string $shortcutName
+        * @param string $module
+        *
+        * @return string
+        */
+       protected function addShortcut($url, $shortcutName, $module) {
+               // Shorts
+               $db = $this->getDatabaseConnection();
+               $lS = $this->getLanguageService();
+
+               if ($shortcutName === 'Shortcut' && !empty($lS->moduleLabels['labels'][$module . '_tablabel'])) {
+                       $shortcutName = $lS->moduleLabels['labels'][$module . '_tablabel'];
+               }
+
+               $motherModule = GeneralUtility::_POST('motherModName');
+               $fieldValues = [
+                       'userid' => $this->getBackendUser()->user['uid'],
+                       'module_name' => $module . '|' . $motherModule,
+                       'url' => $url,
+                       'description' => $shortcutName,
+                       'sorting' => $GLOBALS['EXEC_TIME']
+               ];
+
+               $db->exec_INSERTquery('sys_be_shortcuts', $fieldValues);
+
+               $shortcutCreated = 'failed';
+               if ($db->sql_affected_rows() === 1) {
+                       $shortcutCreated = 'success';
+               }
+
+               return $shortcutCreated;
+       }
+
+       /**
+        * Exists already a shortcut entry for this TYPO3 url?
+        *
+        * @param string $url
+        *
+        * @return bool
+        */
+       protected function shortcutExists($url) {
+               $statement = $this->getDatabaseConnection()->prepare_SELECTquery(
+                       'uid',
+                       'sys_be_shortcuts',
+                       'userid = :userid AND url = :url'
+               );
+
+               $statement->bindValues([
+                       ':userid' => $this->getBackendUser()->user['uid'],
+                       ':url' => $url
+               ]);
+
+               $statement->execute();
+               $rows = $statement->fetch(PreparedStatement::FETCH_ASSOC);
+               $statement->free();
+
+               return !empty($rows);
        }
 
        /**
index e6b190a..2613d42 100644 (file)
@@ -6766,7 +6766,7 @@ button.close {
   right: 0;
   bottom: 0;
   left: 0;
-  z-index: 1050;
+  z-index: 5000;
   -webkit-overflow-scrolling: touch;
   outline: 0;
 }