Merge remote branch 'gitorious/1.0.x' into 1.0.x
This commit is contained in:
commit
004e42e3e0
62
README
62
README
@ -2,8 +2,8 @@
|
||||
README
|
||||
------
|
||||
|
||||
StatusNet 0.9.1 ("Everybody Hurts")
|
||||
28 Mar 2010
|
||||
StatusNet 0.9.2 ("King of Birds")
|
||||
3 May 2010
|
||||
|
||||
This is the README file for StatusNet, the Open Source microblogging
|
||||
platform. It includes installation instructions, descriptions of
|
||||
@ -77,7 +77,7 @@ for additional terms.
|
||||
New this version
|
||||
================
|
||||
|
||||
This is a minor bug and feature release since version 0.9.0 released 4
|
||||
This is a minor bug and feature release since version 0.9.1 released 28
|
||||
March 2010.
|
||||
|
||||
Because of fixes to OStatus bugs, it is highly recommended that all
|
||||
@ -85,26 +85,32 @@ public sites upgrade to the new version immediately.
|
||||
|
||||
Notable changes this version:
|
||||
|
||||
- Twitter bridge truncates and links back to original for long
|
||||
notices.
|
||||
- Changed "Home" link in main menu to "Personal".
|
||||
- A new memcached plugin (using pecl/memcached versus pecl/memcache)
|
||||
- Opt-in subscription to update@status.net
|
||||
- Script to run commands on behalf of a user.
|
||||
- Better Web UI for long notices.
|
||||
- A plugin to open external links in their own window or tab
|
||||
- Fixes to Salmon protocol for compatibility with other systems.
|
||||
- Updates to latest ActivityStreams definition.
|
||||
- Twitpic-compatible API for image upload.
|
||||
- Background deletion of user accounts.
|
||||
- Better support for HTTP basic authentication with CGI/FastCGI
|
||||
- Better discovery on OStatus
|
||||
- Support for PuSH-enabled RSS 2.0 feeds
|
||||
- OpenID-only mode
|
||||
- OpenID blacklist/whitelist
|
||||
- OStatus unit tests
|
||||
- Installer no longer fails with a PHP fatal error when trying to set up the
|
||||
subscription to update@status.net
|
||||
- Fixed email notifications for @-replies that come in via OStatus
|
||||
- OStatus related Fixes to the cloudy theme
|
||||
- Pass geo locations over Twitter bridge (will only be used if enabled on the
|
||||
Twitter side)
|
||||
- scripts/showplugins.php - script to dump the list of activated plugins and
|
||||
their settings
|
||||
- scripts/fixup_blocks.php - script to finds any stray subscriptions in
|
||||
violation of blocks, and removes them
|
||||
- Allow blocking someone who's not currently subscribed to you (prevents
|
||||
seeing @-replies from them, or them subbing to you in future)
|
||||
- Default 2-second timeout on Geonames web service lookups
|
||||
- Improved localization for plugins
|
||||
- New anti-spam measures: added nofollow rels to group members list,
|
||||
subscribers list
|
||||
- Shared cache key option for Geonames plugin (lets multi-instance sites
|
||||
share their cached geoname lookups)
|
||||
- Stability fixes to the TwitterStatusFetcher
|
||||
- If user allows location sharing but turned off browser location use profile
|
||||
location
|
||||
- Improved group listing via the API
|
||||
- Improved FOAF output
|
||||
- Several other bugfixes
|
||||
|
||||
A full changelog is available at http://status.net/wiki/StatusNet_0.9.1.
|
||||
A full changelog is available at http://status.net/wiki/StatusNet_0.9.2.
|
||||
|
||||
Prerequisites
|
||||
=============
|
||||
@ -216,9 +222,9 @@ especially if you've previously installed PHP/MySQL packages.
|
||||
1. Unpack the tarball you downloaded on your Web server. Usually a
|
||||
command like this will work:
|
||||
|
||||
tar zxf statusnet-0.9.1.tar.gz
|
||||
tar zxf statusnet-0.9.2.tar.gz
|
||||
|
||||
...which will make a statusnet-0.9.1 subdirectory in your current
|
||||
...which will make a statusnet-0.9.2 subdirectory in your current
|
||||
directory. (If you don't have shell access on your Web server, you
|
||||
may have to unpack the tarball on your local computer and FTP the
|
||||
files to the server.)
|
||||
@ -226,7 +232,7 @@ especially if you've previously installed PHP/MySQL packages.
|
||||
2. Move the tarball to a directory of your choosing in your Web root
|
||||
directory. Usually something like this will work:
|
||||
|
||||
mv statusnet-0.9.1 /var/www/statusnet
|
||||
mv statusnet-0.9.2 /var/www/statusnet
|
||||
|
||||
This will make your StatusNet instance available in the statusnet path of
|
||||
your server, like "http://example.net/statusnet". "microblog" or
|
||||
@ -641,7 +647,7 @@ with this situation.
|
||||
If you've been using StatusNet 0.7, 0.6, 0.5 or lower, or if you've
|
||||
been tracking the "git" version of the software, you will probably
|
||||
want to upgrade and keep your existing data. There is no automated
|
||||
upgrade procedure in StatusNet 0.9.1. Try these step-by-step
|
||||
upgrade procedure in StatusNet 0.9.2. Try these step-by-step
|
||||
instructions; read to the end first before trying them.
|
||||
|
||||
0. Download StatusNet and set up all the prerequisites as if you were
|
||||
@ -662,7 +668,7 @@ instructions; read to the end first before trying them.
|
||||
5. Once all writing processes to your site are turned off, make a
|
||||
final backup of the Web directory and database.
|
||||
6. Move your StatusNet directory to a backup spot, like "statusnet.bak".
|
||||
7. Unpack your StatusNet 0.9.1 tarball and move it to "statusnet" or
|
||||
7. Unpack your StatusNet 0.9.2 tarball and move it to "statusnet" or
|
||||
wherever your code used to be.
|
||||
8. Copy the config.php file and avatar directory from your old
|
||||
directory to your new directory.
|
||||
@ -1539,7 +1545,7 @@ repository (see below), and you get a compilation error ("unexpected
|
||||
T_STRING") in the browser, check to see that you don't have any
|
||||
conflicts in your code.
|
||||
|
||||
If you upgraded to StatusNet 0.9.1 without reading the "Notice
|
||||
If you upgraded to StatusNet 0.9.2 without reading the "Notice
|
||||
inboxes" section above, and all your users' 'Personal' tabs are empty,
|
||||
read the "Notice inboxes" section above.
|
||||
|
||||
|
@ -18,15 +18,19 @@
|
||||
*
|
||||
* @category Actions
|
||||
* @package Actions
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||
* @author Robin Millette <millette@controlyourself.ca>
|
||||
* @author Adrian Lang <mail@adrianlang.de>
|
||||
* @author Meitar Moscovitz <meitarm@gmail.com>
|
||||
* @author Sarven Capadisli <csarven@status.net>
|
||||
* @author Brenda Wallace <shiny@cpan.org>
|
||||
* @author Brion Vibber <brion@pobox.com>
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Zach Copley <zach@controlyourself.ca>
|
||||
* @author Meitar Moscovitz <meitarm@gmail.com>
|
||||
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||
* @author Robin Millette <millette@status.net>
|
||||
* @author Sarven Capadisli <csarven@status.net>
|
||||
* @author Siebrand Mazeland <s.mazeland@xs4all.nl>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license GNU Affero General Public License http://www.gnu.org/licenses/
|
||||
* @link http://status.net
|
||||
*/
|
||||
|
@ -21,8 +21,10 @@
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
* @author Brion Vibber <brion@pobox.com>
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Robin Millette <robin@millette.info>
|
||||
* @author Siebrand Mazeland <s.mazeland@xs4all.nl>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
|
@ -21,6 +21,7 @@
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
* @author Siebrand Mazeland <s.mazeland@xs4all.nl>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
|
@ -75,7 +75,7 @@ class ApiAccountVerifyCredentialsAction extends ApiAuthAction
|
||||
|
||||
if ($this->format == 'xml') {
|
||||
$this->initDocument('xml');
|
||||
$this->showTwitterXmlUser($twitter_user);
|
||||
$this->showTwitterXmlUser($twitter_user, 'user', true);
|
||||
$this->endDocument('xml');
|
||||
} elseif ($this->format == 'json') {
|
||||
$this->initDocument('json');
|
||||
|
@ -232,7 +232,8 @@ class ApiDirectMessageAction extends ApiAuthAction
|
||||
function showXmlDirectMessages()
|
||||
{
|
||||
$this->initDocument('xml');
|
||||
$this->elementStart('direct-messages', array('type' => 'array'));
|
||||
$this->elementStart('direct-messages', array('type' => 'array',
|
||||
'xmlns:statusnet' => 'http://status.net/schema/api/1/'));
|
||||
|
||||
foreach ($this->messages as $m) {
|
||||
$dm_array = $this->directMessageArray($m);
|
||||
|
@ -52,7 +52,6 @@ require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
|
||||
class ApiDirectMessageNewAction extends ApiAuthAction
|
||||
{
|
||||
var $source = null;
|
||||
var $other = null;
|
||||
var $content = null;
|
||||
|
||||
@ -76,13 +75,6 @@ class ApiDirectMessageNewAction extends ApiAuthAction
|
||||
return;
|
||||
}
|
||||
|
||||
$this->source = $this->trimmed('source'); // Not supported by Twitter.
|
||||
|
||||
$reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api');
|
||||
if (empty($this->source) || in_array($this->source, $reserved_sources)) {
|
||||
$source = 'api';
|
||||
}
|
||||
|
||||
$this->content = $this->trimmed('text');
|
||||
|
||||
$this->user = $this->auth_user;
|
||||
|
@ -25,6 +25,7 @@
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -25,6 +25,7 @@
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -26,6 +26,7 @@
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -26,6 +26,7 @@
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -26,6 +26,7 @@
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -26,6 +26,7 @@
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -26,6 +26,7 @@
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -26,6 +26,7 @@
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -26,6 +26,7 @@
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
367
actions/apigroupprofileupdate.php
Normal file
367
actions/apigroupprofileupdate.php
Normal file
@ -0,0 +1,367 @@
|
||||
<?php
|
||||
/**
|
||||
* StatusNet, the distributed open-source microblogging tool
|
||||
*
|
||||
* Update a group's profile
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* LICENCE: 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 Zach Copley <zach@status.net>
|
||||
* @copyright 2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR . '/lib/apiauth.php';
|
||||
|
||||
/**
|
||||
* API analog to the group edit page
|
||||
*
|
||||
* @category API
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
class ApiGroupProfileUpdateAction extends ApiAuthAction
|
||||
{
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
* @param array $args $_REQUEST args
|
||||
*
|
||||
* @return boolean success flag
|
||||
*
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
$this->nickname = common_canonical_nickname($this->trimmed('nickname'));
|
||||
|
||||
$this->fullname = $this->trimmed('fullname');
|
||||
$this->homepage = $this->trimmed('homepage');
|
||||
$this->description = $this->trimmed('description');
|
||||
$this->location = $this->trimmed('location');
|
||||
$this->aliasstring = $this->trimmed('aliases');
|
||||
|
||||
$this->user = $this->auth_user;
|
||||
$this->group = $this->getTargetGroup($this->arg('id'));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the request
|
||||
*
|
||||
* See which request params have been set, and update the profile
|
||||
*
|
||||
* @param array $args $_REQUEST data (unused)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
$this->clientError(
|
||||
_('This method requires a POST.'),
|
||||
400, $this->format
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(
|
||||
_('API method not found.'),
|
||||
404,
|
||||
$this->format
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->user)) {
|
||||
$this->clientError(_('No such user.'), 404, $this->format);
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->group)) {
|
||||
$this->clientError(_('Group not found.'), 404, $this->format);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->user->isAdmin($this->group)) {
|
||||
$this->clientError(_('You must be an admin to edit the group.'), 403);
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->group->query('BEGIN');
|
||||
|
||||
$orig = clone($this->group);
|
||||
|
||||
try {
|
||||
|
||||
if (!empty($this->nickname)) {
|
||||
if ($this->validateNickname()) {
|
||||
$this->group->nickname = $this->nickname;
|
||||
$this->group->mainpage = common_local_url(
|
||||
'showgroup',
|
||||
array('nickname' => $this->nickname)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->fullname)) {
|
||||
$this->validateFullname();
|
||||
$this->group->fullname = $this->fullname;
|
||||
}
|
||||
|
||||
if (!empty($this->homepage)) {
|
||||
$this->validateHomepage();
|
||||
$this->group->homepage = $this->hompage;
|
||||
}
|
||||
|
||||
if (!empty($this->description)) {
|
||||
$this->validateDescription();
|
||||
$this->group->description = $this->decription;
|
||||
}
|
||||
|
||||
if (!empty($this->location)) {
|
||||
$this->validateLocation();
|
||||
$this->group->location = $this->location;
|
||||
}
|
||||
|
||||
} catch (ApiValidationException $ave) {
|
||||
$this->clientError(
|
||||
$ave->getMessage(),
|
||||
403,
|
||||
$this->format
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
$result = $this->group->update($orig);
|
||||
|
||||
if (!$result) {
|
||||
common_log_db_error($this->group, 'UPDATE', __FILE__);
|
||||
$this->serverError(_('Could not update group.'));
|
||||
}
|
||||
|
||||
$aliases = array();
|
||||
|
||||
try {
|
||||
|
||||
if (!empty($this->aliasstring)) {
|
||||
$aliases = $this->validateAliases();
|
||||
}
|
||||
|
||||
} catch (ApiValidationException $ave) {
|
||||
$this->clientError(
|
||||
$ave->getMessage(),
|
||||
403,
|
||||
$this->format
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
$result = $this->group->setAliases($aliases);
|
||||
|
||||
if (!$result) {
|
||||
$this->serverError(_('Could not create aliases.'));
|
||||
}
|
||||
|
||||
if (!empty($this->nickname) && ($this->nickname != $orig->nickname)) {
|
||||
common_log(LOG_INFO, "Saving local group info.");
|
||||
$local = Local_group::staticGet('group_id', $this->group->id);
|
||||
$local->setNickname($this->nickname);
|
||||
}
|
||||
|
||||
$this->group->query('COMMIT');
|
||||
|
||||
switch($this->format) {
|
||||
case 'xml':
|
||||
$this->showSingleXmlGroup($this->group);
|
||||
break;
|
||||
case 'json':
|
||||
$this->showSingleJsonGroup($this->group);
|
||||
break;
|
||||
default:
|
||||
$this->clientError(_('API method not found.'), 404, $this->format);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function nicknameExists($nickname)
|
||||
{
|
||||
$group = Local_group::staticGet('nickname', $nickname);
|
||||
|
||||
if (!empty($group) &&
|
||||
$group->group_id != $this->group->id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$alias = Group_alias::staticGet('alias', $nickname);
|
||||
|
||||
if (!empty($alias) &&
|
||||
$alias->group_id != $this->group->id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function validateNickname()
|
||||
{
|
||||
if (!Validate::string(
|
||||
$this->nickname, array(
|
||||
'min_length' => 1,
|
||||
'max_length' => 64,
|
||||
'format' => NICKNAME_FMT
|
||||
)
|
||||
)
|
||||
) {
|
||||
throw new ApiValidationException(
|
||||
_(
|
||||
'Nickname must have only lowercase letters ' .
|
||||
'and numbers and no spaces.'
|
||||
)
|
||||
);
|
||||
} else if ($this->nicknameExists($this->nickname)) {
|
||||
throw new ApiValidationException(
|
||||
_('Nickname already in use. Try another one.')
|
||||
);
|
||||
} else if (!User_group::allowedNickname($this->nickname)) {
|
||||
throw new ApiValidationException(
|
||||
_('Not a valid nickname.')
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function validateHomepage()
|
||||
{
|
||||
if (!is_null($this->homepage)
|
||||
&& (strlen($this->homepage) > 0)
|
||||
&& !Validate::uri(
|
||||
$this->homepage,
|
||||
array('allowed_schemes' => array('http', 'https')
|
||||
)
|
||||
)
|
||||
) {
|
||||
throw new ApiValidationException(
|
||||
_('Homepage is not a valid URL.')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function validateFullname()
|
||||
{
|
||||
if (!is_null($this->fullname) && mb_strlen($this->fullname) > 255) {
|
||||
throw new ApiValidationException(
|
||||
_('Full name is too long (max 255 chars).')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function validateDescription()
|
||||
{
|
||||
if (User_group::descriptionTooLong($this->description)) {
|
||||
throw new ApiValidationException(
|
||||
sprintf(
|
||||
_('description is too long (max %d chars).'),
|
||||
User_group::maxDescription()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function validateLocation()
|
||||
{
|
||||
if (!is_null($this->location) && mb_strlen($this->location) > 255) {
|
||||
throw new ApiValidationException(
|
||||
_('Location is too long (max 255 chars).')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function validateAliases()
|
||||
{
|
||||
$aliases = array_map(
|
||||
'common_canonical_nickname',
|
||||
array_unique(
|
||||
preg_split('/[\s,]+/',
|
||||
$this->aliasstring
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if (count($aliases) > common_config('group', 'maxaliases')) {
|
||||
throw new ApiValidationException(
|
||||
sprintf(
|
||||
_('Too many aliases! Maximum %d.'),
|
||||
common_config('group', 'maxaliases')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($aliases as $alias) {
|
||||
if (!Validate::string(
|
||||
$alias, array(
|
||||
'min_length' => 1,
|
||||
'max_length' => 64,
|
||||
'format' => NICKNAME_FMT)
|
||||
)
|
||||
) {
|
||||
throw new ApiValidationException(
|
||||
sprintf(
|
||||
_('Invalid alias: "%s"'),
|
||||
$alias
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->nicknameExists($alias)) {
|
||||
throw new ApiValidationException(
|
||||
sprintf(
|
||||
_('Alias "%s" already in use. Try another one.'),
|
||||
$alias)
|
||||
);
|
||||
}
|
||||
|
||||
// XXX assumes alphanum nicknames
|
||||
if (strcmp($alias, $this->nickname) == 0) {
|
||||
throw new ApiValidationException(
|
||||
_('Alias can\'t be the same as nickname.')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $aliases;
|
||||
}
|
||||
|
||||
}
|
@ -26,6 +26,7 @@
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -22,7 +22,7 @@
|
||||
* @category Search
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2008-2009 StatusNet, Inc.
|
||||
* @copyright 2008-2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
@ -31,6 +31,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR.'/lib/apiprivateauth.php';
|
||||
|
||||
/**
|
||||
* Action for outputting search results in Twitter compatible Atom
|
||||
* format.
|
||||
@ -44,10 +46,10 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*
|
||||
* @see ApiAction
|
||||
* @see ApiPrivateAuthAction
|
||||
*/
|
||||
|
||||
class TwitapisearchatomAction extends ApiAction
|
||||
class ApiSearchAtomAction extends ApiPrivateAuthAction
|
||||
{
|
||||
|
||||
var $cnt;
|
||||
@ -96,8 +98,11 @@ class TwitapisearchatomAction extends ApiAction
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
common_debug("in apisearchatom prepare()");
|
||||
|
||||
parent::prepare($args);
|
||||
|
||||
|
||||
$this->query = $this->trimmed('q');
|
||||
$this->lang = $this->trimmed('lang');
|
||||
$this->rpp = $this->trimmed('rpp');
|
||||
@ -138,6 +143,7 @@ class TwitapisearchatomAction extends ApiAction
|
||||
function handle($args)
|
||||
{
|
||||
parent::handle($args);
|
||||
common_debug("In apisearchatom handle()");
|
||||
$this->showAtom();
|
||||
}
|
||||
|
||||
@ -342,10 +348,24 @@ class TwitapisearchatomAction extends ApiAction
|
||||
'rel' => 'related',
|
||||
'href' => $profile->avatarUrl()));
|
||||
|
||||
// TODO: Here is where we'd put in a link to an atom feed for threads
|
||||
// @todo: Here is where we'd put in a link to an atom feed for threads
|
||||
|
||||
$this->element("twitter:source", null,
|
||||
htmlentities($this->sourceLink($notice->source)));
|
||||
$source = null;
|
||||
|
||||
$ns = $notice->getSource();
|
||||
if ($ns) {
|
||||
if (!empty($ns->name) && !empty($ns->url)) {
|
||||
$source = '<a href="'
|
||||
. htmlspecialchars($ns->url)
|
||||
. '" rel="nofollow">'
|
||||
. htmlspecialchars($ns->name)
|
||||
. '</a>';
|
||||
} else {
|
||||
$source = $ns->code;
|
||||
}
|
||||
}
|
||||
|
||||
$this->element("twitter:source", null, $source);
|
||||
|
||||
$this->elementStart('author');
|
||||
|
@ -22,7 +22,7 @@
|
||||
* @category Search
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2008-2009 StatusNet, Inc.
|
||||
* @copyright 2008-2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
@ -31,6 +31,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR.'/lib/apiprivateauth.php';
|
||||
require_once INSTALLDIR.'/lib/jsonsearchresultslist.php';
|
||||
|
||||
/**
|
||||
@ -44,7 +45,7 @@ require_once INSTALLDIR.'/lib/jsonsearchresultslist.php';
|
||||
* @see ApiAction
|
||||
*/
|
||||
|
||||
class TwitapisearchjsonAction extends ApiAction
|
||||
class ApiSearchJSONAction extends ApiPrivateAuthAction
|
||||
{
|
||||
var $query;
|
||||
var $lang;
|
||||
@ -64,6 +65,8 @@ class TwitapisearchjsonAction extends ApiAction
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
common_debug("apisearchjson prepare()");
|
||||
|
||||
parent::prepare($args);
|
||||
|
||||
$this->query = $this->trimmed('q');
|
@ -29,6 +29,7 @@
|
||||
* @author Robin Millette <robin@millette.info>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
@ -99,19 +100,27 @@ class ApiStatusesDestroyAction extends ApiAuthAction
|
||||
parent::handle($args);
|
||||
|
||||
if (!in_array($this->format, array('xml', 'json'))) {
|
||||
$this->clientError(_('API method not found.'), $code = 404);
|
||||
$this->clientError(
|
||||
_('API method not found.'),
|
||||
404
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
|
||||
$this->clientError(_('This method requires a POST or DELETE.'),
|
||||
400, $this->format);
|
||||
$this->clientError(
|
||||
_('This method requires a POST or DELETE.'),
|
||||
400,
|
||||
$this->format
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (empty($this->notice)) {
|
||||
$this->clientError(_('No status found with that ID.'),
|
||||
404, $this->format);
|
||||
$this->clientError(
|
||||
_('No status found with that ID.'),
|
||||
404, $this->format
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -120,18 +129,14 @@ class ApiStatusesDestroyAction extends ApiAuthAction
|
||||
$replies->get('notice_id', $this->notice_id);
|
||||
$replies->delete();
|
||||
$this->notice->delete();
|
||||
|
||||
if ($this->format == 'xml') {
|
||||
$this->showSingleXmlStatus($this->notice);
|
||||
} elseif ($this->format == 'json') {
|
||||
$this->show_single_json_status($this->notice);
|
||||
}
|
||||
} else {
|
||||
$this->clientError(_('You may not delete another user\'s status.'),
|
||||
403, $this->format);
|
||||
}
|
||||
|
||||
$this->showNotice();
|
||||
} else {
|
||||
$this->clientError(
|
||||
_('You may not delete another user\'s status.'),
|
||||
403,
|
||||
$this->format
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,7 +79,7 @@ class ApiStatusesRetweetAction extends ApiAuthAction
|
||||
|
||||
$this->user = $this->auth_user;
|
||||
|
||||
if ($this->user->id == $notice->profile_id) {
|
||||
if ($this->user->id == $this->original->profile_id) {
|
||||
$this->clientError(_('Cannot repeat your own notice.'),
|
||||
400, $this->format);
|
||||
return false;
|
||||
|
@ -29,6 +29,7 @@
|
||||
* @author Robin Millette <robin@millette.info>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -29,10 +29,102 @@
|
||||
* @author Robin Millette <robin@millette.info>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009-2010 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
/* External API usage documentation. Please update when you change how this method works. */
|
||||
|
||||
/*! @page statusesupdate statuses/update
|
||||
|
||||
@section Description
|
||||
Updates the authenticating user's status. Requires the status parameter specified below.
|
||||
Request must be a POST.
|
||||
|
||||
@par URL pattern
|
||||
/api/statuses/update.:format
|
||||
|
||||
@par Formats (:format)
|
||||
xml, json
|
||||
|
||||
@par HTTP Method(s)
|
||||
POST
|
||||
|
||||
@par Requires Authentication
|
||||
Yes
|
||||
|
||||
@param status (Required) The URL-encoded text of the status update.
|
||||
@param source (Optional) The source of the status.
|
||||
@param in_reply_to_status_id (Optional) The ID of an existing status that the update is in reply to.
|
||||
@param lat (Optional) The latitude the status refers to.
|
||||
@param long (Optional) The longitude the status refers to.
|
||||
@param media (Optional) a media upload, such as an image or movie file.
|
||||
|
||||
@sa @ref authentication
|
||||
@sa @ref apiroot
|
||||
|
||||
@subsection usagenotes Usage notes
|
||||
|
||||
@li The URL pattern is relative to the @ref apiroot.
|
||||
@li If the @e source parameter is not supplied the source of the status will default to 'api'.
|
||||
@li The XML response uses <a href="http://georss.org/Main_Page">GeoRSS</a>
|
||||
to encode the latitude and longitude (see example response below <georss:point>).
|
||||
@li Data uploaded via the @e media parameter should be multipart/form-data encoded.
|
||||
|
||||
@subsection exampleusage Example usage
|
||||
|
||||
@verbatim
|
||||
curl -u username:password http://example.com/api/statuses/update.xml -d status='Howdy!' -d lat='30.468' -d long='-94.743'
|
||||
@endverbatim
|
||||
|
||||
@subsection exampleresponse Example response
|
||||
|
||||
@verbatim
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<status>
|
||||
<text>Howdy!</text>
|
||||
<truncated>false</truncated>
|
||||
<created_at>Tue Mar 30 23:28:05 +0000 2010</created_at>
|
||||
<in_reply_to_status_id/>
|
||||
<source>api</source>
|
||||
<id>26668724</id>
|
||||
<in_reply_to_user_id/>
|
||||
<in_reply_to_screen_name/>
|
||||
<geo xmlns:georss="http://www.georss.org/georss">
|
||||
<georss:point>30.468 -94.743</georss:point>
|
||||
</geo>
|
||||
<favorited>false</favorited>
|
||||
<user>
|
||||
<id>25803</id>
|
||||
<name>Jed Sanders</name>
|
||||
<screen_name>jedsanders</screen_name>
|
||||
<location>Hoop and Holler, Texas</location>
|
||||
<description>I like to think of myself as America's Favorite.</description>
|
||||
<profile_image_url>http://avatar.example.com/25803-48-20080924200604.png</profile_image_url>
|
||||
<url>http://jedsanders.net</url>
|
||||
<protected>false</protected>
|
||||
<followers_count>5</followers_count>
|
||||
<profile_background_color/>
|
||||
<profile_text_color/>
|
||||
<profile_link_color/>
|
||||
<profile_sidebar_fill_color/>
|
||||
<profile_sidebar_border_color/>
|
||||
<friends_count>2</friends_count>
|
||||
<created_at>Wed Sep 24 20:04:00 +0000 2008</created_at>
|
||||
<favourites_count>0</favourites_count>
|
||||
<utc_offset>0</utc_offset>
|
||||
<time_zone>UTC</time_zone>
|
||||
<profile_background_image_url/>
|
||||
<profile_background_tile>false</profile_background_tile>
|
||||
<statuses_count>70</statuses_count>
|
||||
<following>true</following>
|
||||
<notifications>true</notifications>
|
||||
</user>
|
||||
</status>
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
@ -64,8 +156,6 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
var $lat = null;
|
||||
var $lon = null;
|
||||
|
||||
static $reserved_sources = array('web', 'omb', 'mail', 'xmpp', 'api');
|
||||
|
||||
/**
|
||||
* Take arguments for running
|
||||
*
|
||||
@ -80,19 +170,9 @@ class ApiStatusesUpdateAction extends ApiAuthAction
|
||||
parent::prepare($args);
|
||||
|
||||
$this->status = $this->trimmed('status');
|
||||
$this->source = $this->trimmed('source');
|
||||
$this->lat = $this->trimmed('lat');
|
||||
$this->lon = $this->trimmed('long');
|
||||
|
||||
// try to set the source attr from OAuth app
|
||||
if (empty($this->source)) {
|
||||
$this->source = $this->oauth_source;
|
||||
}
|
||||
|
||||
if (empty($this->source) || in_array($this->source, self::$reserved_sources)) {
|
||||
$this->source = 'api';
|
||||
}
|
||||
|
||||
$this->in_reply_to_status_id
|
||||
= intval($this->trimmed('in_reply_to_status_id'));
|
||||
|
||||
|
@ -206,7 +206,8 @@ class ApiSubscriptionsAction extends ApiBareAuthAction
|
||||
{
|
||||
switch ($this->format) {
|
||||
case 'xml':
|
||||
$this->elementStart('users', array('type' => 'array'));
|
||||
$this->elementStart('users', array('type' => 'array',
|
||||
'xmlns:statusnet' => 'http://status.net/schema/api/1/'));
|
||||
foreach ($this->profiles as $profile) {
|
||||
$this->showProfile(
|
||||
$profile,
|
||||
|
@ -25,6 +25,7 @@
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009-2010 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
@ -150,7 +151,7 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$atom = new AtomNoticeFeed();
|
||||
$atom = new AtomNoticeFeed($this->auth_user);
|
||||
|
||||
$atom->setId($id);
|
||||
$atom->setTitle($title);
|
||||
@ -185,17 +186,23 @@ class ApiTimelineFavoritesAction extends ApiBareAuthAction
|
||||
{
|
||||
$notices = array();
|
||||
|
||||
common_debug("since id = " . $this->since_id . " max id = " . $this->max_id);
|
||||
|
||||
if (!empty($this->auth_user) && $this->auth_user->id == $this->user->id) {
|
||||
$notice = $this->user->favoriteNotices(
|
||||
true,
|
||||
($this->page-1) * $this->count,
|
||||
$this->count,
|
||||
true
|
||||
$this->since_id,
|
||||
$this->max_id
|
||||
);
|
||||
} else {
|
||||
$notice = $this->user->favoriteNotices(
|
||||
false,
|
||||
($this->page-1) * $this->count,
|
||||
$this->count,
|
||||
false
|
||||
$this->since_id,
|
||||
$this->max_id
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -28,11 +28,107 @@
|
||||
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||
* @author Robin Millette <robin@millette.info>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009-2010 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
/* External API usage documentation. Please update when you change how this method works. */
|
||||
|
||||
/*! @page friendstimeline statuses/friends_timeline
|
||||
|
||||
@section Description
|
||||
Returns the 20 most recent statuses posted by the authenticating
|
||||
user and that user's friends. This is the equivalent of "You and
|
||||
friends" page in the web interface.
|
||||
|
||||
@par URL patterns
|
||||
@li /api/statuses/friends_timeline.:format
|
||||
@li /api/statuses/friends_timeline/:id.:format
|
||||
|
||||
@par Formats (:format)
|
||||
xml, json, rss, atom
|
||||
|
||||
@par ID (:id)
|
||||
username, user id
|
||||
|
||||
@par HTTP Method(s)
|
||||
GET
|
||||
|
||||
@par Requires Authentication
|
||||
Sometimes (see: @ref authentication)
|
||||
|
||||
@param user_id (Optional) Specifies a user by ID
|
||||
@param screen_name (Optional) Specifies a user by screename (nickname)
|
||||
@param since_id (Optional) Returns only statuses with an ID greater
|
||||
than (that is, more recent than) the specified ID.
|
||||
@param max_id (Optional) Returns only statuses with an ID less than
|
||||
(that is, older than) or equal to the specified ID.
|
||||
@param count (Optional) Specifies the number of statuses to retrieve.
|
||||
@param page (Optional) Specifies the page of results to retrieve.
|
||||
|
||||
@sa @ref authentication
|
||||
@sa @ref apiroot
|
||||
|
||||
@subsection usagenotes Usage notes
|
||||
@li The URL pattern is relative to the @ref apiroot.
|
||||
@li The XML response uses <a href="http://georss.org/Main_Page">GeoRSS</a>
|
||||
to encode the latitude and longitude (see example response below <georss:point>).
|
||||
|
||||
@subsection exampleusage Example usage
|
||||
|
||||
@verbatim
|
||||
curl http://identi.ca/api/statuses/friends_timeline/evan.xml?count=1&page=2
|
||||
@endverbatim
|
||||
|
||||
@subsection exampleresponse Example response
|
||||
|
||||
@verbatim
|
||||
<?xml version="1.0"?>
|
||||
<statuses type="array">
|
||||
<status>
|
||||
<text>back from the !yul !drupal meet with Evolving Web folk, @anarcat, @webchick and others, and an interesting refresher on SQL indexing</text>
|
||||
<truncated>false</truncated>
|
||||
<created_at>Wed Mar 31 01:33:02 +0000 2010</created_at>
|
||||
<in_reply_to_status_id/>
|
||||
<source><a href="http://code.google.com/p/microblog-purple/">mbpidgin</a></source>
|
||||
<id>26674201</id>
|
||||
<in_reply_to_user_id/>
|
||||
<in_reply_to_screen_name/>
|
||||
<geo/>
|
||||
<favorited>false</favorited>
|
||||
<user>
|
||||
<id>246</id>
|
||||
<name>Mark</name>
|
||||
<screen_name>lambic</screen_name>
|
||||
<location>Montreal, Canada</location>
|
||||
<description>Geek</description>
|
||||
<profile_image_url>http://avatar.identi.ca/246-48-20080702141545.png</profile_image_url>
|
||||
<url>http://lambic.co.uk</url>
|
||||
<protected>false</protected>
|
||||
<followers_count>73</followers_count>
|
||||
<profile_background_color>#F0F2F5</profile_background_color>
|
||||
<profile_text_color/>
|
||||
<profile_link_color>#002E6E</profile_link_color>
|
||||
<profile_sidebar_fill_color>#CEE1E9</profile_sidebar_fill_color>
|
||||
<profile_sidebar_border_color/>
|
||||
<friends_count>58</friends_count>
|
||||
<created_at>Wed Jul 02 14:12:15 +0000 2008</created_at>
|
||||
<favourites_count>2</favourites_count>
|
||||
<utc_offset>-14400</utc_offset>
|
||||
<time_zone>US/Eastern</time_zone>
|
||||
<profile_background_image_url/>
|
||||
<profile_background_tile>false</profile_background_tile>
|
||||
<statuses_count>933</statuses_count>
|
||||
<following>false</following>
|
||||
<notifications>false</notifications>
|
||||
</user>
|
||||
</status>
|
||||
</statuses>
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
@ -153,7 +249,7 @@ class ApiTimelineFriendsAction extends ApiBareAuthAction
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$atom = new AtomNoticeFeed();
|
||||
$atom = new AtomNoticeFeed($this->auth_user);
|
||||
|
||||
$atom->setId($id);
|
||||
$atom->setTitle($title);
|
||||
|
@ -26,6 +26,7 @@
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
@ -105,7 +106,7 @@ class ApiTimelineGroupAction extends ApiPrivateAuthAction
|
||||
function showTimeline()
|
||||
{
|
||||
// We'll pull common formatting out of this for other formats
|
||||
$atom = new AtomGroupNoticeFeed($this->group);
|
||||
$atom = new AtomGroupNoticeFeed($this->group, $this->auth_user);
|
||||
|
||||
$self = $this->getSelfUri();
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
* @author Robin Millette <robin@millette.info>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
@ -152,7 +153,7 @@ class ApiTimelineHomeAction extends ApiBareAuthAction
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$atom = new AtomNoticeFeed();
|
||||
$atom = new AtomNoticeFeed($this->auth_user);
|
||||
|
||||
$atom->setId($id);
|
||||
$atom->setTitle($title);
|
||||
|
@ -29,6 +29,7 @@
|
||||
* @author Robin Millette <robin@millette.info>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
@ -151,7 +152,7 @@ class ApiTimelineMentionsAction extends ApiBareAuthAction
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$atom = new AtomNoticeFeed();
|
||||
$atom = new AtomNoticeFeed($this->auth_user);
|
||||
|
||||
$atom->setId($id);
|
||||
$atom->setTitle($title);
|
||||
|
@ -29,6 +29,7 @@
|
||||
* @author Robin Millette <robin@millette.info>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
@ -55,6 +56,95 @@ require_once INSTALLDIR . '/lib/apiprivateauth.php';
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
/* External API usage documentation. Please update when you change how this method works. */
|
||||
|
||||
/*! @page publictimeline statuses/public_timeline
|
||||
|
||||
@section Description
|
||||
Returns the 20 most recent notices from users throughout the system who have
|
||||
uploaded their own avatars. Depending on configuration, it may or may not
|
||||
not include notices from automatic posting services.
|
||||
|
||||
@par URL patterns
|
||||
@li /api/statuses/public_timeline.:format
|
||||
|
||||
@par Formats (:format)
|
||||
xml, json, rss, atom
|
||||
|
||||
@par HTTP Method(s)
|
||||
GET
|
||||
|
||||
@par Requires Authentication
|
||||
No
|
||||
|
||||
@param since_id (Optional) Returns only statuses with an ID greater
|
||||
than (that is, more recent than) the specified ID.
|
||||
@param max_id (Optional) Returns only statuses with an ID less than
|
||||
(that is, older than) or equal to the specified ID.
|
||||
@param count (Optional) Specifies the number of statuses to retrieve.
|
||||
@param page (Optional) Specifies the page of results to retrieve.
|
||||
|
||||
@sa @ref apiroot
|
||||
|
||||
@subsection usagenotes Usage notes
|
||||
@li The URL pattern is relative to the @ref apiroot.
|
||||
@li The XML response uses <a href="http://georss.org/Main_Page">GeoRSS</a>
|
||||
to encode the latitude and longitude (see example response below <georss:point>).
|
||||
|
||||
@subsection exampleusage Example usage
|
||||
|
||||
@verbatim
|
||||
curl http://identi.ca/api/statuses/friends_timeline/evan.xml?count=1&page=2
|
||||
@endverbatim
|
||||
|
||||
@subsection exampleresponse Example response
|
||||
|
||||
@verbatim
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<statuses type="array">
|
||||
<status>
|
||||
<text>@skwashd oh, commbank reenabled me super quick both times. but disconcerting when you don't expect it though</text>
|
||||
<truncated>false</truncated>
|
||||
<created_at>Sat Apr 17 00:49:12 +0000 2010</created_at>
|
||||
<in_reply_to_status_id>28838393</in_reply_to_status_id>
|
||||
<source>xmpp</source>
|
||||
<id>28838456</id>
|
||||
<in_reply_to_user_id>39303</in_reply_to_user_id>
|
||||
<in_reply_to_screen_name>skwashd</in_reply_to_screen_name>
|
||||
<geo></geo>
|
||||
<favorited>false</favorited>
|
||||
<user>
|
||||
<id>44517</id>
|
||||
<name>joshua may</name>
|
||||
<screen_name>notjosh</screen_name>
|
||||
<location></location>
|
||||
<description></description>
|
||||
<profile_image_url>http://avatar.identi.ca/44517-48-20090321004106.jpeg</profile_image_url>
|
||||
<url></url>
|
||||
<protected>false</protected>
|
||||
<followers_count>17</followers_count>
|
||||
<profile_background_color></profile_background_color>
|
||||
<profile_text_color></profile_text_color>
|
||||
<profile_link_color></profile_link_color>
|
||||
<profile_sidebar_fill_color></profile_sidebar_fill_color>
|
||||
<profile_sidebar_border_color></profile_sidebar_border_color>
|
||||
<friends_count>20</friends_count>
|
||||
<created_at>Sat Mar 21 00:40:25 +0000 2009</created_at>
|
||||
<favourites_count>0</favourites_count>
|
||||
<utc_offset>0</utc_offset>
|
||||
<time_zone>UTC</time_zone>
|
||||
<profile_background_image_url></profile_background_image_url>
|
||||
<profile_background_tile>false</profile_background_tile>
|
||||
<statuses_count>100</statuses_count>
|
||||
<following>false</following>
|
||||
<notifications>false</notifications>
|
||||
</user>
|
||||
</status>
|
||||
[....]
|
||||
</statuses>
|
||||
@endverbatim
|
||||
*/
|
||||
|
||||
class ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||
{
|
||||
|
||||
@ -130,7 +220,7 @@ class ApiTimelinePublicAction extends ApiPrivateAuthAction
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$atom = new AtomNoticeFeed();
|
||||
$atom = new AtomNoticeFeed($this->auth_user);
|
||||
|
||||
$atom->setId($id);
|
||||
$atom->setTitle($title);
|
||||
|
@ -117,7 +117,7 @@ class ApiTimelineRetweetsOfMeAction extends ApiAuthAction
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$atom = new AtomNoticeFeed();
|
||||
$atom = new AtomNoticeFeed($this->auth_user);
|
||||
|
||||
$atom->setId($id);
|
||||
$atom->setTitle($title);
|
||||
|
@ -26,6 +26,7 @@
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009-2010 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
@ -138,7 +139,7 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
|
||||
|
||||
header('Content-Type: application/atom+xml; charset=utf-8');
|
||||
|
||||
$atom = new AtomNoticeFeed();
|
||||
$atom = new AtomNoticeFeed($this->auth_user);
|
||||
|
||||
$atom->setId($id);
|
||||
$atom->setTitle($title);
|
||||
|
@ -29,6 +29,7 @@
|
||||
* @author Robin Millette <robin@millette.info>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
@ -115,7 +116,7 @@ class ApiTimelineUserAction extends ApiBareAuthAction
|
||||
|
||||
// We'll use the shared params from the Atom stub
|
||||
// for other feed types.
|
||||
$atom = new AtomUserNoticeFeed($this->user);
|
||||
$atom = new AtomUserNoticeFeed($this->user, $this->auth_user);
|
||||
|
||||
$link = common_local_url(
|
||||
'showstream',
|
||||
|
@ -22,7 +22,7 @@
|
||||
* @category Search
|
||||
* @package StatusNet
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2008-2009 StatusNet, Inc.
|
||||
* @copyright 2008-2010 StatusNet, Inc.
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
@ -31,6 +31,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once INSTALLDIR.'/lib/apiprivateauth.php';
|
||||
|
||||
/**
|
||||
* Returns the top ten queries that are currently trending
|
||||
*
|
||||
@ -43,7 +45,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @see ApiAction
|
||||
*/
|
||||
|
||||
class TwitapitrendsAction extends ApiAction
|
||||
class ApiTrendsAction extends ApiPrivateAuthAction
|
||||
{
|
||||
|
||||
var $callback;
|
||||
@ -82,7 +84,7 @@ class TwitapitrendsAction extends ApiAction
|
||||
*/
|
||||
function showTrends()
|
||||
{
|
||||
$this->serverError(_('API method under construction.'), $code = 501);
|
||||
$this->serverError(_('API method under construction.'), 501);
|
||||
}
|
||||
|
||||
}
|
@ -113,7 +113,7 @@ class ApiUserShowAction extends ApiPrivateAuthAction
|
||||
|
||||
if ($this->format == 'xml') {
|
||||
$this->initDocument('xml');
|
||||
$this->showTwitterXmlUser($twitter_user);
|
||||
$this->showTwitterXmlUser($twitter_user, 'user', true);
|
||||
$this->endDocument('xml');
|
||||
} elseif ($this->format == 'json') {
|
||||
$this->initDocument('json');
|
||||
|
@ -87,13 +87,15 @@ class BlockAction extends ProfileFormAction
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if ($this->arg('no')) {
|
||||
$this->returnToArgs();
|
||||
$this->returnToPrevious();
|
||||
} elseif ($this->arg('yes')) {
|
||||
$this->handlePost();
|
||||
$this->returnToArgs();
|
||||
$this->returnToPrevious();
|
||||
} else {
|
||||
$this->showPage();
|
||||
}
|
||||
} else {
|
||||
$this->showPage();
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,6 +120,12 @@ class BlockAction extends ProfileFormAction
|
||||
*/
|
||||
function areYouSureForm()
|
||||
{
|
||||
// @fixme if we ajaxify the confirmation form, skip the preview on ajax hits
|
||||
$profile = new ArrayWrapper(array($this->profile));
|
||||
$preview = new ProfileList($profile, $this);
|
||||
$preview->show();
|
||||
|
||||
|
||||
$id = $this->profile->id;
|
||||
$this->elementStart('form', array('id' => 'block-' . $id,
|
||||
'method' => 'post',
|
||||
@ -187,4 +195,38 @@ class BlockAction extends ProfileFormAction
|
||||
$this->autofocus('form_action-yes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Override for form session token checks; on our first hit we're just
|
||||
* requesting confirmation, which doesn't need a token. We need to be
|
||||
* able to take regular GET requests from email!
|
||||
*
|
||||
* @throws ClientException if token is bad on POST request or if we have
|
||||
* confirmation parameters which could trigger something.
|
||||
*/
|
||||
function checkSessionToken()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST' ||
|
||||
$this->arg('yes') ||
|
||||
$this->arg('no')) {
|
||||
|
||||
return parent::checkSessionToken();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we reached this form without returnto arguments, return to the
|
||||
* current user's subscription list.
|
||||
*
|
||||
* @return string URL
|
||||
*/
|
||||
function defaultReturnTo()
|
||||
{
|
||||
$user = common_current_user();
|
||||
if ($user) {
|
||||
return common_local_url('subscribers',
|
||||
array('nickname' => $user->nickname));
|
||||
} else {
|
||||
return common_local_url('public');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,10 +92,10 @@ class DeleteuserAction extends ProfileFormAction
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if ($this->arg('no')) {
|
||||
$this->returnToArgs();
|
||||
$this->returnToPrevious();
|
||||
} elseif ($this->arg('yes')) {
|
||||
$this->handlePost();
|
||||
$this->returnToArgs();
|
||||
$this->returnToPrevious();
|
||||
} else {
|
||||
$this->showPage();
|
||||
}
|
||||
|
@ -126,9 +126,19 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
return;
|
||||
}
|
||||
|
||||
// check for an image upload
|
||||
// check for file uploads
|
||||
|
||||
$bgimage = $this->saveBackgroundImage();
|
||||
$customTheme = $this->saveCustomTheme();
|
||||
|
||||
$oldtheme = common_config('site', 'theme');
|
||||
if ($customTheme) {
|
||||
// This feels pretty hacky :D
|
||||
$this->args['theme'] = $customTheme;
|
||||
$themeChanged = true;
|
||||
} else {
|
||||
$themeChanged = ($this->trimmed('theme') != $oldtheme);
|
||||
}
|
||||
|
||||
static $settings = array('theme', 'logo');
|
||||
|
||||
@ -140,15 +150,13 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
|
||||
$this->validate($values);
|
||||
|
||||
$oldtheme = common_config('site', 'theme');
|
||||
|
||||
$config = new Config();
|
||||
|
||||
$config->query('BEGIN');
|
||||
|
||||
// Only update colors if the theme has not changed.
|
||||
|
||||
if ($oldtheme == $values['theme']) {
|
||||
if (!$themeChanged) {
|
||||
|
||||
$bgcolor = new WebColor($this->trimmed('design_background'));
|
||||
$ccolor = new WebColor($this->trimmed('design_content'));
|
||||
@ -190,6 +198,13 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
Config::save('design', 'backgroundimage', $bgimage);
|
||||
}
|
||||
|
||||
if (common_config('custom_css', 'enabled')) {
|
||||
$css = $this->arg('css');
|
||||
if ($css != common_config('custom_css', 'css')) {
|
||||
Config::save('custom_css', 'css', $css);
|
||||
}
|
||||
}
|
||||
|
||||
$config->query('COMMIT');
|
||||
}
|
||||
|
||||
@ -263,6 +278,33 @@ class DesignadminpanelAction extends AdminPanelAction
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the custom theme if the user uploaded one.
|
||||
*
|
||||
* @return mixed custom theme name, if succesful, or null if no theme upload.
|
||||
* @throws ClientException for invalid theme archives
|
||||
* @throws ServerException if trouble saving the theme files
|
||||
*/
|
||||
|
||||
function saveCustomTheme()
|
||||
{
|
||||
if (common_config('theme_upload', 'enabled') &&
|
||||
$_FILES['design_upload_theme']['error'] == UPLOAD_ERR_OK) {
|
||||
|
||||
$upload = ThemeUploader::fromUpload('design_upload_theme');
|
||||
$basedir = common_config('local', 'dir');
|
||||
if (empty($basedir)) {
|
||||
$basedir = INSTALLDIR . '/local';
|
||||
}
|
||||
$name = 'custom'; // @todo allow multiples, custom naming?
|
||||
$outdir = $basedir . '/theme/' . $name;
|
||||
$upload->extract($outdir);
|
||||
return $name;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to validate setting values
|
||||
*
|
||||
@ -371,7 +413,15 @@ class DesignAdminPanelForm extends AdminForm
|
||||
|
||||
function formData()
|
||||
{
|
||||
$this->showLogo();
|
||||
$this->showTheme();
|
||||
$this->showBackground();
|
||||
$this->showColors();
|
||||
$this->showAdvanced();
|
||||
}
|
||||
|
||||
function showLogo()
|
||||
{
|
||||
$this->out->elementStart('fieldset', array('id' => 'settings_design_logo'));
|
||||
$this->out->element('legend', null, _('Change logo'));
|
||||
|
||||
@ -384,6 +434,11 @@ class DesignAdminPanelForm extends AdminForm
|
||||
$this->out->elementEnd('ul');
|
||||
|
||||
$this->out->elementEnd('fieldset');
|
||||
|
||||
}
|
||||
|
||||
function showTheme()
|
||||
{
|
||||
$this->out->elementStart('fieldset', array('id' => 'settings_design_theme'));
|
||||
$this->out->element('legend', null, _('Change theme'));
|
||||
|
||||
@ -407,10 +462,23 @@ class DesignAdminPanelForm extends AdminForm
|
||||
false, $this->value('theme'));
|
||||
$this->unli();
|
||||
|
||||
if (common_config('theme_upload', 'enabled')) {
|
||||
$this->li();
|
||||
$this->out->element('label', array('for' => 'design_upload_theme'), _('Custom theme'));
|
||||
$this->out->element('input', array('id' => 'design_upload_theme',
|
||||
'name' => 'design_upload_theme',
|
||||
'type' => 'file'));
|
||||
$this->out->element('p', 'form_guide', _('You can upload a custom StatusNet theme as a .ZIP archive.'));
|
||||
$this->unli();
|
||||
}
|
||||
|
||||
$this->out->elementEnd('ul');
|
||||
|
||||
$this->out->elementEnd('fieldset');
|
||||
}
|
||||
|
||||
function showBackground()
|
||||
{
|
||||
$design = $this->out->design;
|
||||
|
||||
$this->out->elementStart('fieldset', array('id' =>
|
||||
@ -486,6 +554,11 @@ class DesignAdminPanelForm extends AdminForm
|
||||
|
||||
$this->out->elementEnd('ul');
|
||||
$this->out->elementEnd('fieldset');
|
||||
}
|
||||
|
||||
function showColors()
|
||||
{
|
||||
$design = $this->out->design;
|
||||
|
||||
$this->out->elementStart('fieldset', array('id' => 'settings_design_color'));
|
||||
$this->out->element('legend', null, _('Change colours'));
|
||||
@ -493,6 +566,7 @@ class DesignAdminPanelForm extends AdminForm
|
||||
$this->out->elementStart('ul', 'form_data');
|
||||
|
||||
try {
|
||||
// @fixme avoid loop unrolling in non-performance-critical contexts like this
|
||||
|
||||
$bgcolor = new WebColor($design->backgroundcolor);
|
||||
|
||||
@ -560,6 +634,7 @@ class DesignAdminPanelForm extends AdminForm
|
||||
$this->unli();
|
||||
|
||||
} catch (WebColorException $e) {
|
||||
// @fixme normalize them individually!
|
||||
common_log(LOG_ERR, 'Bad color values in site design: ' .
|
||||
$e->getMessage());
|
||||
}
|
||||
@ -569,6 +644,27 @@ class DesignAdminPanelForm extends AdminForm
|
||||
$this->out->elementEnd('ul');
|
||||
}
|
||||
|
||||
function showAdvanced()
|
||||
{
|
||||
if (common_config('custom_css', 'enabled')) {
|
||||
$this->out->elementStart('fieldset', array('id' => 'settings_design_advanced'));
|
||||
$this->out->element('legend', null, _('Advanced'));
|
||||
$this->out->elementStart('ul', 'form_data');
|
||||
|
||||
$this->li();
|
||||
$this->out->element('label', array('for' => 'css'), _('Custom CSS'));
|
||||
$this->out->element('textarea', array('name' => 'css',
|
||||
'id' => 'css',
|
||||
'cols' => '50',
|
||||
'rows' => '10'),
|
||||
strval(common_config('custom_css', 'css')));
|
||||
$this->unli();
|
||||
|
||||
$this->out->elementEnd('fieldset');
|
||||
$this->out->elementEnd('ul');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Action elements
|
||||
*
|
||||
|
@ -89,7 +89,7 @@ class FavoritesrssAction extends Rss10Action
|
||||
function getNotices($limit=0)
|
||||
{
|
||||
$user = $this->user;
|
||||
$notice = $user->favoriteNotices(0, $limit);
|
||||
$notice = $user->favoriteNotices(false, 0, $limit);
|
||||
$notices = array();
|
||||
while ($notice->fetch()) {
|
||||
$notices[] = clone($notice);
|
||||
|
@ -95,7 +95,9 @@ class FoafAction extends Action
|
||||
// Would be nice to tell if they were a Person or not (e.g. a #person usertag?)
|
||||
$this->elementStart('Agent', array('rdf:about' =>
|
||||
$this->user->uri));
|
||||
if ($this->user->email) {
|
||||
$this->element('mbox_sha1sum', null, sha1('mailto:' . $this->user->email));
|
||||
}
|
||||
if ($this->profile->fullname) {
|
||||
$this->element('name', null, $this->profile->fullname);
|
||||
}
|
||||
@ -152,7 +154,9 @@ class FoafAction extends Action
|
||||
}
|
||||
|
||||
$person = $this->showMicrobloggingAccount($this->profile,
|
||||
common_root_url(), $this->user->uri, false);
|
||||
common_root_url(), $this->user->uri,
|
||||
/*$fetchSubscriptions*/true,
|
||||
/*$isSubscriber*/false);
|
||||
|
||||
// Get people who subscribe to user
|
||||
|
||||
@ -207,7 +211,8 @@ class FoafAction extends Action
|
||||
$this->showMicrobloggingAccount($profile,
|
||||
($local == 'local') ? common_root_url() : null,
|
||||
$uri,
|
||||
true);
|
||||
/*$fetchSubscriptions*/false,
|
||||
/*$isSubscriber*/($type == LISTENER || $type == BOTH));
|
||||
if ($foaf_url) {
|
||||
$this->element('rdfs:seeAlso', array('rdf:resource' => $foaf_url));
|
||||
}
|
||||
@ -232,7 +237,21 @@ class FoafAction extends Action
|
||||
$this->elementEnd('PersonalProfileDocument');
|
||||
}
|
||||
|
||||
function showMicrobloggingAccount($profile, $service=null, $useruri=null, $isSubscriber=false)
|
||||
/**
|
||||
* Output FOAF <account> bit for the given profile.
|
||||
*
|
||||
* @param Profile $profile
|
||||
* @param mixed $service Root URL of this StatusNet instance for a local
|
||||
* user, otherwise null.
|
||||
* @param mixed $useruri URI string for the referenced profile..
|
||||
* @param boolean $fetchSubscriptions Should we load and list all their subscriptions?
|
||||
* @param boolean $isSubscriber if not fetching subs, we can still mark the user as following the current page.
|
||||
*
|
||||
* @return array if $fetchSubscribers is set, return a list of info on those
|
||||
* subscriptions.
|
||||
*/
|
||||
|
||||
function showMicrobloggingAccount($profile, $service=null, $useruri=null, $fetchSubscriptions=false, $isSubscriber=false)
|
||||
{
|
||||
$attr = array();
|
||||
if ($useruri) {
|
||||
@ -254,9 +273,7 @@ class FoafAction extends Action
|
||||
|
||||
$person = array();
|
||||
|
||||
if ($isSubscriber) {
|
||||
$this->element('sioc:follows', array('rdf:resource'=>$this->user->uri . '#acct'));
|
||||
} else {
|
||||
if ($fetchSubscriptions) {
|
||||
// Get people user is subscribed to
|
||||
$sub = new Subscription();
|
||||
$sub->subscriber = $profile->id;
|
||||
@ -281,6 +298,9 @@ class FoafAction extends Action
|
||||
}
|
||||
|
||||
unset($sub);
|
||||
} else if ($isSubscriber) {
|
||||
// Just declare that they follow the user whose FOAF we're showing.
|
||||
$this->element('sioc:follows', array('rdf:resource' => $this->user->uri . '#acct'));
|
||||
}
|
||||
|
||||
$this->elementEnd('OnlineAccount');
|
||||
|
@ -37,6 +37,7 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -117,7 +117,7 @@ class GroupblockAction extends RedirectingAction
|
||||
parent::handle($args);
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
if ($this->arg('no')) {
|
||||
$this->returnToArgs();
|
||||
$this->returnToPrevious();
|
||||
} elseif ($this->arg('yes')) {
|
||||
$this->blockProfile();
|
||||
} elseif ($this->arg('blockto')) {
|
||||
@ -207,7 +207,7 @@ class GroupblockAction extends RedirectingAction
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->returnToArgs();
|
||||
$this->returnToPrevious();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,8 +133,7 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
'message with further instructions. '.
|
||||
'(Did you add %s to your buddy list?)'),
|
||||
$transport_info['display'],
|
||||
$transport_info['daemon_screenname'],
|
||||
jabber_daemon_address()));
|
||||
$transport_info['daemon_screenname']));
|
||||
$this->hidden('screenname', $confirm->address);
|
||||
// TRANS: Button label to cancel an IM address confirmation procedure.
|
||||
$this->submit('cancel', _m('BUTTON','Cancel'));
|
||||
@ -163,12 +162,11 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
'action' =>
|
||||
common_local_url('imsettings')));
|
||||
$this->elementStart('fieldset', array('id' => 'settings_im_preferences'));
|
||||
$this->element('legend', null, _('Preferences'));
|
||||
// TRANS: Header for IM preferences form.
|
||||
$this->element('legend', null, _('IM Preferences'));
|
||||
$this->hidden('token', common_session_token());
|
||||
$this->elementStart('table');
|
||||
$this->elementStart('tr');
|
||||
// TRANS: Header for IM preferences form.
|
||||
$this->element('th', null, _('IM Preferences'));
|
||||
foreach($user_im_prefs_by_transport as $transport=>$user_im_prefs)
|
||||
{
|
||||
$this->element('th', null, $transports[$transport]['display']);
|
||||
@ -278,19 +276,20 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
$user = common_current_user();
|
||||
|
||||
$user_im_prefs = new User_im_prefs();
|
||||
$user_im_prefs->query('BEGIN');
|
||||
$user_im_prefs->user_id = $user->id;
|
||||
if($user_im_prefs->find() && $user_im_prefs->fetch())
|
||||
{
|
||||
$preferences = array('notify', 'updatefrompresence', 'replies', 'microid');
|
||||
$user_im_prefs->query('BEGIN');
|
||||
do
|
||||
{
|
||||
$original = clone($user_im_prefs);
|
||||
$new = clone($user_im_prefs);
|
||||
foreach($preferences as $preference)
|
||||
{
|
||||
$user_im_prefs->$preference = $this->boolean($user_im_prefs->transport . '_' . $preference);
|
||||
$new->$preference = $this->boolean($new->transport . '_' . $preference);
|
||||
}
|
||||
$result = $user_im_prefs->update($original);
|
||||
$result = $new->update($original);
|
||||
|
||||
if ($result === false) {
|
||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||
@ -299,8 +298,8 @@ class ImsettingsAction extends ConnectSettingsAction
|
||||
return;
|
||||
}
|
||||
}while($user_im_prefs->fetch());
|
||||
$user_im_prefs->query('COMMIT');
|
||||
}
|
||||
$user_im_prefs->query('COMMIT');
|
||||
// TRANS: Confirmation message for successful IM preferences save.
|
||||
$this->showForm(_('Preferences saved.'), true);
|
||||
}
|
||||
|
@ -62,6 +62,28 @@ class LoginAction extends Action
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare page to run
|
||||
*
|
||||
*
|
||||
* @param $args
|
||||
* @return string title
|
||||
*/
|
||||
|
||||
function prepare($args)
|
||||
{
|
||||
parent::prepare($args);
|
||||
|
||||
// @todo this check should really be in index.php for all sensitive actions
|
||||
$ssl = common_config('site', 'ssl');
|
||||
if (empty($_SERVER['HTTPS']) && ($ssl == 'always' || $ssl == 'sometimes')) {
|
||||
common_redirect(common_local_url('login'));
|
||||
// exit
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle input, produce output
|
||||
*
|
||||
@ -267,10 +289,14 @@ class LoginAction extends Action
|
||||
'user name and password ' .
|
||||
'before changing your settings.');
|
||||
} else {
|
||||
return _('Login with your username and password. ' .
|
||||
'Don\'t have a username yet? ' .
|
||||
$prompt = _('Login with your username and password.');
|
||||
if (!common_config('site', 'closed') && !common_config('site', 'inviteonly')) {
|
||||
$prompt .= ' ';
|
||||
$prompt .= _('Don\'t have a username yet? ' .
|
||||
'[Register](%%action.register%%) a new account.');
|
||||
}
|
||||
return $prompt;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,6 +23,7 @@
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @copyright 2008 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -8,7 +8,9 @@
|
||||
* @category Action
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @author Robin Millette <millette@status.net>
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
@ -44,6 +46,7 @@ require_once INSTALLDIR.'/lib/xrdsoutputter.php';
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Robin Millette <millette@status.net>
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*
|
||||
|
@ -74,6 +74,13 @@ class RegisterAction extends Action
|
||||
parent::prepare($args);
|
||||
$this->code = $this->trimmed('code');
|
||||
|
||||
// @todo this check should really be in index.php for all sensitive actions
|
||||
$ssl = common_config('site', 'ssl');
|
||||
if (empty($_SERVER['HTTPS']) && ($ssl == 'always' || $ssl == 'sometimes')) {
|
||||
common_redirect(common_local_url('register'));
|
||||
// exit
|
||||
}
|
||||
|
||||
if (empty($this->code)) {
|
||||
common_ensure_session();
|
||||
if (array_key_exists('invitecode', $_SESSION)) {
|
||||
@ -491,6 +498,45 @@ class RegisterAction extends Action
|
||||
$this->elementStart('li');
|
||||
$this->element('input', $attrs);
|
||||
$this->elementStart('label', array('class' => 'checkbox', 'for' => 'license'));
|
||||
$this->raw($this->licenseCheckbox());
|
||||
$this->elementEnd('label');
|
||||
$this->elementEnd('li');
|
||||
}
|
||||
$this->elementEnd('ul');
|
||||
$this->submit('submit', _('Register'));
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
}
|
||||
|
||||
function licenseCheckbox()
|
||||
{
|
||||
$out = '';
|
||||
switch (common_config('license', 'type')) {
|
||||
case 'private':
|
||||
// TRANS: Copyright checkbox label in registration dialog, for private sites.
|
||||
$out .= htmlspecialchars(sprintf(
|
||||
_('I understand that content and data of %1$s are private and confidential.'),
|
||||
common_config('site', 'name')));
|
||||
// fall through
|
||||
case 'allrightsreserved':
|
||||
if ($out != '') {
|
||||
$out .= ' ';
|
||||
}
|
||||
if (common_config('license', 'owner')) {
|
||||
// TRANS: Copyright checkbox label in registration dialog, for all rights reserved with a specified copyright owner.
|
||||
$out .= htmlspecialchars(sprintf(
|
||||
_('My text and files are copyright by %1$s.'),
|
||||
common_config('license', 'owner')));
|
||||
} else {
|
||||
// TRANS: Copyright checkbox label in registration dialog, for all rights reserved with ownership left to contributors.
|
||||
$out .= htmlspecialchars(_('My text and files remain under my own copyright.'));
|
||||
}
|
||||
// TRANS: Copyright checkbox label in registration dialog, for all rights reserved.
|
||||
$out .= ' ' . _('All rights reserved.');
|
||||
break;
|
||||
case 'cc': // fall through
|
||||
default:
|
||||
// TRANS: Copyright checkbox label in registration dialog, for Creative Commons-style licenses.
|
||||
$message = _('My text and files are available under %s ' .
|
||||
'except this private data: password, ' .
|
||||
'email address, IM address, and phone number.');
|
||||
@ -499,14 +545,9 @@ class RegisterAction extends Action
|
||||
'">' .
|
||||
htmlspecialchars(common_config('license', 'title')) .
|
||||
'</a>';
|
||||
$this->raw(sprintf(htmlspecialchars($message), $link));
|
||||
$this->elementEnd('label');
|
||||
$this->elementEnd('li');
|
||||
$out .= sprintf(htmlspecialchars($message), $link);
|
||||
}
|
||||
$this->elementEnd('ul');
|
||||
$this->submit('submit', _('Register'));
|
||||
$this->elementEnd('fieldset');
|
||||
$this->elementEnd('form');
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -121,11 +121,11 @@ class ShowfavoritesAction extends OwnerDesignAction
|
||||
// Show imported/gateway notices as well as local if
|
||||
// the user is looking at his own favorites
|
||||
|
||||
$this->notice = $this->user->favoriteNotices(($this->page-1)*NOTICES_PER_PAGE,
|
||||
NOTICES_PER_PAGE + 1, true);
|
||||
$this->notice = $this->user->favoriteNotices(true, ($this->page-1)*NOTICES_PER_PAGE,
|
||||
NOTICES_PER_PAGE + 1);
|
||||
} else {
|
||||
$this->notice = $this->user->favoriteNotices(($this->page-1)*NOTICES_PER_PAGE,
|
||||
NOTICES_PER_PAGE + 1, false);
|
||||
$this->notice = $this->user->favoriteNotices(false, ($this->page-1)*NOTICES_PER_PAGE,
|
||||
NOTICES_PER_PAGE + 1);
|
||||
}
|
||||
|
||||
if (empty($this->notice)) {
|
||||
|
@ -430,14 +430,6 @@ class ShowgroupAction extends GroupDesignAction
|
||||
|
||||
function showStatistics()
|
||||
{
|
||||
// XXX: WORM cache this
|
||||
$members = $this->group->getMembers();
|
||||
$members_count = 0;
|
||||
/** $member->count() doesn't work. */
|
||||
while ($members->fetch()) {
|
||||
$members_count++;
|
||||
}
|
||||
|
||||
$this->elementStart('div', array('id' => 'entity_statistics',
|
||||
'class' => 'section'));
|
||||
|
||||
@ -451,7 +443,7 @@ class ShowgroupAction extends GroupDesignAction
|
||||
|
||||
$this->elementStart('dl', 'entity_members');
|
||||
$this->element('dt', null, _('Members'));
|
||||
$this->element('dd', null, (is_int($members_count)) ? $members_count : '0');
|
||||
$this->element('dd', null, $this->group->getMemberCount());
|
||||
$this->elementEnd('dl');
|
||||
|
||||
$this->elementEnd('div');
|
||||
|
@ -185,7 +185,9 @@ class SubscriptionsListItem extends SubscriptionListItem
|
||||
return;
|
||||
}
|
||||
|
||||
if (!common_config('xmpp', 'enabled') && !common_config('sms', 'enabled')) {
|
||||
$transports = array();
|
||||
Event::handle('GetImTransports', array(&$transports));
|
||||
if (!$transports && !common_config('sms', 'enabled')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -195,7 +197,7 @@ class SubscriptionsListItem extends SubscriptionListItem
|
||||
'action' => common_local_url('subedit')));
|
||||
$this->out->hidden('token', common_session_token());
|
||||
$this->out->hidden('profile', $this->profile->id);
|
||||
if (common_config('xmpp', 'enabled')) {
|
||||
if ($transports) {
|
||||
$attrs = array('name' => 'jabber',
|
||||
'type' => 'checkbox',
|
||||
'class' => 'checkbox',
|
||||
@ -205,7 +207,7 @@ class SubscriptionsListItem extends SubscriptionListItem
|
||||
}
|
||||
|
||||
$this->out->element('input', $attrs);
|
||||
$this->out->element('label', array('for' => 'jabber-'.$this->profile->id), _('Jabber'));
|
||||
$this->out->element('label', array('for' => 'jabber-'.$this->profile->id), _('IM'));
|
||||
} else {
|
||||
$this->out->hidden('jabber', $sub->jabber);
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ if (!defined('STATUSNET')) {
|
||||
* @category Info
|
||||
* @package StatusNet
|
||||
* @author Evan Prodromou <evan@status.net>
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
0
avatar/.gitignore
vendored
Normal file → Executable file
0
avatar/.gitignore
vendored
Normal file → Executable file
@ -75,13 +75,13 @@ class Fave extends Memcached_DataObject
|
||||
return Memcached_DataObject::pkeyGet('Fave', $kv);
|
||||
}
|
||||
|
||||
function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $own=false)
|
||||
function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $own=false, $since_id=0, $max_id=0)
|
||||
{
|
||||
$ids = Notice::stream(array('Fave', '_streamDirect'),
|
||||
array($user_id, $own),
|
||||
($own) ? 'fave:ids_by_user_own:'.$user_id :
|
||||
'fave:ids_by_user:'.$user_id,
|
||||
$offset, $limit);
|
||||
$offset, $limit, $since_id, $max_id);
|
||||
return $ids;
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,11 @@ class File extends Memcached_DataObject
|
||||
return false;
|
||||
}
|
||||
|
||||
function processNew($given_url, $notice_id=null) {
|
||||
/**
|
||||
* @fixme refactor this mess, it's gotten pretty scary.
|
||||
* @param bool $followRedirects
|
||||
*/
|
||||
function processNew($given_url, $notice_id=null, $followRedirects=true) {
|
||||
if (empty($given_url)) return -1; // error, no url to process
|
||||
$given_url = File_redirection::_canonUrl($given_url);
|
||||
if (empty($given_url)) return -1; // error, no url to process
|
||||
@ -124,6 +128,10 @@ class File extends Memcached_DataObject
|
||||
if (empty($file)) {
|
||||
$file_redir = File_redirection::staticGet('url', $given_url);
|
||||
if (empty($file_redir)) {
|
||||
// @fixme for new URLs this also looks up non-redirect data
|
||||
// such as target content type, size, etc, which we need
|
||||
// for File::saveNew(); so we call it even if not following
|
||||
// new redirects.
|
||||
$redir_data = File_redirection::where($given_url);
|
||||
if (is_array($redir_data)) {
|
||||
$redir_url = $redir_data['url'];
|
||||
@ -134,11 +142,19 @@ class File extends Memcached_DataObject
|
||||
throw new ServerException("Can't process url '$given_url'");
|
||||
}
|
||||
// TODO: max field length
|
||||
if ($redir_url === $given_url || strlen($redir_url) > 255) {
|
||||
if ($redir_url === $given_url || strlen($redir_url) > 255 || !$followRedirects) {
|
||||
$x = File::saveNew($redir_data, $given_url);
|
||||
$file_id = $x->id;
|
||||
} else {
|
||||
$x = File::processNew($redir_url, $notice_id);
|
||||
// This seems kind of messed up... for now skipping this part
|
||||
// if we're already under a redirect, so we don't go into
|
||||
// horrible infinite loops if we've been given an unstable
|
||||
// redirect (where the final destination of the first request
|
||||
// doesn't match what we get when we ask for it again).
|
||||
//
|
||||
// Seen in the wild with clojure.org, which redirects through
|
||||
// wikispaces for auth and appends session data in the URL params.
|
||||
$x = File::processNew($redir_url, $notice_id, /*followRedirects*/false);
|
||||
$file_id = $x->id;
|
||||
File_redirection::saveNew($redir_data, $file_id, $given_url);
|
||||
}
|
||||
|
@ -115,9 +115,12 @@ class Inbox extends Memcached_DataObject
|
||||
*/
|
||||
static function insertNotice($user_id, $notice_id)
|
||||
{
|
||||
$inbox = DB_DataObject::staticGet('inbox', 'user_id', $user_id);
|
||||
|
||||
if (empty($inbox)) {
|
||||
// Going straight to the DB rather than trusting our caching
|
||||
// during an update. Note: not using DB_DataObject::staticGet,
|
||||
// which is unsafe to use directly (in-process caching causes
|
||||
// memory leaks, which accumulate in queue processes).
|
||||
$inbox = new Inbox();
|
||||
if (!$inbox->get('user_id', $user_id)) {
|
||||
$inbox = Inbox::initialize($user_id);
|
||||
}
|
||||
|
||||
|
@ -128,12 +128,13 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
}
|
||||
|
||||
static function cacheKey($cls, $k, $v) {
|
||||
if (is_object($cls) || is_object($k) || is_object($v)) {
|
||||
if (is_object($cls) || is_object($k) || (is_object($v) && !($v instanceof DB_DataObject_Cast))) {
|
||||
$e = new Exception();
|
||||
common_log(LOG_ERR, __METHOD__ . ' object in param: ' .
|
||||
str_replace("\n", " ", $e->getTraceAsString()));
|
||||
}
|
||||
return common_cache_key(strtolower($cls).':'.$k.':'.$v);
|
||||
$vstr = self::valueString($v);
|
||||
return common_cache_key(strtolower($cls).':'.$k.':'.$vstr);
|
||||
}
|
||||
|
||||
static function getcached($cls, $k, $v) {
|
||||
@ -229,10 +230,10 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
if (empty($this->$key)) {
|
||||
continue;
|
||||
}
|
||||
$ckeys[] = $this->cacheKey($this->tableName(), $key, $this->$key);
|
||||
$ckeys[] = $this->cacheKey($this->tableName(), $key, self::valueString($this->$key));
|
||||
} else if ($type == 'K' || $type == 'N') {
|
||||
$pkey[] = $key;
|
||||
$pval[] = $this->$key;
|
||||
$pval[] = self::valueString($this->$key);
|
||||
} else {
|
||||
throw new Exception("Unknown key type $key => $type for " . $this->tableName());
|
||||
}
|
||||
@ -604,5 +605,30 @@ class Memcached_DataObject extends Safe_DataObject
|
||||
|
||||
return $c->set($cacheKey, $value);
|
||||
}
|
||||
|
||||
static function valueString($v)
|
||||
{
|
||||
$vstr = null;
|
||||
if (is_object($v) && $v instanceof DB_DataObject_Cast) {
|
||||
switch ($v->type) {
|
||||
case 'date':
|
||||
$vstr = $v->year . '-' . $v->month . '-' . $v->day;
|
||||
break;
|
||||
case 'blob':
|
||||
case 'string':
|
||||
case 'sql':
|
||||
case 'datetime':
|
||||
case 'time':
|
||||
throw new ServerException("Unhandled DB_DataObject_Cast type passed as cacheKey value: '$v->type'");
|
||||
break;
|
||||
default:
|
||||
throw new ServerException("Unknown DB_DataObject_Cast type passed as cacheKey value: '$v->type'");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$vstr = strval($v);
|
||||
}
|
||||
return $vstr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
* @author Robin Millette <millette@controlyourself.ca>
|
||||
* @author Sarven Capadisli <csarven@controlyourself.ca>
|
||||
* @author Tom Adams <tom@holizz.com>
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license GNU Affero General Public License http://www.gnu.org/licenses/
|
||||
*/
|
||||
|
||||
@ -97,6 +98,10 @@ class Notice extends Memcached_DataObject
|
||||
// For auditing purposes, save a record that the notice
|
||||
// was deleted.
|
||||
|
||||
// @fixme we have some cases where things get re-run and so the
|
||||
// insert fails.
|
||||
$deleted = Deleted_notice::staticGet('id', $this->id);
|
||||
if (!$deleted) {
|
||||
$deleted = new Deleted_notice();
|
||||
|
||||
$deleted->id = $this->id;
|
||||
@ -106,6 +111,7 @@ class Notice extends Memcached_DataObject
|
||||
$deleted->deleted = common_sql_now();
|
||||
|
||||
$deleted->insert();
|
||||
}
|
||||
|
||||
// Clear related records
|
||||
|
||||
@ -981,8 +987,7 @@ class Notice extends Memcached_DataObject
|
||||
* messages, we won't deliver to any remote targets as that's the
|
||||
* source service's responsibility.
|
||||
*
|
||||
* @fixme Unlike saveReplies() there's no mail notification here.
|
||||
* Move that to distrib queue handler?
|
||||
* Mail notifications etc will be handled later.
|
||||
*
|
||||
* @param array of unique identifier URIs for recipients
|
||||
*/
|
||||
@ -1008,8 +1013,6 @@ class Notice extends Memcached_DataObject
|
||||
$reply->profile_id = $user->id;
|
||||
|
||||
$id = $reply->insert();
|
||||
|
||||
self::blow('reply:stream:%d', $user->id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1021,8 +1024,7 @@ class Notice extends Memcached_DataObject
|
||||
* and save reply records indicating that this message needs to be
|
||||
* delivered to those users.
|
||||
*
|
||||
* Side effect: local recipients get e-mail notifications here.
|
||||
* @fixme move mail notifications to distrib?
|
||||
* Mail notifications to local profiles will be sent later.
|
||||
*
|
||||
* @return array of integer profile IDs
|
||||
*/
|
||||
@ -1076,23 +1078,21 @@ class Notice extends Memcached_DataObject
|
||||
throw new ServerException("Couldn't save reply for {$this->id}, {$mentioned->id}");
|
||||
} else {
|
||||
$replied[$mentioned->id] = 1;
|
||||
self::blow('reply:stream:%d', $mentioned->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$recipientIds = array_keys($replied);
|
||||
|
||||
foreach ($recipientIds as $recipientId) {
|
||||
$user = User::staticGet('id', $recipientId);
|
||||
if (!empty($user)) {
|
||||
self::blow('reply:stream:%d', $reply->profile_id);
|
||||
mail_notify_attn($user, $this);
|
||||
}
|
||||
}
|
||||
|
||||
return $recipientIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull the complete list of @-reply targets for this notice.
|
||||
*
|
||||
* @return array of integer profile ids
|
||||
*/
|
||||
function getReplies()
|
||||
{
|
||||
// XXX: cache me
|
||||
@ -1115,6 +1115,30 @@ class Notice extends Memcached_DataObject
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send e-mail notifications to local @-reply targets.
|
||||
*
|
||||
* Replies must already have been saved; this is expected to be run
|
||||
* from the distrib queue handler.
|
||||
*/
|
||||
function sendReplyNotifications()
|
||||
{
|
||||
// Don't send reply notifications for repeats
|
||||
|
||||
if (!empty($this->repeat_of)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$recipientIds = $this->getReplies();
|
||||
|
||||
foreach ($recipientIds as $recipientId) {
|
||||
$user = User::staticGet('id', $recipientId);
|
||||
if (!empty($user)) {
|
||||
mail_notify_attn($user, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull list of groups this notice needs to be delivered to,
|
||||
* as previously recorded by saveGroups() or saveKnownGroups().
|
||||
@ -1154,7 +1178,7 @@ class Notice extends Memcached_DataObject
|
||||
return $groups;
|
||||
}
|
||||
|
||||
function asAtomEntry($namespace=false, $source=false, $author=true)
|
||||
function asAtomEntry($namespace=false, $source=false, $author=true, $cur=null)
|
||||
{
|
||||
$profile = $this->getProfile();
|
||||
|
||||
@ -1167,7 +1191,8 @@ class Notice extends Memcached_DataObject
|
||||
'xmlns:activity' => 'http://activitystrea.ms/spec/1.0/',
|
||||
'xmlns:media' => 'http://purl.org/syndication/atommedia',
|
||||
'xmlns:poco' => 'http://portablecontacts.net/spec/1.0',
|
||||
'xmlns:ostatus' => 'http://ostatus.org/schema/1.0');
|
||||
'xmlns:ostatus' => 'http://ostatus.org/schema/1.0',
|
||||
'xmlns:statusnet' => 'http://status.net/schema/api/1/');
|
||||
} else {
|
||||
$attrs = array();
|
||||
}
|
||||
@ -1202,7 +1227,7 @@ class Notice extends Memcached_DataObject
|
||||
$xs->element('title', null, common_xml_safe_str($this->content));
|
||||
|
||||
if ($author) {
|
||||
$xs->raw($profile->asAtomAuthor());
|
||||
$xs->raw($profile->asAtomAuthor($cur));
|
||||
$xs->raw($profile->asActivityActor());
|
||||
}
|
||||
|
||||
@ -1215,6 +1240,46 @@ class Notice extends Memcached_DataObject
|
||||
$xs->element('published', null, common_date_w3dtf($this->created));
|
||||
$xs->element('updated', null, common_date_w3dtf($this->created));
|
||||
|
||||
$source = null;
|
||||
|
||||
$ns = $this->getSource();
|
||||
|
||||
if ($ns) {
|
||||
if (!empty($ns->name) && !empty($ns->url)) {
|
||||
$source = '<a href="'
|
||||
. htmlspecialchars($ns->url)
|
||||
. '" rel="nofollow">'
|
||||
. htmlspecialchars($ns->name)
|
||||
. '</a>';
|
||||
} else {
|
||||
$source = $ns->code;
|
||||
}
|
||||
}
|
||||
|
||||
$noticeInfoAttr = array(
|
||||
'local_id' => $this->id, // local notice ID (useful to clients for ordering)
|
||||
'source' => $source, // the client name (source attribution)
|
||||
);
|
||||
|
||||
$ns = $this->getSource();
|
||||
if ($ns) {
|
||||
if (!empty($ns->url)) {
|
||||
$noticeInfoAttr['source_link'] = $ns->url;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($cur)) {
|
||||
$noticeInfoAttr['favorite'] = ($cur->hasFave($this)) ? "true" : "false";
|
||||
$profile = $cur->getProfile();
|
||||
$noticeInfoAttr['repeated'] = ($profile->hasRepeated($this->id)) ? "true" : "false";
|
||||
}
|
||||
|
||||
if (!empty($this->repeat_of)) {
|
||||
$noticeInfoAttr['repeat_of'] = $this->repeat_of;
|
||||
}
|
||||
|
||||
$xs->element('statusnet:notice_info', $noticeInfoAttr, null);
|
||||
|
||||
if ($this->reply_to) {
|
||||
$reply_notice = Notice::staticGet('id', $this->reply_to);
|
||||
if (!empty($reply_notice)) {
|
||||
@ -1781,4 +1846,53 @@ class Notice extends Memcached_DataObject
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the source of the notice
|
||||
*
|
||||
* @return Notice_source $ns A notice source object. 'code' is the only attribute
|
||||
* guaranteed to be populated.
|
||||
*/
|
||||
function getSource()
|
||||
{
|
||||
$ns = new Notice_source();
|
||||
if (!empty($this->source)) {
|
||||
switch ($this->source) {
|
||||
case 'web':
|
||||
case 'xmpp':
|
||||
case 'mail':
|
||||
case 'omb':
|
||||
case 'system':
|
||||
case 'api':
|
||||
$ns->code = $this->source;
|
||||
break;
|
||||
default:
|
||||
$ns = Notice_source::staticGet($this->source);
|
||||
if (!$ns) {
|
||||
$ns = new Notice_source();
|
||||
$ns->code = $this->source;
|
||||
$app = Oauth_application::staticGet('name', $this->source);
|
||||
if ($app) {
|
||||
$ns->name = $app->name;
|
||||
$ns->url = $app->source_url;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $ns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the notice was locally created
|
||||
*
|
||||
* @return boolean locality
|
||||
*/
|
||||
|
||||
public function isLocal()
|
||||
{
|
||||
return ($this->is_local == Notice::LOCAL_PUBLIC ||
|
||||
$this->is_local == Notice::LOCAL_NONPUBLIC);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -849,15 +849,23 @@ class Profile extends Memcached_DataObject
|
||||
*
|
||||
* Assumes that Atom has been previously set up as the base namespace.
|
||||
*
|
||||
* @param Profile $cur the current authenticated user
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function asAtomAuthor()
|
||||
function asAtomAuthor($cur = null)
|
||||
{
|
||||
$xs = new XMLStringer(true);
|
||||
|
||||
$xs->elementStart('author');
|
||||
$xs->element('name', null, $this->nickname);
|
||||
$xs->element('uri', null, $this->getUri());
|
||||
if ($cur != null) {
|
||||
$attrs = Array();
|
||||
$attrs['following'] = $cur->isSubscribed($this) ? 'true' : 'false';
|
||||
$attrs['blocking'] = $cur->hasBlocked($this) ? 'true' : 'false';
|
||||
$xs->element('statusnet:profile_info', $attrs, null);
|
||||
}
|
||||
$xs->elementEnd('author');
|
||||
|
||||
return $xs->getString();
|
||||
|
@ -64,4 +64,17 @@ class Queue_item extends Memcached_DataObject
|
||||
$qi = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release a claimed item.
|
||||
*/
|
||||
function releaseCLaim()
|
||||
{
|
||||
// DB_DataObject doesn't let us save nulls right now
|
||||
$sql = sprintf("UPDATE queue_item SET claimed=NULL WHERE id=%d", $this->id);
|
||||
$this->query($sql);
|
||||
|
||||
$this->claimed = null;
|
||||
$this->encache();
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,20 @@ class Reply extends Memcached_DataObject
|
||||
/* the code above is auto generated do not remove the tag below */
|
||||
###END_AUTOCODE
|
||||
|
||||
/**
|
||||
* Wrapper for record insertion to update related caches
|
||||
*/
|
||||
function insert()
|
||||
{
|
||||
$result = parent::insert();
|
||||
|
||||
if ($result) {
|
||||
self::blow('reply:stream:%d', $this->profile_id);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0)
|
||||
{
|
||||
$ids = Notice::stream(array('Reply', '_streamDirect'),
|
||||
|
@ -144,6 +144,35 @@ class Status_network extends Safe_DataObject
|
||||
return parent::update($orig);
|
||||
}
|
||||
|
||||
/**
|
||||
* DB_DataObject doesn't allow updating keys (even non-primary)
|
||||
*/
|
||||
function updateKeys(&$orig)
|
||||
{
|
||||
$this->_connect();
|
||||
foreach (array('hostname', 'pathname') as $k) {
|
||||
if (strcmp($this->$k, $orig->$k) != 0) {
|
||||
$parts[] = $k . ' = ' . $this->_quote($this->$k);
|
||||
}
|
||||
}
|
||||
if (count($parts) == 0) {
|
||||
// No changes
|
||||
return true;
|
||||
}
|
||||
|
||||
$toupdate = implode(', ', $parts);
|
||||
|
||||
$table = common_database_tablename($this->tableName());
|
||||
$qry = 'UPDATE ' . $table . ' SET ' . $toupdate .
|
||||
' WHERE nickname = ' . $this->_quote($this->nickname);
|
||||
$orig->decache();
|
||||
$result = $this->query($qry);
|
||||
if ($result) {
|
||||
$this->encache();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function delete()
|
||||
{
|
||||
$this->decache(); # while we still have the values!
|
||||
@ -152,18 +181,12 @@ class Status_network extends Safe_DataObject
|
||||
|
||||
/**
|
||||
* @param string $servername hostname
|
||||
* @param string $pathname URL base path
|
||||
* @param string $wildcard hostname suffix to match wildcard config
|
||||
* @return mixed Status_network or null
|
||||
*/
|
||||
static function setupSite($servername, $pathname, $wildcard)
|
||||
static function getFromHostname($servername, $wildcard)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$sn = null;
|
||||
|
||||
// XXX I18N, probably not crucial for hostnames
|
||||
// XXX This probably needs a tune up
|
||||
|
||||
if (0 == strncasecmp(strrev($wildcard), strrev($servername), strlen($wildcard))) {
|
||||
// special case for exact match
|
||||
if (0 == strcasecmp($servername, $wildcard)) {
|
||||
@ -182,6 +205,23 @@ class Status_network extends Safe_DataObject
|
||||
}
|
||||
}
|
||||
}
|
||||
return $sn;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $servername hostname
|
||||
* @param string $pathname URL base path
|
||||
* @param string $wildcard hostname suffix to match wildcard config
|
||||
*/
|
||||
static function setupSite($servername, $pathname, $wildcard)
|
||||
{
|
||||
global $config;
|
||||
|
||||
$sn = null;
|
||||
|
||||
// XXX I18N, probably not crucial for hostnames
|
||||
// XXX This probably needs a tune up
|
||||
$sn = self::getFromHostname($servername, $wildcard);
|
||||
|
||||
if (!empty($sn)) {
|
||||
|
||||
|
@ -459,9 +459,9 @@ class User extends Memcached_DataObject
|
||||
return $profile->getNotices($offset, $limit, $since_id, $before_id);
|
||||
}
|
||||
|
||||
function favoriteNotices($offset=0, $limit=NOTICES_PER_PAGE, $own=false)
|
||||
function favoriteNotices($own=false, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0)
|
||||
{
|
||||
$ids = Fave::stream($this->id, $offset, $limit, $own);
|
||||
$ids = Fave::stream($this->id, $offset, $limit, $own, $since_id, $max_id);
|
||||
return Notice::getStreamByIds($ids);
|
||||
}
|
||||
|
||||
|
@ -154,6 +154,21 @@ class User_group extends Memcached_DataObject
|
||||
return $members;
|
||||
}
|
||||
|
||||
function getMemberCount()
|
||||
{
|
||||
// XXX: WORM cache this
|
||||
|
||||
$members = $this->getMembers();
|
||||
$member_count = 0;
|
||||
|
||||
/** $member->count() doesn't work. */
|
||||
while ($members->fetch()) {
|
||||
$member_count++;
|
||||
}
|
||||
|
||||
return $member_count;
|
||||
}
|
||||
|
||||
function getAdmins($offset=0, $limit=null)
|
||||
{
|
||||
$qry =
|
||||
|
@ -68,4 +68,27 @@ class User_im_prefs extends Memcached_DataObject
|
||||
{
|
||||
return array(false,false);
|
||||
}
|
||||
|
||||
/**
|
||||
* We have two compound keys with unique constraints:
|
||||
* (transport, user_id) which is our primary key, and
|
||||
* (transport, screenname) which is an additional constraint.
|
||||
*
|
||||
* Currently there's not a way to represent that second key
|
||||
* in the general keys list, so we're adding it here to the
|
||||
* list of keys to use for caching, ensuring that it gets
|
||||
* cleared as well when we change.
|
||||
*
|
||||
* @return array of cache keys
|
||||
*/
|
||||
function _allCacheKeys()
|
||||
{
|
||||
$ukeys = 'transport,screenname';
|
||||
$uvals = $this->transport . ',' . $this->screenname;
|
||||
|
||||
$ckeys = parent::_allCacheKeys();
|
||||
$ckeys[] = $this->cacheKey($this->tableName(), $ukeys, $uvals);
|
||||
return $ckeys;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -647,8 +647,10 @@ modified = 384
|
||||
[user_im_prefs__keys]
|
||||
user_id = K
|
||||
transport = K
|
||||
transport = U
|
||||
screenname = U
|
||||
; There's another unique index on (transport, screenname)
|
||||
; but we have no way to represent a compound index other than
|
||||
; the primary key in here. To ensure proper cache purging,
|
||||
; we need to tweak the class.
|
||||
|
||||
[user_urlshortener_prefs]
|
||||
user_id = 129
|
||||
|
@ -45,7 +45,7 @@ $config['site']['path'] = 'statusnet';
|
||||
// lighttpd, nginx), you can enable X-Sendfile support for better
|
||||
// performance. Presently, only attachment serving when the site is
|
||||
// in private mode will use X-Sendfile.
|
||||
// $config['site']['X-Sendfile'] = false;
|
||||
// $config['site']['use_x_sendfile'] = false;
|
||||
// You may also need to enable X-Sendfile support for your web server and
|
||||
// allow it to access files outside of the web root. For Apache with
|
||||
// mod_xsendfile, you can add these to your .htaccess or server config:
|
||||
|
@ -81,3 +81,42 @@ ALTER TABLE profile ADD COLUMN lon decimal(10,7) /*comment 'longitude'*/;
|
||||
ALTER TABLE profile ADD COLUMN location_id integer /* comment 'location id if possible'*/;
|
||||
ALTER TABLE profile ADD COLUMN location_ns integer /* comment 'namespace for location'*/;
|
||||
|
||||
ALTER TABLE consumer add COLUMN consumer_secret varchar(255) not null ; /*comment 'secret value'*/
|
||||
|
||||
ALTER TABLE token ADD COLUMN verifier varchar(255); /* comment 'verifier string for OAuth 1.0a',*/
|
||||
ALTER TABLE token ADD COLUMN verified_callback varchar(255); /* comment 'verified callback URL for OAuth 1.0a',*/
|
||||
|
||||
create table queue_item_new (
|
||||
id serial /* comment 'unique identifier'*/,
|
||||
frame bytea not null /* comment 'data: object reference or opaque string'*/,
|
||||
transport varchar(8) not null /*comment 'queue for what? "email", "jabber", "sms", "irc", ...'*/,
|
||||
created timestamp not null default CURRENT_TIMESTAMP /*comment 'date this record was created'*/,
|
||||
claimed timestamp /*comment 'date this item was claimed'*/,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
insert into queue_item_new (frame,transport,created,claimed)
|
||||
select ('0x' || notice_id::text)::bytea,transport,created,claimed from queue_item;
|
||||
alter table queue_item rename to queue_item_old;
|
||||
alter table queue_item_new rename to queue_item;
|
||||
|
||||
ALTER TABLE confirm_address ALTER column sent set default CURRENT_TIMESTAMP;
|
||||
|
||||
create table user_location_prefs (
|
||||
user_id integer not null /*comment 'user who has the preference'*/ references "user" (id),
|
||||
share_location int default 1 /* comment 'Whether to share location data'*/,
|
||||
created timestamp not null /*comment 'date this record was created'*/,
|
||||
modified timestamp /* comment 'date this record was modified'*/,
|
||||
|
||||
primary key (user_id)
|
||||
);
|
||||
|
||||
create table inbox (
|
||||
|
||||
user_id integer not null /* comment 'user receiving the notice' */ references "user" (id),
|
||||
notice_ids bytea /* comment 'packed list of notice ids' */,
|
||||
|
||||
primary key (user_id)
|
||||
|
||||
);
|
||||
|
||||
|
@ -9,13 +9,16 @@ VALUES
|
||||
('bti','bti','http://gregkh.github.com/bti/', now()),
|
||||
('choqok', 'Choqok', 'http://choqok.gnufolks.org/', now()),
|
||||
('cliqset', 'Cliqset', 'http://www.cliqset.com/', now()),
|
||||
('DarterosStatus', 'Darteros Status', 'http://www.darteros.com/doc/Darteros_Status', now()),
|
||||
('deskbar','Deskbar-Applet','http://www.gnome.org/projects/deskbar-applet/', now()),
|
||||
('Do','Gnome Do','http://do.davebsd.com/wiki/index.php?title=Microblog_Plugin', now()),
|
||||
('drupal','Drupal','http://drupal.org/', now()),
|
||||
('eventbox','EventBox','http://thecosmicmachine.com/eventbox/', now()),
|
||||
('identica-mode','Emacs Identica-mode','http://nongnu.org/identica-mode/', now()),
|
||||
('Facebook','Facebook','http://apps.facebook.com/identica/', now()),
|
||||
('feed2omb','feed2omb','http://projects.ciarang.com/p/feed2omb/', now()),
|
||||
('get2gnow', 'get2gnow', 'http://uberchicgeekchick.com/?projects=get2gnow', now()),
|
||||
('gNewBook', 'gNewBook', 'http://www.gnewbook.org/', now()),
|
||||
('gravity', 'Gravity', 'http://mobileways.de/gravity', now()),
|
||||
('Gwibber','Gwibber','http://launchpad.net/gwibber', now()),
|
||||
('HelloTxt','HelloTxt','http://hellotxt.com/', now()),
|
||||
@ -53,6 +56,7 @@ VALUES
|
||||
('tr.im','tr.im','http://tr.im/', now()),
|
||||
('triklepost', 'Tricklepost', 'http://github.com/zcopley/tricklepost/tree/master', now()),
|
||||
('tweenky','Tweenky','http://beta.tweenky.com/', now()),
|
||||
('TweetDeck', 'TweetDeck', 'http://www.tweetdeck.com/', now()),
|
||||
('twhirl','Twhirl','http://www.twhirl.org/', now()),
|
||||
('twibble','twibble','http://www.twibble.de/', now()),
|
||||
('Twidge','Twidge','http://software.complete.org/twidge', now()),
|
||||
|
@ -8,6 +8,10 @@ create table profile (
|
||||
homepage varchar(255) /* comment 'identifying URL' */,
|
||||
bio varchar(140) /* comment 'descriptive biography' */,
|
||||
location varchar(255) /* comment 'physical location' */,
|
||||
lat decimal(10,7) /* comment 'latitude'*/ ,
|
||||
lon decimal(10,7) /* comment 'longitude'*/ ,
|
||||
location_id integer /* comment 'location id if possible'*/ ,
|
||||
location_ns integer /* comment 'namespace for location'*/ ,
|
||||
created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
|
||||
modified timestamp /* comment 'date this record was modified' */,
|
||||
|
||||
@ -132,6 +136,7 @@ create table notice (
|
||||
is_local integer default 0 /* comment 'notice was generated by a user' */,
|
||||
source varchar(32) /* comment 'source of comment, like "web", "im", or "clientname"' */,
|
||||
conversation integer /*id of root notice in this conversation' */ references notice (id),
|
||||
location varchar(255) /* comment 'physical location' */,
|
||||
lat decimal(10,7) /* comment 'latitude'*/ ,
|
||||
lon decimal(10,7) /* comment 'longitude'*/ ,
|
||||
location_id integer /* comment 'location id if possible'*/ ,
|
||||
@ -182,6 +187,7 @@ create index fave_modified_idx on fave using btree(modified);
|
||||
|
||||
create table consumer (
|
||||
consumer_key varchar(255) primary key /* comment 'unique identifier, root URL' */,
|
||||
consumer_secret varchar(255) not null /* comment 'secret value', */,
|
||||
seed char(32) not null /* comment 'seed for new tokens by this consumer' */,
|
||||
|
||||
created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
|
||||
@ -195,6 +201,9 @@ create table token (
|
||||
type integer not null default 0 /* comment 'request or access' */,
|
||||
state integer default 0 /* comment 'for requests 0 = initial, 1 = authorized, 2 = used' */,
|
||||
|
||||
verifier varchar(255) /*comment 'verifier string for OAuth 1.0a'*/,
|
||||
verified_callback varchar(255) /*comment 'verified callback URL for OAuth 1.0a'*/,
|
||||
|
||||
created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
|
||||
modified timestamp /* comment 'date this record was modified' */,
|
||||
|
||||
@ -213,17 +222,33 @@ create table nonce (
|
||||
primary key (consumer_key, ts, nonce)
|
||||
);
|
||||
|
||||
/* One-to-many relationship of user to openid_url */
|
||||
|
||||
create table user_openid (
|
||||
canonical varchar(255) primary key /* comment 'Canonical true URL' */,
|
||||
display varchar(255) not null unique /* comment 'URL for viewing, may be different from canonical' */,
|
||||
user_id integer not null /* comment 'user owning this URL' */ references "user" (id) ,
|
||||
create sequence oauth_application_seq;
|
||||
create table oauth_application (
|
||||
id bigint default nextval('oauth_application_seq') primary key /* comment 'unique identifier' */,
|
||||
owner integer not null /* comment 'owner of the application' */ references profile (id),
|
||||
consumer_key varchar(255) not null /* comment 'application consumer key' */ references consumer (consumer_key),
|
||||
name varchar(255) unique not null /* comment 'name of the application' */,
|
||||
description varchar(255) /* comment 'description of the application' */,
|
||||
icon varchar(255) not null /* comment 'application icon' */,
|
||||
source_url varchar(255) /* comment 'application homepage - used for source link' */,
|
||||
organization varchar(255) /* comment 'name of the organization running the application' */,
|
||||
homepage varchar(255) /* comment 'homepage for the organization' */,
|
||||
callback_url varchar(255) /* comment 'url to redirect to after authentication' */,
|
||||
"type" integer default 0 /* comment 'type of app, 1 = browser, 2 = desktop' */,
|
||||
access_type integer default 0 /* comment 'default access type, bit 1 = read, bit 2 = write' */,
|
||||
created timestamp not null default CURRENT_TIMESTAMP /* comment 'date this record was created' */,
|
||||
modified timestamp /* comment 'date this record was modified' */
|
||||
|
||||
);
|
||||
create index user_openid_user_id_idx on user_openid using btree(user_id);
|
||||
|
||||
create table oauth_application_user (
|
||||
profile_id integer not null /* 'user of the application' */ references profile (id),
|
||||
application_id integer not null /* 'id of the application' */ references oauth_application (id),
|
||||
access_type integer default 0 /* 'access type, bit 1 = read, bit 2 = write' */,
|
||||
token varchar(255) /* 'request or access token' */,
|
||||
created timestamp not null default CURRENT_TIMESTAMP /* 'date this record was created' */,
|
||||
modified timestamp /* 'date this record was modified' */,
|
||||
primary key (profile_id, application_id)
|
||||
);
|
||||
|
||||
/* These are used by JanRain OpenID library */
|
||||
|
||||
@ -251,7 +276,7 @@ create table confirm_address (
|
||||
address_extra varchar(255) not null default '' /* comment 'carrier ID, for SMS' */,
|
||||
address_type varchar(8) not null /* comment 'address type ("email", "jabber", "sms")' */,
|
||||
claimed timestamp /* comment 'date this was claimed for queueing' */,
|
||||
sent timestamp /* comment 'date this was sent for queueing' */,
|
||||
sent timestamp default CURRENT_TIMESTAMP /* comment 'date this was sent for queueing' */,
|
||||
modified timestamp /* comment 'date this record was modified' */
|
||||
);
|
||||
|
||||
@ -262,14 +287,12 @@ create table remember_me (
|
||||
);
|
||||
|
||||
create table queue_item (
|
||||
|
||||
notice_id integer not null /* comment 'notice queued' */ references notice (id) ,
|
||||
id serial /* comment 'unique identifier'*/,
|
||||
frame bytea not null /* comment 'data: object reference or opaque string'*/,
|
||||
transport varchar(8) not null /*comment 'queue for what? "email", "jabber", "sms", "irc", ...'*/,
|
||||
created timestamp not null default CURRENT_TIMESTAMP /*comment 'date this record was created'*/,
|
||||
claimed timestamp /*comment 'date this item was claimed'*/,
|
||||
|
||||
primary key (notice_id, transport)
|
||||
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
create index queue_item_created_idx on queue_item using btree(created);
|
||||
|
||||
@ -589,3 +612,39 @@ create table login_token (
|
||||
primary key (user_id)
|
||||
);
|
||||
|
||||
create table user_location_prefs (
|
||||
user_id integer not null /* comment 'user who has the preference' */ references "user" (id),
|
||||
share_location integer default 1 /* comment 'Whether to share location data' */,
|
||||
created timestamp not null DEFAULT CURRENT_TIMESTAMP /* comment 'date this record was created' */,
|
||||
modified timestamp /* comment 'date this record was modified' */,
|
||||
|
||||
primary key (user_id)
|
||||
);
|
||||
|
||||
create table inbox (
|
||||
|
||||
user_id integer not null /* comment 'user receiving the notice' */ references "user" (id),
|
||||
notice_ids bytea /* comment 'packed list of notice ids' */,
|
||||
|
||||
primary key (user_id)
|
||||
|
||||
);
|
||||
|
||||
create sequence conversation_seq;
|
||||
create table conversation (
|
||||
id bigint default nextval('conversation_seq') primary key /* comment 'unique identifier' */,
|
||||
uri varchar(225) unique /* comment 'URI of the conversation' */,
|
||||
created timestamp not null DEFAULT CURRENT_TIMESTAMP /* comment 'date this record was created' */,
|
||||
modified timestamp /* comment 'date this record was modified' */
|
||||
);
|
||||
|
||||
create table local_group (
|
||||
|
||||
group_id integer primary key /* comment 'group represented' */ references user_group (id),
|
||||
nickname varchar(64) unique /* comment 'group represented' */,
|
||||
|
||||
created timestamp not null DEFAULT CURRENT_TIMESTAMP /* comment 'date this record was created' */,
|
||||
modified timestamp /* comment 'date this record was modified' */
|
||||
|
||||
);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
You can post messages to %%site.name%% using a many kinds of cell
|
||||
You can post messages to %%site.name%% using many kinds of cell
|
||||
phones that support SMS messaging. This site does not support SMS
|
||||
directly; rather, it uses your carrier's email gateway to send and
|
||||
receive messages.
|
||||
|
80
extlib/Mail.php
Normal file → Executable file
80
extlib/Mail.php
Normal file → Executable file
@ -1,22 +1,47 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: Mail.php,v 1.17 2006/09/15 03:41:18 jon Exp $
|
||||
/**
|
||||
* PEAR's Mail:: interface.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2002-2007, Richard Heyes
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* o Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* o The names of the authors may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category Mail
|
||||
* @package Mail
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
* @copyright 1997-2010 Chuck Hagenbuch
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: Mail.php 294747 2010-02-08 08:18:33Z clockwerx $
|
||||
* @link http://pear.php.net/package/Mail/
|
||||
*/
|
||||
|
||||
require_once 'PEAR.php';
|
||||
|
||||
@ -26,7 +51,7 @@ require_once 'PEAR.php';
|
||||
* useful in multiple mailer backends.
|
||||
*
|
||||
* @access public
|
||||
* @version $Revision: 1.17 $
|
||||
* @version $Revision: 294747 $
|
||||
* @package Mail
|
||||
*/
|
||||
class Mail
|
||||
@ -82,12 +107,20 @@ class Mail
|
||||
* @return mixed Returns true on success, or a PEAR_Error
|
||||
* containing a descriptive error message on
|
||||
* failure.
|
||||
*
|
||||
* @access public
|
||||
* @deprecated use Mail_mail::send instead
|
||||
*/
|
||||
function send($recipients, $headers, $body)
|
||||
{
|
||||
$this->_sanitizeHeaders($headers);
|
||||
if (!is_array($headers)) {
|
||||
return PEAR::raiseError('$headers must be an array');
|
||||
}
|
||||
|
||||
$result = $this->_sanitizeHeaders($headers);
|
||||
if (is_a($result, 'PEAR_Error')) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// if we're passed an array of recipients, implode it.
|
||||
if (is_array($recipients)) {
|
||||
@ -106,7 +139,6 @@ class Mail
|
||||
list(, $text_headers) = Mail::prepareHeaders($headers);
|
||||
|
||||
return mail($recipients, $subject, $body, $text_headers);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -151,9 +183,9 @@ class Mail
|
||||
foreach ($headers as $key => $value) {
|
||||
if (strcasecmp($key, 'From') === 0) {
|
||||
include_once 'Mail/RFC822.php';
|
||||
$parser = &new Mail_RFC822();
|
||||
$parser = new Mail_RFC822();
|
||||
$addresses = $parser->parseAddressList($value, 'localhost', false);
|
||||
if (PEAR::isError($addresses)) {
|
||||
if (is_a($addresses, 'PEAR_Error')) {
|
||||
return $addresses;
|
||||
}
|
||||
|
||||
@ -221,7 +253,7 @@ class Mail
|
||||
$addresses = Mail_RFC822::parseAddressList($recipients, 'localhost', false);
|
||||
|
||||
// If parseAddressList() returned a PEAR_Error object, just return it.
|
||||
if (PEAR::isError($addresses)) {
|
||||
if (is_a($addresses, 'PEAR_Error')) {
|
||||
return $addresses;
|
||||
}
|
||||
|
||||
|
83
extlib/Mail/RFC822.php
Normal file → Executable file
83
extlib/Mail/RFC822.php
Normal file → Executable file
@ -1,37 +1,48 @@
|
||||
<?php
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Copyright (c) 2001-2002, Richard Heyes |
|
||||
// | All rights reserved. |
|
||||
// | |
|
||||
// | Redistribution and use in source and binary forms, with or without |
|
||||
// | modification, are permitted provided that the following conditions |
|
||||
// | are met: |
|
||||
// | |
|
||||
// | o Redistributions of source code must retain the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer. |
|
||||
// | o Redistributions in binary form must reproduce the above copyright |
|
||||
// | notice, this list of conditions and the following disclaimer in the |
|
||||
// | documentation and/or other materials provided with the distribution.|
|
||||
// | o The names of the authors may not be used to endorse or promote |
|
||||
// | products derived from this software without specific prior written |
|
||||
// | permission. |
|
||||
// | |
|
||||
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
||||
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
||||
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
||||
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
||||
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
||||
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
||||
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
||||
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
||||
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
||||
// | |
|
||||
// +-----------------------------------------------------------------------+
|
||||
// | Authors: Richard Heyes <richard@phpguru.org> |
|
||||
// | Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +-----------------------------------------------------------------------+
|
||||
/**
|
||||
* RFC 822 Email address list validation Utility
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2001-2010, Richard Heyes
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* o Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* o The names of the authors may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category Mail
|
||||
* @package Mail
|
||||
* @author Richard Heyes <richard@phpguru.org>
|
||||
* @author Chuck Hagenbuch <chuck@horde.org
|
||||
* @copyright 2001-2010 Richard Heyes
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: RFC822.php 294749 2010-02-08 08:22:25Z clockwerx $
|
||||
* @link http://pear.php.net/package/Mail/
|
||||
*/
|
||||
|
||||
/**
|
||||
* RFC 822 Email address list validation Utility
|
||||
@ -52,7 +63,7 @@
|
||||
*
|
||||
* @author Richard Heyes <richard@phpguru.org>
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
* @version $Revision: 1.24 $
|
||||
* @version $Revision: 294749 $
|
||||
* @license BSD
|
||||
* @package Mail
|
||||
*/
|
||||
@ -635,8 +646,8 @@ class Mail_RFC822 {
|
||||
$comment = $this->_splitCheck($parts, ')');
|
||||
$comments[] = $comment;
|
||||
|
||||
// +1 is for the trailing )
|
||||
$_mailbox = substr($_mailbox, strpos($_mailbox, $comment)+strlen($comment)+1);
|
||||
// +2 is for the brackets
|
||||
$_mailbox = substr($_mailbox, strpos($_mailbox, '('.$comment)+strlen($comment)+2);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
63
extlib/Mail/mail.php
Normal file → Executable file
63
extlib/Mail/mail.php
Normal file → Executable file
@ -1,27 +1,52 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: mail.php,v 1.20 2007/10/06 17:00:00 chagenbu Exp $
|
||||
/**
|
||||
* internal PHP-mail() implementation of the PEAR Mail:: interface.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2010 Chuck Hagenbuch
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* o Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* o The names of the authors may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category Mail
|
||||
* @package Mail
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
* @copyright 2010 Chuck Hagenbuch
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: mail.php 294747 2010-02-08 08:18:33Z clockwerx $
|
||||
* @link http://pear.php.net/package/Mail/
|
||||
*/
|
||||
|
||||
/**
|
||||
* internal PHP-mail() implementation of the PEAR Mail:: interface.
|
||||
* @package Mail
|
||||
* @version $Revision: 1.20 $
|
||||
* @version $Revision: 294747 $
|
||||
*/
|
||||
class Mail_mail extends Mail {
|
||||
|
||||
|
64
extlib/Mail/mock.php
Normal file → Executable file
64
extlib/Mail/mock.php
Normal file → Executable file
@ -1,29 +1,53 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Chuck Hagenbuch <chuck@horde.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: mock.php,v 1.1 2007/12/08 17:57:54 chagenbu Exp $
|
||||
//
|
||||
/**
|
||||
* Mock implementation
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2010 Chuck Hagenbuch
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* o Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* o The names of the authors may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category Mail
|
||||
* @package Mail
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
* @copyright 2010 Chuck Hagenbuch
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: mock.php 294747 2010-02-08 08:18:33Z clockwerx $
|
||||
* @link http://pear.php.net/package/Mail/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Mock implementation of the PEAR Mail:: interface for testing.
|
||||
* @access public
|
||||
* @package Mail
|
||||
* @version $Revision: 1.1 $
|
||||
* @version $Revision: 294747 $
|
||||
*/
|
||||
class Mail_mock extends Mail {
|
||||
|
||||
|
64
extlib/Mail/null.php
Normal file → Executable file
64
extlib/Mail/null.php
Normal file → Executable file
@ -1,29 +1,53 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Phil Kernick <philk@rotfl.com.au> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: null.php,v 1.2 2004/04/06 05:19:03 jon Exp $
|
||||
//
|
||||
/**
|
||||
* Null implementation of the PEAR Mail interface
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2010 Phil Kernick
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* o Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* o The names of the authors may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category Mail
|
||||
* @package Mail
|
||||
* @author Phil Kernick <philk@rotfl.com.au>
|
||||
* @copyright 2010 Phil Kernick
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: null.php 294747 2010-02-08 08:18:33Z clockwerx $
|
||||
* @link http://pear.php.net/package/Mail/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Null implementation of the PEAR Mail:: interface.
|
||||
* @access public
|
||||
* @package Mail
|
||||
* @version $Revision: 1.2 $
|
||||
* @version $Revision: 294747 $
|
||||
*/
|
||||
class Mail_null extends Mail {
|
||||
|
||||
|
7
extlib/Mail/sendmail.php
Normal file → Executable file
7
extlib/Mail/sendmail.php
Normal file → Executable file
@ -20,7 +20,7 @@
|
||||
* Sendmail implementation of the PEAR Mail:: interface.
|
||||
* @access public
|
||||
* @package Mail
|
||||
* @version $Revision: 1.19 $
|
||||
* @version $Revision: 294744 $
|
||||
*/
|
||||
class Mail_sendmail extends Mail {
|
||||
|
||||
@ -117,7 +117,7 @@ class Mail_sendmail extends Mail {
|
||||
if (is_a($recipients, 'PEAR_Error')) {
|
||||
return $recipients;
|
||||
}
|
||||
$recipients = escapeShellCmd(implode(' ', $recipients));
|
||||
$recipients = implode(' ', array_map('escapeshellarg', $recipients));
|
||||
|
||||
$headerElements = $this->prepareHeaders($headers);
|
||||
if (is_a($headerElements, 'PEAR_Error')) {
|
||||
@ -141,7 +141,8 @@ class Mail_sendmail extends Mail {
|
||||
return PEAR::raiseError('From address specified with dangerous characters.');
|
||||
}
|
||||
|
||||
$from = escapeShellCmd($from);
|
||||
$from = escapeshellarg($from); // Security bug #16200
|
||||
|
||||
$mail = @popen($this->sendmail_path . (!empty($this->sendmail_args) ? ' ' . $this->sendmail_args : '') . " -f$from -- $recipients", 'w');
|
||||
if (!$mail) {
|
||||
return PEAR::raiseError('Failed to open sendmail [' . $this->sendmail_path . '] for execution.');
|
||||
|
73
extlib/Mail/smtp.php
Normal file → Executable file
73
extlib/Mail/smtp.php
Normal file → Executable file
@ -1,21 +1,48 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2003 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Chuck Hagenbuch <chuck@horde.org> |
|
||||
// | Jon Parise <jon@php.net> |
|
||||
// +----------------------------------------------------------------------+
|
||||
/**
|
||||
* SMTP implementation of the PEAR Mail interface. Requires the Net_SMTP class.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2010, Chuck Hagenbuch
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* o Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* o The names of the authors may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category HTTP
|
||||
* @package HTTP_Request
|
||||
* @author Jon Parise <jon@php.net>
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
* @copyright 2010 Chuck Hagenbuch
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: smtp.php 294747 2010-02-08 08:18:33Z clockwerx $
|
||||
* @link http://pear.php.net/package/Mail/
|
||||
*/
|
||||
|
||||
/** Error: Failed to create a Net_SMTP object */
|
||||
define('PEAR_MAIL_SMTP_ERROR_CREATE', 10000);
|
||||
@ -42,7 +69,7 @@ define('PEAR_MAIL_SMTP_ERROR_DATA', 10006);
|
||||
* SMTP implementation of the PEAR Mail interface. Requires the Net_SMTP class.
|
||||
* @access public
|
||||
* @package Mail
|
||||
* @version $Revision: 1.33 $
|
||||
* @version $Revision: 294747 $
|
||||
*/
|
||||
class Mail_smtp extends Mail {
|
||||
|
||||
@ -278,6 +305,16 @@ class Mail_smtp extends Mail {
|
||||
|
||||
/* Send the message's headers and the body as SMTP data. */
|
||||
$res = $this->_smtp->data($textHeaders . "\r\n\r\n" . $body);
|
||||
list(,$args) = $this->_smtp->getResponse();
|
||||
|
||||
if (preg_match("/Ok: queued as (.*)/", $args, $queued)) {
|
||||
$this->queued_as = $queued[1];
|
||||
}
|
||||
|
||||
/* we need the greeting; from it we can extract the authorative name of the mail server we've really connected to.
|
||||
* ideal if we're connecting to a round-robin of relay servers and need to track which exact one took the email */
|
||||
$this->greeting = $this->_smtp->getGreeting();
|
||||
|
||||
if (is_a($res, 'PEAR_Error')) {
|
||||
$error = $this->_error('Failed to send data', $res);
|
||||
$this->_smtp->rset();
|
||||
|
44
extlib/Mail/smtpmx.php
Normal file → Executable file
44
extlib/Mail/smtpmx.php
Normal file → Executable file
@ -8,19 +8,43 @@
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: This source file is subject to version 3.0 of the PHP license
|
||||
* that is available through the world-wide-web at the following URI:
|
||||
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
|
||||
* the PHP License and are unable to obtain it through the web, please
|
||||
* send a note to license@php.net so we can mail you a copy immediately.
|
||||
* LICENSE:
|
||||
*
|
||||
* Copyright (c) 2010, gERD Schaufelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* o Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* o Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* o The names of the authors may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* @category Mail
|
||||
* @package Mail_smtpmx
|
||||
* @author gERD Schaufelberger <gerd@php-tools.net>
|
||||
* @copyright 1997-2005 The PHP Group
|
||||
* @license http://www.php.net/license/3_0.txt PHP License 3.0
|
||||
* @version CVS: $Id: smtpmx.php,v 1.2 2007/10/06 17:00:00 chagenbu Exp $
|
||||
* @see Mail
|
||||
* @copyright 2010 gERD Schaufelberger
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version CVS: $Id: smtpmx.php 294747 2010-02-08 08:18:33Z clockwerx $
|
||||
* @link http://pear.php.net/package/Mail/
|
||||
*/
|
||||
|
||||
require_once 'Net/SMTP.php';
|
||||
@ -32,7 +56,7 @@ require_once 'Net/SMTP.php';
|
||||
* @access public
|
||||
* @author gERD Schaufelberger <gerd@php-tools.net>
|
||||
* @package Mail
|
||||
* @version $Revision: 1.2 $
|
||||
* @version $Revision: 294747 $
|
||||
*/
|
||||
class Mail_smtpmx extends Mail {
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
// | Damian Alejandro Fernandez Sosa <damlists@cnba.uba.ar> |
|
||||
// +----------------------------------------------------------------------+
|
||||
//
|
||||
// $Id: SMTP.php,v 1.63 2008/06/10 05:39:12 jon Exp $
|
||||
// $Id: SMTP.php 293948 2010-01-24 21:46:00Z jon $
|
||||
|
||||
require_once 'PEAR.php';
|
||||
require_once 'Net/Socket.php';
|
||||
@ -91,6 +91,13 @@ class Net_SMTP
|
||||
*/
|
||||
var $_debug = false;
|
||||
|
||||
/**
|
||||
* Debug output handler.
|
||||
* @var callback
|
||||
* @access private
|
||||
*/
|
||||
var $_debug_handler = null;
|
||||
|
||||
/**
|
||||
* The socket resource being used to connect to the SMTP server.
|
||||
* @var resource
|
||||
@ -112,6 +119,13 @@ class Net_SMTP
|
||||
*/
|
||||
var $_arguments = array();
|
||||
|
||||
/**
|
||||
* Stores the SMTP server's greeting string.
|
||||
* @var string
|
||||
* @access private
|
||||
*/
|
||||
var $_greeting = null;
|
||||
|
||||
/**
|
||||
* Stores detected features of the SMTP server.
|
||||
* @var array
|
||||
@ -172,9 +186,30 @@ class Net_SMTP
|
||||
* @access public
|
||||
* @since 1.1.0
|
||||
*/
|
||||
function setDebug($debug)
|
||||
function setDebug($debug, $handler = null)
|
||||
{
|
||||
$this->_debug = $debug;
|
||||
$this->_debug_handler = $handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the given debug text to the current debug output handler.
|
||||
*
|
||||
* @param string $message Debug mesage text.
|
||||
*
|
||||
* @access private
|
||||
* @since 1.3.3
|
||||
*/
|
||||
function _debug($message)
|
||||
{
|
||||
if ($this->_debug) {
|
||||
if ($this->_debug_handler) {
|
||||
call_user_func_array($this->_debug_handler,
|
||||
array(&$this, $message));
|
||||
} else {
|
||||
echo "DEBUG: $message\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -189,13 +224,12 @@ class Net_SMTP
|
||||
*/
|
||||
function _send($data)
|
||||
{
|
||||
if ($this->_debug) {
|
||||
echo "DEBUG: Send: $data\n";
|
||||
}
|
||||
$this->_debug("Send: $data");
|
||||
|
||||
if (PEAR::isError($error = $this->_socket->write($data))) {
|
||||
return PEAR::raiseError('Failed to write to socket: ' .
|
||||
$error->getMessage());
|
||||
$error = $this->_socket->write($data);
|
||||
if ($error === false || PEAR::isError($error)) {
|
||||
$msg = ($error) ? $error->getMessage() : "unknown error";
|
||||
return PEAR::raiseError("Failed to write to socket: $msg");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -262,9 +296,7 @@ class Net_SMTP
|
||||
|
||||
for ($i = 0; $i <= $this->_pipelined_commands; $i++) {
|
||||
while ($line = $this->_socket->readLine()) {
|
||||
if ($this->_debug) {
|
||||
echo "DEBUG: Recv: $line\n";
|
||||
}
|
||||
$this->_debug("Recv: $line");
|
||||
|
||||
/* If we receive an empty line, the connection has been closed. */
|
||||
if (empty($line)) {
|
||||
@ -319,6 +351,20 @@ class Net_SMTP
|
||||
return array($this->_code, join("\n", $this->_arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the SMTP server's greeting string.
|
||||
*
|
||||
* @return string A string containing the greeting string, or null if a
|
||||
* greeting has not been received.
|
||||
*
|
||||
* @access public
|
||||
* @since 1.3.3
|
||||
*/
|
||||
function getGreeting()
|
||||
{
|
||||
return $this->_greeting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to connect to the SMTP server.
|
||||
*
|
||||
@ -334,6 +380,7 @@ class Net_SMTP
|
||||
*/
|
||||
function connect($timeout = null, $persistent = false)
|
||||
{
|
||||
$this->_greeting = null;
|
||||
$result = $this->_socket->connect($this->host, $this->port,
|
||||
$persistent, $timeout);
|
||||
if (PEAR::isError($result)) {
|
||||
@ -344,6 +391,10 @@ class Net_SMTP
|
||||
if (PEAR::isError($error = $this->_parseResponse(220))) {
|
||||
return $error;
|
||||
}
|
||||
|
||||
/* Extract and store a copy of the server's greeting string. */
|
||||
list(, $this->_greeting) = $this->getResponse();
|
||||
|
||||
if (PEAR::isError($error = $this->_negotiate())) {
|
||||
return $error;
|
||||
}
|
||||
@ -452,19 +503,24 @@ class Net_SMTP
|
||||
* @param string The password to authenticate with.
|
||||
* @param string The requested authentication method. If none is
|
||||
* specified, the best supported method will be used.
|
||||
* @param bool Flag indicating whether or not TLS should be attempted.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
* @since 1.0
|
||||
*/
|
||||
function auth($uid, $pwd , $method = '')
|
||||
function auth($uid, $pwd , $method = '', $tls = true)
|
||||
{
|
||||
if (empty($this->_esmtp['AUTH'])) {
|
||||
if (version_compare(PHP_VERSION, '5.1.0', '>=')) {
|
||||
if (!isset($this->_esmtp['STARTTLS'])) {
|
||||
return PEAR::raiseError('SMTP server does not support authentication');
|
||||
}
|
||||
/* We can only attempt a TLS connection if one has been requested,
|
||||
* we're running PHP 5.1.0 or later, have access to the OpenSSL
|
||||
* extension, are connected to an SMTP server which supports the
|
||||
* STARTTLS extension, and aren't already connected over a secure
|
||||
* (SSL) socket connection. */
|
||||
if ($tls && version_compare(PHP_VERSION, '5.1.0', '>=') &&
|
||||
extension_loaded('openssl') && isset($this->_esmtp['STARTTLS']) &&
|
||||
strncasecmp($this->host, 'ssl://', 6) !== 0) {
|
||||
/* Start the TLS connection attempt. */
|
||||
if (PEAR::isError($result = $this->_put('STARTTLS'))) {
|
||||
return $result;
|
||||
}
|
||||
@ -480,13 +536,11 @@ class Net_SMTP
|
||||
/* Send EHLO again to recieve the AUTH string from the
|
||||
* SMTP server. */
|
||||
$this->_negotiate();
|
||||
}
|
||||
|
||||
if (empty($this->_esmtp['AUTH'])) {
|
||||
return PEAR::raiseError('SMTP server does not support authentication');
|
||||
}
|
||||
} else {
|
||||
return PEAR::raiseError('SMTP server does not support authentication');
|
||||
}
|
||||
}
|
||||
|
||||
/* If no method has been specified, get the name of the best
|
||||
* supported method advertised by the SMTP server. */
|
||||
@ -844,30 +898,51 @@ class Net_SMTP
|
||||
/**
|
||||
* Send the DATA command.
|
||||
*
|
||||
* @param string $data The message body to send.
|
||||
* @param mixed $data The message data, either as a string or an open
|
||||
* file resource.
|
||||
* @param string $headers The message headers. If $headers is provided,
|
||||
* $data is assumed to contain only body data.
|
||||
*
|
||||
* @return mixed Returns a PEAR_Error with an error message on any
|
||||
* kind of failure, or true on success.
|
||||
* @access public
|
||||
* @since 1.0
|
||||
*/
|
||||
function data($data)
|
||||
function data($data, $headers = null)
|
||||
{
|
||||
/* Verify that $data is a supported type. */
|
||||
if (!is_string($data) && !is_resource($data)) {
|
||||
return PEAR::raiseError('Expected a string or file resource');
|
||||
}
|
||||
|
||||
/* RFC 1870, section 3, subsection 3 states "a value of zero
|
||||
* indicates that no fixed maximum message size is in force".
|
||||
* Furthermore, it says that if "the parameter is omitted no
|
||||
* information is conveyed about the server's fixed maximum
|
||||
* message size". */
|
||||
if (isset($this->_esmtp['SIZE']) && ($this->_esmtp['SIZE'] > 0)) {
|
||||
if (strlen($data) >= $this->_esmtp['SIZE']) {
|
||||
/* Start by considering the size of the optional headers string.
|
||||
* We also account for the addition 4 character "\r\n\r\n"
|
||||
* separator sequence. */
|
||||
$size = (is_null($headers)) ? 0 : strlen($headers) + 4;
|
||||
|
||||
if (is_resource($data)) {
|
||||
$stat = fstat($data);
|
||||
if ($stat === false) {
|
||||
return PEAR::raiseError('Failed to get file size');
|
||||
}
|
||||
$size += $stat['size'];
|
||||
} else {
|
||||
$size += strlen($data);
|
||||
}
|
||||
|
||||
if ($size >= $this->_esmtp['SIZE']) {
|
||||
$this->disconnect();
|
||||
return PEAR::raiseError('Message size excedes the server limit');
|
||||
return PEAR::raiseError('Message size exceeds server limit');
|
||||
}
|
||||
}
|
||||
|
||||
/* Quote the data based on the SMTP standards. */
|
||||
$this->quotedata($data);
|
||||
|
||||
/* Initiate the DATA command. */
|
||||
if (PEAR::isError($error = $this->_put('DATA'))) {
|
||||
return $error;
|
||||
}
|
||||
@ -875,9 +950,40 @@ class Net_SMTP
|
||||
return $error;
|
||||
}
|
||||
|
||||
/* If we have a separate headers string, send it first. */
|
||||
if (!is_null($headers)) {
|
||||
$this->quotedata($headers);
|
||||
if (PEAR::isError($result = $this->_send($headers . "\r\n\r\n"))) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we can send the message body data. */
|
||||
if (is_resource($data)) {
|
||||
/* Stream the contents of the file resource out over our socket
|
||||
* connection, line by line. Each line must be run through the
|
||||
* quoting routine. */
|
||||
while ($line = fgets($data, 1024)) {
|
||||
$this->quotedata($line);
|
||||
if (PEAR::isError($result = $this->_send($line))) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, send the DATA terminator sequence. */
|
||||
if (PEAR::isError($result = $this->_send("\r\n.\r\n"))) {
|
||||
return $result;
|
||||
}
|
||||
} else {
|
||||
/* Just send the entire quoted string followed by the DATA
|
||||
* terminator. */
|
||||
$this->quotedata($data);
|
||||
if (PEAR::isError($result = $this->_send($data . "\r\n.\r\n"))) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/* Verify that the data was successfully received by the server. */
|
||||
if (PEAR::isError($error = $this->_parseResponse(250, $this->pipelining))) {
|
||||
return $error;
|
||||
}
|
||||
|
@ -19,16 +19,20 @@
|
||||
* @category StatusNet
|
||||
* @package StatusNet
|
||||
* @author Brenda Wallace <shiny@cpan.org>
|
||||
* @author Brion Vibber <brion@pobox.com>
|
||||
* @author Christopher Vollick <psycotica0@gmail.com>
|
||||
* @author CiaranG <ciaran@ciarang.com>
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @author Evan Prodromou <evan@controlezvous.ca>
|
||||
* @author Gina Haeussge <osd@foosel.net>
|
||||
* @author James Walker <walkah@walkah.net>
|
||||
* @author Jeffery To <jeffery.to@gmail.com>
|
||||
* @author Mike Cochrane <mikec@mikenz.geek.nz>
|
||||
* @author Robin Millette <millette@controlyourself.ca>
|
||||
* @author Sarven Capadisli <csarven@controlyourself.ca>
|
||||
* @author Tom Adams <tom@holizz.com>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
*
|
||||
* @license GNU Affero General Public License http://www.gnu.org/licenses/
|
||||
*/
|
||||
@ -200,7 +204,7 @@ function checkMirror($action_obj, $args)
|
||||
|
||||
function isLoginAction($action)
|
||||
{
|
||||
static $loginActions = array('login', 'recoverpassword', 'api', 'doc', 'register', 'publicxrds', 'otp', 'opensearch');
|
||||
static $loginActions = array('login', 'recoverpassword', 'api', 'doc', 'register', 'publicxrds', 'otp', 'opensearch', 'rsd');
|
||||
|
||||
$login = null;
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
* @author Sarven Capadisli <csarven@status.net>
|
||||
* @author Tom Adams <tom@holizz.com>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license GNU Affero General Public License http://www.gnu.org/licenses/
|
||||
* @version 0.9.x
|
||||
* @link http://status.net
|
||||
|
@ -84,7 +84,7 @@ var SN = { // StatusNet
|
||||
form.find('#'+SN.C.S.NoticeTextCount).text(jQuery.data(form[0], 'ElementData').MaxLength);
|
||||
}
|
||||
|
||||
if ($('body')[0].id != 'conversation' && window.location.hash.length === 0) {
|
||||
if ($('body')[0].id != 'conversation' && window.location.hash.length === 0 && $(window).scrollTop() == 0) {
|
||||
form.find('textarea').focus();
|
||||
}
|
||||
},
|
||||
|
@ -235,6 +235,16 @@ class Action extends HTMLOutputter // lawsuit
|
||||
Event::handle('EndShowDesign', array($this));
|
||||
}
|
||||
Event::handle('EndShowStyles', array($this));
|
||||
|
||||
if (common_config('custom_css', 'enabled')) {
|
||||
$css = common_config('custom_css', 'css');
|
||||
if (Event::handle('StartShowCustomCss', array($this, &$css))) {
|
||||
if (trim($css) != '') {
|
||||
$this->style($css);
|
||||
}
|
||||
Event::handle('EndShowCustomCss', array($this));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -467,7 +477,7 @@ class Action extends HTMLOutputter // lawsuit
|
||||
_m('MENU', 'Logout'), $tooltip, false, 'nav_logout');
|
||||
}
|
||||
else {
|
||||
if (!common_config('site', 'closed')) {
|
||||
if (!common_config('site', 'closed') && !common_config('site', 'inviteonly')) {
|
||||
// TRANS: Tooltip for main menu option "Register"
|
||||
$tooltip = _m('TOOLTIP', 'Create an account');
|
||||
$this->menuItem(common_local_url('register'),
|
||||
|
@ -83,6 +83,7 @@ class Activity
|
||||
const CREATOR = 'creator';
|
||||
|
||||
const CONTENTNS = 'http://purl.org/rss/1.0/modules/content/';
|
||||
const ENCODED = 'encoded';
|
||||
|
||||
public $actor; // an ActivityObject
|
||||
public $verb; // a string (the URL)
|
||||
@ -269,14 +270,21 @@ class Activity
|
||||
|
||||
$this->title = ActivityUtils::childContent($item, ActivityObject::TITLE, self::RSS);
|
||||
|
||||
$contentEl = ActivityUtils::child($item, ActivityUtils::CONTENT, self::CONTENTNS);
|
||||
$contentEl = ActivityUtils::child($item, self::ENCODED, self::CONTENTNS);
|
||||
|
||||
if (!empty($contentEl)) {
|
||||
$this->content = htmlspecialchars_decode($contentEl->textContent, ENT_QUOTES);
|
||||
// <content:encoded> XML node's text content is HTML; no further processing needed.
|
||||
$this->content = $contentEl->textContent;
|
||||
} else {
|
||||
$descriptionEl = ActivityUtils::child($item, self::DESCRIPTION, self::RSS);
|
||||
if (!empty($descriptionEl)) {
|
||||
$this->content = htmlspecialchars_decode($descriptionEl->textContent, ENT_QUOTES);
|
||||
// Per spec, <description> must be plaintext.
|
||||
// In practice, often there's HTML... but these days good
|
||||
// feeds are using <content:encoded> which is explicitly
|
||||
// real HTML.
|
||||
// We'll treat this following spec, and do HTML escaping
|
||||
// to convert from plaintext to HTML.
|
||||
$this->content = htmlspecialchars($descriptionEl->textContent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,11 +213,19 @@ class ActivityUtils
|
||||
// slavishly following http://atompub.org/rfc4287.html#rfc.section.4.1.3.3
|
||||
|
||||
if (empty($type) || $type == 'text') {
|
||||
return $el->textContent;
|
||||
// We have plaintext saved as the XML text content.
|
||||
// Since we want HTML, we need to escape any special chars.
|
||||
return htmlspecialchars($el->textContent);
|
||||
} else if ($type == 'html') {
|
||||
// We have HTML saved as the XML text content.
|
||||
// No additional processing required once we've got it.
|
||||
$text = $el->textContent;
|
||||
return htmlspecialchars_decode($text, ENT_QUOTES);
|
||||
return $text;
|
||||
} else if ($type == 'xhtml') {
|
||||
// Per spec, the <content type="xhtml"> contains a single
|
||||
// HTML <div> with XHTML namespace on it as a child node.
|
||||
// We need to pull all of that <div>'s child nodes and
|
||||
// serialize them back to an (X)HTML source fragment.
|
||||
$divEl = ActivityUtils::child($el, 'div', 'http://www.w3.org/1999/xhtml');
|
||||
if (empty($divEl)) {
|
||||
return null;
|
||||
|
@ -284,9 +284,10 @@ class AdminPanelAction extends Action
|
||||
$this->clientError(_("Unable to delete design setting."));
|
||||
return null;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $result;
|
||||
return null;
|
||||
}
|
||||
|
||||
function canAdmin($name)
|
||||
|
@ -28,14 +28,78 @@
|
||||
* @author Toby Inkster <mail@tobyinkster.co.uk>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
/* External API usage documentation. Please update when you change how the API works. */
|
||||
|
||||
/*! @mainpage StatusNet REST API
|
||||
|
||||
@section Introduction
|
||||
|
||||
Some explanatory text about the API would be nice.
|
||||
|
||||
@section API Methods
|
||||
|
||||
@subsection timelinesmethods_sec Timeline Methods
|
||||
|
||||
@li @ref publictimeline
|
||||
@li @ref friendstimeline
|
||||
|
||||
@subsection statusmethods_sec Status Methods
|
||||
|
||||
@li @ref statusesupdate
|
||||
|
||||
@subsection usermethods_sec User Methods
|
||||
|
||||
@subsection directmessagemethods_sec Direct Message Methods
|
||||
|
||||
@subsection friendshipmethods_sec Friendship Methods
|
||||
|
||||
@subsection socialgraphmethods_sec Social Graph Methods
|
||||
|
||||
@subsection accountmethods_sec Account Methods
|
||||
|
||||
@subsection favoritesmethods_sec Favorites Methods
|
||||
|
||||
@subsection blockmethods_sec Block Methods
|
||||
|
||||
@subsection oauthmethods_sec OAuth Methods
|
||||
|
||||
@subsection helpmethods_sec Help Methods
|
||||
|
||||
@subsection groupmethods_sec Group Methods
|
||||
|
||||
@page apiroot API Root
|
||||
|
||||
The URLs for methods referred to in this API documentation are
|
||||
relative to the StatusNet API root. The API root is determined by the
|
||||
site's @b server and @b path variables, which are generally specified
|
||||
in config.php. For example:
|
||||
|
||||
@code
|
||||
$config['site']['server'] = 'example.org';
|
||||
$config['site']['path'] = 'statusnet'
|
||||
@endcode
|
||||
|
||||
The pattern for a site's API root is: @c protocol://server/path/api E.g:
|
||||
|
||||
@c http://example.org/statusnet/api
|
||||
|
||||
The @b path can be empty. In that case the API root would simply be:
|
||||
|
||||
@c http://example.org/api
|
||||
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
class ApiValidationException extends Exception { }
|
||||
|
||||
/**
|
||||
* Contains most of the Twitter-compatible API output functions.
|
||||
*
|
||||
@ -63,9 +127,12 @@ class ApiAction extends Action
|
||||
var $count = null;
|
||||
var $max_id = null;
|
||||
var $since_id = null;
|
||||
var $source = null;
|
||||
|
||||
var $access = self::READ_ONLY; // read (default) or read-write
|
||||
|
||||
static $reserved_sources = array('web', 'omb', 'ostatus', 'mail', 'xmpp', 'api');
|
||||
|
||||
/**
|
||||
* Initialization.
|
||||
*
|
||||
@ -89,6 +156,12 @@ class ApiAction extends Action
|
||||
header('X-StatusNet-Warning: since parameter is disabled; use since_id');
|
||||
}
|
||||
|
||||
$this->source = $this->trimmed('source');
|
||||
|
||||
if (empty($this->source) || in_array($this->source, self::$reserved_sources)) {
|
||||
$this->source = 'api';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -200,11 +273,13 @@ class ApiAction extends Action
|
||||
|
||||
// Is the requesting user following this user?
|
||||
$twitter_user['following'] = false;
|
||||
$twitter_user['statusnet:blocking'] = false;
|
||||
$twitter_user['notifications'] = false;
|
||||
|
||||
if (isset($this->auth_user)) {
|
||||
|
||||
$twitter_user['following'] = $this->auth_user->isSubscribed($profile);
|
||||
$twitter_user['statusnet:blocking'] = $this->auth_user->hasBlocked($profile);
|
||||
|
||||
// Notifications on?
|
||||
$sub = Subscription::pkeyGet(array('subscriber' =>
|
||||
@ -224,6 +299,10 @@ class ApiAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
// StatusNet-specific
|
||||
|
||||
$twitter_user['statusnet:profile_url'] = $profile->profileurl;
|
||||
|
||||
return $twitter_user;
|
||||
}
|
||||
|
||||
@ -252,7 +331,23 @@ class ApiAction extends Action
|
||||
$twitter_status['created_at'] = $this->dateTwitter($notice->created);
|
||||
$twitter_status['in_reply_to_status_id'] = ($notice->reply_to) ?
|
||||
intval($notice->reply_to) : null;
|
||||
$twitter_status['source'] = $this->sourceLink($notice->source);
|
||||
|
||||
$source = null;
|
||||
|
||||
$ns = $notice->getSource();
|
||||
if ($ns) {
|
||||
if (!empty($ns->name) && !empty($ns->url)) {
|
||||
$source = '<a href="'
|
||||
. htmlspecialchars($ns->url)
|
||||
. '" rel="nofollow">'
|
||||
. htmlspecialchars($ns->name)
|
||||
. '</a>';
|
||||
} else {
|
||||
$source = $ns->code;
|
||||
}
|
||||
}
|
||||
|
||||
$twitter_status['source'] = $source;
|
||||
$twitter_status['id'] = intval($notice->id);
|
||||
|
||||
$replier_profile = null;
|
||||
@ -309,16 +404,31 @@ class ApiAction extends Action
|
||||
$twitter_status['user'] = $twitter_user;
|
||||
}
|
||||
|
||||
// StatusNet-specific
|
||||
|
||||
$twitter_status['statusnet:html'] = $notice->rendered;
|
||||
|
||||
return $twitter_status;
|
||||
}
|
||||
|
||||
function twitterGroupArray($group)
|
||||
{
|
||||
$twitter_group = array();
|
||||
|
||||
$twitter_group['id'] = $group->id;
|
||||
$twitter_group['url'] = $group->permalink();
|
||||
$twitter_group['nickname'] = $group->nickname;
|
||||
$twitter_group['fullname'] = $group->fullname;
|
||||
|
||||
if (isset($this->auth_user)) {
|
||||
$twitter_group['member'] = $this->auth_user->isMember($group);
|
||||
$twitter_group['blocked'] = Group_block::isBlocked(
|
||||
$group,
|
||||
$this->auth_user->getProfile()
|
||||
);
|
||||
}
|
||||
|
||||
$twitter_group['member_count'] = $group->getMemberCount();
|
||||
$twitter_group['original_logo'] = $group->original_logo;
|
||||
$twitter_group['homepage_logo'] = $group->homepage_logo;
|
||||
$twitter_group['stream_logo'] = $group->stream_logo;
|
||||
@ -328,6 +438,7 @@ class ApiAction extends Action
|
||||
$twitter_group['location'] = $group->location;
|
||||
$twitter_group['created'] = $this->dateTwitter($group->created);
|
||||
$twitter_group['modified'] = $this->dateTwitter($group->modified);
|
||||
|
||||
return $twitter_group;
|
||||
}
|
||||
|
||||
@ -476,9 +587,13 @@ class ApiAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function showTwitterXmlStatus($twitter_status, $tag='status')
|
||||
function showTwitterXmlStatus($twitter_status, $tag='status', $namespaces=false)
|
||||
{
|
||||
$this->elementStart($tag);
|
||||
$attrs = array();
|
||||
if ($namespaces) {
|
||||
$attrs['xmlns:statusnet'] = 'http://status.net/schema/api/1/';
|
||||
}
|
||||
$this->elementStart($tag, $attrs);
|
||||
foreach($twitter_status as $element => $value) {
|
||||
switch ($element) {
|
||||
case 'user':
|
||||
@ -512,9 +627,13 @@ class ApiAction extends Action
|
||||
$this->elementEnd('group');
|
||||
}
|
||||
|
||||
function showTwitterXmlUser($twitter_user, $role='user')
|
||||
function showTwitterXmlUser($twitter_user, $role='user', $namespaces=false)
|
||||
{
|
||||
$this->elementStart($role);
|
||||
$attrs = array();
|
||||
if ($namespaces) {
|
||||
$attrs['xmlns:statusnet'] = 'http://status.net/schema/api/1/';
|
||||
}
|
||||
$this->elementStart($role, $attrs);
|
||||
foreach($twitter_user as $element => $value) {
|
||||
if ($element == 'status') {
|
||||
$this->showTwitterXmlStatus($twitter_user['status']);
|
||||
@ -596,7 +715,7 @@ class ApiAction extends Action
|
||||
{
|
||||
$this->initDocument('xml');
|
||||
$twitter_status = $this->twitterStatusArray($notice);
|
||||
$this->showTwitterXmlStatus($twitter_status);
|
||||
$this->showTwitterXmlStatus($twitter_status, 'status', true);
|
||||
$this->endDocument('xml');
|
||||
}
|
||||
|
||||
@ -612,7 +731,8 @@ class ApiAction extends Action
|
||||
{
|
||||
|
||||
$this->initDocument('xml');
|
||||
$this->elementStart('statuses', array('type' => 'array'));
|
||||
$this->elementStart('statuses', array('type' => 'array',
|
||||
'xmlns:statusnet' => 'http://status.net/schema/api/1/'));
|
||||
|
||||
if (is_array($notice)) {
|
||||
foreach ($notice as $n) {
|
||||
@ -779,9 +899,13 @@ class ApiAction extends Action
|
||||
$this->elementEnd('entry');
|
||||
}
|
||||
|
||||
function showXmlDirectMessage($dm)
|
||||
function showXmlDirectMessage($dm, $namespaces=false)
|
||||
{
|
||||
$this->elementStart('direct_message');
|
||||
$attrs = array();
|
||||
if ($namespaces) {
|
||||
$attrs['xmlns:statusnet'] = 'http://status.net/schema/api/1/';
|
||||
}
|
||||
$this->elementStart('direct_message', $attrs);
|
||||
foreach($dm as $element => $value) {
|
||||
switch ($element) {
|
||||
case 'sender':
|
||||
@ -858,7 +982,7 @@ class ApiAction extends Action
|
||||
{
|
||||
$this->initDocument('xml');
|
||||
$dmsg = $this->directMessageArray($message);
|
||||
$this->showXmlDirectMessage($dmsg);
|
||||
$this->showXmlDirectMessage($dmsg, true);
|
||||
$this->endDocument('xml');
|
||||
}
|
||||
|
||||
@ -975,7 +1099,8 @@ class ApiAction extends Action
|
||||
{
|
||||
|
||||
$this->initDocument('xml');
|
||||
$this->elementStart('users', array('type' => 'array'));
|
||||
$this->elementStart('users', array('type' => 'array',
|
||||
'xmlns:statusnet' => 'http://status.net/schema/api/1/'));
|
||||
|
||||
if (is_array($user)) {
|
||||
foreach ($user as $u) {
|
||||
@ -1293,43 +1418,6 @@ class ApiAction extends Action
|
||||
}
|
||||
}
|
||||
|
||||
function sourceLink($source)
|
||||
{
|
||||
$source_name = _($source);
|
||||
switch ($source) {
|
||||
case 'web':
|
||||
case 'xmpp':
|
||||
case 'mail':
|
||||
case 'omb':
|
||||
case 'api':
|
||||
break;
|
||||
default:
|
||||
|
||||
$name = null;
|
||||
$url = null;
|
||||
|
||||
$ns = Notice_source::staticGet($source);
|
||||
|
||||
if ($ns) {
|
||||
$name = $ns->name;
|
||||
$url = $ns->url;
|
||||
} else {
|
||||
$app = Oauth_application::staticGet('name', $source);
|
||||
if ($app) {
|
||||
$name = $app->name;
|
||||
$url = $app->source_url;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($name) && !empty($url)) {
|
||||
$source_name = '<a href="' . $url . '">' . $name . '</a>';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return $source_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns query argument or default value if not found. Certain
|
||||
* parameters used throughout the API are lightly scrubbed and
|
||||
|
@ -30,10 +30,29 @@
|
||||
* @author Sarven Capadisli <csarven@status.net>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009-2010 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
||||
/* External API usage documentation. Please update when you change how this method works. */
|
||||
|
||||
/*! @page authentication Authentication
|
||||
|
||||
StatusNet supports HTTP Basic Authentication and OAuth for API calls.
|
||||
|
||||
@warning Currently, users who have created accounts without setting a
|
||||
password via OpenID, Facebook Connect, etc., cannot use the API until
|
||||
they set a password with their account settings panel.
|
||||
|
||||
@section HTTP Basic Auth
|
||||
|
||||
|
||||
|
||||
@section OAuth
|
||||
|
||||
*/
|
||||
|
||||
if (!defined('STATUSNET')) {
|
||||
exit(1);
|
||||
}
|
||||
@ -54,7 +73,6 @@ class ApiAuthAction extends ApiAction
|
||||
{
|
||||
var $auth_user_nickname = null;
|
||||
var $auth_user_password = null;
|
||||
var $oauth_source = null;
|
||||
|
||||
/**
|
||||
* Take arguments for running, looks for an OAuth request,
|
||||
@ -163,7 +181,7 @@ class ApiAuthAction extends ApiAction
|
||||
|
||||
// set the source attr
|
||||
|
||||
$this->oauth_source = $app->name;
|
||||
$this->source = $app->name;
|
||||
|
||||
$appUser = Oauth_application_user::staticGet('token', $access_token);
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
* @author Sarven Capadisli <csarven@status.net>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -31,6 +31,7 @@
|
||||
* @author Sarven Capadisli <csarven@status.net>
|
||||
* @author Zach Copley <zach@status.net>
|
||||
* @copyright 2009 StatusNet, Inc.
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -50,12 +50,13 @@ class AtomGroupNoticeFeed extends AtomNoticeFeed
|
||||
* Constructor
|
||||
*
|
||||
* @param Group $group the group for the feed
|
||||
* @param User $cur the current authenticated user, if any
|
||||
* @param boolean $indent flag to turn indenting on or off
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function __construct($group, $indent = true) {
|
||||
parent::__construct($indent);
|
||||
function __construct($group, $cur = null, $indent = true) {
|
||||
parent::__construct($cur, $indent);
|
||||
$this->group = $group;
|
||||
|
||||
// TRANS: Title in atom group notice feed. %s is a group name.
|
||||
@ -95,4 +96,23 @@ class AtomGroupNoticeFeed extends AtomNoticeFeed
|
||||
return $this->group;
|
||||
}
|
||||
|
||||
function initFeed()
|
||||
{
|
||||
parent::initFeed();
|
||||
|
||||
$attrs = array();
|
||||
|
||||
if (!empty($this->cur)) {
|
||||
$attrs['member'] = $this->cur->isMember($this->group)
|
||||
? 'true' : 'false';
|
||||
$attrs['blocked'] = Group_block::isBlocked(
|
||||
$this->group,
|
||||
$this->cur->getProfile()
|
||||
) ? 'true' : 'false';
|
||||
}
|
||||
|
||||
$attrs['member_count'] = $this->group->getMemberCount();
|
||||
|
||||
$this->element('statusnet:group_info', $attrs, null);
|
||||
}
|
||||
}
|
||||
|
@ -44,9 +44,22 @@ if (!defined('STATUSNET'))
|
||||
*/
|
||||
class AtomNoticeFeed extends Atom10Feed
|
||||
{
|
||||
function __construct($indent = true) {
|
||||
var $cur;
|
||||
|
||||
/**
|
||||
* Constructor - adds a bunch of XML namespaces we need in our
|
||||
* notice-specific Atom feeds, and allows setting the current
|
||||
* authenticated user (useful for API methods).
|
||||
*
|
||||
* @param User $cur the current authenticated user (optional)
|
||||
* @param boolean $indent Whether to indent XML output
|
||||
*
|
||||
*/
|
||||
function __construct($cur = null, $indent = true) {
|
||||
parent::__construct($indent);
|
||||
|
||||
$this->cur = $cur;
|
||||
|
||||
// Feeds containing notice info use these namespaces
|
||||
|
||||
$this->addNamespace(
|
||||
@ -79,6 +92,11 @@ class AtomNoticeFeed extends Atom10Feed
|
||||
'ostatus',
|
||||
'http://ostatus.org/schema/1.0'
|
||||
);
|
||||
|
||||
$this->addNamespace(
|
||||
'statusnet',
|
||||
'http://status.net/schema/api/1/'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -110,7 +128,9 @@ class AtomNoticeFeed extends Atom10Feed
|
||||
$source = $this->showSource();
|
||||
$author = $this->showAuthor();
|
||||
|
||||
$this->addEntryRaw($notice->asAtomEntry(false, $source, $author));
|
||||
$cur = empty($this->cur) ? common_current_user() : $this->cur;
|
||||
|
||||
$this->addEntryRaw($notice->asAtomEntry(false, $source, $author, $cur));
|
||||
}
|
||||
|
||||
function showSource()
|
||||
|
@ -50,13 +50,14 @@ class AtomUserNoticeFeed extends AtomNoticeFeed
|
||||
* Constructor
|
||||
*
|
||||
* @param User $user the user for the feed
|
||||
* @param User $cur the current authenticated user, if any
|
||||
* @param boolean $indent flag to turn indenting on or off
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
||||
function __construct($user, $indent = true) {
|
||||
parent::__construct($indent);
|
||||
function __construct($user, $cur = null, $indent = true) {
|
||||
parent::__construct($cur, $indent);
|
||||
$this->user = $user;
|
||||
if (!empty($user)) {
|
||||
$profile = $user->getProfile();
|
||||
|
@ -22,6 +22,7 @@
|
||||
* @category Plugin
|
||||
* @package StatusNet
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -22,6 +22,7 @@
|
||||
* @category Plugin
|
||||
* @package StatusNet
|
||||
* @author Craig Andrews <candrews@integralblue.com>
|
||||
* @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
|
||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||
* @link http://status.net/
|
||||
*/
|
||||
|
@ -76,8 +76,8 @@ class AvatarLink
|
||||
$alink = new AvatarLink();
|
||||
$alink->url = $filename;
|
||||
$alink->height = $size;
|
||||
if (!empty($filename)) {
|
||||
$alink->width = $size;
|
||||
if (!empty($filename)) {
|
||||
$alink->type = self::mediatype($filename);
|
||||
} else {
|
||||
$alink->url = User_group::defaultLogo($size);
|
||||
|
@ -22,10 +22,10 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
||||
//exit with 200 response, if this is checking fancy from the installer
|
||||
if (isset($_REQUEST['p']) && $_REQUEST['p'] == 'check-fancy') { exit; }
|
||||
|
||||
define('STATUSNET_VERSION', '0.9.1');
|
||||
define('STATUSNET_VERSION', '0.9.2');
|
||||
define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility
|
||||
|
||||
define('STATUSNET_CODENAME', 'Everybody Hurts');
|
||||
define('STATUSNET_CODENAME', 'King of Birds');
|
||||
|
||||
define('AVATAR_PROFILE_SIZE', 96);
|
||||
define('AVATAR_STREAM_SIZE', 48);
|
||||
@ -132,6 +132,12 @@ require_once INSTALLDIR.'/lib/serverexception.php';
|
||||
//set PEAR error handling to use regular PHP exceptions
|
||||
function PEAR_ErrorToPEAR_Exception($err)
|
||||
{
|
||||
//DB_DataObject throws error when an empty set would be returned
|
||||
//That behavior is weird, and not how the rest of StatusNet works.
|
||||
//So just ignore those errors.
|
||||
if ($err->getCode() == DB_DATAOBJECT_ERROR_NODATA) {
|
||||
return;
|
||||
}
|
||||
if ($err->getCode()) {
|
||||
throw new PEAR_Exception($err->getMessage(), $err->getCode());
|
||||
}
|
||||
|
@ -105,7 +105,9 @@ class ConnectSettingsNav extends Widget
|
||||
|
||||
# action => array('prompt', 'title')
|
||||
$menu = array();
|
||||
if (common_config('xmpp', 'enabled')) {
|
||||
$transports = array();
|
||||
Event::handle('GetImTransports', array(&$transports));
|
||||
if ($transports) {
|
||||
$menu['imsettings'] =
|
||||
array(_('IM'),
|
||||
_('Updates by instant messenger (IM)'));
|
||||
|
@ -135,9 +135,7 @@ class DBQueueManager extends QueueManager
|
||||
if (empty($qi->claimed)) {
|
||||
$this->_log(LOG_WARNING, "[$queue:item $qi->id] Ignoring failure for unclaimed queue item");
|
||||
} else {
|
||||
$orig = clone($qi);
|
||||
$qi->claimed = null;
|
||||
$qi->update($orig);
|
||||
$qi->releaseClaim();
|
||||
}
|
||||
|
||||
$this->stats('error', $queue);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user