diff options
Diffstat (limited to 'actions')
-rw-r--r-- | actions/apitimelinegroup.php | 2 | ||||
-rw-r--r-- | actions/apitimelineuser.php | 5 | ||||
-rw-r--r-- | actions/groupmembers.php | 4 | ||||
-rw-r--r-- | actions/makeadmin.php | 3 | ||||
-rw-r--r-- | actions/public.php | 10 | ||||
-rw-r--r-- | actions/rsd.php | 226 | ||||
-rw-r--r-- | actions/showgroup.php | 4 | ||||
-rw-r--r-- | actions/showstream.php | 13 | ||||
-rw-r--r-- | actions/userauthorization.php | 21 |
9 files changed, 271 insertions, 17 deletions
diff --git a/actions/apitimelinegroup.php b/actions/apitimelinegroup.php index af414c680..fd2ed9ff9 100644 --- a/actions/apitimelinegroup.php +++ b/actions/apitimelinegroup.php @@ -130,7 +130,7 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction case 'atom': $selfuri = common_root_url() . 'api/statusnet/groups/timeline/' . - $this->group->nickname . '.atom'; + $this->group->id . '.atom'; $this->showAtomTimeline( $this->notices, $title, diff --git a/actions/apitimelineuser.php b/actions/apitimelineuser.php index 830b16941..ed9104905 100644 --- a/actions/apitimelineuser.php +++ b/actions/apitimelineuser.php @@ -145,10 +145,11 @@ class ApiTimelineUserAction extends ApiBareAuthAction ); break; case 'atom': - if (isset($apidata['api_arg'])) { + $id = $this->arg('id'); + if ($id) { $selfuri = common_root_url() . 'api/statuses/user_timeline/' . - $apidata['api_arg'] . '.atom'; + rawurlencode($id) . '.atom'; } else { $selfuri = common_root_url() . 'api/statuses/user_timeline.atom'; diff --git a/actions/groupmembers.php b/actions/groupmembers.php index 0f47c268d..f16e972a4 100644 --- a/actions/groupmembers.php +++ b/actions/groupmembers.php @@ -192,7 +192,9 @@ class GroupMemberListItem extends ProfileListItem { $user = common_current_user(); - if (!empty($user) && $user->id != $this->profile->id && $user->isAdmin($this->group) && + if (!empty($user) && + $user->id != $this->profile->id && + ($user->isAdmin($this->group) || $user->hasRight(Right::MAKEGROUPADMIN)) && !$this->profile->isAdmin($this->group)) { $this->out->elementStart('li', 'entity_make_admin'); $maf = new MakeAdminForm($this->out, $this->profile, $this->group, diff --git a/actions/makeadmin.php b/actions/makeadmin.php index 9ad7d6e7c..f19348648 100644 --- a/actions/makeadmin.php +++ b/actions/makeadmin.php @@ -87,7 +87,8 @@ class MakeadminAction extends Action return false; } $user = common_current_user(); - if (!$user->isAdmin($this->group)) { + if (!$user->isAdmin($this->group) && + !$user->hasRight(Right::MAKEGROUPADMIN)) { $this->clientError(_('Only an admin can make another user an admin.'), 401); return false; } diff --git a/actions/public.php b/actions/public.php index 982dfde15..50278bfce 100644 --- a/actions/public.php +++ b/actions/public.php @@ -131,12 +131,20 @@ class PublicAction extends Action return _('Public timeline'); } } - + function extraHead() { parent::extraHead(); $this->element('meta', array('http-equiv' => 'X-XRDS-Location', 'content' => common_local_url('publicxrds'))); + + $rsd = common_local_url('rsd'); + + // RSD, http://tales.phrasewise.com/rfc/rsd + + $this->element('link', array('rel' => 'EditURI', + 'type' => 'application/rsd+xml', + 'href' => $rsd)); } /** diff --git a/actions/rsd.php b/actions/rsd.php new file mode 100644 index 000000000..f88bf2e9a --- /dev/null +++ b/actions/rsd.php @@ -0,0 +1,226 @@ +<?php +/** + * StatusNet - the distributed open-source microblogging tool + * Copyright (C) 2008-2010, StatusNet, Inc. + * + * Really Simple Discovery (RSD) for API access + * + * PHP version 5 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * @category API + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 + * @link http://status.net/ + * + */ + +if (!defined('STATUSNET')) { + exit(1); +} + +/** + * RSD action class + * + * Really Simple Discovery (RSD) is a simple (to a fault, maybe) + * discovery tool for blog APIs. + * + * http://tales.phrasewise.com/rfc/rsd + * + * Anil Dash suggested that RSD be used for services that implement + * the Twitter API: + * + * http://dashes.com/anil/2009/12/the-twitter-api-is-finished.html + * + * It's in use now for WordPress.com blogs: + * + * http://matt.wordpress.com/xmlrpc.php?rsd + * + * I (evan@status.net) have tried to stay faithful to the premise of + * RSD, while adding information useful to StatusNet client developers. + * In particular: + * + * - There is a link from each user's profile page to their personal + * RSD feed. A personal rsd.xml includes a 'blogID' element that is + * their username. + * - There is a link from the public root to '/rsd.xml', a public RSD + * feed. It's identical to the personal rsd except it doesn't include + * a blogId. + * - I've added a setting to the API to indicate that OAuth support is + * available. + * + * @category API + * @package StatusNet + * @author Evan Prodromou <evan@status.net> + * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 + * @link http://status.net/ + */ + +class RsdAction extends Action +{ + /** + * Optional attribute for the personal rsd.xml file. + */ + + var $user = null; + + /** + * Prepare the action for use. + * + * Check for a nickname; redirect if non-canonical; if + * not provided, assume public rsd.xml. + * + * @param array $args GET, POST, and URI arguments. + * + * @return boolean success flag + */ + + function prepare($args) + { + parent::prepare($args); + + // optional argument + + $nickname_arg = $this->arg('nickname'); + + if (empty($nickname_arg)) { + $this->user = null; + } else { + $nickname = common_canonical_nickname($nickname_arg); + + // Permanent redirect on non-canonical nickname + + if ($nickname_arg != $nickname) { + common_redirect(common_local_url('rsd', + array('nickname' => $nickname)), + 301); + return false; + } + + $this->user = User::staticGet('nickname', $nickname); + + if (empty($this->user)) { + $this->clientError(_('No such user.'), 404); + return false; + } + } + + return true; + } + + /** + * Action handler. + * + * Outputs the XML format for an RSD file. May include + * personal information if this is a personal file + * (based on whether $user attribute is set). + * + * @param array $args array of arguments + * + * @return nothing + */ + + function handle($args) + { + header('Content-Type: application/rsd+xml'); + + $this->startXML(); + + $rsdNS = 'http://archipelago.phrasewise.com/rsd'; + $this->elementStart('rsd', array('version' => '1.0', + 'xmlns' => $rsdNS)); + $this->elementStart('service'); + $this->element('engineName', null, _('StatusNet')); + $this->element('engineLink', null, 'http://status.net/'); + $this->elementStart('apis'); + if (Event::handle('StartRsdListApis', array($this, $this->user))) { + + $blogID = (empty($this->user)) ? '' : $this->user->nickname; + $apiAttrs = array('name' => 'Twitter', + 'preferred' => 'true', + 'apiLink' => $this->_apiRoot(), + 'blogID' => $blogID); + + $this->elementStart('api', $apiAttrs); + $this->elementStart('settings'); + $this->element('docs', null, + 'http://status.net/wiki/TwitterCompatibleAPI'); + $this->element('setting', array('name' => 'OAuth'), + 'true'); + $this->elementEnd('settings'); + $this->elementEnd('api'); + Event::handle('EndRsdListApis', array($this, $this->user)); + } + $this->elementEnd('apis'); + $this->elementEnd('service'); + $this->elementEnd('rsd'); + + $this->endXML(); + + return true; + } + + /** + * Returns last-modified date for use in caching + * + * Per-user rsd.xml is dated to last change of user + * (in case of nickname change); public has no date. + * + * @return string date of last change of this page + */ + + function lastModified() + { + if (!empty($this->user)) { + return $this->user->modified; + } else { + return null; + } + } + + /** + * Flag to indicate if this action is read-only + * + * It is; it doesn't change the DB. + * + * @param array $args ignored + * + * @return boolean true + */ + + function isReadOnly($args) + { + return true; + } + + /** + * Return current site's API root + * + * Varies based on URL parameters, like if fancy URLs are + * turned on. + * + * @return string API root URI for this site + */ + + private function _apiRoot() + { + if (common_config('site', 'fancy')) { + return common_path('api/', true); + } else { + return common_path('index.php/api/', true); + } + } +} diff --git a/actions/showgroup.php b/actions/showgroup.php index 8042a4951..eb1238902 100644 --- a/actions/showgroup.php +++ b/actions/showgroup.php @@ -330,13 +330,13 @@ class ShowgroupAction extends GroupDesignAction new Feed(Feed::RSS2, common_local_url('ApiTimelineGroup', array('format' => 'rss', - 'id' => $this->group->nickname)), + 'id' => $this->group->id)), sprintf(_('Notice feed for %s group (RSS 2.0)'), $this->group->nickname)), new Feed(Feed::ATOM, common_local_url('ApiTimelineGroup', array('format' => 'atom', - 'id' => $this->group->nickname)), + 'id' => $this->group->id)), sprintf(_('Notice feed for %s group (Atom)'), $this->group->nickname)), new Feed(Feed::FOAF, diff --git a/actions/showstream.php b/actions/showstream.php index c52919386..f9407e35a 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -131,14 +131,14 @@ class ShowstreamAction extends ProfileAction new Feed(Feed::RSS2, common_local_url('ApiTimelineUser', array( - 'id' => $this->user->nickname, + 'id' => $this->user->id, 'format' => 'rss')), sprintf(_('Notice feed for %s (RSS 2.0)'), $this->user->nickname)), new Feed(Feed::ATOM, common_local_url('ApiTimelineUser', array( - 'id' => $this->user->nickname, + 'id' => $this->user->id, 'format' => 'atom')), sprintf(_('Notice feed for %s (Atom)'), $this->user->nickname)), @@ -178,6 +178,15 @@ class ShowstreamAction extends ProfileAction $this->element('link', array('rel' => 'microsummary', 'href' => common_local_url('microsummary', array('nickname' => $this->profile->nickname)))); + + $rsd = common_local_url('rsd', + array('nickname' => $this->profile->nickname)); + + // RSD, http://tales.phrasewise.com/rfc/rsd + $this->element('link', array('rel' => 'EditURI', + 'type' => 'application/rsd+xml', + 'href' => $rsd)); + } function showProfile() diff --git a/actions/userauthorization.php b/actions/userauthorization.php index 4321f1302..7f71c60db 100644 --- a/actions/userauthorization.php +++ b/actions/userauthorization.php @@ -127,10 +127,10 @@ class UserauthorizationAction extends Action $location = $params->getLocation(); $avatar = $params->getAvatarURL(); - $this->elementStart('div', array('class' => 'profile')); $this->elementStart('div', 'entity_profile vcard'); - $this->elementStart('a', array('href' => $profile, - 'class' => 'url')); + $this->elementStart('dl', 'entity_depiction'); + $this->element('dt', null, _('Photo')); + $this->elementStart('dd'); if ($avatar) { $this->element('img', array('src' => $avatar, 'class' => 'photo avatar', @@ -138,11 +138,19 @@ class UserauthorizationAction extends Action 'height' => AVATAR_PROFILE_SIZE, 'alt' => $nickname)); } + $this->elementEnd('dd'); + $this->elementEnd('dl'); + + $this->elementStart('dl', 'entity_nickname'); + $this->element('dt', null, _('Nickname')); + $this->elementStart('dd'); $hasFN = ($fullname !== '') ? 'nickname' : 'fn nickname'; - $this->elementStart('span', $hasFN); + $this->elementStart('a', array('href' => $profile, + 'class' => 'url '.$hasFN)); $this->raw($nickname); - $this->elementEnd('span'); $this->elementEnd('a'); + $this->elementEnd('dd'); + $this->elementEnd('dl'); if (!is_null($fullname)) { $this->elementStart('dl', 'entity_fn'); @@ -214,7 +222,6 @@ class UserauthorizationAction extends Action $this->elementEnd('li'); $this->elementEnd('ul'); $this->elementEnd('div'); - $this->elementEnd('div'); } function sendAuthorization() @@ -350,4 +357,4 @@ class UserauthorizationAction extends Action } } } -}
\ No newline at end of file +} |