Clipboard now removes zombie object ids
authorAlexander Ebert <ebert@woltlab.com>
Tue, 11 Dec 2012 15:19:45 +0000 (16:19 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Tue, 11 Dec 2012 15:19:45 +0000 (16:19 +0100)
wcfsetup/install/files/lib/action/ClipboardAction.class.php
wcfsetup/install/files/lib/system/clipboard/ClipboardHandler.class.php

index e12ae3228bbb08178d79468133c10895cd494b20..f31a7f6803e80b191c7cade255e292f79f204426 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 namespace wcf\action;
 use wcf\system\clipboard\ClipboardHandler;
-use wcf\system\exception\AJAXException;
+use wcf\system\exception\UserInputException;
 use wcf\system\WCF;
 use wcf\util\ArrayUtil;
 use wcf\util\JSON;
@@ -17,7 +17,7 @@ use wcf\util\StringUtil;
  * @subpackage action
  * @category   Community Framework
  */
-class ClipboardAction extends AbstractSecureAction {
+class ClipboardAction extends AJAXInvokeAction {
        /**
         * clipboard action
         * @var string
@@ -54,28 +54,11 @@ class ClipboardAction extends AbstractSecureAction {
         */
        protected $objectTypeID = 0;
        
-       /**
-        * @see wcf\action\IAction::__run()
-        */
-       public function __run() {
-               try {
-                       parent::__run();
-               }
-               catch (\Exception $e) {
-                       if ($e instanceof AJAXException) {
-                               throw $e;
-                       }
-                       else {
-                               throw new AJAXException($e->getMessage());
-                       }
-               }
-       }
-       
        /**
         * @see wcf\action\Action::readParameters()
         */
        public function readParameters() {
-               parent::readParameters();
+               AbstractSecureAction::readParameters();
                
                if (isset($_POST['action'])) $this->action = StringUtil::trim($_POST['action']);
                if (isset($_POST['containerData']) && is_array($_POST['containerData'])) $this->containerData = $_POST['containerData'];
@@ -88,7 +71,7 @@ class ClipboardAction extends AbstractSecureAction {
         * @see wcf\action\Action::execute()
         */
        public function execute() {
-               parent::execute();
+               AbstractSecureAction::execute();
                
                // execute clipboard action
                $this->executeAction();
@@ -154,20 +137,20 @@ class ClipboardAction extends AbstractSecureAction {
         */
        protected function validate() {
                if (empty($this->objectIDs)) {
-                       throw new AJAXException("Invalid object ids given.");
+                       throw new UserInputException('objectIDs');
                }
                
                if (empty($this->pageClassName)) {
-                       throw new AJAXException("page not given");
+                       throw new UserInputException('pageClassName');
                }
                
                if ($this->action != 'mark' && $this->action != 'unmark') {
-                       throw new AJAXException("Clipboard action '".$this->action."' is invalid.");
+                       throw new UserInputException('action');
                }
                
                $this->objectTypeID = (!empty($this->type)) ? ClipboardHandler::getInstance()->getObjectTypeID($this->type) : null;
                if ($this->objectTypeID === null) {
-                       throw new AJAXException("object type '".$this->type."' is invalid.");
+                       throw new UserInputException('type');
                }
        }
 }
index ee3e2f592eeef02f45d4ecbc98c661818e82c063..f94bc44f6bab00425abfdc42d34fb959abd2d6b9 100644 (file)
@@ -148,6 +148,22 @@ class ClipboardHandler extends SingletonFactory {
                return null;
        }
        
+       /**
+        * Returns object type by object type name.
+        * 
+        * @param       string          $objectType
+        * @return      integer
+        */
+       public function getObjectTypeByName($objectType) {
+               foreach ($this->cache['objectTypes'] as $objectTypeID => $objectTypeObj) {
+                       if ($objectTypeObj->objectType == $objectType) {
+                               return $objectTypeID;
+                       }
+               }
+               
+               return null;
+       }
+       
        /**
         * Loads a list of marked items grouped by type name.
         * 
@@ -212,6 +228,25 @@ class ClipboardHandler extends SingletonFactory {
                        $objectList->readObjects();
                        
                        $this->markedItems[$objectType] = $objectList->getObjects();
+                       
+                       // validate object ids against loaded items (check for zombie object ids)
+                       $indexName = $objectList->getDatabaseTableIndexName();
+                       foreach ($this->markedItems[$objectType] as $object) {
+                               $index = array_search($object->$indexName, $objectData['objectIDs']);
+                               unset($objectData['objectIDs'][$index]);
+                       }
+                       
+                       if (!empty($objectData['objectIDs'])) {
+                               $conditions = new PreparedStatementConditionBuilder();
+                               $conditions->add("objectTypeID = ?", array($this->getObjectTypeByName($objectType)));
+                               $conditions->add("userID = ?", array(WCF::getUser()->userID));
+                               $conditions->add("objectID IN (?)", array($objectData['objectIDs']));
+                               
+                               $sql = "DELETE FROM     wcf".WCF_N."_clipboard_item
+                                       ".$conditions;
+                               $statement = WCF::getDB()->prepareStatement($sql);
+                               $statement->execute($conditions->getParameters());
+                       }
                }
        }
        
@@ -287,7 +322,7 @@ class ClipboardHandler extends SingletonFactory {
                foreach ($actions as $actionData) {
                        // get accepted objects
                        $typeName = $actionData['object']->getTypeName();
-                       if (!isset($this->markedItems[$typeName])) continue;
+                       if (!isset($this->markedItems[$typeName]) || empty($this->markedItems[$typeName])) continue;
                        
                        $editorData[$typeName] = array(
                                'label' => $actionData['object']->getEditorLabel($this->markedItems[$typeName]),