protected function atompubPrepare() { $subscriberId = $this->trimmed('subscriber'); $this->_subscriber = Profile::getKV('id', $subscriberId); if (!$this->_subscriber instanceof Profile) { // TRANS: Client exception thrown when trying to display a subscription for a non-existing profile ID. // TRANS: %d is the non-existing profile ID number. throw new ClientException(sprintf(_('No such profile id: %d.'), $subscriberId), 404); } $subscribedId = $this->trimmed('subscribed'); $this->_subscribed = Profile::getKV('id', $subscribedId); if (!$this->_subscribed instanceof Profile) { // TRANS: Client exception thrown when trying to display a subscription for a non-existing profile ID. // TRANS: %d is the non-existing profile ID number. throw new ClientException(sprintf(_('No such profile id: %d.'), $subscribedId), 404); } $this->_subscription = Subscription::pkeyGet(array('subscriber' => $subscriberId, 'subscribed' => $subscribedId)); if (!$this->_subscription instanceof Subscription) { // TRANS: Client exception thrown when trying to display a subscription for a non-subscribed profile ID. // TRANS: %1$d is the non-existing subscriber ID number, $2$d is the ID of the profile that was not subscribed to. $msg = sprintf(_('Profile %1$d not subscribed to profile %2$d.'), $subscriberId, $subscribedId); throw new ClientException($msg, 404); } return true; }
/** * For initializing members of the class. * * @param array $argarray misc. arguments * * @return boolean true */ function prepare($argarray) { parent::prepare($argarray); $subscriberId = $this->trimmed('subscriber'); $this->_subscriber = Profile::staticGet('id', $subscriberId); if (empty($this->_subscriber)) { // TRANS: Client exception thrown when trying to display a subscription for a non-existing profile ID. // TRANS: %d is the non-existing profile ID number. throw new ClientException(sprintf(_('No such profile id: %d.'), $subscriberId), 404); } $subscribedId = $this->trimmed('subscribed'); $this->_subscribed = Profile::staticGet('id', $subscribedId); if (empty($this->_subscribed)) { // TRANS: Client exception thrown when trying to display a subscription for a non-existing profile ID. // TRANS: %d is the non-existing profile ID number. throw new ClientException(sprintf(_('No such profile id: %d.'), $subscribedId), 404); } $this->_subscription = Subscription::pkeyGet(array('subscriber' => $subscriberId, 'subscribed' => $subscribedId)); if (empty($this->_subscription)) { // TRANS: Client exception thrown when trying to display a subscription for a non-subscribed profile ID. // TRANS: %1$d is the non-existing subscriber ID number, $2$d is the ID of the profile that was not subscribed to. $msg = sprintf(_('Profile %1$d not subscribed to profile %2$d.'), $subscriberId, $subscribedId); throw new ClientException($msg, 404); } return true; }
function onEndSubscribe($subscriber, $other) { // Only do this if config is enabled if (!$this->StartFollowUser) { return true; } $user = $subscriber->getUser(); if (!empty($user)) { $sub = Subscription::pkeyGet(array('subscriber' => $subscriber->id, 'subscribed' => $other->id)); // TRANS: Text for "started following" item in activity plugin. // TRANS: %1$s is a profile URL, %2$s is a profile name, // TRANS: %3$s is a profile URL, %4$s is a profile name. $rendered = sprintf(_m('<a href="%1$s">%2$s</a> started following <a href="%3$s">%4$s</a>.'), $subscriber->profileurl, $subscriber->getBestName(), $other->profileurl, $other->getBestName()); // TRANS: Text for "started following" item in activity plugin. // TRANS: %1$s is a profile name, %2$s is a profile URL, // TRANS: %3$s is a profile name, %4$s is a profile URL. $content = sprintf(_m('%1$s (%2$s) started following %3$s (%4$s).'), $subscriber->getBestName(), $subscriber->profileurl, $other->getBestName(), $other->profileurl); $notice = Notice::saveNew($user->id, $content, ActivityPlugin::SOURCE, array('rendered' => $rendered, 'urls' => array(), 'replies' => array($other->getUri()), 'verb' => ActivityVerb::FOLLOW, 'object_type' => ActivityObject::PERSON, 'content_type' => NOTICE::CONTENT_TYPE_ACTIVITY, 'uri' => $sub->uri)); } return true; }
function showOwnerControls() { $sub = Subscription::pkeyGet(array('subscriber' => $this->owner->id, 'subscribed' => $this->profile->id)); if (!$sub) { return; } $transports = array(); Event::handle('GetImTransports', array(&$transports)); if (!$transports && !common_config('sms', 'enabled')) { return; } $this->out->elementStart('form', array('id' => 'subedit-' . $this->profile->id, 'method' => 'post', 'class' => 'form_subscription_edit', 'action' => common_local_url('subedit'))); $this->out->hidden('token', common_session_token()); $this->out->hidden('profile', $this->profile->id); if ($transports) { $attrs = array('name' => 'jabber', 'type' => 'checkbox', 'class' => 'checkbox', 'id' => 'jabber-' . $this->profile->id); if ($sub->jabber) { $attrs['checked'] = 'checked'; } $this->out->element('input', $attrs); // TRANS: Checkbox label for enabling IM messages for a profile in a subscriptions list. $this->out->element('label', array('for' => 'jabber-' . $this->profile->id), _m('LABEL', 'IM')); } else { $this->out->hidden('jabber', $sub->jabber); } if (common_config('sms', 'enabled')) { $attrs = array('name' => 'sms', 'type' => 'checkbox', 'class' => 'checkbox', 'id' => 'sms-' . $this->profile->id); if ($sub->sms) { $attrs['checked'] = 'checked'; } $this->out->element('input', $attrs); // TRANS: Checkbox label for enabling SMS messages for a profile in a subscriptions list. $this->out->element('label', array('for' => 'sms-' . $this->profile->id), _('SMS')); } else { $this->out->hidden('sms', $sub->sms); } // TRANS: Save button for settings for a profile in a subscriptions list. $this->out->submit('save', _m('BUTTON', 'Save')); $this->out->elementEnd('form'); }
function onEndSubscribe(Profile $profile, Profile $other) { // Only do this if config is enabled if (!$this->StartFollowUser) { return true; } if (!$profile->isLocal()) { // can't do anything with remote user anyway return true; } $sub = Subscription::pkeyGet(array('subscriber' => $profile->id, 'subscribed' => $other->id)); // TRANS: Text for "started following" item in activity plugin. // TRANS: %1$s is a profile URL, %2$s is a profile name, // TRANS: %3$s is a profile URL, %4$s is a profile name. $rendered = sprintf(_m('<a href="%1$s">%2$s</a> started following <a href="%3$s">%4$s</a>.'), $profile->getUrl(), $profile->getBestName(), $other->getUrl(), $other->getBestName()); // TRANS: Text for "started following" item in activity plugin. // TRANS: %1$s is a profile name, %2$s is a profile URL, // TRANS: %3$s is a profile name, %4$s is a profile URL. $content = sprintf(_m('%1$s (%2$s) started following %3$s (%4$s).'), $profile->getBestName(), $profile->getUrl(), $other->getBestName(), $other->getUrl()); $notice = Notice::saveNew($profile->id, $content, ActivityPlugin::SOURCE, array('rendered' => $rendered, 'urls' => array(), 'replies' => array($other->getUri()), 'verb' => ActivityVerb::FOLLOW, 'object_type' => ActivityObject::PERSON, 'uri' => $sub->uri)); return true; }
function handle($args) { parent::handle($args); if ($_SERVER['REQUEST_METHOD'] == 'POST') { $cur = common_current_user(); $sub = Subscription::pkeyGet(array('subscriber' => $cur->id, 'subscribed' => $this->profile->id)); if (!$sub) { $this->clientError(_('You are not subscribed to that profile.')); return false; } $orig = clone $sub; $sub->jabber = $this->boolean('jabber'); $sub->sms = $this->boolean('sms'); $result = $sub->update($orig); if (!$result) { common_log_db_error($sub, 'UPDATE', __FILE__); $this->serverError(_('Could not save subscription.')); return false; } common_redirect(common_local_url('subscriptions', array('nickname' => $cur->nickname)), 303); } }
function handle($args) { parent::handle($args); if ($_SERVER['REQUEST_METHOD'] == 'POST') { $cur = common_current_user(); $sub = Subscription::pkeyGet(array('subscriber' => $cur->id, 'subscribed' => $this->profile->id)); if (!$sub) { // TRANS: Client error displayed trying a change a subscription for a non-subscribed profile. $this->clientError(_('You are not subscribed to that profile.')); } $orig = clone $sub; $sub->jabber = $this->boolean('jabber'); $sub->sms = $this->boolean('sms'); $result = $sub->update($orig); if (!$result) { common_log_db_error($sub, 'UPDATE', __FILE__); // TRANS: Server error displayed when updating a subscription fails with a database error. $this->serverError(_('Could not save subscription.')); } common_redirect(common_local_url('subscriptions', array('nickname' => $cur->nickname)), 303); } }
/** * Having established a remote subscription, send a notification to the * remote OStatus profile's endpoint. * * @param Profile $subscriber * @param Profile $other * * @return hook return code * * @throws Exception */ function onEndSubscribe($subscriber, $other) { $user = User::staticGet('id', $subscriber->id); if (empty($user)) { return true; } $oprofile = Ostatus_profile::staticGet('profile_id', $other->id); if (empty($oprofile)) { return true; } $sub = Subscription::pkeyGet(array('subscriber' => $subscriber->id, 'subscribed' => $other->id)); $act = $sub->asActivity(); $oprofile->notifyActivity($act, $subscriber); return true; }
function saveTags() { $id = $this->trimmed('id'); $tagstring = $this->trimmed('tags'); $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { $this->showForm(_('There was a problem with your session token.' . ' Try again, please.')); return; } if (is_string($tagstring) && strlen($tagstring) > 0) { $tags = array_map('common_canonical_tag', preg_split('/[\\s,]+/', $tagstring)); foreach ($tags as $tag) { if (!common_valid_profile_tag($tag)) { $this->showForm(sprintf(_('Invalid tag: "%s"'), $tag)); return; } } } else { $tags = array(); } $user = common_current_user(); if (!Subscription::pkeyGet(array('subscriber' => $user->id, 'subscribed' => $this->profile->id)) && !Subscription::pkeyGet(array('subscriber' => $this->profile->id, 'subscribed' => $user->id))) { $this->clientError(_('You can only tag people you are subscribed to or who are subscribed to you.')); return; } $result = Profile_tag::setTags($user->id, $this->profile->id, $tags); if (!$result) { $this->clientError(_('Could not save tags.')); return; } $action = $user->isSubscribed($this->profile) ? 'subscriptions' : 'subscribers'; if ($this->boolean('ajax')) { $this->startHTML('text/xml;charset=utf-8'); $this->elementStart('head'); $this->element('title', null, _('Tags')); $this->elementEnd('head'); $this->elementStart('body'); $this->elementStart('p', 'subtags'); foreach ($tags as $tag) { $this->element('a', array('href' => common_local_url($action, array('nickname' => $user->nickname, 'tag' => $tag))), $tag); } $this->elementEnd('p'); $this->elementEnd('body'); $this->elementEnd('html'); } else { common_redirect(common_local_url($action, array('nickname' => $user->nickname))); } }
function show($args, $apidata) { parent::handle($args); if (!in_array($apidata['content-type'], array('xml', 'json'))) { $this->clientError(_('API method not found!'), $code = 404); return; } $user = null; $email = $this->arg('email'); $user_id = $this->arg('user_id'); if ($email) { $user = User::staticGet('email', $email); } elseif ($user_id) { $user = $this->get_user($user_id); } elseif (isset($apidata['api_arg'])) { $user = $this->get_user($apidata['api_arg']); } elseif (isset($apidata['user'])) { $user = $apidata['user']; } if (!$user) { // XXX: Twitter returns a random(?) user instead of throwing and err! -- Zach $this->client_error(_('Not found.'), 404, $apidata['content-type']); return; } $profile = $user->getProfile(); if (!$profile) { common_server_error(_('User has no profile.')); return; } $twitter_user = $this->twitter_user_array($profile, true); // Add in extended user fields offered up by this method $twitter_user['created_at'] = $this->date_twitter($profile->created); $subbed = DB_DataObject::factory('subscription'); $subbed->subscriber = $profile->id; $subbed_count = (int) $subbed->count() - 1; $notices = DB_DataObject::factory('notice'); $notices->profile_id = $profile->id; $notice_count = (int) $notices->count(); $twitter_user['friends_count'] = is_int($subbed_count) ? $subbed_count : 0; $twitter_user['statuses_count'] = is_int($notice_count) ? $notice_count : 0; // Other fields Twitter sends... $twitter_user['profile_background_color'] = ''; $twitter_user['profile_background_image_url'] = ''; $twitter_user['profile_text_color'] = ''; $twitter_user['profile_link_color'] = ''; $twitter_user['profile_sidebar_fill_color'] = ''; $twitter_user['profile_sidebar_border_color'] = ''; $twitter_user['profile_background_tile'] = 'false'; $faves = DB_DataObject::factory('fave'); $faves->user_id = $user->id; $faves_count = (int) $faves->count(); $twitter_user['favourites_count'] = $faves_count; $timezone = 'UTC'; if ($user->timezone) { $timezone = $user->timezone; } $t = new DateTime(); $t->setTimezone(new DateTimeZone($timezone)); $twitter_user['utc_offset'] = $t->format('Z'); $twitter_user['time_zone'] = $timezone; if (isset($apidata['user'])) { if ($apidata['user']->isSubscribed($profile)) { $twitter_user['following'] = 'true'; } else { $twitter_user['following'] = 'false'; } // Notifications on? $sub = Subscription::pkeyGet(array('subscriber' => $apidata['user']->id, 'subscribed' => $profile->id)); if ($sub) { if ($sub->jabber || $sub->sms) { $twitter_user['notifications'] = 'true'; } else { $twitter_user['notifications'] = 'false'; } } } if ($apidata['content-type'] == 'xml') { $this->init_document('xml'); $this->show_twitter_xml_user($twitter_user); $this->end_document('xml'); } elseif ($apidata['content-type'] == 'json') { $this->init_document('json'); $this->show_json_objects($twitter_user); $this->end_document('json'); } else { // This is in case 'show' was called via /account/verify_credentials // without a format (xml or json). header('Content-Type: text/html; charset=utf-8'); print 'Authorized'; } }
/** * Remove old OMB subscription tokens * * @param User $user subscriber * @param Profile $other subscribee * @return hook return value */ function onEndUnsubscribe($profile, $other) { $sub = Subscription::pkeyGet(array('subscriber' => $subscriber->id, 'subscribed' => $other->id)); if (!empty($sub->token)) { $token = new Token(); $token->tok = $sub->token; if ($token->find(true)) { $result = $token->delete(); if (!$result) { common_log_db_error($token, 'DELETE', __FILE__); throw new Exception(_m('Could not delete subscription OMB token.')); } } else { common_log(LOG_ERR, "Couldn't find credentials with token {$token->tok}", __FILE__); } } return true; }
function exists($subscriber, $other) { $sub = Subscription::pkeyGet(array('subscriber' => $subscriber->id, 'subscribed' => $other->id)); return empty($sub) ? false : true; }
function showOwnerControls() { $sub = Subscription::pkeyGet(array('subscriber' => $this->owner->id, 'subscribed' => $this->profile->id)); if (!$sub) { return; } if (!common_config('xmpp', 'enabled') && !common_config('sms', 'enabled')) { return; } $this->out->elementStart('form', array('id' => 'subedit-' . $this->profile->id, 'method' => 'post', 'class' => 'form_subscription_edit', 'action' => common_local_url('subedit'))); $this->out->hidden('token', common_session_token()); $this->out->hidden('profile', $this->profile->id); if (common_config('xmpp', 'enabled')) { $attrs = array('name' => 'jabber', 'type' => 'checkbox', 'class' => 'checkbox', 'id' => 'jabber-' . $this->profile->id); if ($sub->jabber) { $attrs['checked'] = 'checked'; } $this->out->element('input', $attrs); $this->out->element('label', array('for' => 'jabber-' . $this->profile->id), _('Jabber')); } else { $this->out->hidden('jabber', $sub->jabber); } if (common_config('sms', 'enabled')) { $attrs = array('name' => 'sms', 'type' => 'checkbox', 'class' => 'checkbox', 'id' => 'sms-' . $this->profile->id); if ($sub->sms) { $attrs['checked'] = 'checked'; } $this->out->element('input', $attrs); $this->out->element('label', array('for' => 'sms-' . $this->profile->id), _('SMS')); } else { $this->out->hidden('sms', $sub->sms); } $this->out->submit('save', _('Save')); $this->out->elementEnd('form'); return; }
function showOwnerControls() { $sub = Subscription::pkeyGet(array('subscriber' => $this->owner->id, 'subscribed' => $this->profile->id)); if (!$sub) { return; } if (!common_config('xmpp', 'enabled') && !common_config('sms', 'enabled')) { return; } $this->out->elementStart('form', array('id' => 'subedit-' . $this->profile->id, 'method' => 'post', 'class' => 'form_subscription_edit', 'action' => common_local_url('subedit'))); $this->out->hidden('token', common_session_token()); $this->out->hidden('profile', $this->profile->id); $this->out->elementEnd('form'); return; }
/** * Having established a remote subscription, send a notification to the * remote OStatus profile's endpoint. * * @param Profile $profile subscriber * @param Profile $other subscribee * * @return hook return code * * @throws Exception */ function onEndSubscribe(Profile $profile, Profile $other) { if (!$profile->isLocal()) { return true; } $oprofile = Ostatus_profile::getKV('profile_id', $other->id); if (!$oprofile instanceof Ostatus_profile) { return true; } $sub = Subscription::pkeyGet(array('subscriber' => $profile->id, 'subscribed' => $other->id)); $act = $sub->asActivity(); $oprofile->notifyActivity($act, $profile); return true; }
/** * Cancel a subscription * */ static function cancel(Profile $subscriber, Profile $other) { if (!self::exists($subscriber, $other)) { // TRANS: Exception thrown when trying to unsibscribe without a subscription. throw new AlreadyFulfilledException(_('Not subscribed!')); } // Don't allow deleting self subs if ($subscriber->id == $other->id) { // TRANS: Exception thrown when trying to unsubscribe a user from themselves. throw new Exception(_('Could not delete self-subscription.')); } if (Event::handle('StartUnsubscribe', array($subscriber, $other))) { $sub = Subscription::pkeyGet(array('subscriber' => $subscriber->id, 'subscribed' => $other->id)); // note we checked for existence above assert(!empty($sub)); $result = $sub->delete(); if (!$result) { common_log_db_error($sub, 'DELETE', __FILE__); // TRANS: Exception thrown when a subscription could not be deleted on the server. throw new Exception(_('Could not delete subscription.')); } self::blow('user:notices_with_friends:%d', $subscriber->id); self::blow('subscription:by-subscriber:' . $subscriber->id); self::blow('subscription:by-subscribed:' . $other->id); $subscriber->blowSubscriptionCount(); $other->blowSubscriberCount(); Event::handle('EndUnsubscribe', array($subscriber, $other)); } return; }
function showOwnerControls($profile) { $sub = Subscription::pkeyGet(array('subscriber' => $this->owner->id, 'subscribed' => $profile->id)); if (!$sub) { return; } $this->out->elementStart('form', array('id' => 'subedit-' . $profile->id, 'method' => 'post', 'class' => 'form_subcription_edit', 'action' => common_local_url('subedit'))); $this->out->hidden('token', common_session_token()); $this->out->hidden('profile', $profile->id); $this->out->checkbox('jabber', _('Jabber'), $sub->jabber); $this->out->checkbox('sms', _('SMS'), $sub->sms); $this->out->submit('save', _('Save')); $this->out->elementEnd('form'); return; }
/** * broadcast a notice to all subscribers and reply recipients * * This function will send a notice to all subscribers on the local server * who have IM addresses, and have IM notification enabled, and * have this subscription enabled for IM. It also sends the notice to * all recipients of @-replies who have IM addresses and IM notification * enabled. This is really the heart of IM distribution in StatusNet. * * @param Notice $notice The notice to broadcast * * @return boolean success flag */ function broadcastNotice($notice) { $ni = $notice->whoGets(); foreach ($ni as $user_id => $reason) { $user = User::getKV($user_id); if (empty($user)) { // either not a local user, or just not found continue; } $user_im_prefs = $this->getUserImPrefsFromUser($user); if (!$user_im_prefs || !$user_im_prefs->notify) { continue; } switch ($reason) { case NOTICE_INBOX_SOURCE_REPLY: if (!$user_im_prefs->replies) { continue 2; } break; case NOTICE_INBOX_SOURCE_SUB: $sub = Subscription::pkeyGet(array('subscriber' => $user->id, 'subscribed' => $notice->profile_id)); if (empty($sub) || !$sub->jabber) { continue 2; } break; case NOTICE_INBOX_SOURCE_GROUP: break; default: // TRANS: Exception thrown when trying to deliver a notice to an unknown inbox. // TRANS: %d is the unknown inbox ID (number). throw new Exception(sprintf(_('Unknown inbox source %d.'), $reason)); } common_log(LOG_INFO, 'Sending notice ' . $notice->id . ' to ' . $user_im_prefs->screenname, __FILE__); $this->sendNotice($user_im_prefs->screenname, $notice); $user_im_prefs->free(); } return true; }
/** * Queue broadcast of a notice to all subscribers and reply recipients * * This function will send a notice to all subscribers on the local server * who have Jabber addresses, and have Jabber notification enabled, and * have this subscription enabled for Jabber. It also sends the notice to * all recipients of @-replies who have Jabber addresses and Jabber notification * enabled. This is really the heart of Jabber distribution in StatusNet. * * @param Notice $notice The notice to broadcast * * @return boolean success flag */ function jabber_broadcast_notice($notice) { if (!common_config('xmpp', 'enabled')) { return true; } $profile = Profile::staticGet($notice->profile_id); if (!$profile) { common_log(LOG_WARNING, 'Refusing to broadcast notice with ' . 'unknown profile ' . common_log_objstring($notice), __FILE__); return true; // not recoverable; discard. } $msg = jabber_format_notice($profile, $notice); $entry = jabber_format_entry($profile, $notice); $profile->free(); unset($profile); $sent_to = array(); $conn = jabber_proxy(); $ni = $notice->whoGets(); foreach ($ni as $user_id => $reason) { $user = User::staticGet($user_id); if (empty($user) || empty($user->jabber) || !$user->jabbernotify) { // either not a local user, or just not found continue; } switch ($reason) { case NOTICE_INBOX_SOURCE_REPLY: if (!$user->jabberreplies) { continue 2; } break; case NOTICE_INBOX_SOURCE_SUB: $sub = Subscription::pkeyGet(array('subscriber' => $user->id, 'subscribed' => $notice->profile_id)); if (empty($sub) || !$sub->jabber) { continue 2; } break; case NOTICE_INBOX_SOURCE_GROUP: break; default: throw new Exception(sprintf(_("Unknown inbox source %d."), $reason)); } common_log(LOG_INFO, 'Sending notice ' . $notice->id . ' to ' . $user->jabber, __FILE__); $conn->message($user->jabber, $msg, 'chat', null, $entry); } return true; }
function relationshipDetailsArray($source, $target) { $details = array(); $details['screen_name'] = $source->nickname; $details['followed_by'] = $target->isSubscribed($source); $details['following'] = $source->isSubscribed($target); $notifications = false; if ($source->isSubscribed($target)) { $sub = Subscription::pkeyGet(array('subscriber' => $source->id, 'subscribed' => $target->id)); if (!empty($sub)) { $notifications = $sub->jabber || $sub->sms; } } $details['notifications_enabled'] = $notifications; $details['blocking'] = $source->hasBlocked($target); $details['id'] = intval($source->id); return $details; }
function block($other) { # Add a new block record $block = new Profile_block(); # Begin a transaction $block->query('BEGIN'); $block->blocker = $this->id; $block->blocked = $other->id; $result = $block->insert(); if (!$result) { common_log_db_error($block, 'INSERT', __FILE__); return false; } # Cancel their subscription, if it exists $sub = Subscription::pkeyGet(array('subscriber' => $other->id, 'subscribed' => $this->id)); if ($sub) { $result = $sub->delete(); if (!$result) { common_log_db_error($sub, 'DELETE', __FILE__); return false; } } $block->query('COMMIT'); return true; }