function moveActivity($act, $sink, $user, $remote) { if (empty($user)) { // TRANS: Exception thrown if a non-existing user is provided. %s is a user ID. throw new Exception(sprintf(_('No such user "%s".'), $act->actor->id)); } switch ($act->verb) { case ActivityVerb::FAVORITE: $this->log(LOG_INFO, "Moving favorite of {$act->objects[0]->id} by " . "{$act->actor->id} to {$remote->nickname}."); // push it, then delete local $sink->postActivity($act); $notice = Notice::staticGet('uri', $act->objects[0]->id); if (!empty($notice)) { $fave = Fave::pkeyGet(array('user_id' => $user->id, 'notice_id' => $notice->id)); $fave->delete(); } break; case ActivityVerb::POST: $this->log(LOG_INFO, "Moving notice {$act->objects[0]->id} by " . "{$act->actor->id} to {$remote->nickname}."); // XXX: send a reshare, not a post $sink->postActivity($act); $notice = Notice::staticGet('uri', $act->objects[0]->id); if (!empty($notice)) { $notice->delete(); } break; case ActivityVerb::JOIN: $this->log(LOG_INFO, "Moving group join of {$act->objects[0]->id} by " . "{$act->actor->id} to {$remote->nickname}."); $sink->postActivity($act); $group = User_group::staticGet('uri', $act->objects[0]->id); if (!empty($group)) { $user->leaveGroup($group); } break; case ActivityVerb::FOLLOW: if ($act->actor->id == $user->uri) { $this->log(LOG_INFO, "Moving subscription to {$act->objects[0]->id} by " . "{$act->actor->id} to {$remote->nickname}."); $sink->postActivity($act); $other = Profile::fromURI($act->objects[0]->id); if (!empty($other)) { Subscription::cancel($user->getProfile(), $other); } } else { $otherUser = User::staticGet('uri', $act->actor->id); if (!empty($otherUser)) { $this->log(LOG_INFO, "Changing sub to {$act->objects[0]->id}" . "by {$act->actor->id} to {$remote->nickname}."); $otherProfile = $otherUser->getProfile(); Subscription::start($otherProfile, $remote); Subscription::cancel($otherProfile, $user->getProfile()); } else { $this->log(LOG_NOTICE, "Not changing sub to {$act->objects[0]->id}" . "by remote {$act->actor->id} " . "to {$remote->nickname}."); } } break; } }
/** * For initializing members of the class. * * @param array $args misc. arguments * * @return boolean true */ protected function prepare(array $args = array()) { parent::prepare($args); $profileId = $this->trimmed('profile'); $noticeId = $this->trimmed('notice'); $this->_profile = Profile::getKV('id', $profileId); if (empty($this->_profile)) { // TRANS: Client exception. throw new ClientException(_('No such profile.'), 404); } $this->_notice = Notice::getKV('id', $noticeId); if (empty($this->_notice)) { // TRANS: Client exception thrown when referencing a non-existing notice. throw new ClientException(_('No such notice.'), 404); } $this->_fave = Fave::pkeyGet(array('user_id' => $profileId, 'notice_id' => $noticeId)); if (empty($this->_fave)) { // TRANS: Client exception thrown when referencing a non-existing favorite. throw new ClientException(_('No such favorite.'), 404); } return true; }
/** * Notify remote users when their notices get favorited. * * @param Profile or User $profile of local user doing the faving * @param Notice $notice being favored * @return hook return value */ function onEndFavorNotice(Profile $profile, Notice $notice) { $user = User::staticGet('id', $profile->id); if (empty($user)) { return true; } $oprofile = Ostatus_profile::staticGet('profile_id', $notice->profile_id); if (empty($oprofile)) { return true; } $fav = Fave::pkeyGet(array('user_id' => $user->id, 'notice_id' => $notice->id)); if (empty($fav)) { // That's weird. return true; } $act = $fav->asActivity(); $oprofile->notifyActivity($act, $profile); return true; }
/** * add a new favorite * * @return void */ function addFavorite() { // XXX: Refactor this; all the same for atompub if (empty($this->auth_user) || $this->auth_user->id != $this->_profile->id) { // TRANS: Client exception thrown when trying to set a favorite for another user. throw new ClientException(_("Cannot add someone else's" . " subscription."), 403); } $xml = file_get_contents('php://input'); $dom = DOMDocument::loadXML($xml); if ($dom->documentElement->namespaceURI != Activity::ATOM || $dom->documentElement->localName != 'entry') { // TRANS: Client error displayed when not using an Atom entry. throw new ClientException(_('Atom post must be an Atom entry.')); return; } $activity = new Activity($dom->documentElement); $fave = null; if (Event::handle('StartAtomPubNewActivity', array(&$activity))) { if ($activity->verb != ActivityVerb::FAVORITE) { // TRANS: Client exception thrown when trying use an incorrect activity verb for the Atom pub method. throw new ClientException(_('Can only handle favorite activities.')); return; } $note = $activity->objects[0]; if (!in_array($note->type, array(ActivityObject::NOTE, ActivityObject::BLOGENTRY, ActivityObject::STATUS))) { // TRANS: Client exception thrown when trying favorite an object that is not a notice. throw new ClientException(_('Can only fave notices.')); return; } $notice = Notice::staticGet('uri', $note->id); if (empty($notice)) { // XXX: import from listed URL or something // TRANS: Client exception thrown when trying favorite a notice without content. throw new ClientException(_('Unknown note.')); } $old = Fave::pkeyGet(array('user_id' => $this->auth_user->id, 'notice_id' => $notice->id)); if (!empty($old)) { // TRANS: Client exception thrown when trying favorite an already favorited notice. throw new ClientException(_('Already a favorite.')); } $profile = $this->auth_user->getProfile(); $fave = Fave::addNew($profile, $notice); if (!empty($fave)) { $this->_profile->blowFavesCache(); $this->notify($fave, $notice, $this->auth_user); } Event::handle('EndAtomPubNewActivity', array($activity, $fave)); } if (!empty($fave)) { $act = $fave->asActivity(); header('Content-Type: application/atom+xml; charset=utf-8'); header('Content-Location: ' . $act->selfLink); $this->startXML(); $this->raw($act->asString(true, true, true)); $this->endXML(); } }
function hasFave($notice) { $cache = common_memcache(); // XXX: Kind of a hack. if (!empty($cache)) { // This is the stream of favorite notices, in rev chron // order. This forces it into cache. $ids = Fave::stream($this->id, 0, NOTICE_CACHE_WINDOW); // If it's in the list, then it's a fave if (in_array($notice->id, $ids)) { return true; } // If we're not past the end of the cache window, // then the cache has all available faves, so this one // is not a fave. if (count($ids) < NOTICE_CACHE_WINDOW) { return false; } // Otherwise, cache doesn't have all faves; // fall through to the default } $fave = Fave::pkeyGet(array('user_id' => $this->id, 'notice_id' => $notice->id)); return is_null($fave) ? false : true; }
/** * Remote user doesn't like one of our posts after all! * Confirm the post is ours, and save a local favorite event. */ function handleUnfavorite() { $notice = $this->getNotice($this->activity->objects[0]); $profile = $this->ensureProfile()->localProfile(); $fave = Fave::pkeyGet(array('user_id' => $profile->id, 'notice_id' => $notice->id)); if (empty($fave)) { // TRANS: Client exception. throw new ClientException(_('Notice wasn\'t favorited!')); } $fave->delete(); }
function hasFave($notice) { $fave = Fave::pkeyGet(array('user_id' => $this->id, 'notice_id' => $notice->id)); return is_null($fave) ? false : true; }
/** * Notify remote users when their notices get favorited. * * @param Profile or User $profile of local user doing the faving * @param Notice $notice being favored * @return hook return value */ function onEndFavorNotice(Profile $profile, Notice $notice) { // Only distribute local users' favor actions, remote users // will have already distributed theirs. if (!$profile->isLocal()) { return true; } $oprofile = Ostatus_profile::getKV('profile_id', $notice->profile_id); if (!$oprofile instanceof Ostatus_profile) { return true; } $fav = Fave::pkeyGet(array('user_id' => $profile->id, 'notice_id' => $notice->id)); if (!$fav instanceof Fave) { // That's weird. // TODO: Make pkeyGet throw exception, since this is a critical failure. return true; } $act = $fav->asActivity(); $oprofile->notifyActivity($act, $profile); return true; }
function onEndFavorNotice($profile, $notice) { // Only do this if config is enabled if (!$this->StartLike) { return true; } $user = $profile->getUser(); if (!empty($user)) { $author = $notice->getProfile(); $fave = Fave::pkeyGet(array('user_id' => $user->id, 'notice_id' => $notice->id)); // TRANS: Text for "liked" item in activity plugin. // TRANS: %1$s is a profile URL, %2$s is a profile name, // TRANS: %3$s is a notice URL, %4$s is an author name. $rendered = sprintf(_m('<a href="%1$s">%2$s</a> liked <a href="%3$s">%4$s\'s update</a>.'), $profile->profileurl, $profile->getBestName(), $notice->bestUrl(), $author->getBestName()); // TRANS: Text for "liked" item in activity plugin. // TRANS: %1$s is a profile name, %2$s is a profile URL, // TRANS: %3$s is an author name, %4$s is a notice URL. $content = sprintf(_m('%1$s (%2$s) liked %3$s\'s status (%4$s).'), $profile->getBestName(), $profile->profileurl, $author->getBestName(), $notice->bestUrl()); $notice = Notice::saveNew($user->id, $content, ActivityPlugin::SOURCE, array('rendered' => $rendered, 'urls' => array(), 'replies' => array($author->getUri()), 'uri' => $fave->getURI(), 'verb' => ActivityVerb::FAVORITE, 'content_type' => NOTICE::CONTENT_TYPE_ACTIVITY, 'object_type' => $notice->verb == ActivityVerb::POST ? $notice->object_type : ActivityObject::ACTIVITY)); } return true; }
function hasFave($notice) { $cache = common_memcache(); # XXX: Kind of a hack. if ($cache) { # This is the stream of favorite notices, in rev chron # order. This forces it into cache. $faves = $this->favoriteNotices(0, NOTICE_CACHE_WINDOW); $cnt = 0; while ($faves->fetch()) { if ($faves->id < $notice->id) { # If we passed it, it's not a fave return false; } else { if ($faves->id == $notice->id) { # If it matches a cached notice, then it's a fave return true; } } $cnt++; } # If we're not past the end of the cache window, # then the cache has all available faves, so this one # is not a fave. if ($cnt < NOTICE_CACHE_WINDOW) { return false; } # Otherwise, cache doesn't have all faves; # fall through to the default } $fave = Fave::pkeyGet(array('user_id' => $this->id, 'notice_id' => $notice->id)); return is_null($fave) ? false : true; }