diff options
author | Brion Vibber <brion@pobox.com> | 2010-12-15 11:59:31 -0800 |
---|---|---|
committer | Brion Vibber <brion@pobox.com> | 2010-12-15 11:59:31 -0800 |
commit | bf20258f4b61dd8396db9a1980463c060dab292c (patch) | |
tree | f43d7d73e9877bb40fe373afcf3849f9cd5c3398 /lib | |
parent | 9df856e667a12cd217576263efbc72fff12692d9 (diff) | |
parent | 6c671141982c5837a2e5bf1e90de389c728d5dee (diff) |
Merge branch '0.9.x' into 1.0.x
Diffstat (limited to 'lib')
-rw-r--r-- | lib/activity.php | 14 | ||||
-rw-r--r-- | lib/nickname.php | 22 | ||||
-rw-r--r-- | lib/router.php | 183 | ||||
-rw-r--r-- | lib/xrd.php | 10 | ||||
-rw-r--r-- | lib/xrdaction.php | 97 |
5 files changed, 199 insertions, 127 deletions
diff --git a/lib/activity.php b/lib/activity.php index d3eeadcee..c3a984a7b 100644 --- a/lib/activity.php +++ b/lib/activity.php @@ -327,16 +327,8 @@ class Activity return null; } - function asString($namespace=false, $author=true) + function asString($namespace=false, $author=true, $source=false) { - $c = Cache::instance(); - - $str = $c->get(Cache::codeKey('activity:as-string:'.$this->id)); - - if (!empty($str)) { - return $str; - } - $xs = new XMLStringer(true); if ($namespace) { @@ -502,7 +494,7 @@ class Activity // Info on the source feed - if (!empty($this->source)) { + if ($source && !empty($this->source)) { $xs->elementStart('source'); $xs->element('id', null, $this->source->id); @@ -559,8 +551,6 @@ class Activity $str = $xs->getString(); - $c->set(Cache::codeKey('activity:as-string:'.$this->id), $str); - return $str; } diff --git a/lib/nickname.php b/lib/nickname.php index a0c9378cd..562f1e205 100644 --- a/lib/nickname.php +++ b/lib/nickname.php @@ -20,7 +20,25 @@ class Nickname { /** - * Regex fragment for pulling an arbitrarily-formated nickname. + * Regex fragment for pulling a formated nickname *OR* ID number. + * Suitable for router def of 'id' parameters on API actions. + * + * Not guaranteed to be valid after normalization; run the string through + * Nickname::normalize() to get the canonical form, or Nickname::isValid() + * if you just need to check if it's properly formatted. + * + * This, DISPLAY_FMT, and CANONICAL_FMT replace the old NICKNAME_FMT, + * but be aware that these should not be enclosed in []s. + * + * @fixme would prefer to define in reference to the other constants + */ + const INPUT_FMT = '(?:[0-9]+|[0-9a-zA-Z_]{1,64})'; + + /** + * Regex fragment for acceptable user-formatted variant of a nickname. + * This includes some chars such as underscore which will be removed + * from the normalized canonical form, but still must fit within + * field length limits. * * Not guaranteed to be valid after normalization; run the string through * Nickname::normalize() to get the canonical form, or Nickname::isValid() @@ -29,7 +47,7 @@ class Nickname * This and CANONICAL_FMT replace the old NICKNAME_FMT, but be aware * that these should not be enclosed in []s. */ - const DISPLAY_FMT = '[0-9a-zA-Z_]+'; + const DISPLAY_FMT = '[0-9a-zA-Z_]{1,64}'; /** * Regex fragment for checking a canonical nickname. diff --git a/lib/router.php b/lib/router.php index 9dfa6e00b..f33aebe3c 100644 --- a/lib/router.php +++ b/lib/router.php @@ -55,14 +55,14 @@ class StatusNet_URL_Mapper extends Net_URL_Mapper $result = null; if (Event::handle('StartConnectPath', array(&$path, &$defaults, &$rules, &$result))) { $result = parent::connect($path, $defaults, $rules); - if (array_key_exists('action', $defaults)) { - $action = $defaults['action']; - } elseif (array_key_exists('action', $rules)) { - $action = $rules['action']; - } else { - $action = null; - } - $this->_mapAction($action, $result); + if (array_key_exists('action', $defaults)) { + $action = $defaults['action']; + } elseif (array_key_exists('action', $rules)) { + $action = $rules['action']; + } else { + $action = null; + } + $this->_mapAction($action, $result); Event::handle('EndConnectPath', array($path, $defaults, $rules, $result)); } return $result; @@ -70,31 +70,31 @@ class StatusNet_URL_Mapper extends Net_URL_Mapper protected function _mapAction($action, $path) { - if (!array_key_exists($action, $this->_actionToPath)) { - $this->_actionToPath[$action] = array(); - } - $this->_actionToPath[$action][] = $path; - return; + if (!array_key_exists($action, $this->_actionToPath)) { + $this->_actionToPath[$action] = array(); + } + $this->_actionToPath[$action][] = $path; + return; } public function generate($values = array(), $qstring = array(), $anchor = '') { - if (!array_key_exists('action', $values)) { - return parent::generate($values, $qstring, $anchor); - } + if (!array_key_exists('action', $values)) { + return parent::generate($values, $qstring, $anchor); + } - $action = $values['action']; + $action = $values['action']; - if (!array_key_exists($action, $this->_actionToPath)) { - return parent::generate($values, $qstring, $anchor); - } + if (!array_key_exists($action, $this->_actionToPath)) { + return parent::generate($values, $qstring, $anchor); + } - $oldPaths = $this->paths; - $this->paths = $this->_actionToPath[$action]; - $result = parent::generate($values, $qstring, $anchor); - $this->paths = $oldPaths; + $oldPaths = $this->paths; + $this->paths = $this->_actionToPath[$action]; + $result = parent::generate($values, $qstring, $anchor); + $this->paths = $oldPaths; - return $result; + return $result; } } @@ -127,19 +127,19 @@ class Router function __construct() { if (empty($this->m)) { - if (!common_config('router', 'cache')) { + if (!common_config('router', 'cache')) { $this->m = $this->initialize(); - } else { - $k = self::cacheKey(); - $c = Cache::instance(); - $m = $c->get($k); - if (!empty($m)) { - $this->m = $m; - } else { - $this->m = $this->initialize(); - $c->set($k, $this->m); - } - } + } else { + $k = self::cacheKey(); + $c = Cache::instance(); + $m = $c->get($k); + if (!empty($m)) { + $this->m = $m; + } else { + $this->m = $this->initialize(); + $c->set($k, $this->m); + } + } } } @@ -199,7 +199,7 @@ class Router 'deleteuser', 'geocode', 'version', - ); + ); foreach ($main as $a) { $m->connect('main/'.$a, array('action' => $a)); @@ -222,8 +222,8 @@ class Router array('action' => 'publicxrds')); $m->connect('.well-known/host-meta', array('action' => 'hostmeta')); - $m->connect('main/xrd', - array('action' => 'userxrd')); + $m->connect('main/xrd', + array('action' => 'userxrd')); // these take a code @@ -248,19 +248,19 @@ class Router } $m->connect('settings/oauthapps/show/:id', - array('action' => 'showapplication'), - array('id' => '[0-9]+') + array('action' => 'showapplication'), + array('id' => '[0-9]+') ); $m->connect('settings/oauthapps/new', - array('action' => 'newapplication') + array('action' => 'newapplication') ); $m->connect('settings/oauthapps/edit/:id', - array('action' => 'editapplication'), - array('id' => '[0-9]+') + array('action' => 'editapplication'), + array('id' => '[0-9]+') ); $m->connect('settings/oauthapps/delete/:id', - array('action' => 'deleteapplication'), - array('id' => '[0-9]+') + array('action' => 'deleteapplication'), + array('id' => '[0-9]+') ); // search @@ -408,7 +408,7 @@ class Router $m->connect('api/statuses/friends_timeline/:id.:format', array('action' => 'ApiTimelineFriends', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json|rss|atom)')); $m->connect('api/statuses/home_timeline.:format', @@ -417,7 +417,7 @@ class Router $m->connect('api/statuses/home_timeline/:id.:format', array('action' => 'ApiTimelineHome', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json|rss|atom)')); $m->connect('api/statuses/user_timeline.:format', @@ -426,7 +426,7 @@ class Router $m->connect('api/statuses/user_timeline/:id.:format', array('action' => 'ApiTimelineUser', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json|rss|atom)')); $m->connect('api/statuses/mentions.:format', @@ -435,7 +435,7 @@ class Router $m->connect('api/statuses/mentions/:id.:format', array('action' => 'ApiTimelineMentions', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json|rss|atom)')); $m->connect('api/statuses/replies.:format', @@ -444,7 +444,7 @@ class Router $m->connect('api/statuses/replies/:id.:format', array('action' => 'ApiTimelineMentions', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json|rss|atom)')); $m->connect('api/statuses/retweeted_by_me.:format', @@ -465,7 +465,7 @@ class Router $m->connect('api/statuses/friends/:id.:format', array('action' => 'ApiUserFriends', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json)')); $m->connect('api/statuses/followers.:format', @@ -474,7 +474,7 @@ class Router $m->connect('api/statuses/followers/:id.:format', array('action' => 'ApiUserFollowers', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json)')); $m->connect('api/statuses/show.:format', @@ -517,7 +517,7 @@ class Router $m->connect('api/users/show/:id.:format', array('action' => 'ApiUserShow', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json)')); // direct messages @@ -555,12 +555,12 @@ class Router $m->connect('api/friendships/create/:id.:format', array('action' => 'ApiFriendshipsCreate', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json)')); $m->connect('api/friendships/destroy/:id.:format', array('action' => 'ApiFriendshipsDestroy', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json)')); // Social graph @@ -617,17 +617,17 @@ class Router $m->connect('api/favorites/:id.:format', array('action' => 'ApiTimelineFavorites', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json|rss|atom)')); $m->connect('api/favorites/create/:id.:format', array('action' => 'ApiFavoriteCreate', - 'id' => Nickname::DISPLAY_FMT, + 'id' => '[0-9]+', 'format' => '(xml|json)')); $m->connect('api/favorites/destroy/:id.:format', array('action' => 'ApiFavoriteDestroy', - 'id' => Nickname::DISPLAY_FMT, + 'id' => '[0-9]+', 'format' => '(xml|json)')); // blocks @@ -637,7 +637,7 @@ class Router $m->connect('api/blocks/create/:id.:format', array('action' => 'ApiBlockCreate', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json)')); $m->connect('api/blocks/destroy.:format', @@ -646,7 +646,7 @@ class Router $m->connect('api/blocks/destroy/:id.:format', array('action' => 'ApiBlockDestroy', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json)')); // help @@ -682,7 +682,7 @@ class Router $m->connect('api/statusnet/groups/timeline/:id.:format', array('action' => 'ApiTimelineGroup', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json|rss|atom)')); $m->connect('api/statusnet/groups/show.:format', @@ -691,12 +691,12 @@ class Router $m->connect('api/statusnet/groups/show/:id.:format', array('action' => 'ApiGroupShow', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json)')); $m->connect('api/statusnet/groups/join.:format', array('action' => 'ApiGroupJoin', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json)')); $m->connect('api/statusnet/groups/join/:id.:format', @@ -705,7 +705,7 @@ class Router $m->connect('api/statusnet/groups/leave.:format', array('action' => 'ApiGroupLeave', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json)')); $m->connect('api/statusnet/groups/leave/:id.:format', @@ -722,7 +722,7 @@ class Router $m->connect('api/statusnet/groups/list/:id.:format', array('action' => 'ApiGroupList', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json|rss|atom)')); $m->connect('api/statusnet/groups/list_all.:format', @@ -735,7 +735,7 @@ class Router $m->connect('api/statusnet/groups/membership/:id.:format', array('action' => 'ApiGroupMembership', - 'id' => Nickname::DISPLAY_FMT, + 'id' => Nickname::INPUT_FMT, 'format' => '(xml|json)')); $m->connect('api/statusnet/groups/create.:format', @@ -772,13 +772,6 @@ class Router $m->connect('api/oauth/authorize', array('action' => 'ApiOauthAuthorize')); - $m->connect('api/statusnet/app/service/:id.xml', - array('action' => 'ApiAtomService', - 'id' => Nickname::DISPLAY_FMT)); - - $m->connect('api/statusnet/app/service.xml', - array('action' => 'ApiAtomService')); - // Admin $m->connect('admin/site', array('action' => 'siteadminpanel')); @@ -928,6 +921,42 @@ class Router array('nickname' => Nickname::DISPLAY_FMT)); } + // AtomPub API + + $m->connect('api/statusnet/app/service/:id.xml', + array('action' => 'ApiAtomService'), + array('id' => Nickname::DISPLAY_FMT)); + + $m->connect('api/statusnet/app/service.xml', + array('action' => 'ApiAtomService')); + + $m->connect('api/statusnet/app/subscriptions/:subscriber/:subscribed.atom', + array('action' => 'AtomPubShowSubscription'), + array('subscriber' => '[0-9]+', + 'subscribed' => '[0-9]+')); + + $m->connect('api/statusnet/app/subscriptions/:subscriber.atom', + array('action' => 'AtomPubSubscriptionFeed'), + array('subscriber' => '[0-9]+')); + + $m->connect('api/statusnet/app/favorites/:profile/:notice.atom', + array('action' => 'AtomPubShowFavorite'), + array('profile' => '[0-9]+', + 'notice' => '[0-9]+')); + + $m->connect('api/statusnet/app/favorites/:profile.atom', + array('action' => 'AtomPubFavoriteFeed'), + array('profile' => '[0-9]+')); + + $m->connect('api/statusnet/app/memberships/:profile/:group.atom', + array('action' => 'AtomPubShowMembership'), + array('profile' => '[0-9]+', + 'group' => '[0-9]+')); + + $m->connect('api/statusnet/app/memberships/:profile.atom', + array('action' => 'AtomPubMembershipFeed'), + array('profile' => '[0-9]+')); + // user stuff Event::handle('RouterInitialized', array($m)); @@ -970,14 +999,14 @@ class Router $qpos = strpos($url, '?'); if ($qpos !== false) { $url = substr($url, 0, $qpos+1) . - str_replace('?', '&', substr($url, $qpos+1)); + str_replace('?', '&', substr($url, $qpos+1)); // @fixme this is a hacky workaround for http_build_query in the // lower-level code and bad configs that set the default separator // to & instead of &. Encoded &s in parameters will not be // affected. $url = substr($url, 0, $qpos+1) . - str_replace('&', '&', substr($url, $qpos+1)); + str_replace('&', '&', substr($url, $qpos+1)); } diff --git a/lib/xrd.php b/lib/xrd.php index c8cffed9c..9c6d9f3ab 100644 --- a/lib/xrd.php +++ b/lib/xrd.php @@ -130,14 +130,24 @@ class XRD foreach ($this->links as $link) { $titles = array(); + $properties = array(); if (isset($link['title'])) { $titles = $link['title']; unset($link['title']); } + if (isset($link['property'])) { + $properties = $link['property']; + unset($link['property']); + } $xs->elementStart('Link', $link); foreach ($titles as $title) { $xs->element('Title', null, $title); } + foreach ($properties as $property) { + $xs->element('Property', + array('type' => $property['type']), + $property['value']); + } $xs->elementEnd('Link'); } diff --git a/lib/xrdaction.php b/lib/xrdaction.php index 43826b32b..855ed1ea8 100644 --- a/lib/xrdaction.php +++ b/lib/xrdaction.php @@ -53,54 +53,67 @@ class XrdAction extends Action $xrd->subject = self::normalize($this->uri); } - if (Event::handle('StartXrdActionAliases', array(&$xrd, $this->user))) { + if (Event::handle('StartXrdActionAliases', array(&$xrd, $this->user))) { - // Possible aliases for the user + // Possible aliases for the user - $uris = array($this->user->uri, $profile->profileurl); + $uris = array($this->user->uri, $profile->profileurl); - // FIXME: Webfinger generation code should live somewhere on its own + // FIXME: Webfinger generation code should live somewhere on its own - $path = common_config('site', 'path'); + $path = common_config('site', 'path'); - if (empty($path)) { - $uris[] = sprintf('acct:%s@%s', $nick, common_config('site', 'server')); - } + if (empty($path)) { + $uris[] = sprintf('acct:%s@%s', $nick, common_config('site', 'server')); + } - foreach ($uris as $uri) { - if ($uri != $xrd->subject) { - $xrd->alias[] = $uri; - } - } + foreach ($uris as $uri) { + if ($uri != $xrd->subject) { + $xrd->alias[] = $uri; + } + } - Event::handle('EndXrdActionAliases', array(&$xrd, $this->user)); - } + Event::handle('EndXrdActionAliases', array(&$xrd, $this->user)); + } - if (Event::handle('StartXrdActionLinks', array(&$xrd, $this->user))) { - - $xrd->links[] = array('rel' => self::PROFILEPAGE, - 'type' => 'text/html', - 'href' => $profile->profileurl); + if (Event::handle('StartXrdActionLinks', array(&$xrd, $this->user))) { - // hCard - $xrd->links[] = array('rel' => self::HCARD, - 'type' => 'text/html', - 'href' => common_local_url('hcard', array('nickname' => $nick))); + $xrd->links[] = array('rel' => self::PROFILEPAGE, + 'type' => 'text/html', + 'href' => $profile->profileurl); - // XFN - $xrd->links[] = array('rel' => 'http://gmpg.org/xfn/11', - 'type' => 'text/html', - 'href' => $profile->profileurl); - // FOAF - $xrd->links[] = array('rel' => 'describedby', - 'type' => 'application/rdf+xml', - 'href' => common_local_url('foaf', - array('nickname' => $nick))); + // hCard + $xrd->links[] = array('rel' => self::HCARD, + 'type' => 'text/html', + 'href' => common_local_url('hcard', array('nickname' => $nick))); - - Event::handle('EndXrdActionLinks', array(&$xrd, $this->user)); - } + // XFN + $xrd->links[] = array('rel' => 'http://gmpg.org/xfn/11', + 'type' => 'text/html', + 'href' => $profile->profileurl); + // FOAF + $xrd->links[] = array('rel' => 'describedby', + 'type' => 'application/rdf+xml', + 'href' => common_local_url('foaf', + array('nickname' => $nick))); + $xrd->links[] = array('rel' => 'http://apinamespace.org/atom', + 'type' => 'application/atomsvc+xml', + 'href' => common_local_url('ApiAtomService', array('id' => $nick))); + + if (common_config('site', 'fancy')) { + $apiRoot = common_path('api/', true); + } else { + $apiRoot = common_path('index.php/api/', true); + } + + $xrd->links[] = array('rel' => 'http://apinamespace.org/twitter', + 'href' => $apiRoot, + 'property' => array(array('type' => 'http://apinamespace.org/twitter/username', + 'value' => $nick))); + + Event::handle('EndXrdActionLinks', array(&$xrd, $this->user)); + } header('Content-type: application/xrd+xml'); print $xrd->toXML(); @@ -132,4 +145,16 @@ class XrdAction extends Action return (substr($uri, 0, 5) == 'acct:'); } + + /** + * Is this action read-only? + * + * @param array $args other arguments + * + * @return boolean is read only action? + */ + function isReadOnly($args) + { + return true; + } } |