Marked items are now displayed on page load.
authorAlexander Ebert <ebert@woltlab.com>
Thu, 15 Sep 2011 11:52:48 +0000 (13:52 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Thu, 15 Sep 2011 11:53:08 +0000 (13:53 +0200)
Reworked ClipboardAction to allow a better inheritance. ClipboardHandler now caches raw data for marked items, allowing further processing.

wcfsetup/install/files/acp/templates/userList.tpl
wcfsetup/install/files/js/WCF.js
wcfsetup/install/files/lib/acp/action/ClipboardLoadMarkedItemsAction.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/acp/page/UserListPage.class.php
wcfsetup/install/files/lib/action/ClipboardAction.class.php
wcfsetup/install/files/lib/action/ClipboardLoadMarkedItemsAction.class.php [new file with mode: 0644]
wcfsetup/install/files/lib/system/clipboard/ClipboardHandler.class.php

index 99f5ff76c4c3acb0d9d33afdae16e9578fe5d642..d23a945e36b432701d4c70bc5ebcfb4ee7c1d6f0 100644 (file)
@@ -3,7 +3,7 @@
 <script type="text/javascript">
        //<![CDATA[
        $(function() {
-               WCF.Clipboard.init('wcf\\acp\\page\\UserListPage');
+               WCF.Clipboard.init('wcf\\acp\\page\\UserListPage', {@$hasMarkedItems});
                new WCF.ACP.User.List();
        });
        //]]>
@@ -61,7 +61,7 @@
                                {content}
                                        {foreach from=$users item=user}
                                                <tr id="userRow{@$user->userID}">
-                                                       <td class="columnMark"><input type="checkbox" data-objectID="{@$user->userID}" class="clipboardItem" /></td>
+                                                       <td class="columnMark"><input type="checkbox" class="clipboardItem" data-objectID="{@$user->userID}" /></td>
                                                        <td class="columnIcon">
                                                                {if $user->editable}
                                                                        <a href="index.php?form=UserEdit&amp;userID={@$user->userID}{@SID_ARG_2ND}"><img src="{@RELATIVE_WCF_DIR}icon/edit1.svg" alt="" title="{lang}wcf.acp.user.edit{/lang}" class="balloonTooltip" /></a>
@@ -77,7 +77,7 @@
                                                                {if $additionalButtons[$user->userID]|isset}{@$additionalButtons[$user->userID]}{/if}
                                                        </td>
                                                        <td class="columnUserID columnID"><p>{@$user->userID}</p></td>
-                                                       <td class="columnUsername columnName columnText"><p>{if $user->editable}<a title="{lang}wcf.acp.user.edit{/lang}" href="index.php?form=UserEdit&amp;userID={@$user->userID}{@SID_ARG_2ND}">{$user->username}</a>{else}{$user->username}{/if}</p></td>
+                                                       <td class="columnUsername columnText"><p>{if $user->editable}<a title="{lang}wcf.acp.user.edit{/lang}" href="index.php?form=UserEdit&amp;userID={@$user->userID}{@SID_ARG_2ND}">{$user->username}</a>{else}{$user->username}{/if}</p></td>
                                        
                                                        {foreach from=$columnHeads key=column item=columnLanguageVariable}
                                                                <td class="column{$column|ucfirst}"><p>{if $columnValues[$user->userID][$column]|isset}{@$columnValues[$user->userID][$column]}{/if}</p></td>
index 141ac6ee9d611a9aa810c19f9ef56aa054622f78..43b8a5d83ab6360271f432b9aeab3e316dd442b3 100644 (file)
@@ -418,6 +418,18 @@ WCF.Clipboard = {
         */
        _actionProxy: null,
        
+       /**
+        * list of clipboard containers
+        * @var jQuery
+        */
+       _container: null,
+       
+       /**
+        * user has marked items
+        * @var boolean
+        */
+       _hasMarkedItems: false,
+       
        /**
         * current page
         * @var string
@@ -433,8 +445,9 @@ WCF.Clipboard = {
        /**
         * Initializes the clipboard API.
         */
-       init: function(page) {
+       init: function(page, hasMarkedItems) {
                this._page = page;
+               if (hasMarkedItems) this._hasMarkedItems = true;
                
                this._actionProxy = new WCF.Action.Proxy({
                        success: $.proxy(this._actionSuccess, this),
@@ -447,9 +460,82 @@ WCF.Clipboard = {
                });
                
                // init containers first
-               $('.clipboardContainer').each($.proxy(function(index, container) {
+               this._containers = $('.clipboardContainer').each($.proxy(function(index, container) {
                        this._initContainer(container);
                }, this));
+               
+               // loads marked items
+               if (this._hasMarkedItems) {
+                       this._loadMarkedItems();
+               }
+       },
+       
+       /**
+        * Loads marked items on init.
+        */
+       _loadMarkedItems: function() {
+               new WCF.Action.Proxy({
+                       autoSend: true,
+                       data: {
+                               pageClassName: this._page
+                       },
+                       success: $.proxy(this._loadMarkedItemsSuccess, this),
+                       url: 'index.php?action=ClipboardLoadMarkedItems&t=' + SECURITY_TOKEN + SID_ARG_2ND
+               });
+       },
+       
+       /**
+        * Marks all returned items as marked
+        * 
+        * @param       object          data
+        * @param       string          textStatus
+        * @param       jQuery          jqXHR
+        */
+       _loadMarkedItemsSuccess: function(data, textStatus, jqXHR) {
+               for (var $typeName in data.markedItems) {
+                       var $objectData = data.markedItems[$typeName];
+                       var $objectIDs = [];
+                       for (var $i in $objectData) {
+                               $objectIDs.push($objectData[$i]);
+                       }
+                       
+                       // loop through all containers
+                       this._containers.each(function(index, container) {
+                               var $container = $(container);
+                               
+                               // typeName does not match, continue
+                               if ($container.data('type') != $typeName) {
+                                       return true;
+                               }
+                               
+                               // mark items as marked
+                               $container.find('input.clipboardItem').each(function(innerIndex, item) {
+                                       var $item = $(item);
+                                       if (WCF.inArray($item.data('objectID'), $objectIDs)) {
+                                               $item.attr('checked', 'checked');
+                                       }
+                               });
+                               
+                               // check if there is a markAll-checkbox
+                               $container.find('input.clipboardMarkAll').each(function(innerIndex, markAll) {
+                                       var $allItemsMarked = true;
+                                       
+                                       $container.find('input.clipboardItem').each(function(itemIndex, item) {
+                                               var $item = $(item);
+                                               if (!$item.attr('checked')) {
+                                                       $allItemsMarked = false;
+                                               }
+                                       });
+                                       
+                                       if ($allItemsMarked) {
+                                               $(markAll).attr('checked', 'checked');
+                                       }
+                               });
+                       });
+               }
+               
+               // call success method to build item list editors
+               this._success(data, textStatus, jqXHR);
        },
        
        /**
diff --git a/wcfsetup/install/files/lib/acp/action/ClipboardLoadMarkedItemsAction.class.php b/wcfsetup/install/files/lib/acp/action/ClipboardLoadMarkedItemsAction.class.php
new file mode 100644 (file)
index 0000000..6392bb4
--- /dev/null
@@ -0,0 +1,14 @@
+<?php
+namespace wcf\acp\action;
+
+/**
+ * Copy of the default implementation for loading marked items from clipboard API.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2011 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage acp.action
+ * @category   Community Framework
+ */
+class ClipboardLoadMarkedItemsAction extends \wcf\action\ClipboardLoadMarkedItemsAction { }
index 81b6dedc1e908373b3a6f8637efacadf6c322bb4..002d3c2489a2fac67a3d3748755dc1e589fd1293 100755 (executable)
@@ -5,6 +5,7 @@ use wcf\data\user\User;
 use wcf\data\user\group\UserGroup;
 use wcf\page\SortablePage;
 use wcf\system\cache\CacheHandler;
+use wcf\system\clipboard\ClipboardHandler;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\event\EventHandler;
 use wcf\system\WCF;
@@ -125,7 +126,7 @@ class UserListPage extends SortablePage {
                WCF::getTPL()->assign(array(
                        'users' => $this->users,
                        'searchID' => $this->searchID,
-                       'markedUsers' => count($this->markedUsers),
+                       'hasMarkedItems' => ClipboardHandler::getInstance()->hasMarkedItems(),
                        'url' => $this->url,
                        'columnHeads' => $this->columnHeads,
                        'columnValues' => $this->columnValues
index 115e423a1eaa8ee5f2db52e1d74b295128fe768f..451ea5971f247293ba08b945a79ee3a20fd291c5 100644 (file)
@@ -83,22 +83,28 @@ class ClipboardAction extends AbstractSecureAction {
        public function execute() {
                parent::execute();
                
-               // validate parameters
-               $this->validate();
-               
-               // execute action
-               ClipboardHandler::getInstance()->{$this->action}($this->objectIDs, $this->typeID);
+               // execute clipboard action
+               $this->executeAction();
                
                // get editor items
-               $editorItems = $this->getEditorItems();
+               $returnValues = $this->getEditorItems();
                // send JSON response
                header('Content-type: application/json');
-               echo JSON::encode(array(
-                       'items' => $editorItems
-               ));
+               echo JSON::encode($returnValues);
                exit;
        }
        
+       /**
+        * Executes clipboard action.
+        */
+       protected function executeAction() {
+               // validate parameters
+               $this->validate();
+               
+               // execute action
+               ClipboardHandler::getInstance()->{$this->action}($this->objectIDs, $this->typeID);
+       }
+       
        /**
         * Returns a list of clipboard editor items grouped by type name.
         * 
@@ -106,6 +112,7 @@ class ClipboardAction extends AbstractSecureAction {
         */
        protected function getEditorItems() {
                $data = ClipboardHandler::getInstance()->getEditorItems($this->pageClassName);
+               
                if ($data === null) {
                        return array();
                }
@@ -130,7 +137,9 @@ class ClipboardAction extends AbstractSecureAction {
                        $editorItems[$typeName] = $items;
                }
                
-               return $editorItems;
+               return array(
+                       'items' => $editorItems
+               );
        }
        
        /**
diff --git a/wcfsetup/install/files/lib/action/ClipboardLoadMarkedItemsAction.class.php b/wcfsetup/install/files/lib/action/ClipboardLoadMarkedItemsAction.class.php
new file mode 100644 (file)
index 0000000..e157d39
--- /dev/null
@@ -0,0 +1,44 @@
+<?php
+namespace wcf\action;
+use wcf\system\clipboard\ClipboardHandler;
+
+/**
+ * Handles marked clipboard items once DOM is loaded.
+ * 
+ * @author     Alexander Ebert
+ * @copyright  2001-2011 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage action
+ * @category   Community Framework
+ */
+class ClipboardLoadMarkedItemsAction extends ClipboardAction {
+       /**
+        * @see wcf\action\ClipboardAction::executeAction()
+        */
+       protected function executeAction() { }
+       
+       /**
+        * @see wcf\action\ClipboardAction::getEditorItems()
+        */
+       protected function getEditorItems() {
+               $returnValues = parent::getEditorItems();
+               $returnValues['markedItems'] = array();
+               
+               // break if no items are available (status was cached by browser)
+               if (empty($returnValues['items'])) {
+                       return $returnValues;
+               }
+               
+               // load marked items from runtime cache
+               $data = ClipboardHandler::getInstance()->getMarkedItems();
+               
+               // insert object ids for each type of marked items
+               $returnValues['markedItems'] = array();
+               foreach ($data as $typeName => $itemData) {
+                       $returnValues['markedItems'][$typeName] = array_keys($itemData);
+               }
+               
+               return $returnValues;
+       }
+}
index bba1af2fa0094a942ade7fa01749dc7e8289e207..f3f4afacbda19bea9ad50df2d1003bdf68c804a7 100644 (file)
@@ -24,6 +24,12 @@ class ClipboardHandler extends SingletonFactory {
         */
        protected $actionCache = null;
        
+       /**
+        * list of marked items
+        * @var array<array>
+        */
+       protected $markedItems = null;
+       
        /**
         * cached list of page actions
         * @var array
@@ -139,12 +145,11 @@ class ClipboardHandler extends SingletonFactory {
        }
        
        /**
-        * Returns a list of marked items grouped by type name.
+        * Loads a list of marked items grouped by type name.
         * 
         * @param       integer         $typeID
-        * @return      array<array>
         */
-       public function getMarkedItems($typeID = null) {
+       protected function loadMarkedItems($typeID = null) {
                $conditions = new PreparedStatementConditionBuilder();
                $conditions->add("userID = ?", array(WCF::getUser()->userID));
                if ($typeID !== null) $conditions->add("typeID = ?", array($typeID));
@@ -175,17 +180,28 @@ class ClipboardHandler extends SingletonFactory {
                }
                
                // read objects
-               $objects = array();
+               $this->markedItems = array();
                foreach ($data as $typeName => $objectData) {
                        $objectList = new $objectData['className']();
                        $objectList->getConditionBuilder()->add($objectList->getDatabaseTableAlias() . "." . $objectList->getDatabaseTableIndexName() . " IN (?)", array($objectData['objectIDs']));
                        $objectList->sqlLimit = 0;
                        $objectList->readObjects();
                        
-                       $objects[$typeName] = $objectList->getObjects();
+                       $this->markedItems[$typeName] = $objectList->getObjects();
+               }
+       }
+       
+       /**
+        * Loads a list of marked items grouped by type name.
+        * 
+        * @param       integer         $typeID
+        */
+       public function getMarkedItems($typeID = null) {
+               if ($this->markedItems === null) {
+                       $this->loadMarkedItems($typeID);
                }
                
-               return $objects;
+               return $this->markedItems;
        }
        
        /**
@@ -199,8 +215,8 @@ class ClipboardHandler extends SingletonFactory {
                if (!isset($this->pageCache[$page])) return null;
                
                // get objects
-               $objects = $this->getMarkedItems();
-               if (!count($objects)) return null;
+               $this->loadMarkedItems();
+               if (!count($this->markedItems)) return null;
                
                // fetch action ids
                $this->loadActionCache();
@@ -237,15 +253,15 @@ class ClipboardHandler extends SingletonFactory {
                foreach ($actions as $actionData) {
                        // get accepted objects
                        $typeName = $actionData['object']->getTypeName();
-                       if (!isset($objects[$typeName])) continue;
+                       if (!isset($this->markedItems[$typeName])) continue;
                        
                        $editorData[$typeName] = array(
-                               'label' => $actionData['object']->getEditorLabel($objects[$typeName]),
+                               'label' => $actionData['object']->getEditorLabel($this->markedItems[$typeName]),
                                'items' => array()
                        );
                        
                        foreach ($actionData['actions'] as $action) {
-                               $data = $actionData['object']->execute($objects[$typeName], $action);
+                               $data = $actionData['object']->execute($this->markedItems[$typeName], $action);
                                if ($data === null) {
                                        continue;
                                }
@@ -272,4 +288,26 @@ class ClipboardHandler extends SingletonFactory {
                $statement = WCF::getDB()->prepareStatement($sql);
                $statement->execute($conditions->getParameters());
        }
+       
+       /**
+        * Returns true (1) if at least one item is marked.
+        * 
+        * @return      integer
+        */
+       public function hasMarkedItems() {
+               if (!WCF::getUser()->userID) return 0;
+               
+               $sql = "SELECT  COUNT(*) AS count
+                       FROM    wcf".WCF_N."_clipboard_item
+                       WHERE   userID = ?";
+               $statement = WCF::getDB()->prepareStatement($sql);
+               $statement->execute(array(WCF::getUser()->userID));
+               $count = $statement->fetchArray();
+               
+               if ($count['count']) {
+                       return 1;
+               }
+               
+               return 0;
+       }
 }