function onRouterInitialized($m)
{
// Discovery actions
- $m->connect('main/xrd',
- array('action' => 'userxrd'));
$m->connect('main/ownerxrd',
array('action' => 'ownerxrd'));
$m->connect('main/ostatus',
array('action' => 'ostatusinit'));
+ $m->connect('main/ostatustag',
+ array('action' => 'ostatustag'));
+ $m->connect('main/ostatustag?nickname=:nickname',
+ array('action' => 'ostatustag'), array('nickname' => '[A-Za-z0-9_-]+'));
$m->connect('main/ostatus?nickname=:nickname',
array('action' => 'ostatusinit'), array('nickname' => '[A-Za-z0-9_-]+'));
$m->connect('main/ostatus?group=:group',
array('action' => 'ostatusinit'), array('group' => '[A-Za-z0-9_-]+'));
+ $m->connect('main/ostatus?peopletag=:peopletag&tagger=:tagger',
+ array('action' => 'ostatusinit'), array('tagger' => '[A-Za-z0-9_-]+',
+ 'peopletag' => '[A-Za-z0-9_-]+'));
+
+ // Remote subscription actions
$m->connect('main/ostatussub',
array('action' => 'ostatussub'));
$m->connect('main/ostatusgroup',
array('action' => 'ostatusgroup'));
+ $m->connect('main/ostatuspeopletag',
+ array('action' => 'ostatuspeopletag'));
// PuSH actions
$m->connect('main/push/hub', array('action' => 'pushhub'));
$m->connect('main/salmon/group/:id',
array('action' => 'groupsalmon'),
array('id' => '[0-9]+'));
+ $m->connect('main/salmon/peopletag/:id',
+ array('action' => 'peopletagsalmon'),
+ array('id' => '[0-9]+'));
return true;
}
$user = $feed->getUser();
$id = $user->id;
$profile = $user->getProfile();
- $feed->setActivitySubject($profile->asActivityNoun('subject'));
} else if ($feed instanceof AtomGroupNoticeFeed) {
$salmonAction = 'groupsalmon';
$group = $feed->getGroup();
$id = $group->id;
- $feed->setActivitySubject($group->asActivitySubject());
+ } else if ($feed instanceof AtomListNoticeFeed) {
+ $salmonAction = 'peopletagsalmon';
+ $peopletag = $feed->getList();
+ $id = $peopletag->id;
} else {
return true;
}
* Add in an OStatus subscribe button
*/
function onStartProfileRemoteSubscribe($output, $profile)
+ {
+ $this->onStartProfileListItemActionElements($output, $profile);
+ return false;
+ }
+
+ function onStartGroupSubscribe($output, $group)
{
$cur = common_current_user();
if (empty($cur)) {
// Add an OStatus subscribe
- $output->elementStart('li', 'entity_subscribe');
$url = common_local_url('ostatusinit',
- array('nickname' => $profile->nickname));
+ array('group' => $group->nickname));
$output->element('a', array('href' => $url,
'class' => 'entity_remote_subscribe'),
- // TRANS: Link description for link to subscribe to a remote user.
- _m('Subscribe'));
+ _m('Join'));
- $output->elementEnd('li');
}
- return false;
+ return true;
}
- function onStartGroupSubscribe($output, $group)
+ function onStartSubscribePeopletagForm($output, $peopletag)
{
$cur = common_current_user();
if (empty($cur)) {
- // Add an OStatus subscribe
+ $output->elementStart('li', 'entity_subscribe');
+ $profile = $peopletag->getTagger();
$url = common_local_url('ostatusinit',
- array('group' => $group->nickname));
+ array('tagger' => $profile->nickname, 'peopletag' => $peopletag->tag));
$output->element('a', array('href' => $url,
'class' => 'entity_remote_subscribe'),
- // TRANS: Link description for link to join a remote group.
- _m('Join'));
+ _m('Subscribe'));
+
+ $output->elementEnd('li');
+ return false;
}
return true;
}
+ function onStartShowTagProfileForm($action, $profile)
+ {
+ $action->elementStart('form', array('method' => 'post',
+ 'id' => 'form_tag_user',
+ 'class' => 'form_settings',
+ 'name' => 'tagprofile',
+ 'action' => common_local_url('tagprofile', array('id' => @$profile->id))));
+
+ $action->elementStart('fieldset');
+ $action->element('legend', null, _('Tag remote profile'));
+ $action->hidden('token', common_session_token());
+
+ $user = common_current_user();
+
+ $action->elementStart('ul', 'form_data');
+ $action->elementStart('li');
+
+ $action->input('uri', _('Remote profile'), $action->trimmed('uri'),
+ _('OStatus user\'s address, like nickname@example.com or http://example.net/nickname'));
+ $action->elementEnd('li');
+ $action->elementEnd('ul');
+ $action->submit('fetch', _('Fetch'));
+ $action->elementEnd('fieldset');
+ $action->elementEnd('form');
+ }
+
+ function onStartTagProfileAction($action, $profile)
+ {
+ $err = null;
+ $uri = $action->trimmed('uri');
+
+ if (!$profile && $uri) {
+ try {
+ if (Validate::email($uri)) {
+ $oprofile = Ostatus_profile::ensureWebfinger($uri);
+ } else if (Validate::uri($uri)) {
+ $oprofile = Ostatus_profile::ensureProfileURL($uri);
+ } else {
+ throw new Exception('Invalid URI');
+ }
+
+ // redirect to the new profile.
+ common_redirect(common_local_url('tagprofile', array('id' => $oprofile->profile_id)), 303);
+ return false;
+
+ } catch (Exception $e) {
+ $err = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname");
+ }
+
+ $action->showForm($err);
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * If the field being looked for is URI look for the profile
+ */
+ function onStartProfileCompletionSearch($action, $profile, $search_engine) {
+ if ($action->field == 'uri') {
+ $user = new User();
+ $profile->joinAdd($user);
+ $profile->whereAdd('uri LIKE "%' . $profile->escape($q) . '%"');
+ $profile->query();
+
+ if ($profile->N == 0) {
+ try {
+ if (Validate::email($q)) {
+ $oprofile = Ostatus_profile::ensureWebfinger($q);
+ } else if (Validate::uri($q)) {
+ $oprofile = Ostatus_profile::ensureProfileURL($q);
+ } else {
+ throw new Exception('Invalid URI');
+ }
+ return $this->filter(array($oprofile->localProfile()));
+
+ } catch (Exception $e) {
+ $this->msg = _m("Sorry, we could not reach that address. Please make sure that the OStatus address is like nickname@example.com or http://example.net/nickname");
+ return array();
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+
/**
* Find any explicit remote mentions. Accepted forms:
* Webfinger: @user@example.com
}
function onEndShowStatusNetStyles($action) {
- $action->cssLink('plugins/OStatus/theme/base/css/ostatus.css');
+ $action->cssLink($this->path('theme/base/css/ostatus.css'));
return true;
}
function onEndShowStatusNetScripts($action) {
- $action->script('plugins/OStatus/js/ostatus.js');
+ $action->script($this->path('js/ostatus.js'));
return true;
}
}
}
+ /**
+ * When one of our local users tries to subscribe to a remote peopletag,
+ * notify the remote server. If the notification is rejected,
+ * deny the subscription.
+ *
+ * @param Profile_list $peopletag
+ * @param User $user
+ *
+ * @return mixed hook return value
+ */
+
+ function onStartSubscribePeopletag($peopletag, $user)
+ {
+ $oprofile = Ostatus_profile::staticGet('peopletag_id', $peopletag->id);
+ if ($oprofile) {
+ if (!$oprofile->subscribe()) {
+ throw new Exception(_m('Could not set up remote peopletag subscription.'));
+ }
+
+ $sub = $user->getProfile();
+ $tagger = Profile::staticGet($peopletag->tagger);
+
+ $act = new Activity();
+ $act->id = TagURI::mint('subscribe_peopletag:%d:%d:%s',
+ $sub->id,
+ $peopletag->id,
+ common_date_iso8601(time()));
+
+ $act->actor = ActivityObject::fromProfile($sub);
+ $act->verb = ActivityVerb::FOLLOW;
+ $act->object = $oprofile->asActivityObject();
+
+ $act->time = time();
+ $act->title = _m("Follow list");
+ $act->content = sprintf(_m("%s is now following people tagged %s by %s."),
+ $sub->getBestName(),
+ $oprofile->getBestName(),
+ $tagger->getBestName());
+
+ if ($oprofile->notifyActivity($act, $sub)) {
+ return true;
+ } else {
+ $oprofile->garbageCollect();
+ throw new Exception(_m("Failed subscribing to remote peopletag."));
+ }
+ }
+ }
+
+ /**
+ * When one of our local users unsubscribes to a remote peopletag, notify the remote
+ * server.
+ *
+ * @param Profile_list $peopletag
+ * @param User $user
+ *
+ * @return mixed hook return value
+ */
+
+ function onEndUnsubscribePeopletag($peopletag, $user)
+ {
+ $oprofile = Ostatus_profile::staticGet('peopletag_id', $peopletag->id);
+ if ($oprofile) {
+ // Drop the PuSH subscription if there are no other subscribers.
+ $oprofile->garbageCollect();
+
+ $sub = Profile::staticGet($user->id);
+ $tagger = Profile::staticGet($peopletag->tagger);
+
+ $act = new Activity();
+ $act->id = TagURI::mint('unsubscribe_peopletag:%d:%d:%s',
+ $sub->id,
+ $peopletag->id,
+ common_date_iso8601(time()));
+
+ $act->actor = ActivityObject::fromProfile($member);
+ $act->verb = ActivityVerb::UNFOLLOW;
+ $act->object = $oprofile->asActivityObject();
+
+ $act->time = time();
+ $act->title = _m("Unfollow peopletag");
+ $act->content = sprintf(_m("%s stopped following the list %s by %s."),
+ $sub->getBestName(),
+ $oprofile->getBestName(),
+ $tagger->getBestName());
+
+ $oprofile->notifyActivity($act, $user);
+ }
+ }
+
/**
* Notify remote users when their notices get favorited.
*
return true;
}
+ function onEndTagProfile($ptag)
+ {
+ $oprofile = Ostatus_profile::staticGet('profile_id', $ptag->tagged);
+
+ if (empty($oprofile)) {
+ return true;
+ }
+
+ $plist = $ptag->getMeta();
+ if ($plist->private) {
+ return true;
+ }
+
+ $act = new Activity();
+
+ $tagger = $plist->getTagger();
+ $tagged = Profile::staticGet('id', $ptag->tagged);
+
+ $act->verb = ActivityVerb::TAG;
+ $act->id = TagURI::mint('tag_profile:%d:%d:%s',
+ $plist->tagger, $plist->id,
+ common_date_iso8601(time()));
+ $act->time = time();
+ $act->title = _("Tag");
+ $act->content = sprintf(_("%s tagged %s in the list %s"),
+ $tagger->getBestName(),
+ $tagged->getBestName(),
+ $plist->getBestName());
+
+ $act->actor = ActivityObject::fromProfile($tagger);
+ $act->objects = array(ActivityObject::fromProfile($tagged));
+ $act->target = ActivityObject::fromPeopletag($plist);
+
+ $oprofile->notifyActivity($act, $tagger);
+
+ // initiate a PuSH subscription for the person being tagged
+ if (!$oprofile->subscribe()) {
+ throw new Exception(sprintf(_('Could not complete subscription to remote '.
+ 'profile\'s feed. Tag %s could not be saved.'), $ptag->tag));
+ return false;
+ }
+ return true;
+ }
+
+ function onEndUntagProfile($ptag)
+ {
+ $oprofile = Ostatus_profile::staticGet('profile_id', $ptag->tagged);
+
+ if (empty($oprofile)) {
+ return true;
+ }
+
+ $plist = $ptag->getMeta();
+ if ($plist->private) {
+ return true;
+ }
+
+ $act = new Activity();
+
+ $tagger = $plist->getTagger();
+ $tagged = Profile::staticGet('id', $ptag->tagged);
+
+ $act->verb = ActivityVerb::UNTAG;
+ $act->id = TagURI::mint('untag_profile:%d:%d:%s',
+ $plist->tagger, $plist->id,
+ common_date_iso8601(time()));
+ $act->time = time();
+ $act->title = _("Untag");
+ $act->content = sprintf(_("%s untagged %s from the list %s"),
+ $tagger->getBestName(),
+ $tagged->getBestName(),
+ $plist->getBestName());
+
+ $act->actor = ActivityObject::fromProfile($tagger);
+ $act->objects = array(ActivityObject::fromProfile($tagged));
+ $act->target = ActivityObject::fromPeopletag($plist);
+
+ $oprofile->notifyActivity($act, $tagger);
+
+ // unsubscribe to PuSH feed if no more required
+ $oprofile->garbageCollect();
+
+ return true;
+ }
+
/**
* Notify remote users when their notices get de-favorited.
*
return true;
}
- function onStartProfileListItemActionElements($item)
+ function onStartProfileListItemActionElements($item, $profile=null)
{
if (!common_logged_in()) {
if (!empty($profileUser)) {
- $output = $item->out;
+ if ($item instanceof Action) {
+ $output = $item;
+ $profile = $item->profile;
+ } else {
+ $output = $item->out;
+ }
// Add an OStatus subscribe
$output->elementStart('li', 'entity_subscribe');
// TRANS: Link text for a user to subscribe to an OStatus user.
_m('Subscribe'));
$output->elementEnd('li');
+
+ $output->elementStart('li', 'entity_tag');
+ $url = common_local_url('ostatustag',
+ array('nickname' => $profileUser->nickname));
+ $output->element('a', array('href' => $url,
+ 'class' => 'entity_remote_tag'),
+ _m('Tag'));
+ $output->elementEnd('li');
}
}
return false;
}
- function onStartGetProfileFromURI($uri, &$profile) {
+ function onStartGetProfileFromURI($uri, &$profile)
+ {
+ // Don't want to do Web-based discovery on our own server,
+ // so we check locally first.
- // XXX: do discovery here instead (OStatus_profile::ensureProfileURI($uri))
+ $user = User::staticGet('uri', $uri);
+
+ if (!empty($user)) {
+ $profile = $user->getProfile();
+ return false;
+ }
- $oprofile = Ostatus_profile::staticGet('uri', $uri);
+ // Now, check remotely
- if (!empty($oprofile) && !$oprofile->isGroup()) {
+ $oprofile = Ostatus_profile::ensureProfileURI($uri);
+
+ if (!empty($oprofile)) {
$profile = $oprofile->localProfile();
return false;
}
+ // Still not a hit, so give up.
+
return true;
}
- function onStartHostMetaLinks(&$links) {
- $url = common_local_url('userxrd');
- $url.= '?uri={uri}';
- $links[] = array('rel' => Discovery::LRDD_REL,
- 'template' => $url,
- 'title' => array('Resource Descriptor'));
+ function onEndXrdActionLinks(&$xrd, $user)
+ {
+ $xrd->links[] = array('rel' => Discovery::UPDATESFROM,
+ 'href' => common_local_url('ApiTimelineUser',
+ array('id' => $user->id,
+ 'format' => 'atom')),
+ 'type' => 'application/atom+xml');
+
+ // Salmon
+ $salmon_url = common_local_url('usersalmon',
+ array('id' => $user->id));
+
+ $xrd->links[] = array('rel' => Salmon::REL_SALMON,
+ 'href' => $salmon_url);
+ // XXX : Deprecated - to be removed.
+ $xrd->links[] = array('rel' => Salmon::NS_REPLIES,
+ 'href' => $salmon_url);
+
+ $xrd->links[] = array('rel' => Salmon::NS_MENTIONS,
+ 'href' => $salmon_url);
+
+ // Get this user's keypair
+ $magickey = Magicsig::staticGet('user_id', $user->id);
+ if (!$magickey) {
+ // No keypair yet, let's generate one.
+ $magickey = new Magicsig();
+ $magickey->generate($user->id);
+ }
+
+ $xrd->links[] = array('rel' => Magicsig::PUBLICKEYREL,
+ 'href' => 'data:application/magic-public-key,'. $magickey->toString(false));
+
+ // TODO - finalize where the redirect should go on the publisher
+ $url = common_local_url('ostatussub') . '?profile={uri}';
+ $xrd->links[] = array('rel' => 'http://ostatus.org/schema/1.0/subscribe',
+ 'template' => $url );
+
+ return true;
}
}