123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- <?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(array $args = array())
- {
- 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);
- }
- $this->user = User::getKV('nickname', $nickname);
- if (empty($this->user)) {
- // TRANS: Client error.
- $this->clientError(_('No such user.'), 404);
- }
- }
- 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()
- {
- 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');
- // TRANS: Engine name for RSD.
- $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,
- common_local_url('doc', array('title' => 'api')));
- $this->element('setting', array('name' => 'OAuth'),
- 'true');
- $this->elementEnd('settings');
- $this->elementEnd('api');
- // Atom API
- if (empty($this->user)) {
- $service = common_local_url('ApiAtomService');
- } else {
- $service = common_local_url('ApiAtomService', array('id' => $this->user->nickname));
- }
- $this->element('api', array('name' => 'Atom',
- 'preferred' => 'false',
- 'apiLink' => $service,
- 'blogID' => $blogID));
- 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);
- }
- }
- }
|