--- /dev/null
+<?php
+namespace wcf\acp\action;
+
+/**
+ * Copy of the default implementation for the 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 ClipboardAction extends \wcf\action\ClipboardAction { }
--- /dev/null
+<?php
+namespace wcf\acp\action;
+
+/**
+ * Copy of the default implementation for the clipboard proxy 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 ClipboardProxyAction extends \wcf\action\ClipboardProxyAction { }
--- /dev/null
+<?php
+namespace wcf\action;
+use wcf\system\clipboard\ClipboardHandler;
+use wcf\system\exception\AJAXException;
+use wcf\system\WCF;
+use wcf\util\ArrayUtil;
+use wcf\util\JSON;
+use wcf\util\StringUtil;
+
+/**
+ * Handles clipboard items.
+ *
+ * @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 ClipboardAction extends AbstractSecureAction {
+ /**
+ * clipboard action
+ * @var string
+ */
+ protected $action = '';
+
+ /**
+ * list of object ids
+ * @var array<integer>
+ */
+ protected $objectIDs = array();
+
+ /**
+ * clipboard page class name
+ * @var string
+ */
+ protected $pageClassName = '';
+
+ /**
+ * object type
+ * @var string
+ */
+ protected $type = '';
+
+ /**
+ * clipboard item type id
+ * @var integer
+ */
+ protected $typeID = 0;
+
+ /**
+ * @see wcf\action\AbstractAction::_construct()
+ */
+ public function __construct() {
+ try {
+ parent::__construct();
+ }
+ 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();
+
+ if (isset($_POST['action'])) $this->action = StringUtil::trim($_POST['action']);
+ if (isset($_POST['objectIDs']) && is_array($_POST['objectIDs'])) $this->objectIDs = ArrayUtil::toIntegerArray($_POST['objectIDs']);
+ if (isset($_POST['pageClassName'])) $this->pageClassName = StringUtil::trim($_POST['pageClassName']);
+ if (isset($_POST['type'])) $this->type = StringUtil::trim($_POST['type']);
+ }
+
+ /**
+ * @see wcf\action\Action::execute()
+ */
+ public function execute() {
+ parent::execute();
+
+ // validate parameters
+ $this->validate();
+
+ // execute action
+ ClipboardHandler::getInstance()->{$this->action}($this->objectIDs, $this->typeID);
+
+ // get editor items
+ $editorItems = $this->getEditorItems();
+ // send JSON response
+ header('Content-type: application/json');
+ echo JSON::encode(array(
+ 'items' => $editorItems
+ ));
+ exit;
+ }
+
+ /**
+ * Returns a list of clipboard editor items grouped by type name.
+ *
+ * @return array<array>
+ */
+ protected function getEditorItems() {
+ $data = ClipboardHandler::getInstance()->getEditorItems($this->pageClassName);
+ if ($data === null) {
+ return array();
+ }
+
+ $editorItems = array();
+ foreach ($data as $typeName => $itemData) {
+ $items = array(
+ 'label' => $itemData['label'],
+ 'items' => array()
+ );
+
+ foreach ($itemData['items'] as $item) {
+ $items['items'][] = array(
+ 'actionName' => $item->getName(),
+ 'internalData' => $item->getInternalData(),
+ 'parameters' => $item->getParameters(),
+ 'label' => WCF::getLanguage()->get('wcf.clipboard.item.' . $item->getName()),
+ 'url' => $item->getURL()
+ );
+ }
+
+ $editorItems[$typeName] = $items;
+ }
+
+ return $editorItems;
+ }
+
+ /**
+ * Validates parameters.
+ */
+ protected function validate() {
+ if (empty($this->objectIDs)) {
+ throw new AJAXException("Invalid object ids given.");
+ }
+
+ if (empty($this->pageClassName)) {
+ throw new AJAXException("page not given");
+ }
+
+ if ($this->action != 'mark' && $this->action != 'unmark') {
+ throw new AJAXException("Clipboard action '".$this->action."' is invalid.");
+ }
+
+ $this->typeID = (!empty($this->type)) ? ClipboardHandler::getInstance()->getTypeID($this->type) : null;
+ if ($this->typeID === null) {
+ throw new AJAXException("Clipboard item type '".$this->type."' is invalid.");
+ }
+ }
+}
--- /dev/null
+<?php
+namespace wcf\action;
+use wcf\system\clipboard\ClipboardHandler;
+use wcf\system\exception\AJAXException;
+use wcf\system\exception\ValidateActionException;
+use wcf\util\StringUtil;
+
+/**
+ * Clipboard proxy implementation.
+ *
+ * @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 ClipboardProxyAction extends AbstractSecureAction {
+ /**
+ * IDatabaseObjectAction object
+ * @var wcf\data\IDatabaseObjectAction
+ */
+ protected $objectAction = null;
+
+ /**
+ * list of parameters
+ * @var array
+ */
+ protected $parameters = array();
+
+ /**
+ * type name identifier
+ * @var string
+ */
+ protected $typeName = '';
+
+ /**
+ * @see wcf\action\AbstractAction::_construct()
+ */
+ public function __construct() {
+ try {
+ parent::__construct();
+ }
+ catch (\Exception $e) {
+ if ($e instanceof AJAXException) {
+ throw $e;
+ }
+ else {
+ throw new AJAXException($e->getMessage());
+ }
+ }
+ }
+
+ /**
+ * @see wcf\action\IAction::readParameters()
+ */
+ public function readParameters() {
+ parent::readParameters();
+
+ if (isset($_POST['parameters']) && is_array($_POST['parameters'])) $this->parameters = $_POST['parameters'];
+ if (isset($_POST['typeName'])) $this->typeName = StringUtil::trim($_POST['typeName']);
+ }
+
+ /**
+ * Validates parameters.
+ */
+ protected function validate() {
+ // validate required parameters
+ if (!isset($this->parameters['className']) || empty($this->parameters['className'])) {
+ throw new AJAXException("missing class name");
+ }
+ if (!isset($this->parameters['actionName']) || empty($this->parameters['actionName'])) {
+ throw new AJAXException("missing action name");
+ }
+ if (empty($this->typeName)) {
+ throw new AJAXException("type name cannot be empty");
+ }
+
+ // validate class name
+ if (!class_exists($this->parameters['className'])) {
+ throw new AJAXException("unknown class '".$this->parameters['className']."'");
+ }
+ if (!ClassUtil::isInstanceOf($this->parameters['className'], 'wcf\data\IDatabaseObjectAction')) {
+ throw new AJAXException("'".$this->parameters['className']."' should implement wcf\system\IDatabaseObjectAction");
+ }
+ }
+
+ /**
+ * Loads object ids from clipboard.
+ *
+ * @return array<integer>
+ */
+ protected function getObjectIDs() {
+ $typeID = ClipboardHandler::getInstance()->getTypeID($this->typeName);
+ if ($typeID === null) {
+ throw new AJAXException("clipboard item type '".$this->typeName."' is unknown");
+ }
+
+ $objects = ClipboardHandler::getInstance()->getMarkedItems($typeID);
+ if (!count($objects) || !isset($objects[$this->typeName]) || !count($objects[$this->typeName])) {
+ return null;
+ }
+
+ return array_keys($objects[$this->typeName]);
+ }
+
+ /**
+ * @see wcf\action\IAction::execute()
+ */
+ public function execute() {
+ parent::execute();
+
+ // get object ids
+ $objectIDs = $this->getObjectIDs();
+
+ // create object action instance
+ $this->objectAction = new $this->parameters['className']($objectIDs, $this->actionName);
+
+ // validate action
+ try {
+ $this->objectAction->validateAction();
+ }
+ catch (ValidateActionException $e) {
+ throw new AJAXException("validation failed: ".$e->getMessage());
+ }
+
+ // execute action
+ try {
+ $this->response = $this->objectAction->executeAction();
+ }
+ catch (\Exception $e) {
+ throw new AJAXException('unknown exception caught: '.$e->getMessage());
+ }
+ $this->executed();
+
+ // send JSON-encoded response
+ header('Content-type: application/json');
+ echo JSON::encode($this->response);
+ exit;
+ }
+}