function subs_subscribe_to($user, $other) { try { Subscription::start($user->getProfile(), $other); return true; } catch (Exception $e) { return $e->getMessage(); } }
/** * Complete a pending subscription, as we've got approval of some sort. * * @return Subscription */ public function complete() { $subscriber = Profile::staticGet('id', $this->subscriber); $subscribed = Profile::staticGet('id', $this->subscribed); $sub = Subscription::start($subscriber, $subscribed, Subscription::FORCE); if ($sub) { $this->delete(); } return $sub; }
/** * Complete a pending subscription, as we've got approval of some sort. * * @return Subscription */ public function complete() { $subscriber = Profile::getKV('id', $this->subscriber); $subscribed = Profile::getKV('id', $this->subscribed); try { $sub = Subscription::start($subscriber, $subscribed, Subscription::FORCE); $this->delete(); } catch (AlreadyFulfilledException $e) { common_debug('Tried to start a subscription which already existed.'); } return $sub; }
/** * Called when a new user is registered. * * We find all users, and try to subscribe them to the new user, and * the new user to them. Exceptions (like silenced users or whatever) * are caught, logged, and ignored. * * @param Profile &$newProfile The new user's profile * @param User &$newUser The new user * * @return boolean hook value * */ function onEndUserRegister(&$newProfile, &$newUser) { $otherUser = new User(); $otherUser->whereAdd('id != ' . $newUser->id); if ($otherUser->find()) { while ($otherUser->fetch()) { $otherProfile = $otherUser->getProfile(); try { if (User_followeveryone_prefs::followEveryone($otherUser->id)) { Subscription::start($otherProfile, $newProfile); } Subscription::start($newProfile, $otherProfile); } catch (Exception $e) { common_log(LOG_WARNING, $e->getMessage()); continue; } } } $ufep = new User_followeveryone_prefs(); $ufep->user_id = $newUser->id; $ufep->followeveryone = true; $ufep->insert(); return true; }
function handle($channel) { if (!$this->other) { // TRANS: Error text shown when no username was provided when issuing a subscribe command. $channel->error($this->user, _('Specify the name of the user to subscribe to.')); return; } $target = $this->getProfile($this->other); $remote = Remote_profile::staticGet('id', $target->id); if ($remote) { // TRANS: Command exception text shown when trying to subscribe to an OMB profile using the subscribe command. throw new CommandException(_("Can't subscribe to OMB profiles by command.")); } try { Subscription::start($this->user->getProfile(), $target); // TRANS: Text shown after having subscribed to another user successfully. // TRANS: %s is the name of the user the subscription was requested for. $channel->output($this->user, sprintf(_('Subscribed to %s.'), $this->other)); } catch (Exception $e) { $channel->error($this->user, $e->getMessage()); } }
function moveActivity($act, $sink, $user, $remote) { if (empty($user)) { 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)) { Group_member::leave($group->id, $user->id); } 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; } }
function subscribeProfile($user, $subject, $activity) { $profile = $user->getProfile(); if ($activity->objects[0]->id == $subject->id) { $other = $activity->actor; $otherUser = User::staticGet('uri', $other->id); if (!empty($otherUser)) { $otherProfile = $otherUser->getProfile(); } else { throw new Exception("Can't force remote user to subscribe."); } // XXX: don't do this for untrusted input! Subscription::start($otherProfile, $profile); } else { if (empty($activity->actor) || $activity->actor->id == $subject->id) { $other = $activity->objects[0]; $otherUser = User::staticGet('uri', $other->id); if (!empty($otherUser)) { $otherProfile = $otherUser->getProfile(); } else { $oprofile = Ostatus_profile::ensureActivityObjectProfile($other); $otherProfile = $oprofile->localProfile(); } Subscription::start($profile, $otherProfile); } else { throw new Exception("This activity seems unrelated to our user."); } } }
function subscribeTwitterFriends($flink) { $friends = $this->fetchTwitterFriends($flink); if (empty($friends)) { common_debug($this->name() . ' - Couldn\'t get friends from Twitter for ' . "Twitter user {$flink->foreign_id}."); return false; } $profile = $flink->getProfile(); foreach ($friends as $friend) { $friend_name = $friend->screen_name; $friend_id = (int) $friend->id; // Update or create the Foreign_user record for each // Twitter friend if (!save_twitter_user($friend_id, $friend_name)) { common_log(LOG_WARNING, $this->name() . " - Couldn't save {$screen_name}'s friend, {$friend_name}."); continue; } // Check to see if there's a related local user $friend_flink = Foreign_link::getByForeignID($friend_id, TWITTER_SERVICE); if (!empty($friend_flink)) { // Get associated user and subscribe her $friend_profile = Profile::getKV('id', $friend_flink->user_id); if ($friend_profile instanceof Profile) { try { $other = Profile::getKV('id', $invites->user_id); Subscription::start($profile, $friend_profile); common_log(LOG_INFO, $this->name() . ' - Subscribed ' . "{$friend_profile->nickname} to {$profile->nickname}."); } catch (Exception $e) { common_debug($this->name() . ' - Tried and failed subscribing ' . "{$friend_profile->nickname} to {$profile->nickname} - " . $e->getMessage()); } } } } return true; }
function handle($channel) { if (!$this->other) { $channel->error($this->user, _('Specify the name of the user to subscribe to')); return; } $target = $this->getProfile($this->other); $remote = Remote_profile::staticGet('id', $target->id); if ($remote) { throw new CommandException(_("Can't subscribe to OMB profiles by command.")); } try { Subscription::start($this->user->getProfile(), $target); $channel->output($this->user, sprintf(_('Subscribed to %s'), $this->other)); } catch (Exception $e) { $channel->error($this->user, $e->getMessage()); } }
/** * Handle request * * Does the subscription and returns results. * * @param Array $args unused. * * @return void */ function handle($args) { // Throws exception on error Subscription::start($this->user->getProfile(), $this->other); if ($this->boolean('ajax')) { $this->startHTML('text/xml;charset=utf-8'); $this->elementStart('head'); $this->element('title', null, _('Subscribed')); $this->elementEnd('head'); $this->elementStart('body'); $unsubscribe = new UnsubscribeForm($this, $this->other); $unsubscribe->show(); $this->elementEnd('body'); $this->elementEnd('html'); } else { $url = common_local_url('subscriptions', array('nickname' => $this->user->nickname)); common_redirect($url, 303); } }
function newSub($i) { global $userprefix; $f = rand(0, $i - 1); $fromnick = sprintf('%s%d', $userprefix, $f); $from = User::getKV('nickname', $fromnick); if (empty($from)) { throw new Exception("Can't find user '{$fromnick}'."); } $t = rand(0, $i - 1); if ($t == $f) { $t++; if ($t > $i - 1) { $t = 0; } } $tunic = sprintf('%s%d', $userprefix, $t); $to = User::getKV('nickname', $tunic); if (!$to instanceof User) { throw new Exception("Can't find user '{$tunic}'."); } Subscription::start($from->getProfile(), $to->getProfile()); $from->free(); $to->free(); }
function subscribeTwitterFriends(Foreign_link $flink) { try { $profile = $flink->getProfile(); } catch (NoResultException $e) { common_log(LOG_WARNING, 'Foreign_link has no matching local profile for local ID: ' . $flink->user_id); } $friends = $this->fetchTwitterFriends($flink); if (empty($friends)) { common_debug($this->name() . ' - Couldn\'t get friends from Twitter for ' . "Twitter user {$flink->foreign_id}."); return false; } foreach ($friends as $friend) { $friend_name = $friend->screen_name; $friend_id = (int) $friend->id; // Update or create the Foreign_user record for each // Twitter friend if (!save_twitter_user($friend_id, $friend_name)) { common_log(LOG_WARNING, $this->name() . " - Couldn't save {$screen_name}'s friend, {$friend_name}."); continue; } // Check to see if there's a related local user and try to subscribe try { $friend_flink = Foreign_link::getByForeignID($friend_id, TWITTER_SERVICE); // Get associated user and subscribe her $friend_profile = $friend_flink->getProfile(); Subscription::start($profile, $friend_profile); common_log(LOG_INFO, $this->name() . ' - Subscribed ' . "{$friend_profile->nickname} to {$profile->nickname}."); } catch (NoResultException $e) { // either no foreign link for this friend's foreign ID or no profile found on local ID. } catch (Exception $e) { common_debug($this->name() . ' - Tried and failed subscribing ' . "{$friend_profile->nickname} to {$profile->nickname} - " . $e->getMessage()); } } return true; }
/** * 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."); } }
function emailChanged() { $invites = new Invitation(); $invites->address = $this->email; $invites->address_type = 'email'; if ($invites->find()) { while ($invites->fetch()) { try { $other = Profile::getKV('id', $invites->user_id); if (!$other instanceof Profile) { // remove when getKV throws exceptions continue; } Subscription::start($other, $this->getProfile()); } catch (Exception $e) { continue; } } } }
/** * Create the initial admin user account. * Side effect: may load portions of StatusNet framework. * Side effect: outputs program info */ function registerInitialUser() { define('STATUSNET', true); define('LACONICA', true); // compatibility require_once INSTALLDIR . '/lib/common.php'; $data = array('nickname' => $this->adminNick, 'password' => $this->adminPass, 'fullname' => $this->adminNick); if ($this->adminEmail) { $data['email'] = $this->adminEmail; } $user = User::register($data); if (empty($user)) { return false; } // give initial user carte blanche $user->grantRole('owner'); $user->grantRole('moderator'); $user->grantRole('administrator'); // Attempt to do a remote subscribe to update@status.net // Will fail if instance is on a private network. if ($this->adminUpdates && class_exists('Ostatus_profile')) { try { $oprofile = Ostatus_profile::ensureProfileURL('http://update.status.net/'); Subscription::start($user->getProfile(), $oprofile->localProfile()); $this->updateStatus("Set up subscription to <a href='http://update.status.net/'>update@status.net</a>."); } catch (Exception $e) { $this->updateStatus("Could not set up subscription to <a href='http://update.status.net/'>update@status.net</a>.", true); } } return true; }
function updateOStatus($user) { if (!have_option('q', 'quiet')) { echo "{$user->nickname}..."; } $up = $user->getProfile(); $sp = $user->getSubscriptions(); $rps = array(); while ($sp->fetch()) { $remote = Remote_profile::staticGet('id', $sp->id); if (!empty($remote)) { $rps[] = clone $sp; } } if (!have_option('q', 'quiet')) { echo count($rps) . "\n"; } foreach ($rps as $rp) { try { if (!have_option('q', 'quiet')) { echo "Checking {$rp->nickname}..."; } $op = Ostatus_profile::ensureProfileURL($rp->profileurl); if (empty($op)) { echo "can't convert.\n"; continue; } else { if (!have_option('q', 'quiet')) { echo "Converting..."; } Subscription::start($up, $op->localProfile()); Subscription::cancel($up, $rp); if (!have_option('q', 'quiet')) { echo "done.\n"; } } } catch (Exception $e) { if (!have_option('q', 'quiet')) { echo "fail.\n"; } common_log(LOG_NOTICE, "Couldn't convert OMB subscription (" . $up->nickname . ", " . $rp->nickname . ") to OStatus: " . $e->getMessage()); continue; } } }
function handle($channel) { if (!$this->other) { // TRANS: Error text shown when no username was provided when issuing a subscribe command. $channel->error($this->user, _('Specify the name of the user to subscribe to.')); return; } $target = $this->getProfile($this->other); try { Subscription::start($this->user->getProfile(), $target); // TRANS: Text shown after having subscribed to another user successfully. // TRANS: %s is the name of the user the subscription was requested for. $channel->output($this->user, sprintf(_('Subscribed to %s.'), $this->other)); } catch (Exception $e) { $channel->error($this->user, $e->getMessage()); } }
/** * Add a new subscription * * Handling the POST method for AtomPub * * @return void */ function addSubscription() { if (empty($this->auth_user) || $this->auth_user->id != $this->_profile->id) { // TRANS: Client exception thrown when trying to subscribe 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. $this->clientError(_('Atom post must be an Atom entry.')); } $activity = new Activity($dom->documentElement); $sub = null; if (Event::handle('StartAtomPubNewActivity', array(&$activity))) { if ($activity->verb != ActivityVerb::FOLLOW) { // TRANS: Client error displayed when not using the follow verb. $this->clientError(_('Can only handle Follow activities.')); } $person = $activity->objects[0]; if ($person->type != ActivityObject::PERSON) { // TRANS: Client exception thrown when subscribing to an object that is not a person. $this->clientError(_('Can only follow people.')); } // XXX: OStatus discovery (maybe) try { $profile = Profile::fromUri($person->id); } catch (UnknownUriException $e) { // TRANS: Client exception thrown when subscribing to a non-existing profile. // TRANS: %s is the unknown profile ID. $this->clientError(sprintf(_('Unknown profile %s.'), $person->id)); } try { $sub = Subscription::start($this->_profile, $profile); } catch (AlreadyFulfilledException $e) { // 409 Conflict $this->clientError($e->getMessage(), 409); } Event::handle('EndAtomPubNewActivity', array($activity, $sub)); } if (!empty($sub)) { $act = $sub->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 subscribeProfile($user, $author, $activity) { $profile = $user->getProfile(); if ($activity->objects[0]->id == $author->id) { if (!$this->trusted) { // TRANS: Client exception thrown when trying to force a subscription for an untrusted user. throw new ClientException(_("Cannot force subscription for untrusted user.")); } $other = $activity->actor; $otherUser = User::staticGet('uri', $other->id); if (!empty($otherUser)) { $otherProfile = $otherUser->getProfile(); } else { // TRANS: Client exception thrown when trying to for a remote user to subscribe. throw new Exception(_("Cannot force remote user to subscribe.")); } // XXX: don't do this for untrusted input! Subscription::start($otherProfile, $profile); } else { if (empty($activity->actor) || $activity->actor->id == $author->id) { $other = $activity->objects[0]; $otherProfile = Profile::fromUri($other->id); if (empty($otherProfile)) { // TRANS: Client exception thrown when trying to subscribe to an unknown profile. throw new ClientException(_("Unknown profile.")); } Subscription::start($profile, $otherProfile); } else { // TRANS: Client exception thrown when trying to import an event not related to the importing user. throw new Exception(_("This activity seems unrelated to our user.")); } } }
/** * Attempt to finalize subscription. * validateFeed must have been run first. * * Calls showForm on failure or success on success. */ function saveFeed() { // And subscribe the current user to the local profile $local = $this->oprofile->localProfile(); if ($this->scoped->isSubscribed($local)) { // TRANS: OStatus remote subscription dialog error. $this->showForm(_m('Already subscribed!')); } elseif (Subscription::start($this->scoped, $local)) { $this->success(); } else { // TRANS: OStatus remote subscription dialog error. $this->showForm(_m('Remote subscription failed!')); } }
/** * Register a new user account and profile and set up default subscriptions. * If a new-user welcome message is configured, this will be sent. * * @param array $fields associative array of optional properties * string 'bio' * string 'email' * bool 'email_confirmed' pass true to mark email as pre-confirmed * string 'fullname' * string 'homepage' * string 'location' informal string description of geolocation * float 'lat' decimal latitude for geolocation * float 'lon' decimal longitude for geolocation * int 'location_id' geoname identifier * int 'location_ns' geoname namespace to interpret location_id * string 'nickname' REQUIRED * string 'password' (may be missing for eg OpenID registrations) * string 'code' invite code * ?string 'uri' permalink to notice; defaults to local notice URL * @return mixed User object or false on failure */ static function register($fields) { // MAGICALLY put fields into current scope extract($fields); $profile = new Profile(); if (!empty($email)) { $email = common_canonical_email($email); } $nickname = common_canonical_nickname($nickname); $profile->nickname = $nickname; if (!User::allowed_nickname($nickname)) { common_log(LOG_WARNING, sprintf("Attempted to register a nickname that is not allowed: %s", $profile->nickname), __FILE__); return false; } $profile->profileurl = common_profile_url($nickname); if (!empty($fullname)) { $profile->fullname = $fullname; } if (!empty($homepage)) { $profile->homepage = $homepage; } if (!empty($bio)) { $profile->bio = $bio; } if (!empty($location)) { $profile->location = $location; $loc = Location::fromName($location); if (!empty($loc)) { $profile->lat = $loc->lat; $profile->lon = $loc->lon; $profile->location_id = $loc->location_id; $profile->location_ns = $loc->location_ns; } } $profile->created = common_sql_now(); $user = new User(); $user->nickname = $nickname; // Users who respond to invite email have proven their ownership of that address if (!empty($code)) { $invite = Invitation::staticGet($code); if ($invite && $invite->address && $invite->address_type == 'email' && $invite->address == $email) { $user->email = $invite->address; } } if (isset($email_confirmed) && $email_confirmed) { $user->email = $email; } // This flag is ignored but still set to 1 $user->inboxed = 1; // Set default-on options here, otherwise they'll be disabled // initially for sites using caching, since the initial encache // doesn't know about the defaults in the database. $user->emailnotifysub = 1; $user->emailnotifyfav = 1; $user->emailnotifynudge = 1; $user->emailnotifymsg = 1; $user->emailnotifyattn = 1; $user->emailmicroid = 1; $user->emailpost = 1; $user->jabbermicroid = 1; $user->viewdesigns = 1; $user->created = common_sql_now(); if (Event::handle('StartUserRegister', array(&$user, &$profile))) { $profile->query('BEGIN'); $id = $profile->insert(); if (empty($id)) { common_log_db_error($profile, 'INSERT', __FILE__); return false; } $user->id = $id; if (!empty($uri)) { $user->uri = $uri; } else { $user->uri = common_user_uri($user); } if (!empty($password)) { // may not have a password for OpenID users $user->password = common_munge_password($password, $id); } $result = $user->insert(); if (!$result) { common_log_db_error($user, 'INSERT', __FILE__); return false; } // Everyone gets an inbox $inbox = new Inbox(); $inbox->user_id = $user->id; $inbox->notice_ids = ''; $result = $inbox->insert(); if (!$result) { common_log_db_error($inbox, 'INSERT', __FILE__); return false; } // Everyone is subscribed to themself $subscription = new Subscription(); $subscription->subscriber = $user->id; $subscription->subscribed = $user->id; $subscription->created = $user->created; $result = $subscription->insert(); if (!$result) { common_log_db_error($subscription, 'INSERT', __FILE__); return false; } if (!empty($email) && !$user->email) { $confirm = new Confirm_address(); $confirm->code = common_confirmation_code(128); $confirm->user_id = $user->id; $confirm->address = $email; $confirm->address_type = 'email'; $result = $confirm->insert(); if (!$result) { common_log_db_error($confirm, 'INSERT', __FILE__); return false; } } if (!empty($code) && $user->email) { $user->emailChanged(); } // Default system subscription $defnick = common_config('newuser', 'default'); if (!empty($defnick)) { $defuser = User::staticGet('nickname', $defnick); if (empty($defuser)) { common_log(LOG_WARNING, sprintf("Default user %s does not exist.", $defnick), __FILE__); } else { Subscription::start($user, $defuser); } } $profile->query('COMMIT'); if (!empty($email) && !$user->email) { mail_confirm_address($user, $confirm->code, $profile->nickname, $email); } // Welcome message $welcome = common_config('newuser', 'welcome'); if (!empty($welcome)) { $welcomeuser = User::staticGet('nickname', $welcome); if (empty($welcomeuser)) { common_log(LOG_WARNING, sprintf("Welcome user %s does not exist.", $defnick), __FILE__); } else { $notice = Notice::saveNew($welcomeuser->id, sprintf(_('Welcome to %1$s, @%2$s!'), common_config('site', 'name'), $user->nickname), 'system'); } } Event::handle('EndUserRegister', array(&$profile, &$user)); } return $user; }
/** * Handle the request * * Check the format and show the user info * * @return void */ protected function handle() { parent::handle(); if (!in_array($this->format, array('xml', 'json'))) { // TRANS: Client error displayed when coming across a non-supported API method. $this->clientError(_('API method not found.'), 404); } if (empty($this->other)) { // TRANS: Client error displayed when trying follow who's profile could not be found. $this->clientError(_('Could not follow user: profile not found.'), 403); } if ($this->scoped->isSubscribed($this->other)) { $errmsg = sprintf(_('Could not follow user: %s is already on your list.'), $this->other->nickname); $this->clientError($errmsg, 403); } try { Subscription::start($this->scoped, $this->other); } catch (AlreadyFulfilledException $e) { $this->clientError($e->getMessage(), 409); } $this->initDocument($this->format); $this->showProfile($this->other, $this->format); $this->endDocument($this->format); }
/** * We've gotten a follow/subscribe notification from a remote user. * Save a subscription relationship for them. */ function handleFollow() { common_log(LOG_INFO, sprintf('Setting up subscription from remote %s to local %s', $this->oprofile->getUri(), $this->target->getNickname())); Subscription::start($this->actor, $this->target); }