Merge branch '2.0'
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / data / like / LikeAction.class.php
CommitLineData
00b6f956
MW
1<?php
2namespace wcf\data\like;
3use wcf\data\AbstractDatabaseObjectAction;
32514cd5 4use wcf\data\IGroupedUserListAction;
00b6f956
MW
5use wcf\system\exception\PermissionDeniedException;
6use wcf\system\exception\UserInputException;
7use wcf\system\like\LikeHandler;
8use wcf\system\user\activity\event\UserActivityEventHandler;
9use wcf\system\user\GroupedUserList;
10use wcf\system\WCF;
11
12/**
13 * Executes like-related actions.
14 *
15 * @author Alexander Ebert
ca4ba303 16 * @copyright 2001-2014 WoltLab GmbH
00b6f956
MW
17 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
18 * @package com.woltlab.wcf
19 * @subpackage data.like
20 * @category Community Framework
21 */
32514cd5 22class LikeAction extends AbstractDatabaseObjectAction implements IGroupedUserListAction {
00b6f956 23 /**
0ad90fc3 24 * @see \wcf\data\AbstractDatabaseObjectAction::$allowGuestAccess
00b6f956 25 */
32514cd5 26 protected $allowGuestAccess = array('getGroupedUserList', 'getLikeDetails');
00b6f956
MW
27
28 /**
0ad90fc3 29 * @see \wcf\data\AbstractDatabaseObjectAction::$className
00b6f956
MW
30 */
31 protected $className = 'wcf\data\like\LikeEditor';
32
33 /**
34 * likeable object
0ad90fc3 35 * @var \wcf\data\like\object\ILikeObject
00b6f956
MW
36 */
37 public $likeableObject = null;
38
39 /**
40 * object type object
0ad90fc3 41 * @var \wcf\data\object\type\ObjectType
00b6f956
MW
42 */
43 public $objectType = null;
44
45 /**
46 * like object type provider object
0ad90fc3 47 * @var \wcf\data\like\ILikeObjectTypeProvider
00b6f956
MW
48 */
49 public $objectTypeProvider = null;
50
51 /**
52 * Validates parameters to fetch like details.
53 */
54 public function validateGetLikeDetails() {
55 $this->validateObjectParameters();
56 }
57
58 /**
59 * Returns like details.
60 *
61 * @return array<string>
62 */
63 public function getLikeDetails() {
cad6116d
MW
64 $sql = "SELECT userID, likeValue
65 FROM wcf".WCF_N."_like
66 WHERE objectID = ?
67 AND objectTypeID = ?
68 ORDER BY time DESC";
00b6f956
MW
69 $statement = WCF::getDB()->prepareStatement($sql);
70 $statement->execute(array(
71 $this->parameters['data']['objectID'],
72 $this->objectType->objectTypeID
73 ));
74 $data = array(
75 Like::LIKE => array(),
76 Like::DISLIKE => array()
77 );
78 while ($row = $statement->fetchArray()) {
79 $data[$row['likeValue']][] = $row['userID'];
80 }
81
82 $values = array();
83 if (!empty($data[Like::LIKE])) {
84 $values[Like::LIKE] = new GroupedUserList(WCF::getLanguage()->get('wcf.like.details.like'));
85 $values[Like::LIKE]->addUserIDs($data[Like::LIKE]);
86 }
87 if (!empty($data[Like::DISLIKE])) {
88 $values[Like::DISLIKE] = new GroupedUserList(WCF::getLanguage()->get('wcf.like.details.dislike'));
89 $values[Like::DISLIKE]->addUserIDs($data[Like::DISLIKE]);
90 }
91
92 // load user profiles
93 GroupedUserList::loadUsers();
94
95 WCF::getTPL()->assign(array(
96 'groupedUsers' => $values
97 ));
98
99 return array(
100 'containerID' => $this->parameters['data']['containerID'],
101 'template' => WCF::getTPL()->fetch('groupedUserList')
102 );
103 }
104
105 /**
106 * Validates parameters for like-related actions.
107 */
108 public function validateLike() {
109 $this->validateObjectParameters();
110
111 // check permissions
112 if (!WCF::getUser()->userID || !WCF::getSession()->getPermission('user.like.canLike')) {
113 throw new PermissionDeniedException();
114 }
115
116 // check if liking own content but forbidden by configuration
117 $this->likeableObject = $this->objectTypeProvider->getObjectByID($this->parameters['data']['objectID']);
118 $this->likeableObject->setObjectType($this->objectType);
119 if (!LIKE_ALLOW_FOR_OWN_CONTENT && ($this->likeableObject->getUserID() == WCF::getUser()->userID)) {
120 throw new PermissionDeniedException();
121 }
122 }
123
124 /**
0ad90fc3 125 * @see \wcf\data\like\LikeAction::updateLike()
00b6f956
MW
126 */
127 public function like() {
128 return $this->updateLike(Like::LIKE);
129 }
130
131 /**
0ad90fc3 132 * @see \wcf\data\like\LikeAction::validateLike()
00b6f956
MW
133 */
134 public function validateDislike() {
d39b7b8f
MW
135 if (!LIKE_ENABLE_DISLIKE) {
136 throw new PermissionDeniedException();
137 }
138
00b6f956
MW
139 $this->validateLike();
140 }
141
142 /**
0ad90fc3 143 * @see \wcf\data\like\LikeAction::updateLike()
00b6f956
MW
144 */
145 public function dislike() {
146 return $this->updateLike(Like::DISLIKE);
147 }
148
149 /**
150 * Sets like/dislike for an object, executing this method again with the same parameters
151 * will revert the status (removing like/dislike).
152 *
153 * @return array
154 */
155 protected function updateLike($likeValue) {
156 $likeData = LikeHandler::getInstance()->like($this->likeableObject, WCF::getUser(), $likeValue);
157
158 // handle activity event
159 if (UserActivityEventHandler::getInstance()->getObjectTypeID($this->objectType->objectType.'.recentActivityEvent')) {
160 if ($likeData['data']['liked'] == 1) {
161 UserActivityEventHandler::getInstance()->fireEvent($this->objectType->objectType.'.recentActivityEvent', $this->parameters['data']['objectID']);
162 }
163 else {
164 UserActivityEventHandler::getInstance()->removeEvents($this->objectType->objectType.'.recentActivityEvent', array($this->parameters['data']['objectID']));
165 }
166 }
167
168 // get stats
169 return array(
170 'likes' => ($likeData['data']['likes'] === null) ? 0 : $likeData['data']['likes'],
171 'dislikes' => ($likeData['data']['dislikes'] === null) ? 0 : $likeData['data']['dislikes'],
172 'cumulativeLikes' => ($likeData['data']['cumulativeLikes'] === null) ? 0 : $likeData['data']['cumulativeLikes'],
173 'isLiked' => ($likeData['data']['liked'] == 1) ? 1 : 0,
174 'isDisliked' => ($likeData['data']['liked'] == -1) ? 1 : 0,
175 'containerID' => $this->parameters['data']['containerID'],
176 'newValue' => $likeData['newValue'],
177 'oldValue' => $likeData['oldValue'],
178 'users' => $likeData['users']
179 );
180 }
181
182 /**
183 * Validates permissions for given object.
184 */
185 protected function validateObjectParameters() {
186 if (!MODULE_LIKE) {
187 throw new PermissionDeniedException();
188 }
189
190 $this->readString('containerID', false, 'data');
191 $this->readInteger('objectID', false, 'data');
192 $this->readString('objectType', false, 'data');
193
194 $this->objectType = LikeHandler::getInstance()->getObjectType($this->parameters['data']['objectType']);
195 if ($this->objectType === null) {
196 throw new UserInputException('objectType');
197 }
198
199 $this->objectTypeProvider = $this->objectType->getProcessor();
200 $this->likeableObject = $this->objectTypeProvider->getObjectByID($this->parameters['data']['objectID']);
201 $this->likeableObject->setObjectType($this->objectType);
202 if (!$this->objectTypeProvider->checkPermissions($this->likeableObject)) {
203 throw new PermissionDeniedException();
204 }
205 }
32514cd5
MS
206
207 /**
208 * @see \wcf\data\IGroupedUserListAction::validateGetGroupedUserList()
209 */
210 public function validateGetGroupedUserList() {
211 $this->validateObjectParameters();
212
213 $this->readInteger('pageNo');
214 }
215
216 /**
217 * @see \wcf\data\IGroupedUserListAction::getGroupedUserList()
218 */
219 public function getGroupedUserList() {
220 // fetch number of pages
221 $sql = "SELECT COUNT(*)
222 FROM wcf".WCF_N."_like
223 WHERE objectID = ?
224 AND objectTypeID = ?";
225 $statement = WCF::getDB()->prepareStatement($sql);
226 $statement->execute(array(
227 $this->parameters['data']['objectID'],
228 $this->objectType->objectTypeID
229 ));
230 $pageCount = ceil($statement->fetchColumn() / 20);
231
232 $sql = "SELECT userID, likeValue
233 FROM wcf".WCF_N."_like
234 WHERE objectID = ?
235 AND objectTypeID = ?
236 ORDER BY likeValue DESC, time DESC";
237 $statement = WCF::getDB()->prepareStatement($sql, 20, ($this->parameters['pageNo'] - 1) * 20);
238 $statement->execute(array(
239 $this->parameters['data']['objectID'],
240 $this->objectType->objectTypeID
241 ));
242 $data = array(
243 Like::LIKE => array(),
244 Like::DISLIKE => array()
245 );
246 while ($row = $statement->fetchArray()) {
247 $data[$row['likeValue']][] = $row['userID'];
248 }
249
250 $values = array();
251 if (!empty($data[Like::LIKE])) {
252 $values[Like::LIKE] = new GroupedUserList(WCF::getLanguage()->get('wcf.like.details.like'));
253 $values[Like::LIKE]->addUserIDs($data[Like::LIKE]);
254 }
255 if (!empty($data[Like::DISLIKE])) {
256 $values[Like::DISLIKE] = new GroupedUserList(WCF::getLanguage()->get('wcf.like.details.dislike'));
257 $values[Like::DISLIKE]->addUserIDs($data[Like::DISLIKE]);
258 }
259
260 // load user profiles
261 GroupedUserList::loadUsers();
262
263 WCF::getTPL()->assign(array(
264 'groupedUsers' => $values
265 ));
266
267 return array(
268 'containerID' => $this->parameters['data']['containerID'],
269 'pageCount' => $pageCount,
270 'template' => WCF::getTPL()->fetch('groupedUserList')
271 );
272 }
00b6f956 273}