--- /dev/null
+<div id="workerContainer">
+ <header class="box48 boxHeadline">
+ <span class="icon icon48 fa-spinner"></span>
+
+ <div>
+ <h1>{lang}wcf.global.worker.executing{/lang}</h1>
+ <small><progress value="0" max="100">0%</progress> <span>0%</span></small>
+ </div>
+ </header>
+</div>
}
});
+/**
+ * Worker support for frontend based upon DatabaseObjectActions.
+ *
+ * @param string className
+ * @param string title
+ * @param object parameters
+ * @param object callback
+ */
+WCF.System.Worker = Class.extend({
+ /**
+ * worker aborted
+ * @var boolean
+ */
+ _aborted: false,
+
+ /**
+ * DBOAction method name
+ * @var string
+ */
+ _actionName: '',
+
+ /**
+ * callback invoked after worker completed
+ * @var object
+ */
+ _callback: null,
+
+ /**
+ * DBOAction class name
+ * @var string
+ */
+ _className: '',
+
+ /**
+ * dialog object
+ * @var jQuery
+ */
+ _dialog: null,
+
+ /**
+ * action proxy
+ * @var WCF.Action.Proxy
+ */
+ _proxy: null,
+
+ /**
+ * dialog title
+ * @var string
+ */
+ _title: '',
+
+ /**
+ * Initializes a new worker instance.
+ *
+ * @param string actionName
+ * @param string className
+ * @param string title
+ * @param object parameters
+ * @param object callback
+ * @param object confirmMessage
+ */
+ init: function(actionName, className, title, parameters, callback) {
+ this._aborted = false;
+ this._actionName = actionName;
+ this._callback = callback || null;
+ this._className = className;
+ this._dialog = null;
+ this._proxy = new WCF.Action.Proxy({
+ autoSend: true,
+ data: {
+ actionName: this._actionName,
+ className: this._className,
+ parameters: parameters || { }
+ },
+ showLoadingOverlay: false,
+ success: $.proxy(this._success, this)
+ });
+ this._title = title;
+ },
+
+ /**
+ * Handles response from server.
+ *
+ * @param object data
+ */
+ _success: function(data) {
+ // init binding
+ if (this._dialog === null) {
+ this._dialog = $('<div />').hide().appendTo(document.body);
+ this._dialog.wcfDialog({
+ closeConfirmMessage: WCF.Language.get('wcf.worker.abort.confirmMessage'),
+ closeViaModal: false,
+ onClose: $.proxy(function() {
+ this._aborted = true;
+ this._proxy.abortPrevious();
+
+ window.location.reload();
+ }, this),
+ title: this._title
+ });
+ }
+
+ if (this._aborted) {
+ return;
+ }
+
+ if (data.returnValues.template) {
+ this._dialog.html(data.returnValues.template);
+ }
+
+ // update progress
+ this._dialog.find('progress').attr('value', data.returnValues.progress).text(data.returnValues.progress + '%').next('span').text(data.returnValues.progress + '%');
+
+ // worker is still busy with its business, carry on
+ if (data.returnValues.progress < 100) {
+ // send request for next loop
+ var $parameters = data.returnValues.parameters || { };
+ $parameters.loopCount = data.returnValues.loopCount;
+
+ this._proxy.setOption('data', {
+ actionName: this._actionName,
+ className: this._className,
+ parameters: $parameters
+ });
+ this._proxy.sendRequest();
+ }
+ else if (this._callback !== null) {
+ this._callback(this, data);
+ }
+ else {
+ // exchange icon
+ this._dialog.find('.fa-spinner').removeClass('fa-spinner').addClass('fa-check green');
+ this._dialog.find('.boxHeadline h1').text(WCF.Language.get('wcf.global.worker.completed'));
+
+ // display continue button
+ var $formSubmit = $('<div class="formSubmit" />').appendTo(this._dialog);
+ $('<button class="buttonPrimary">' + WCF.Language.get('wcf.global.button.next') + '</button>').appendTo($formSubmit).focus().click(function() {
+ if (data.returnValues.redirectURL) {
+ window.location = data.returnValues.redirectURL;
+ }
+ else {
+ window.location.reload();
+ }
+ });
+
+ this._dialog.wcfDialog('render');
+ }
+ }
+});
+
/**
* Default implementation for inline editors.
*
}
WCF::getDB()->commitTransaction();
}
+
+ /**
+ * Copies attachments from one object id to another.
+ */
+ public function copy() {
+ $sourceObjectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.attachment.objectType', $this->parameters['sourceObjectType']);
+ $targetObjectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.attachment.objectType', $this->parameters['targetObjectType']);
+
+ $attachmentList = new AttachmentList();
+ $attachmentList->getConditionBuilder()->add("attachment.objectTypeID = ?", array($sourceObjectType->objectTypeID));
+ $attachmentList->getConditionBuilder()->add("attachment.objectID = ?", array($this->parameters['sourceObjectID']));
+ $attachmentList->readObjects();
+
+ $newAttachmentIDs = array();
+ foreach ($attachmentList as $attachment) {
+ $newAttachment = AttachmentEditor::create(array(
+ 'objectTypeID' => $targetObjectType->objectTypeID,
+ 'objectID' => $this->parameters['targetObjectID'],
+ 'userID' => $attachment->userID,
+ 'filename' => $attachment->filename,
+ 'filesize' => $attachment->filesize,
+ 'fileType' => $attachment->fileType,
+ 'fileHash' => $attachment->fileHash,
+ 'isImage' => $attachment->isImage,
+ 'width' => $attachment->width,
+ 'height' => $attachment->height,
+ 'tinyThumbnailType' => $attachment->tinyThumbnailType,
+ 'tinyThumbnailSize' => $attachment->tinyThumbnailSize,
+ 'tinyThumbnailWidth' => $attachment->tinyThumbnailWidth,
+ 'tinyThumbnailHeight' => $attachment->tinyThumbnailHeight,
+ 'thumbnailType' => $attachment->thumbnailType,
+ 'thumbnailSize' => $attachment->thumbnailSize,
+ 'thumbnailWidth' => $attachment->thumbnailWidth,
+ 'thumbnailHeight' => $attachment->thumbnailHeight,
+ 'downloads' => $attachment->downloads,
+ 'lastDownloadTime' => $attachment->lastDownloadTime,
+ 'uploadTime' => $attachment->uploadTime,
+ 'showOrder' => $attachment->showOrder
+ ));
+
+ // copy attachment
+ @copy($attachment->getLocation(), $newAttachment->getLocation());
+
+ if ($attachment->tinyThumbnailSize) {
+ @copy($attachment->getTinyThumbnailLocation(), $newAttachment->getTinyThumbnailLocation());
+ }
+ if ($attachment->thumbnailSize) {
+ @copy($attachment->getThumbnailLocation(), $newAttachment->getThumbnailLocation());
+ }
+
+ $newAttachmentIDs[$attachment->attachmentID] = $newAttachment->attachmentID;
+ }
+
+ return array(
+ 'attachmentIDs' => $newAttachmentIDs
+ );
+ }
}
<?php
namespace wcf\data\like;
+use wcf\data\object\type\ObjectTypeCache;
use wcf\data\AbstractDatabaseObjectAction;
use wcf\data\IGroupedUserListAction;
use wcf\system\exception\PermissionDeniedException;
use wcf\system\user\activity\event\UserActivityEventHandler;
use wcf\system\user\GroupedUserList;
use wcf\system\WCF;
+use wcf\data\like\object\LikeObjectEditor;
+use wcf\data\user\UserEditor;
+use wcf\data\user\User;
+use wcf\system\user\activity\point\UserActivityPointHandler;
+
/**
* Executes like-related actions.
'template' => WCF::getTPL()->fetch('userProfileLikeItem')
);
}
+
+ /**
+ * Copies a poll from one object id to another.
+ */
+ public function copy() {
+ $sourceObjectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.like.likeableObject', $this->parameters['sourceObjectType']);
+ $targetObjectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.like.likeableObject', $this->parameters['targetObjectType']);
+
+ //
+ // step 1) get data
+ //
+
+ // get like object
+ $sql = "SELECT *
+ FROM wcf".WCF_N."_like_object
+ WHERE objectTypeID = ?
+ AND objectID = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array(
+ $sourceObjectType->objectTypeID,
+ $this->parameters['sourceObjectID']
+ ));
+ $row = $statement->fetchArray();
+
+ // no (dis-)likes at all
+ if ($row === false) {
+ return;
+ }
+
+ unset($row['likeObjectID']);
+ $row['objectTypeID'] = $targetObjectType->objectTypeID;
+ $row['objectID'] = $this->parameters['targetObjectID'];
+ $newLikeObject = LikeObjectEditor::create($row);
+
+ //
+ // step 2) copy
+ //
+
+ $sql = "INSERT INTO wcf".WCF_N."_like
+ (objectID, objectTypeID, objectUserID, userID, time, likeValue)
+ SELECT ".$this->parameters['targetObjectID'].", ".$targetObjectType->objectTypeID.", objectUserID, userID, time, likeValue
+ FROM wcf".WCF_N."_like
+ WHERE objectTypeID = ?
+ AND objectID = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array(
+ $sourceObjectType->objectTypeID,
+ $this->parameters['sourceObjectID']
+ ));
+
+ //
+ // step 3) update owner
+ //
+
+ if ($newLikeObject->objectUserID) {
+ $sql = "SELECT COUNT(*) AS count
+ FROM wcf".WCF_N."_like
+ WHERE objectTypeID = ?
+ AND objectID = ?
+ AND likeValue = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array(
+ $targetObjectType->objectTypeID,
+ $this->parameters['targetObjectID'],
+ Like::LIKE
+ ));
+ $row = $statement->fetchArray();
+
+ if ($row['count']) {
+ // update received likes
+ $userEditor = new UserEditor(new User($newLikeObject->objectUserID));
+ $userEditor->updateCounters(array(
+ 'likesReceived' => $row['count']
+ ));
+
+ // add activity points
+ UserActivityPointHandler::getInstance()->fireEvents('com.woltlab.wcf.like.activityPointEvent.receivedLikes', array($newLikeObject->objectUserID => $row['count']));
+ }
+ }
+ }
}
<?php
namespace wcf\data\poll;
+use wcf\data\object\type\ObjectTypeCache;
+use wcf\data\poll\option\PollOptionEditor;
use wcf\data\poll\option\PollOptionList;
use wcf\data\AbstractDatabaseObjectAction;
use wcf\data\IGroupedUserListAction;
use wcf\system\user\GroupedUserList;
use wcf\system\WCF;
+
/**
* Executes poll-related actions.
*
'template' => WCF::getTPL()->fetch('groupedUserList')
);
}
+
+ /**
+ * Copies a poll from one object id to another.
+ */
+ public function copy() {
+ $sourceObjectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.poll', $this->parameters['sourceObjectType']);
+ $targetObjectType = ObjectTypeCache::getInstance()->getObjectTypeByName('com.woltlab.wcf.poll', $this->parameters['targetObjectType']);
+
+ //
+ // step 1) get data
+ //
+
+ // get poll
+ $sql = "SELECT *
+ FROM wcf".WCF_N."_poll
+ WHERE objectTypeID = ?
+ AND objectID = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array(
+ $sourceObjectType->objectTypeID,
+ $this->parameters['sourceObjectID']
+ ));
+ $row = $statement->fetchArray();
+
+ if ($row === false) {
+ return array(
+ 'pollID' => null
+ );
+ }
+
+ // get options
+ $pollOptionList = new PollOptionList();
+ $pollOptionList->getConditionBuilder()->add("poll_option.pollID = ?", array($row['pollID']));
+ $pollOptionList->readObjects();
+
+ //
+ // step 2) copy
+ //
+
+ // cretae poll
+ $pollData = $row;
+ $pollData['objectTypeID'] = $targetObjectType->objectTypeID;
+ $pollData['objectID'] = $this->parameters['targetObjectID'];
+ unset($pollData['pollID']);
+
+ $newPoll = PollEditor::create($pollData);
+
+ // create options
+ $newOptionIDs = array();
+ foreach ($pollOptionList as $pollOption) {
+ $newOption = PollOptionEditor::create(array(
+ 'pollID' => $newPoll->pollID,
+ 'optionValue' => $pollOption->optionValue,
+ 'votes' => $pollOption->votes,
+ 'showOrder' => $pollOption->showOrder
+ ));
+
+ $newOptionIDs[$pollOption->optionID] = $newOption->optionID;
+ }
+
+ // copy votes
+ WCF::getDB()->beginTransaction();
+ foreach ($newOptionIDs as $oldOptionID => $newOptionID) {
+ $sql = "INSERT INTO wcf".WCF_N."_poll_option_vote
+ (pollID, optionID, userID)
+ SELECT ".$newPoll->pollID.", ".$newOptionID.", userID
+ FROM wcf".WCF_N."_poll_option_vote
+ WHERE optionID = ?";
+ $statement = WCF::getDB()->prepareStatement($sql);
+ $statement->execute(array($oldOptionID));
+ }
+ WCF::getDB()->commitTransaction();
+
+ return array(
+ 'pollID' => $newPoll->pollID
+ );
+ }
}
}
// spinner animation
-.icon-spinner {
+.icon-spinner,
+.fa-spinner {
height: auto;
-moz-animation: spin 2s infinite linear;