X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;ds=sidebyside;f=plugins%2FOStatus%2Factions%2Fusersalmon.php;h=c7ec33eeecd61fd95e30acb5d71ee2923eb1b00a;hb=5dfb8e2bc418d1144c953214a40b4dd730ca148b;hp=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391;hpb=2df3bbc80b6c9dd44134bcf3b5b4a09ea1a803d1;p=quix0rs-gnu-social.git diff --git a/plugins/OStatus/actions/usersalmon.php b/plugins/OStatus/actions/usersalmon.php index e69de29bb2..c7ec33eeec 100644 --- a/plugins/OStatus/actions/usersalmon.php +++ b/plugins/OStatus/actions/usersalmon.php @@ -0,0 +1,226 @@ +. + */ + +if (!defined('STATUSNET')) { + exit(1); +} + +/** + * @package OStatusPlugin + * @author James Walker + */ +class UsersalmonAction extends SalmonAction +{ + function prepare($args) + { + parent::prepare($args); + + $id = $this->trimmed('id'); + + if (!$id) { + $this->clientError(_m('No ID.')); + } + + $this->user = User::staticGet('id', $id); + + if (empty($this->user)) { + $this->clientError(_m('No such user.')); + } + + $this->target = $this->user; + + return true; + } + + /** + * We've gotten a post event on the Salmon backchannel, probably a reply. + * + * @todo validate if we need to handle this post, then call into + * ostatus_profile's general incoming-post handling. + */ + function handlePost() + { + common_log(LOG_INFO, "Received post of '{$this->activity->objects[0]->id}' from '{$this->activity->actor->id}'"); + + // @fixme: process all activity objects? + switch ($this->activity->objects[0]->type) { + case ActivityObject::ARTICLE: + case ActivityObject::BLOGENTRY: + case ActivityObject::NOTE: + case ActivityObject::STATUS: + case ActivityObject::COMMENT: + break; + default: + throw new ClientException("Can't handle that kind of post."); + } + + // Notice must either be a) in reply to a notice by this user + // or b) to the attention of this user + // or c) in reply to a notice to the attention of this user + + $context = $this->activity->context; + + if (!empty($context->replyToID)) { + $notice = Notice::staticGet('uri', $context->replyToID); + if (empty($notice)) { + // TRANS: Client exception. + throw new ClientException(_m('In reply to unknown notice.')); + } + if ($notice->profile_id != $this->user->id && + !in_array($this->user->id, $notice->getReplies())) { + // TRANS: Client exception. + throw new ClientException(_m('In reply to a notice not by this user and not mentioning this user.')); + } + } else if (!empty($context->attention)) { + if (!in_array($this->user->uri, $context->attention) && + !in_array(common_profile_url($this->user->nickname), $context->attention)) { + common_log(LOG_ERR, "{$this->user->uri} not in attention list (".implode(',', $context->attention).")"); + // TRANS: Client exception. + throw new ClientException('To the attention of user(s), not including this one.'); + } + } else { + // TRANS: Client exception. + throw new ClientException('Not to anyone in reply to anything.'); + } + + $existing = Notice::staticGet('uri', $this->activity->objects[0]->id); + + if (!empty($existing)) { + common_log(LOG_ERR, "Not saving notice '{$existing->uri}'; already exists."); + return; + } + + $this->saveNotice(); + } + + /** + * We've gotten a follow/subscribe notification from a remote user. + * Save a subscription relationship for them. + */ + function handleFollow() + { + $oprofile = $this->ensureProfile(); + if ($oprofile) { + common_log(LOG_INFO, "Setting up subscription from remote {$oprofile->uri} to local {$this->user->nickname}"); + Subscription::start($oprofile->localProfile(), + $this->user->getProfile()); + } else { + common_log(LOG_INFO, "Can't set up subscription from remote; missing profile."); + } + } + + /** + * We've gotten an unfollow/unsubscribe notification from a remote user. + * Check if we have a subscription relationship for them and kill it. + * + * @fixme probably catch exceptions on fail? + */ + function handleUnfollow() + { + $oprofile = $this->ensureProfile(); + if ($oprofile) { + common_log(LOG_INFO, "Canceling subscription from remote {$oprofile->uri} to local {$this->user->nickname}"); + Subscription::cancel($oprofile->localProfile(), $this->user->getProfile()); + } else { + common_log(LOG_ERR, "Can't cancel subscription from remote, didn't find the profile"); + } + } + + /** + * Remote user likes one of our posts. + * Confirm the post is ours, and save a local favorite event. + */ + + function handleFavorite() + { + $notice = $this->getNotice($this->activity->objects[0]); + $profile = $this->ensureProfile()->localProfile(); + + $old = Fave::pkeyGet(array('user_id' => $profile->id, + 'notice_id' => $notice->id)); + + if (!empty($old)) { + // TRANS: Client exception. + throw new ClientException(_m('This is already a favorite.')); + } + + if (!Fave::addNew($profile, $notice)) { + // TRANS: Client exception. + throw new ClientException(_m('Could not save new favorite.')); + } + } + + /** + * 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(_m('Notice was not favorited!')); + } + + $fave->delete(); + } + + /** + * @param ActivityObject $object + * @return Notice + * @throws ClientException on invalid input + */ + function getNotice($object) + { + if (!$object) { + // TRANS: Client exception. + throw new ClientException(_m('Can\'t favorite/unfavorite without an object.')); + } + + switch ($object->type) { + case ActivityObject::ARTICLE: + case ActivityObject::BLOGENTRY: + case ActivityObject::NOTE: + case ActivityObject::STATUS: + case ActivityObject::COMMENT: + break; + default: + // TRANS: Client exception. + throw new ClientException(_m('Can\'t handle that kind of object for liking/faving.')); + } + + $notice = Notice::staticGet('uri', $object->id); + + if (empty($notice)) { + // TRANS: Client exception. %s is an object ID. + throw new ClientException(sprintf(_m('Notice with ID %s unknown.'),$object->id)); + } + + if ($notice->profile_id != $this->user->id) { + // TRANS: Client exception. %1$s is a notice ID, %2$s is a user ID. + throw new ClientException(sprintf(_m('Notice with ID %1$s not posted by %2$s.'),$object->id,$this->user->id)); + } + + return $notice; + } +}