Merge branch 'next' into reactions
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / like / LikeHandler.class.php
1 <?php
2 namespace wcf\system\like;
3 use wcf\data\like\object\ILikeObject;
4 use wcf\data\like\object\LikeObject;
5 use wcf\data\like\Like;
6 use wcf\data\object\type\ObjectType;
7 use wcf\data\reaction\type\ReactionType;
8 use wcf\data\reaction\type\ReactionTypeCache;
9 use wcf\data\user\User;
10 use wcf\system\reaction\ReactionHandler;
11 use wcf\system\SingletonFactory;
12 use wcf\system\WCF;
13
14 /**
15 * Handles the likes of liked objects.
16 *
17 * Usage (retrieve all likes for a list of objects):
18 * // get type object
19 * $objectType = LikeHandler::getInstance()->getObjectType('com.woltlab.wcf.foo.bar');
20 * // load like data
21 * LikeHandler::getInstance()->loadLikeObjects($objectType, $objectIDs);
22 * // get like data
23 * $likeObjects = LikeHandler::getInstance()->getLikeObjects($objectType);
24 *
25 * @author Marcel Werk
26 * @copyright 2001-2018 WoltLab GmbH
27 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
28 * @package WoltLabSuite\Core\System\Like
29 * @deprecated The LikeHandler is deprecated since 3.2 in favor of the \wcf\system\reaction\ReactionHandler
30 */
31 class LikeHandler extends SingletonFactory {
32 /**
33 * loaded like objects
34 * @var LikeObject[][]
35 */
36 protected $likeObjectCache = [];
37
38 /**
39 * cached object types
40 * @var ObjectType[]
41 */
42 protected $cache = null;
43
44 /**
45 * Creates a new LikeHandler instance.
46 */
47 protected function init() {
48 // does nothing
49 }
50
51 /**
52 * Returns an object type from cache.
53 *
54 * @param string $objectName
55 * @return ObjectType
56 */
57 public function getObjectType($objectName) {
58 return ReactionHandler::getInstance()->getObjectType($objectName);
59 }
60
61 /**
62 * Returns a like object.
63 *
64 * @param ObjectType $objectType
65 * @param integer $objectID
66 * @return LikeObject|null
67 */
68 public function getLikeObject(ObjectType $objectType, $objectID) {
69 return ReactionHandler::getInstance()->getLikeObject($objectType, $objectID);
70 }
71
72 /**
73 * Returns the like objects of a specific object type.
74 *
75 * @param ObjectType $objectType
76 * @return LikeObject[]
77 */
78 public function getLikeObjects(ObjectType $objectType) {
79 return ReactionHandler::getInstance()->getLikeObjects($objectType);
80 }
81
82 /**
83 * Loads the like data for a set of objects and returns the number of loaded
84 * like objects
85 *
86 * @param ObjectType $objectType
87 * @param array $objectIDs
88 * @return integer
89 */
90 public function loadLikeObjects(ObjectType $objectType, array $objectIDs) {
91 return ReactionHandler::getInstance()->loadLikeObjects($objectType, $objectIDs);
92 }
93
94 /**
95 * Saves the like of an object.
96 *
97 * @param ILikeObject $likeable
98 * @param User $user
99 * @param integer $likeValue
100 * @param integer $time
101 * @return array
102 */
103 public function like(ILikeObject $likeable, User $user, $likeValue, $time = TIME_NOW) {
104 if ($likeValue == 1) {
105 $reactionTypeID = ReactionHandler::getInstance()->getLegacyReactionTypeID(ReactionType::REACTION_TYPE_POSITIVE);
106 }
107 else {
108 $reactionTypeID = ReactionHandler::getInstance()->getLegacyReactionTypeID(ReactionType::REACTION_TYPE_NEGATIVE);
109 }
110
111 if ($reactionTypeID === null) {
112 return [
113 'data' => [],
114 'like' => 0,
115 'newValue' => 0,
116 'oldValue' => 0,
117 'users' => []
118 ];
119 }
120
121 $reactData = ReactionHandler::getInstance()->react($likeable, $user, $reactionTypeID, $time);
122 if ($reactData['reactionTypeID'] === null) {
123 $newValue = 0;
124 }
125 else if (ReactionTypeCache::getInstance()->getReactionTypeByID($reactData['reactionTypeID'])->type == ReactionType::REACTION_TYPE_NEGATIVE) {
126 $newValue = -1;
127 }
128 else {
129 $newValue = 1;
130 }
131
132 return [
133 'data' => $this->loadLikeStatus($reactData['likeObject'], $user),
134 'like' => $reactData['likeObject'],
135 'newValue' => $newValue,
136 'oldValue' => 0, // this value is currently a dummy value, maybe determine a real value
137 'users' => []
138 ];
139 }
140
141 /**
142 * Reverts the like of an object.
143 *
144 * @param Like $like
145 * @param ILikeObject $likeable
146 * @param LikeObject $likeObject
147 * @param User $user
148 * @return array
149 */
150 public function revertLike(Like $like, ILikeObject $likeable, LikeObject $likeObject, User $user) {
151 $reactData = ReactionHandler::getInstance()->revertReact($like, $likeable, $likeObject, $user);
152
153 return [
154 'data' => $this->loadLikeStatus($reactData['likeObject'], $user),
155 'like' => null,
156 'newValue' => 0,
157 'oldValue' => 0, // this value is currently a dummy value, maybe determine a real value
158 'users' => []
159 ];
160 }
161
162 /**
163 * Removes all likes for given objects.
164 *
165 * @param string $objectType
166 * @param integer[] $objectIDs
167 * @param string[] $notificationObjectTypes
168 */
169 public function removeLikes($objectType, array $objectIDs, array $notificationObjectTypes = []) {
170 ReactionHandler::getInstance()->removeReacts($objectType, $objectIDs, $notificationObjectTypes);
171 }
172
173 /**
174 * Returns current like object status.
175 *
176 * @param LikeObject $likeObject
177 * @param User $user
178 * @return array
179 */
180 protected function loadLikeStatus(LikeObject $likeObject, User $user) {
181 $sql = "SELECT like_object.likes, like_object.dislikes, like_object.cumulativeLikes,
182 CASE WHEN like_table.likeValue IS NOT NULL THEN like_table.likeValue ELSE 0 END AS liked
183 FROM wcf".WCF_N."_like_object like_object
184 LEFT JOIN wcf".WCF_N."_like like_table
185 ON (like_table.objectTypeID = ?
186 AND like_table.objectID = like_object.objectID
187 AND like_table.userID = ?)
188 WHERE like_object.likeObjectID = ?";
189 $statement = WCF::getDB()->prepareStatement($sql);
190 $statement->execute([
191 $likeObject->objectTypeID,
192 $user->userID,
193 $likeObject->likeObjectID
194 ]);
195
196 return $statement->fetchArray();
197 }
198 }