Example #1
0
 /**
  * Saves the like of an object.
  * 
  * @param	\wcf\data\like\object\ILikeObject	$likeable
  * @param	\wcf\data\user\User			$user
  * @param	integer					$likeValue
  * @param	integer					$time
  * @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);
     }
     try {
         WCF::getDB()->beginTransaction();
         // like data
         $cumulativeLikes = 0;
         $newValue = $oldValue = null;
         $users = array();
         // 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 = array('likes' => $likes, 'dislikes' => $dislikes, 'cumulativeLikes' => $cumulativeLikes);
             if ($likeValue == 1) {
                 $users = unserialize($likeObject->cachedUsers);
                 if (count($users) < 3) {
                     $users[$user->userID] = array('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 = array();
             if ($likeValue == 1) {
                 $users = array($user->userID => array('userID' => $user->userID, 'username' => $user->username));
             }
             // create cache
             $likeObject = LikeObjectEditor::create(array('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(array('likesReceived' => $like->likeValue == Like::LIKE ? -1 : 1));
             } else {
                 if ($likeValue == Like::LIKE) {
                     $userEditor = new UserEditor(new User($likeable->getUserID()));
                     $userEditor->updateCounters(array('likesReceived' => 1));
                 }
             }
         }
         if (!$like->likeID) {
             // save like
             $like = LikeEditor::create(array('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(array('time' => $time, 'likeValue' => $likeValue));
             if ($likeable->getUserID()) {
                 if ($likeValue == Like::DISLIKE) {
                     UserActivityPointHandler::getInstance()->removeEvents('com.woltlab.wcf.like.activityPointEvent.receivedLikes', array($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();
     } catch (DatabaseException $e) {
         WCF::getDB()->rollBackTransaction();
     }
     return array('data' => $this->loadLikeStatus($likeObject, $user), 'like' => $like, 'newValue' => $newValue, 'oldValue' => $oldValue, 'users' => $users);
 }