namespace wcf\system\like;
use wcf\data\like\object\ILikeObject;
use wcf\data\like\object\LikeObject;
-use wcf\data\like\object\LikeObjectEditor;
-use wcf\data\like\object\LikeObjectList;
use wcf\data\like\Like;
-use wcf\data\like\LikeEditor;
-use wcf\data\like\LikeList;
use wcf\data\object\type\ObjectType;
-use wcf\data\object\type\ObjectTypeCache;
+use wcf\data\reaction\type\ReactionType;
+use wcf\data\reaction\type\ReactionTypeCache;
use wcf\data\user\User;
-use wcf\data\user\UserEditor;
-use wcf\system\database\util\PreparedStatementConditionBuilder;
-use wcf\system\database\DatabaseException;
-use wcf\system\user\activity\event\UserActivityEventHandler;
-use wcf\system\user\activity\point\UserActivityPointHandler;
-use wcf\system\user\notification\UserNotificationHandler;
+use wcf\system\reaction\ReactionHandler;
use wcf\system\SingletonFactory;
use wcf\system\WCF;
* $likeObjects = LikeHandler::getInstance()->getLikeObjects($objectType);
*
* @author Marcel Werk
- * @copyright 2001-2017 WoltLab GmbH
+ * @copyright 2001-2018 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package WoltLabSuite\Core\System\Like
+ * @deprecated The LikeHandler is deprecated since 3.2 in favor of the \wcf\system\reaction\ReactionHandler
*/
class LikeHandler extends SingletonFactory {
/**
* Creates a new LikeHandler instance.
*/
protected function init() {
- // load cache
- $this->cache = ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.like.likeableObject');
+ // does nothing
}
/**
* @return ObjectType
*/
public function getObjectType($objectName) {
- if (isset($this->cache[$objectName])) {
- return $this->cache[$objectName];
- }
-
- return null;
+ return ReactionHandler::getInstance()->getObjectType($objectName);
}
/**
* @return LikeObject|null
*/
public function getLikeObject(ObjectType $objectType, $objectID) {
- if (isset($this->likeObjectCache[$objectType->objectTypeID][$objectID])) {
- return $this->likeObjectCache[$objectType->objectTypeID][$objectID];
- }
-
- return null;
+ return ReactionHandler::getInstance()->getLikeObject($objectType, $objectID);
}
/**
* @return LikeObject[]
*/
public function getLikeObjects(ObjectType $objectType) {
- if (isset($this->likeObjectCache[$objectType->objectTypeID])) {
- return $this->likeObjectCache[$objectType->objectTypeID];
- }
-
- return [];
+ return ReactionHandler::getInstance()->getLikeObjects($objectType);
}
/**
* @return integer
*/
public function loadLikeObjects(ObjectType $objectType, array $objectIDs) {
- if (empty($objectIDs)) {
- return 0;
- }
-
- $i = 0;
-
- $conditions = new PreparedStatementConditionBuilder();
- $conditions->add("like_object.objectTypeID = ?", [$objectType->objectTypeID]);
- $conditions->add("like_object.objectID IN (?)", [$objectIDs]);
- $parameters = $conditions->getParameters();
-
- if (WCF::getUser()->userID) {
- $sql = "SELECT like_object.*,
- CASE WHEN like_table.userID IS NOT NULL THEN like_table.likeValue ELSE 0 END AS liked
- FROM wcf".WCF_N."_like_object like_object
- LEFT JOIN wcf".WCF_N."_like like_table
- ON (like_table.objectTypeID = like_object.objectTypeID
- AND like_table.objectID = like_object.objectID
- AND like_table.userID = ?)
- ".$conditions;
-
- array_unshift($parameters, WCF::getUser()->userID);
- }
- else {
- $sql = "SELECT like_object.*, 0 AS liked
- FROM wcf".WCF_N."_like_object like_object
- ".$conditions;
- }
-
- $statement = WCF::getDB()->prepareStatement($sql);
- $statement->execute($parameters);
- while ($row = $statement->fetchArray()) {
- $this->likeObjectCache[$objectType->objectTypeID][$row['objectID']] = new LikeObject(null, $row);
- $i++;
- }
-
- return $i;
+ return ReactionHandler::getInstance()->loadLikeObjects($objectType, $objectIDs);
}
/**
* @return array
*/
public function like(ILikeObject $likeable, User $user, $likeValue, $time = TIME_NOW) {
- // verify if object is already liked by user
- $like = Like::getLike($likeable->getObjectType()->objectTypeID, $likeable->getObjectID(), $user->userID);
-
- // get like object
- $likeObject = LikeObject::getLikeObject($likeable->getObjectType()->objectTypeID, $likeable->getObjectID());
-
- // if vote is identically just revert the vote
- if ($like->likeID && ($like->likeValue == $likeValue)) {
- return $this->revertLike($like, $likeable, $likeObject, $user);
+ if ($likeValue == 1) {
+ $reactionTypeID = ReactionHandler::getInstance()->getLegacyReactionTypeID(ReactionType::REACTION_TYPE_POSITIVE);
+ }
+ else {
+ $reactionTypeID = ReactionHandler::getInstance()->getLegacyReactionTypeID(ReactionType::REACTION_TYPE_NEGATIVE);
}
- // like data
- /** @noinspection PhpUnusedLocalVariableInspection */
- $cumulativeLikes = 0;
- /** @noinspection PhpUnusedLocalVariableInspection */
- $newValue = $oldValue = null;
- $users = [];
+ if ($reactionTypeID === null) {
+ return [
+ 'data' => [],
+ 'like' => 0,
+ 'newValue' => 0,
+ 'oldValue' => 0,
+ 'users' => []
+ ];
+ }
- try {
- WCF::getDB()->beginTransaction();
-
- // update existing object
- if ($likeObject->likeObjectID) {
- $likes = $likeObject->likes;
- $dislikes = $likeObject->dislikes;
- $cumulativeLikes = $likeObject->cumulativeLikes;
-
- // previous (dis-)like already exists
- if ($like->likeID) {
- $oldValue = $like->likeValue;
-
- // revert like and replace it with a dislike
- if ($like->likeValue == Like::LIKE) {
- $likes--;
- $dislikes++;
- $cumulativeLikes -= 2;
- $newValue = Like::DISLIKE;
- }
- else {
- // revert dislike and replace it with a like
- $likes++;
- $dislikes--;
- $cumulativeLikes += 2;
- $newValue = Like::LIKE;
- }
- }
- else {
- if ($likeValue == Like::LIKE) {
- $likes++;
- $cumulativeLikes++;
- $newValue = Like::LIKE;
- }
- else {
- $dislikes++;
- $cumulativeLikes--;
- $newValue = Like::DISLIKE;
- }
- }
-
- // build update date
- $updateData = [
- 'likes' => $likes,
- 'dislikes' => $dislikes,
- 'cumulativeLikes' => $cumulativeLikes
- ];
-
- if ($likeValue == 1) {
- $users = unserialize($likeObject->cachedUsers);
- if (count($users) < 3) {
- $users[$user->userID] = ['userID' => $user->userID, 'username' => $user->username];
- $updateData['cachedUsers'] = serialize($users);
- }
- }
- else if ($likeValue == -1) {
- $users = unserialize($likeObject->cachedUsers);
- if (isset($users[$user->userID])) {
- unset($users[$user->userID]);
- $updateData['cachedUsers'] = serialize($users);
- }
- }
-
- // update data
- $likeObjectEditor = new LikeObjectEditor($likeObject);
- $likeObjectEditor->update($updateData);
- }
- else {
- $cumulativeLikes = $likeValue;
- $newValue = $likeValue;
- $users = [];
- if ($likeValue == 1) $users = [$user->userID => ['userID' => $user->userID, 'username' => $user->username]];
-
- // create cache
- $likeObject = LikeObjectEditor::create([
- 'objectTypeID' => $likeable->getObjectType()->objectTypeID,
- 'objectID' => $likeable->getObjectID(),
- 'objectUserID' => $likeable->getUserID() ?: null,
- 'likes' => ($likeValue == Like::LIKE) ? 1 : 0,
- 'dislikes' => ($likeValue == Like::DISLIKE) ? 1 : 0,
- 'cumulativeLikes' => $cumulativeLikes,
- 'cachedUsers' => serialize($users)
- ]);
- }
-
- // update owner's like counter
- if ($likeable->getUserID()) {
- if ($like->likeID) {
- $userEditor = new UserEditor(new User($likeable->getUserID()));
- $userEditor->updateCounters([
- 'likesReceived' => $like->likeValue == Like::LIKE ? -1 : 1
- ]);
- }
- else if ($likeValue == Like::LIKE) {
- $userEditor = new UserEditor(new User($likeable->getUserID()));
- $userEditor->updateCounters([
- 'likesReceived' => 1
- ]);
- }
- }
-
- if (!$like->likeID) {
- // save like
- $like = LikeEditor::create([
- 'objectID' => $likeable->getObjectID(),
- 'objectTypeID' => $likeable->getObjectType()->objectTypeID,
- 'objectUserID' => $likeable->getUserID() ?: null,
- 'userID' => $user->userID,
- 'time' => $time,
- 'likeValue' => $likeValue
- ]);
-
- if ($likeValue == Like::LIKE && $likeable->getUserID()) {
- UserActivityPointHandler::getInstance()->fireEvent('com.woltlab.wcf.like.activityPointEvent.receivedLikes', $like->likeID, $likeable->getUserID());
- $likeable->sendNotification($like);
- }
- }
- else {
- $likeEditor = new LikeEditor($like);
- $likeEditor->update([
- 'time' => $time,
- 'likeValue' => $likeValue
- ]);
-
- if ($likeable->getUserID()) {
- if ($likeValue == Like::DISLIKE) {
- UserActivityPointHandler::getInstance()->removeEvents('com.woltlab.wcf.like.activityPointEvent.receivedLikes', [$likeable->getUserID() => 1]);
- }
- else {
- UserActivityPointHandler::getInstance()->fireEvent('com.woltlab.wcf.like.activityPointEvent.receivedLikes', $like->likeID, $likeable->getUserID());
- $likeable->sendNotification($like);
- }
- }
- }
-
- // update object's like counter
- $likeable->updateLikeCounter($cumulativeLikes);
-
- WCF::getDB()->commitTransaction();
+ $reactData = ReactionHandler::getInstance()->react($likeable, $user, $reactionTypeID, $time);
+ if ($reactData['reactionTypeID'] === null) {
+ $newValue = 0;
}
- catch (DatabaseException $e) {
- WCF::getDB()->rollBackTransaction();
+ else if (ReactionTypeCache::getInstance()->getReactionTypeByID($reactData['reactionTypeID'])->type == ReactionType::REACTION_TYPE_NEGATIVE) {
+ $newValue = -1;
+ }
+ else {
+ $newValue = 1;
}
return [
- 'data' => $this->loadLikeStatus($likeObject, $user),
- 'like' => $like,
+ 'data' => $this->loadLikeStatus($reactData['likeObject'], $user),
+ 'like' => $reactData['likeObject'],
'newValue' => $newValue,
- 'oldValue' => $oldValue,
- 'users' => $users
+ 'oldValue' => 0, // this value is currently a dummy value, maybe determine a real value
+ 'users' => []
];
}
* @return array
*/
public function revertLike(Like $like, ILikeObject $likeable, LikeObject $likeObject, User $user) {
- $usersArray = [];
-
- try {
- WCF::getDB()->beginTransaction();
-
- // delete like
- $editor = new LikeEditor($like);
- $editor->delete();
-
- // update like object cache
- $likes = $likeObject->likes;
- $dislikes = $likeObject->dislikes;
- $cumulativeLikes = $likeObject->cumulativeLikes;
-
- if ($like->likeValue == Like::LIKE) {
- $likes--;
- $cumulativeLikes--;
- }
- else {
- $dislikes--;
- $cumulativeLikes++;
- }
-
- // build update data
- $updateData = [
- 'likes' => $likes,
- 'dislikes' => $dislikes,
- 'cumulativeLikes' => $cumulativeLikes
- ];
-
- $users = $likeObject->getUsers();
- foreach ($users as $user2) {
- $usersArray[$user2->userID] = ['userID' => $user2->userID, 'username' => $user2->username];
- }
-
- if (isset($usersArray[$user->userID])) {
- unset($usersArray[$user->userID]);
- $updateData['cachedUsers'] = serialize($usersArray);
- }
-
- $likeObjectEditor = new LikeObjectEditor($likeObject);
- if (!$updateData['likes'] && !$updateData['dislikes']) {
- // remove object instead
- $likeObjectEditor->delete();
- }
- else {
- // update data
- $likeObjectEditor->update($updateData);
- }
-
- // update owner's like counter and activity points
- if ($likeable->getUserID()) {
- if ($like->likeValue == Like::LIKE) {
- $userEditor = new UserEditor(new User($likeable->getUserID()));
- $userEditor->updateCounters([
- 'likesReceived' => -1
- ]);
-
- UserActivityPointHandler::getInstance()->removeEvents('com.woltlab.wcf.like.activityPointEvent.receivedLikes', [$likeable->getUserID() => 1]);
- }
- }
-
- // update object's like counter
- $likeable->updateLikeCounter($cumulativeLikes);
-
- WCF::getDB()->commitTransaction();
- }
- catch (DatabaseException $e) {
- WCF::getDB()->rollBackTransaction();
- }
+ $reactData = ReactionHandler::getInstance()->revertReact($like, $likeable, $likeObject, $user);
return [
- 'data' => $this->loadLikeStatus($likeObject, $user),
- 'newValue' => null,
- 'oldValue' => $like->likeValue,
- 'users' => $usersArray
+ 'data' => $this->loadLikeStatus($reactData['likeObject'], $user),
+ 'like' => null,
+ 'newValue' => 0,
+ 'oldValue' => 0, // this value is currently a dummy value, maybe determine a real value
+ 'users' => []
];
}
* @param string[] $notificationObjectTypes
*/
public function removeLikes($objectType, array $objectIDs, array $notificationObjectTypes = []) {
- $objectTypeObj = $this->getObjectType($objectType);
-
- // get like objects
- $likeObjectList = new LikeObjectList();
- $likeObjectList->getConditionBuilder()->add('like_object.objectTypeID = ?', [$objectTypeObj->objectTypeID]);
- $likeObjectList->getConditionBuilder()->add('like_object.objectID IN (?)', [$objectIDs]);
- $likeObjectList->readObjects();
- $likeObjects = $likeObjectList->getObjects();
- $likeObjectIDs = $likeObjectList->getObjectIDs();
-
- // reduce count of received users
- $users = [];
- foreach ($likeObjects as $likeObject) {
- if ($likeObject->likes) {
- if (!isset($users[$likeObject->objectUserID])) $users[$likeObject->objectUserID] = 0;
- $users[$likeObject->objectUserID] += $likeObject->likes;
- }
- }
- foreach ($users as $userID => $receivedLikes) {
- $userEditor = new UserEditor(new User(null, ['userID' => $userID]));
- $userEditor->updateCounters([
- 'likesReceived' => $receivedLikes * -1
- ]);
- }
-
- // get like ids
- $likeList = new LikeList();
- $likeList->getConditionBuilder()->add('like_table.objectTypeID = ?', [$objectTypeObj->objectTypeID]);
- $likeList->getConditionBuilder()->add('like_table.objectID IN (?)', [$objectIDs]);
- $likeList->readObjects();
-
- if (count($likeList)) {
- $likeData = [];
- foreach ($likeList as $like) {
- $likeData[$like->likeID] = $like->userID;
- }
-
- // delete like notifications
- if (!empty($notificationObjectTypes)) {
- foreach ($notificationObjectTypes as $notificationObjectType) {
- UserNotificationHandler::getInstance()->removeNotifications($notificationObjectType, $likeList->getObjectIDs());
- }
- }
- else if (UserNotificationHandler::getInstance()->getObjectTypeID($objectType.'.notification')) {
- UserNotificationHandler::getInstance()->removeNotifications($objectType.'.notification', $likeList->getObjectIDs());
- }
-
- // revoke activity points
- UserActivityPointHandler::getInstance()->removeEvents('com.woltlab.wcf.like.activityPointEvent.receivedLikes', $likeData);
-
- // delete likes
- LikeEditor::deleteAll(array_keys($likeData));
- }
-
- // delete like objects
- if (!empty($likeObjectIDs)) {
- LikeObjectEditor::deleteAll($likeObjectIDs);
- }
-
- // delete activity events
- if (UserActivityEventHandler::getInstance()->getObjectTypeID($objectTypeObj->objectType.'.recentActivityEvent')) {
- UserActivityEventHandler::getInstance()->removeEvents($objectTypeObj->objectType.'.recentActivityEvent', $objectIDs);
- }
+ ReactionHandler::getInstance()->removeReacts($objectType, $objectIDs, $notificationObjectTypes);
}
/**