Merge remote-tracking branch 'mainline/1.0.x' into people_tags_rebase

Conflicts:
	js/util.min.js
	lib/default.php
This commit is contained in:
Shashi Gowda 2011-04-07 23:13:45 +05:30
commit ad86eb78d3
102 changed files with 1382 additions and 496 deletions

View File

@ -1289,3 +1289,11 @@ StartNoticeWhoGets: Called at start of inbox delivery prep; plugins can schedule
EndNoticeWhoGets: Called at end of inbox delivery prep; plugins can filter out profiles from receiving inbox delivery here. Be aware that output can be cached or used several times, so should remain idempotent.
- $notice Notice
- &$ni: in/out array mapping profile IDs to constants: NOTICE_INBOX_SOURCE_SUB etc
StartDefaultLocalNav: When showing the default local nav
- $menu: the menu
- $user: current user
EndDefaultLocalNav: When showing the default local nav
- $menu: the menu
- $user: current user

16
README
View File

@ -1393,12 +1393,22 @@ desclimit: maximum number of characters to allow in group descriptions.
null (default) means to use the site-wide text limits. 0
means no limit.
oohembed
oembed
--------
oEmbed endpoint for multimedia attachments (links in posts).
oEmbed endpoint for multimedia attachments (links in posts). Will also
work as 'oohembed' for backwards compatibility.
endpoint: oohembed endpoint using http://oohembed.com/ software.
endpoint: oohembed endpoint using http://oohembed.com/ software. Defaults to
'http://oohembed.com/oohembed/'.
order: Array of methods to check for OEmbed data. Methods include 'built-in'
(use a built-in function to simulate oEmbed for some sites),
'well-known' (use well-known public oEmbed endpoints),
'discovery' (discover using <link> headers in HTML), 'service' (use
a third-party service, like oohembed or embed.ly. Default is
array('built-in', 'well-known', 'service', 'discovery'). Note that very
few sites implement oEmbed; 'discovery' is going to fail 99% of the
time.
search
------

View File

@ -89,7 +89,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
$taguribase = TagURI::base();
$id = "tag:$taguribase:Groups";
$link = common_local_url('groups');
// TRANS: Message is used as a subtitle when listing the lastest 20 groups. %s is a site name.
// TRANS: Message is used as a subtitle when listing the latest 20 groups. %s is a site name.
$subtitle = sprintf(_("groups on %s"), $sitename);
switch($this->format) {

View File

@ -85,11 +85,8 @@ class PublicAction extends Action
common_set_returnto($this->selfUrl());
$stream = new PublicNoticeStream(PublicNoticeStream::THREADED);
$this->notice = $stream->getNotices(($this->page-1)*NOTICES_PER_PAGE,
NOTICES_PER_PAGE + 1,
0,
0);
$this->notice = Notice::publicStream(($this->page-1)*NOTICES_PER_PAGE,
NOTICES_PER_PAGE + 1);
if (!$this->notice) {
// TRANS: Server error displayed when a public timeline cannot be retrieved.

View File

@ -74,4 +74,23 @@ class Conversation extends Memcached_DataObject
return $conv;
}
static function noticeCount($id)
{
$keypart = sprintf('conversation:notice_count:%d', $id);
$cnt = self::cacheGet($keypart);
if ($cnt !== false) {
return $cnt;
}
$notice = new Notice();
$notice->conversation = $id;
$cnt = $notice->count();
self::cacheSet($keypart, $cnt);
return $cnt;
}
}

View File

@ -23,8 +23,6 @@ require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
require_once INSTALLDIR.'/classes/File.php';
require_once INSTALLDIR.'/classes/File_oembed.php';
define('USER_AGENT', 'StatusNet user agent / file probe');
/**
* Table Definition for file_redirection
*/

View File

@ -35,7 +35,7 @@ class Group_block extends Memcached_DataObject
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */
function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('Group_block',$k,$v); }
function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Group_block',$k,$v); }
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE

View File

@ -35,7 +35,7 @@ class Login_token extends Memcached_DataObject
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */
function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('Login_token',$k,$v); }
function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Login_token',$k,$v); }
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE

View File

@ -573,6 +573,7 @@ class Notice extends Memcached_DataObject
// was not the root of the conversation. What to do now?
self::blow('notice:conversation_ids:%d', $this->conversation);
self::blow('conversation::notice_count:%d', $this->conversation);
if (!empty($this->repeat_of)) {
self::blow('notice:repeats:%d', $this->repeat_of);
@ -724,18 +725,34 @@ class Notice extends Memcached_DataObject
}
function attachments() {
// XXX: cache this
$att = array();
$f2p = new File_to_post;
$f2p->post_id = $this->id;
if ($f2p->find()) {
while ($f2p->fetch()) {
$f = File::staticGet($f2p->file_id);
if ($f) {
$att[] = clone($f);
$keypart = sprintf('notice:file_ids:%d', $this->id);
$idstr = self::cacheGet($keypart);
if ($idstr !== false) {
$ids = explode(',', $idstr);
} else {
$ids = array();
$f2p = new File_to_post;
$f2p->post_id = $this->id;
if ($f2p->find()) {
while ($f2p->fetch()) {
$ids[] = $f2p->file_id;
}
}
self::cacheSet($keypart, implode(',', $ids));
}
$att = array();
foreach ($ids as $id) {
$f = File::staticGet('id', $id);
if (!empty($f)) {
$att[] = clone($f);
}
}
return $att;
}
@ -1307,23 +1324,28 @@ class Notice extends Memcached_DataObject
*/
function getReplies()
{
// XXX: cache me
$keypart = sprintf('notice:reply_ids:%d', $this->id);
$ids = array();
$idstr = self::cacheGet($keypart);
$reply = new Reply();
$reply->selectAdd();
$reply->selectAdd('profile_id');
$reply->notice_id = $this->id;
if ($idstr !== false) {
$ids = explode(',', $idstr);
} else {
$ids = array();
if ($reply->find()) {
while($reply->fetch()) {
$ids[] = $reply->profile_id;
$reply = new Reply();
$reply->selectAdd();
$reply->selectAdd('profile_id');
$reply->notice_id = $this->id;
if ($reply->find()) {
while($reply->fetch()) {
$ids[] = $reply->profile_id;
}
}
self::cacheSet($keypart, implode(',', $ids));
}
$reply->free();
return $ids;
}
@ -1365,28 +1387,40 @@ class Notice extends Memcached_DataObject
return array();
}
// XXX: cache me
$ids = array();
$keypart = sprintf('notice:groups:%d', $this->id);
$idstr = self::cacheGet($keypart);
if ($idstr !== false) {
$ids = explode(',', $idstr);
} else {
$gi = new Group_inbox();
$gi->selectAdd();
$gi->selectAdd('group_id');
$gi->notice_id = $this->id;
if ($gi->find()) {
while ($gi->fetch()) {
$ids[] = $gi->group_id;
}
}
self::cacheSet($keypart, implode(',', $ids));
}
$groups = array();
$gi = new Group_inbox();
$gi->selectAdd();
$gi->selectAdd('group_id');
$gi->notice_id = $this->id;
if ($gi->find()) {
while ($gi->fetch()) {
$group = User_group::staticGet('id', $gi->group_id);
if ($group) {
$groups[] = $group;
}
foreach ($ids as $id) {
$group = User_group::staticGet('id', $id);
if ($group) {
$groups[] = $group;
}
}
$gi->free();
return $groups;
}
@ -1472,9 +1506,9 @@ class Notice extends Memcached_DataObject
$reply_ids = $this->getReplies();
foreach ($reply_ids as $id) {
$profile = Profile::staticGet('id', $id);
if (!empty($profile)) {
$ctx->attention[] = $profile->getUri();
$rprofile = Profile::staticGet('id', $id);
if (!empty($rprofile)) {
$ctx->attention[] = $rprofile->getUri();
}
}
@ -2106,14 +2140,24 @@ class Notice extends Memcached_DataObject
public function getTags()
{
$tags = array();
$tag = new Notice_tag();
$tag->notice_id = $this->id;
if ($tag->find()) {
while ($tag->fetch()) {
$tags[] = $tag->tag;
$keypart = sprintf('notice:tags:%d', $this->id);
$tagstr = self::cacheGet($keypart);
if ($tagstr !== false) {
$tags = explode(',', $tagstr);
} else {
$tag = new Notice_tag();
$tag->notice_id = $this->id;
if ($tag->find()) {
while ($tag->fetch()) {
$tags[] = $tag->tag;
}
}
self::cacheSet($keypart, implode(',', $tags));
}
$tag->free();
return $tags;
}

View File

@ -211,31 +211,16 @@ class Profile extends Memcached_DataObject
function isMember($group)
{
$mem = new Group_member();
$mem->group_id = $group->id;
$mem->profile_id = $this->id;
if ($mem->find()) {
return true;
} else {
return false;
}
$gm = Group_member::pkeyGet(array('profile_id' => $this->id,
'group_id' => $group->id));
return (!empty($gm));
}
function isAdmin($group)
{
$mem = new Group_member();
$mem->group_id = $group->id;
$mem->profile_id = $this->id;
$mem->is_admin = 1;
if ($mem->find()) {
return true;
} else {
return false;
}
$gm = Group_member::pkeyGet(array('profile_id' => $this->id,
'group_id' => $group->id));
return (!empty($gm) && $gm->is_admin);
}
function isPendingMember($group)
@ -245,30 +230,40 @@ class Profile extends Memcached_DataObject
return !empty($request);
}
function getGroups($offset=0, $limit=null)
function getGroups($offset=0, $limit=PROFILES_PER_PAGE)
{
$qry =
'SELECT user_group.* ' .
'FROM user_group JOIN group_member '.
'ON user_group.id = group_member.group_id ' .
'WHERE group_member.profile_id = %d ' .
'ORDER BY group_member.created DESC ';
$ids = array();
$keypart = sprintf('profile:groups:%d', $this->id);
if ($offset>0 && !is_null($limit)) {
if ($offset) {
if (common_config('db','type') == 'pgsql') {
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
} else {
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
$idstring = self::cacheGet($keypart);
if ($idstring !== false) {
$ids = explode(',', $idstring);
} else {
$gm = new Group_member();
$gm->profile_id = $this->id;
if ($gm->find()) {
while ($gm->fetch()) {
$ids[] = $gm->group_id;
}
}
self::cacheSet($keypart, implode(',', $ids));
}
$groups = array();
foreach ($ids as $id) {
$group = User_group::staticGet('id', $id);
if (!empty($group)) {
$groups[] = $group;
}
}
$groups = new User_group();
$cnt = $groups->query(sprintf($qry, $this->id));
return $groups;
return new ArrayWrapper($groups);
}
function isTagged($peopletag)
@ -463,6 +458,7 @@ class Profile extends Memcached_DataObject
} else {
if (Event::handle('StartJoinGroup', array($group, $this))) {
$join = Group_member::join($group->id, $this->id);
self::blow('profile:groups:%d', $this->id);
Event::handle('EndJoinGroup', array($group, $this));
}
}
@ -482,6 +478,7 @@ class Profile extends Memcached_DataObject
{
if (Event::handle('StartLeaveGroup', array($group, $this))) {
Group_member::leave($group->id, $this->id);
self::blow('profile:groups:%d', $this->id);
Event::handle('EndLeaveGroup', array($group, $this));
}
}

View File

@ -31,7 +31,9 @@ class User_group extends Memcached_DataObject
public $force_scope; // tinyint
/* Static get */
function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('User_group',$k,$v); }
function staticGet($k,$v=NULL) {
return Memcached_DataObject::staticGet('User_group',$k,$v);
}
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE

View File

@ -1628,7 +1628,26 @@ var SN = { // StatusNet
}
}
});
}
},
CheckBoxes: function() {
$("span[class='checkbox-wrapper']").addClass("unchecked");
$(".checkbox-wrapper").click(function(){
if($(this).children("input").attr("checked")){
// uncheck
$(this).children("input").attr({checked: ""});
$(this).removeClass("checked");
$(this).addClass("unchecked");
$(this).children("label").text("Private?");
}else{
// check
$(this).children("input").attr({checked: "checked"});
$(this).removeClass("unchecked");
$(this).addClass("checked");
$(this).children("label").text("Private");
}
});
}
}
};
@ -1642,6 +1661,7 @@ var SN = { // StatusNet
$(document).ready(function(){
SN.Init.AjaxForms();
SN.Init.UploadForms();
SN.Init.CheckBoxes();
if ($('.'+SN.C.S.FormNotice).length > 0) {
SN.Init.NoticeForm();
}
@ -1661,3 +1681,4 @@ $(document).ready(function(){
SN.Init.PeopleTags();
}
});

2
js/util.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -104,7 +104,7 @@ class ActivityImporter extends QueueHandler
if ($activity->objects[0]->id == $author->id) {
if (!$this->trusted) {
// TRANS: Client exception thrown when trying to force a subscription for an untrusted user.
throw new ClientException(_("Cannot force subscription for untrusted user."));
throw new ClientException(_('Cannot force subscription for untrusted user.'));
}
$other = $activity->actor;
@ -113,8 +113,8 @@ class ActivityImporter extends QueueHandler
if (!empty($otherUser)) {
$otherProfile = $otherUser->getProfile();
} else {
// TRANS: Client exception thrown when trying to for a remote user to subscribe.
throw new Exception(_("Cannot force remote user to subscribe."));
// TRANS: Client exception thrown when trying to force a remote user to subscribe.
throw new Exception(_('Cannot force remote user to subscribe.'));
}
// XXX: don't do this for untrusted input!
@ -129,13 +129,13 @@ class ActivityImporter extends QueueHandler
if (empty($otherProfile)) {
// TRANS: Client exception thrown when trying to subscribe to an unknown profile.
throw new ClientException(_("Unknown profile."));
throw new ClientException(_('Unknown profile.'));
}
Subscription::start($profile, $otherProfile);
} else {
// TRANS: Client exception thrown when trying to import an event not related to the importing user.
throw new Exception(_("This activity seems unrelated to our user."));
throw new Exception(_('This activity seems unrelated to our user.'));
}
}
@ -151,7 +151,7 @@ class ActivityImporter extends QueueHandler
$oprofile = Ostatus_profile::ensureActivityObjectProfile($activity->objects[0]);
if (!$oprofile->isGroup()) {
// TRANS: Client exception thrown when trying to join a remote group that is not a group.
throw new ClientException(_("Remote profile is not a group!"));
throw new ClientException(_('Remote profile is not a group!'));
}
$group = $oprofile->localGroup();
}
@ -201,7 +201,7 @@ class ActivityImporter extends QueueHandler
}
} else {
// TRANS: Client exception thrown when trying to overwrite the author information for a non-trusted user during import.
throw new ClientException(_("Not overwriting author info for non-trusted user."));
throw new ClientException(_('Not overwriting author info for non-trusted user.'));
}
}
@ -217,7 +217,7 @@ class ActivityImporter extends QueueHandler
// @fixme fetch from $sourceUrl?
// TRANS: Client exception thrown when trying to import a notice without content.
// TRANS: %s is the notice URI.
throw new ClientException(sprintf(_("No content for notice %s."),$sourceUri));
throw new ClientException(sprintf(_('No content for notice %s.'),$sourceUri));
}
// Get (safe!) HTML and text versions of the content

View File

@ -81,7 +81,7 @@ class ActivityMover extends QueueHandler
function moveActivity($act, $sink, $user, $remote)
{
if (empty($user)) {
// TRANS: Exception thrown if no user is provided. %s is a user ID.
// TRANS: Exception thrown if a non-existing user is provided. %s is a user ID.
throw new Exception(sprintf(_('No such user "%s".'),$act->actor->id));
}

View File

@ -53,7 +53,7 @@ $default =
'broughtbyurl' => null,
'closed' => false,
'inviteonly' => false,
'private' => false,
'private' => true,
'ssl' => 'never',
'sslserver' => null,
'shorturllength' => 30,
@ -274,7 +274,10 @@ $default =
'maxpeople' => 500, // maximum no. of people with the same tag by the same user
'allow_tagging' => array('all' => true), // equivalent to array('local' => true, 'remote' => true)
'desclimit' => null),
'oohembed' => array('endpoint' => 'http://oohembed.com/oohembed/'),
'oembed' =>
array('endpoint' => 'http://oohembed.com/oohembed/',
'order' => array('built-in', 'well-known', 'service', 'discovery'),
),
'search' =>
array('type' => 'fulltext'),
'sessions' =>
@ -306,12 +309,14 @@ $default =
array('disabled' => true),
'plugins' =>
array('default' => array('Geonames' => null,
'Mapstraction' => null,
'OStatus' => null,
'WikiHashtags' => null,
'RSSCloud' => null,
'ClientSideShorten' => null,
'StrictTransportSecurity' => null,
'Bookmark' => null,
'Event' => null,
'Poll' => null,
'QnA' => null,
'SearchSub' => null,
'TagSub' => null,
'OpenID' => null),
'locale_path' => false, // Set to a path to use *instead of* each plugin's own locale subdirectories
'server' => null,

View File

@ -48,19 +48,32 @@ class DefaultLocalNav extends Menu
{
function show()
{
$this->action->elementStart('ul', array('id' => 'nav_local_default'));
$user = common_current_user();
if (!empty($user)) {
$pn = new PersonalGroupNav($this->action);
// TRANS: Menu item in default local navigation panel.
$this->submenu(_m('MENU','Home'), $pn);
}
$this->action->elementStart('ul', array('id' => 'nav_local_default'));
$bn = new PublicGroupNav($this->action);
// TRANS: Menu item in default local navigation panel.
$this->submenu(_m('MENU','Public'), $bn);
if (Event::handle('StartDefaultLocalNav', array($this, $user))) {
if (!empty($user)) {
$pn = new PersonalGroupNav($this->action);
// TRANS: Menu item in default local navigation panel.
$this->submenu(_m('MENU','Home'), $pn);
}
$bn = new PublicGroupNav($this->action);
// TRANS: Menu item in default local navigation panel.
$this->submenu(_m('MENU','Public'), $bn);
if (!empty($user)) {
$sn = new GroupsNav($this->action, $user);
if ($sn->haveGroups()) {
// TRANS: Menu item in default local navigation panel.
$this->submenu(_m('MENU', 'Groups'), $sn);
}
}
Event::handle('EndDefaultLocalNav', array($this, $user));
}
$this->action->elementEnd('ul');
}

View File

@ -60,7 +60,6 @@ class RawFileNoticeStream extends NoticeStream
function __construct($file)
{
parent::__construct();
$this->file = $file;
}

View File

@ -20,7 +20,7 @@
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
define('STATUSNET_BASE_VERSION', '1.0.0');
define('STATUSNET_LIFECYCLE', 'dev'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release'
define('STATUSNET_LIFECYCLE', 'alpha2'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release'
define('STATUSNET_VERSION', STATUSNET_BASE_VERSION . STATUSNET_LIFECYCLE);
define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility

View File

@ -202,10 +202,12 @@ class GroupEditForm extends Form
$this->out->elementEnd('li');
}
$this->out->elementStart('li');
$this->out->checkbox('private', _('Private'),
// TRANS: Checkbox field label on group edit form to mark a group private.
$this->out->checkbox('private', _m('LABEL','Private'),
($this->out->arg('private')) ? $this->out->arg('private') :
((!empty($this->group)) ? $this->group->isPrivate() : false),
_('New members must be approved by admin and all posts are forced to be private'));
// TRANS: Checkbox field title on group edit form to mark a group private.
_('New members must be approved by admin and all posts are forced to be private.'));
$this->out->elementEnd('li');
Event::handle('EndGroupEditFormData', array($this));
}

93
lib/groupsnav.php Normal file
View File

@ -0,0 +1,93 @@
<?php
/**
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2011, StatusNet, Inc.
*
* Menu for streams
*
* PHP version 5
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Cache
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2011 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
// This check helps protect against security problems;
// your code file can't be executed directly from the web.
exit(1);
}
/**
* Menu for streams you follow
*
* @category General
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2011 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class GroupsNav extends Menu
{
protected $user;
protected $groups;
function __construct($action, $user)
{
parent::__construct($action);
$this->user = $user;
$this->groups = $user->getGroups();
}
function haveGroups()
{
return (!empty($this->groups) && ($this->groups->N > 0));
}
/**
* Show the menu
*
* @return void
*/
function show()
{
$action = $this->actionName;
$this->out->elementStart('ul', array('class' => 'nav'));
if (Event::handle('StartGroupsNav', array($this))) {
while ($this->groups->fetch()) {
$this->out->menuItem(($this->groups->mainpage) ?
$this->groups->mainpage :
common_local_url('showgroup',
array('nickname' => $this->groups->nickname)),
$this->groups->getBestName(),
'',
$action == 'showgroup' &&
$this->action->arg('nickname') == $this->groups->nickname,
'nav_timeline_group_'.$this->groups->nickname);
}
Event::handle('EndGroupsNav', array($this));
}
$this->out->elementEnd('ul');
}
}

View File

@ -43,6 +43,13 @@ class oEmbedHelper
protected static $apiMap = array(
'flickr.com' => 'http://www.flickr.com/services/oembed/',
'yfrog.com' => 'http://www.yfrog.com/api/oembed',
'youtube.com' => 'http://www.youtube.com/oembed',
'viddler.com' => 'http://lab.viddler.com/services/oembed/',
'qik.com' => 'http://qik.com/api/oembed.json',
'revision3.com' => 'http://revision3.com/api/oembed/',
'hulu.com' => 'http://www.hulu.com/api/oembed.json',
'vimeo.com' => 'http://www.vimeo.com/api/oembed.json',
'my.opera.com' => 'http://my.opera.com/service/oembed',
);
protected static $functionMap = array(
'twitpic.com' => 'oEmbedHelper::twitPic',
@ -74,30 +81,59 @@ class oEmbedHelper
$host = substr($host, 4);
}
// Blacklist: systems with no oEmbed API of their own, which are
// either missing from or broken on oohembed.com's proxy.
// we know how to look data up in another way...
if (array_key_exists($host, self::$functionMap)) {
$func = self::$functionMap[$host];
return call_user_func($func, $url, $params);
}
common_log(LOG_INFO, 'Checking for oEmbed data for ' . $url);
// Whitelist: known API endpoints for sites that don't provide discovery...
if (array_key_exists($host, self::$apiMap)) {
$api = self::$apiMap[$host];
} else {
try {
$api = self::discover($url);
} catch (Exception $e) {
// Discovery failed... fall back to oohembed if enabled.
$oohembed = common_config('oohembed', 'endpoint');
if ($oohembed) {
$api = $oohembed;
} else {
throw $e;
// You can fiddle with the order of discovery -- either skipping
// some types or re-ordering them.
$order = common_config('oembed', 'order');
foreach ($order as $method) {
switch ($method) {
case 'built-in':
common_log(LOG_INFO, 'Considering built-in oEmbed methods...');
// Blacklist: systems with no oEmbed API of their own, which are
// either missing from or broken on oohembed.com's proxy.
// we know how to look data up in another way...
if (array_key_exists($host, self::$functionMap)) {
common_log(LOG_INFO, 'We have a built-in method for ' . $host);
$func = self::$functionMap[$host];
return call_user_func($func, $url, $params);
}
break;
case 'well-known':
common_log(LOG_INFO, 'Considering well-known oEmbed endpoints...');
// Whitelist: known API endpoints for sites that don't provide discovery...
if (array_key_exists($host, self::$apiMap)) {
$api = self::$apiMap[$host];
common_log(LOG_INFO, 'Using well-known endpoint "' . $api . '" for "' . $host . '"');
break 2;
}
break;
case 'discovery':
try {
common_log(LOG_INFO, 'Trying to discover an oEmbed endpoint using link headers.');
$api = self::discover($url);
common_log(LOG_INFO, 'Found API endpoint ' . $api . ' for URL ' . $url);
break 2;
} catch (Exception $e) {
common_log(LOG_INFO, 'Could not find an oEmbed endpoint using link headers.');
// Just ignore it!
}
break;
case 'service':
$api = common_config('oembed', 'endpoint');
common_log(LOG_INFO, 'Using service API endpoint ' . $api);
break 2;
break;
}
}
if (empty($api)) {
throw new ServerException(_('No oEmbed API endpoint available.'));
}
return self::getObjectFrom($api, $url, $params);
}

View File

@ -47,16 +47,10 @@ if (!defined('STATUSNET')) {
class PublicNoticeStream extends ScopingNoticeStream
{
const THREADED=true;
/**
*
* @param boolean $threaded set to true to exclude replies, for later fetching
*/
function __construct($threaded=false)
function __construct()
{
parent::__construct(new CachingNoticeStream(new RawPublicNoticeStream($threaded),
$threaded ? 'public:threaded' : 'public'));
parent::__construct(new CachingNoticeStream(new RawPublicNoticeStream(),
'public'));
}
}
@ -73,13 +67,6 @@ class PublicNoticeStream extends ScopingNoticeStream
class RawPublicNoticeStream extends NoticeStream
{
var $threaded;
function __construct($threaded=false)
{
$this->threaded = $threaded;
}
function getNoticeIds($offset, $limit, $since_id, $max_id)
{
$notice = new Notice();
@ -100,9 +87,6 @@ class RawPublicNoticeStream extends NoticeStream
$notice->whereAdd('is_local !='. Notice::LOCAL_NONPUBLIC);
$notice->whereAdd('is_local !='. Notice::GATEWAY);
}
if ($this->threaded) {
$notice->whereAdd('reply_to IS NULL');
}
Notice::addWhereSinceId($notice, $since_id);
Notice::addWhereMaxId($notice, $max_id);

View File

@ -284,9 +284,8 @@ class ThreadedNoticeListMoreItem extends NoticeListItem
$id = $this->notice->conversation;
$url = common_local_url('conversationreplies', array('id' => $id));
$notice = new Notice();
$notice->conversation = $id;
$n = $notice->count() - 1;
$n = Conversation::noticeCount($id) - 1;
// TRANS: Link to show replies for a notice.
// TRANS: %d is the number of replies to a notice and used for plural.
$msg = sprintf(_m('Show reply', 'Show all %d replies', $n), $n);

View File

@ -118,10 +118,12 @@ class ToSelector extends Widget
false,
$default);
$this->out->elementStart('span', 'checkbox-wrapper');
$this->out->checkbox('notice_private',
// TRANS: Checkbox label in widget for selecting potential addressees to mark the notice private.
_('Private'),
_('Private?'),
$this->private);
$this->out->elementEnd('span');
}
static function fillOptions($action, &$options)

View File

@ -60,7 +60,6 @@ class APCPlugin extends Plugin
*
* @return boolean hook success
*/
function onStartCacheGet(&$key, &$value)
{
$value = apc_fetch($key);
@ -79,7 +78,6 @@ class APCPlugin extends Plugin
*
* @return boolean hook success
*/
function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
{
$success = apc_store($key, $value, ((is_null($expiry)) ? 0 : $expiry));
@ -97,7 +95,6 @@ class APCPlugin extends Plugin
*
* @return boolean hook success
*/
function onStartCacheDelete(&$key, &$success)
{
$success = apc_delete($key);
@ -112,6 +109,7 @@ class APCPlugin extends Plugin
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:APC',
'rawdescription' =>
// TRANS: Plugin description.
_m('Use the <a href="http://pecl.php.net/package/apc">APC</a> variable cache to cache query results.'));
return true;
}

View File

@ -40,7 +40,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class AccountManagementControlDocumentAction extends Action
{
/**
@ -50,7 +49,6 @@ class AccountManagementControlDocumentAction extends Action
*
* @return void
*/
function handle($args)
{
parent::handle($args);

View File

@ -40,7 +40,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class AccountManagementSessionStatusAction extends Action
{
/**
@ -50,7 +49,6 @@ class AccountManagementSessionStatusAction extends Action
*
* @return void
*/
function handle($args)
{
parent::handle($args);

View File

@ -33,7 +33,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
class AccountManagerPlugin extends Plugin
{
const AM_REL = 'acct-mgmt';
function __construct()
@ -99,7 +98,6 @@ class AccountManagerPlugin extends Plugin
default:
return true;
}
}
function onPluginVersion(&$versions)
@ -109,6 +107,7 @@ class AccountManagerPlugin extends Plugin
'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:AccountManager',
'rawdescription' =>
// TRANS: Plugin description.
_m('The Account Manager plugin implements the Account Manager specification.'));
return true;
}

View File

@ -193,7 +193,7 @@ class AdsensePlugin extends UAPPlugin
// TRANS: Menu item title/tooltip
$menu_title = _m('AdSense configuration');
// TRANS: Menu item for site administration
$menu->out->menuItem(common_local_url('adsenseadminpanel'), _m('AdSense'),
$menu->out->menuItem(common_local_url('adsenseadminpanel'), _m('MENU','AdSense'),
$menu_title, $action_name == 'adsenseadminpanel', 'nav_adsense_admin_panel');
}
return true;
@ -206,6 +206,7 @@ class AdsensePlugin extends UAPPlugin
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:Adsense',
'rawdescription' =>
// TRANS: Plugin description.
_m('Plugin to add Google AdSense to StatusNet sites.'));
return true;
}

View File

@ -49,6 +49,7 @@ class AdsenseadminpanelAction extends AdminPanelAction
*/
function title()
{
// TRANS: Title of AdSense administrator panel.
return _m('TITLE', 'AdSense');
}
@ -59,6 +60,7 @@ class AdsenseadminpanelAction extends AdminPanelAction
*/
function getInstructions()
{
// TRANS: Instructions for AdSense administrator panel.
return _m('AdSense settings for this StatusNet site');
}
@ -161,38 +163,50 @@ class AdsenseAdminPanelForm extends AdminForm
$this->out->elementStart('ul', 'form_data');
$this->li();
$this->input('client',
// TRANS: Field label in AdSense administration panel.
_m('Client ID'),
_m('Google client ID'),
// TRANS: Field title in AdSense administration panel.
_m('Google client ID.'),
'adsense');
$this->unli();
$this->li();
$this->input('adScript',
// TRANS: Field label in AdSense administration panel.
_m('Ad script URL'),
_m('Script URL (advanced)'),
// TRANS: Field title in AdSense administration panel.
_m('Script URL (advanced).'),
'adsense');
$this->unli();
$this->li();
$this->input('mediumRectangle',
// TRANS: Field label in AdSense administration panel.
_m('Medium rectangle'),
_m('Medium rectangle slot code'),
// TRANS: Field title in AdSense administration panel.
_m('Medium rectangle slot code.'),
'adsense');
$this->unli();
$this->li();
$this->input('rectangle',
// TRANS: Field label in AdSense administration panel.
_m('Rectangle'),
_m('Rectangle slot code'),
// TRANS: Field title in AdSense administration panel.
_m('Rectangle slot code.'),
'adsense');
$this->unli();
$this->li();
$this->input('leaderboard',
// TRANS: Field label in AdSense administration panel.
_m('Leaderboard'),
_m('Leaderboard slot code'),
// TRANS: Field title in AdSense administration panel.
_m('Leaderboard slot code.'),
'adsense');
$this->unli();
$this->li();
$this->input('wideSkyscraper',
// TRANS: Field label in AdSense administration panel.
_m('Skyscraper'),
_m('Wide skyscraper slot code'),
// TRANS: Field title in AdSense administration panel.
_m('Wide skyscraper slot code.'),
'adsense');
$this->unli();
$this->out->elementEnd('ul');
@ -205,6 +219,9 @@ class AdsenseAdminPanelForm extends AdminForm
*/
function formActions()
{
$this->out->submit('submit', _m('Save'), 'submit', null, _m('Save AdSense settings'));
// TRANS: Button text to save settings in AdSense administration panel.
$this->out->submit('submit', _m('BUTTON','Save'),
// TRANS: Button title to save settings in AdSense administration panel.
'submit', null, _m('Save AdSense settings.'));
}
}

View File

@ -46,7 +46,6 @@ set_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/ext
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class AimPlugin extends ImPlugin
{
public $user = null;
@ -57,6 +56,7 @@ class AimPlugin extends ImPlugin
function getDisplayName()
{
// TRANS: Display name.
return _m('AIM');
}
@ -116,7 +116,7 @@ class AimPlugin extends ImPlugin
function microiduri($screenname)
{
return 'aim:' . $screenname;
return 'aim:' . $screenname;
}
function sendMessage($screenname, $body)
@ -145,10 +145,12 @@ class AimPlugin extends ImPlugin
function initialize(){
if(!isset($this->user)){
throw new Exception("must specify a user");
// TRANS: Exception thrown in AIM plugin when user has not been specified.
throw new Exception(_m('Must specify a user.'));
}
if(!isset($this->password)){
throw new Exception("must specify a password");
// TRANS: Exception thrown in AIM plugin when password has not been specified.
throw new Exception(_m('Must specify a password.'));
}
$this->fake_aim = new Fake_Aim($this->user,$this->password,4);
@ -162,8 +164,8 @@ class AimPlugin extends ImPlugin
'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:AIM',
'rawdescription' =>
// TRANS: Plugin description.
_m('The AIM plugin allows users to send and receive notices over the AIM network.'));
return true;
}
}

View File

@ -40,4 +40,3 @@ class Fake_Aim extends Aim
$this->would_be_sent = array($sflap_type, $sflap_data, $no_null, $formatted);
}
}

View File

@ -29,10 +29,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
* In a multi-site queuedaemon.php run, one connection will be instantiated
* for each site being handled by the current process that has XMPP enabled.
*/
class AimManager extends ImManager
{
public $conn = null;
/**
* Initialize connection to server.
@ -77,6 +75,8 @@ class AimManager extends ImManager
$this->conn->registerHandler("IMIn",array($this,"handle_aim_message"));
$this->conn->myServer="toc.oscar.aol.com";
$this->conn->signon();
// @todo i18n FIXME: Update translator documentation, please.
// TRANS: No idea what the use case for this message is.
$this->conn->setProfile(_m('Send me a message to post a notice'),false);
}
return $this->conn;

View File

@ -56,10 +56,8 @@ define('ANONYMOUS_FAVE_PLUGIN_VERSION', '0.1');
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class AnonymousFavePlugin extends Plugin
{
// Array of users who should not have anon faving. The default is
// that anonymous faving is allowed for all users.
public $restricted = array();
@ -237,7 +235,7 @@ class AnonymousFavePlugin extends Plugin
if (!$id) {
// TRANS: Server exception.
throw new ServerException(_m("Couldn't create anonymous user session."));
throw new ServerException(_m("Could not create anonymous user session."));
}
// Stick the Profile ID into the nickname
@ -248,7 +246,7 @@ class AnonymousFavePlugin extends Plugin
if (!$result) {
// TRANS: Server exception.
throw new ServerException(_m("Couldn't create anonymous user session."));
throw new ServerException(_m("Could not create anonymous user session."));
}
common_log(
@ -327,5 +325,4 @@ class AnonymousFavePlugin extends Plugin
return true;
}
}

View File

@ -152,7 +152,7 @@ class Fave_tally extends Memcached_DataObject
$msg = sprintf(
// TRANS: Server exception.
// TRANS: %d is the notice ID (number).
_m("Couldn't update favorite tally for notice ID %d."),
_m("Could not update favorite tally for notice ID %d."),
$noticeID
);
throw new ServerException($msg);
@ -181,7 +181,7 @@ class Fave_tally extends Memcached_DataObject
$msg = sprintf(
// TRANS: Server exception.
// TRANS: %d is the notice ID (number).
_m("Couldn't update favorite tally for notice ID %d."),
_m("Could not update favorite tally for notice ID %d."),
$noticeID
);
throw new ServerException($msg);
@ -212,7 +212,7 @@ class Fave_tally extends Memcached_DataObject
$msg = sprintf(
// TRANS: Server exception.
// TRANS: %d is the notice ID (number).
_m("Couldn't create favorite tally for notice ID %d."),
_m("Could not create favorite tally for notice ID %d."),
$noticeID
);
throw new ServerException($msg);

View File

@ -57,7 +57,7 @@ class AnonFavorAction extends RedirectingAction
if (empty($profile) || $_SERVER['REQUEST_METHOD'] != 'POST') {
// TRANS: Client error.
$this->clientError( _m('Could not favor notice! Please make sure your browser has cookies enabled.')
$this->clientError(_m('Could not favor notice! Please make sure your browser has cookies enabled.')
);
return;
}

View File

@ -46,7 +46,6 @@ require_once INSTALLDIR.'/lib/form.php';
*/
class AnonFavorForm extends FavorForm
{
/**
* Constructor
*
@ -67,5 +66,4 @@ class AnonFavorForm extends FavorForm
{
return common_local_url('AnonFavor');
}
}

View File

@ -35,4 +35,3 @@ $notice->find();
while ($notice->fetch()) {
Fave_tally::ensureTally($notice->id);
}

View File

@ -74,4 +74,16 @@ class ApiLoggerPlugin extends Plugin
}
return true;
}
function onPluginVersion(&$versions)
{
$versions[] = array('name' => 'ApiLogger',
'version' => STATUSNET_VERSION,
'author' => 'Brion Vibber',
'homepage' => 'http://status.net/wiki/Plugin:ApiLogger',
'rawdescription' =>
// TRANS: Plugin description.
_m('Allows random sampling of API requests.'));
return true;
}
}

View File

@ -63,21 +63,24 @@ class AutoSandboxPlugin extends Plugin
'author' => 'Sean Carmody',
'homepage' => 'http://status.net/wiki/Plugin:AutoSandbox',
'rawdescription' =>
// TRANS: Plugin description.
_m('Automatically sandboxes newly registered members.'));
return true;
}
function onStartRegistrationFormData($action)
{
// TRANS: User instructions after registration.
$instr = _m('Note you will initially be "sandboxed" so your posts will not appear in the public timeline.');
if (isset($this->contact)) {
$contactuser = User::staticGet('nickname', $this->contact);
if (!empty($contactuser)) {
$contactlink = "@<a href=\"$contactuser->uri\">$contactuser->nickname</a>";
// TRANS: $contactlink is a clickable e-mailaddress.
$instr = _m("Note you will initially be \"sandboxed\" so your posts will not appear in the public timeline. ".
'Send a message to $contactlink to speed up the unsandboxing process.');
// TRANS: User instructions after registration.
// TRANS: %s is a clickable e-mailaddress.
$instr = sprintf(_m('Note you will initially be "sandboxed" so your posts will not appear in the public timeline. '.
'Send a message to %s to speed up the unsandboxing process.'),$contactlink);
}
}

View File

@ -79,7 +79,8 @@ class AutocompletePlugin extends Plugin
'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:Autocomplete',
'rawdescription' =>
_m('The autocomplete plugin allows users to autocomplete screen names in @ replies. When an "@" is typed into the notice text area, an autocomplete box is displayed populated with the user\'s friend\' screen names.'));
// TRANS: Plugin description.
_m('The autocomplete plugin adds autocompletion for @ replies.'));
return true;
}
}

View File

@ -94,7 +94,8 @@ class AutocompleteAction extends Action
$cur = common_current_user();
if (!$cur) {
throw new ClientException('Access forbidden', true);
// TRANS: Client exception in autocomplete plugin.
throw new ClientException(_m('Access forbidden.'), true);
}
$this->groups=array();
$this->users=array();

View File

@ -42,7 +42,7 @@ if (!defined('STATUSNET')) {
class AwesomenessPlugin extends Plugin
{
const VERSION = '0.0.42';
const VERSION = '0.0.42';
public function onPluginVersion(&$versions)
{
@ -72,22 +72,22 @@ class AwesomenessPlugin extends Plugin
$action->elementStart('div', array('id' => 'cornify_section',
'class' => 'section'));
$action->raw(
<<<EOT
<a href="http://www.cornify.com" onclick="cornify_add();return false;">
<img src="http://www.cornify.com/assets/cornify.gif" width="61" height="16" border="0" alt="Cornify" />
</a>
<script type="text/javascript">(function() {
var js = document.createElement('script');
js.type = 'text/javascript';
js.async = true;
js.src = 'http://www.cornify.com/js/cornify.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(js);
$action->raw(
<<<EOT
<a href="http://www.cornify.com" onclick="cornify_add();return false;">
<img src="http://www.cornify.com/assets/cornify.gif" width="61" height="16" border="0" alt="Cornify" />
</a>
<script type="text/javascript">(function() {
var js = document.createElement('script');
js.type = 'text/javascript';
js.async = true;
js.src = 'http://www.cornify.com/js/cornify.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(js);
})();</script>
EOT
);
);
$action->elementEnd('div');
$action->elementEnd('div');
}
/**
@ -102,7 +102,7 @@ EOT
*/
function onStartSaveNewNoticeWeb($action, $user, &$content, &$options)
{
$content = htmlspecialchars($content);
$options['rendered'] = preg_replace("/(^|\s|-)((?:awesome|awesomeness)[\?!\.\,]?)(\s|$)/i", " <b>$2</b> ", $content);
$content = htmlspecialchars($content);
$options['rendered'] = preg_replace("/(^|\s|-)((?:awesome|awesomeness)[\?!\.\,]?)(\s|$)/i", " <b>$2</b> ", $content);
}
}

View File

@ -43,7 +43,8 @@ class BitlyUrlPlugin extends UrlShortenerPlugin
function onInitializePlugin(){
parent::onInitializePlugin();
if(!isset($this->serviceUrl)){
throw new Exception(_m("You must specify a serviceUrl for bit.ly shortening."));
// TRANS: Exception thrown when bit.ly URL shortening plugin was configured incorrectly.
throw new Exception(_m('You must specify a serviceUrl for bit.ly URL shortening.'));
}
}
@ -170,6 +171,7 @@ class BitlyUrlPlugin extends UrlShortenerPlugin
'author' => 'Craig Andrews, Brion Vibber',
'homepage' => 'http://status.net/wiki/Plugin:BitlyUrl',
'rawdescription' =>
// TRANS: Plugin description. %1$s is the URL shortening service base URL (for example "bit.ly").
sprintf(_m('Uses <a href="http://%1$s/">%1$s</a> URL-shortener service.'),
$this->shortenerName));
@ -211,8 +213,10 @@ class BitlyUrlPlugin extends UrlShortenerPlugin
$action_name = $nav->action->trimmed('action');
$nav->out->menuItem(common_local_url('bitlyadminpanel'),
// TRANS: Menu item in administration menus for bit.ly URL shortening settings.
_m('bit.ly'),
_m('bit.ly URL shortening'),
// TRANS: Title for menu item in administration menus for bit.ly URL shortening settings.
_m('bit.ly URL shortening.'),
$action_name == 'bitlyadminpanel',
'nav_bitly_admin_panel');
}

View File

@ -40,7 +40,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class BitlyadminpanelAction extends AdminPanelAction
{
/**
@ -48,9 +47,9 @@ class BitlyadminpanelAction extends AdminPanelAction
*
* @return string page title
*/
function title()
{
// TRANS: Title of administration panel.
return _m('bit.ly URL shortening');
}
@ -59,9 +58,10 @@ class BitlyadminpanelAction extends AdminPanelAction
*
* @return string instructions
*/
function getInstructions()
{
// TRANS: Instructions for administration panel.
// TRANS: This message contains Markdown links in the form [decsription](link).
return _m('URL shortening with bit.ly requires ' .
'[a bit.ly account and API key](http://bit.ly/a/your_api_key). ' .
'This verifies that this is an authorized account, and ' .
@ -73,7 +73,6 @@ class BitlyadminpanelAction extends AdminPanelAction
*
* @return void
*/
function showForm()
{
$form = new BitlyAdminPanelForm($this);
@ -86,7 +85,6 @@ class BitlyadminpanelAction extends AdminPanelAction
*
* @return void
*/
function saveSettings()
{
static $settings = array(
@ -129,13 +127,15 @@ class BitlyadminpanelAction extends AdminPanelAction
if (mb_strlen($values['bitly']['default_apikey']) > 255) {
$this->clientError(
_m("Invalid login. Max length is 255 characters.")
// TRANS: Client error displayed when using too long a key.
_m('Invalid login. Maximum length is 255 characters.')
);
}
if (mb_strlen($values['bitly']['default_apikey']) > 255) {
$this->clientError(
_m("Invalid API key. Max length is 255 characters.")
// TRANS: Client error displayed when using too long a key.
_m('Invalid API key. Maximum length is 255 characters.')
);
}
}
@ -148,7 +148,6 @@ class BitlyAdminPanelForm extends AdminForm
*
* @return int ID of the form
*/
function id()
{
return 'bitlyadminpanel';
@ -159,7 +158,6 @@ class BitlyAdminPanelForm extends AdminForm
*
* @return string class of the form
*/
function formClass()
{
return 'form_settings';
@ -170,7 +168,6 @@ class BitlyAdminPanelForm extends AdminForm
*
* @return string URL of the action
*/
function action()
{
return common_local_url('bitlyadminpanel');
@ -181,14 +178,14 @@ class BitlyAdminPanelForm extends AdminForm
*
* @return void
*/
function formData()
{
$this->out->elementStart(
'fieldset',
array('id' => 'settings_bitly')
);
$this->out->element('legend', null, _m('Credentials'));
// TRANS: Fieldset legend in administration panel for bit.ly username and API key.
$this->out->element('legend', null, _m('LEGEND','Credentials'));
// Do we have global defaults to fall back on?
$login = $apiKey = false;
@ -196,9 +193,11 @@ class BitlyAdminPanelForm extends AdminForm
$haveGlobalDefaults = ($login && $apiKey);
if ($login && $apiKey) {
$this->out->element('p', 'form_guide',
// TRANS: Form guide in administration panel for bit.ly URL shortening.
_m('Leave these empty to use global default credentials.'));
} else {
$this->out->element('p', 'form_guide',
// TRANS: Form guide in administration panel for bit.ly URL shortening.
_m('If you leave these empty, bit.ly will be unavailable to users.'));
}
$this->out->elementStart('ul', 'form_data');
@ -206,6 +205,7 @@ class BitlyAdminPanelForm extends AdminForm
$this->li();
$this->input(
'default_login',
// TRANS: Field label in administration panel for bit.ly URL shortening.
_m('Login name'),
null,
'bitly'
@ -215,6 +215,7 @@ class BitlyAdminPanelForm extends AdminForm
$this->li();
$this->input(
'default_apikey',
// TRANS: Field label in administration panel for bit.ly URL shortening.
_m('API key'),
null,
'bitly'
@ -230,13 +231,14 @@ class BitlyAdminPanelForm extends AdminForm
*
* @return void
*/
function formActions()
{
$this->out->submit('submit',
// TRANS: Button text to save setting in administration panel for bit.ly URL shortening.
_m('BUTTON','Save'),
'submit',
null,
// TRANS: Button title to save setting in administration panel for bit.ly URL shortening.
_m('Save bit.ly settings'));
}
}

View File

@ -126,7 +126,7 @@ class BlacklistPlugin extends Plugin
} else if (is_string($config)) {
return explode("\r\n", $config);
} else {
throw new Exception("Unknown data type for config $section + $setting");
throw new Exception(sprintf(_m('Unknown data type for config %1$s + %2$s.'),$section, $setting));
}
}
@ -340,6 +340,7 @@ class BlacklistPlugin extends Plugin
'homepage' =>
'http://status.net/wiki/Plugin:Blacklist',
'description' =>
// TRANS: Plugin description.
_m('Keeps a blacklist of forbidden nickname '.
'and URL patterns.'));
return true;
@ -380,7 +381,7 @@ class BlacklistPlugin extends Plugin
// TRANS: Menu item in admin panel.
_m('MENU','Blacklist'),
// TRANS: Tooltip for menu item in admin panel.
_m('TOOLTIP','Blacklist configuration'),
_m('TOOLTIP','Blacklist configuration.'),
$action_name == 'blacklistadminpanel',
'nav_blacklist_admin_panel');
}
@ -406,7 +407,7 @@ class BlacklistPlugin extends Plugin
$action->elementStart('li');
$this->checkboxAndText($action,
'blacklistnickname',
// TRANS: Checkbox with text label in the delete user form.
// TRANS: Checkbox label in the blacklist user form.
_m('Add this nickname pattern to blacklist'),
'blacklistnicknamepattern',
$this->patternizeNickname($user->nickname));
@ -416,7 +417,7 @@ class BlacklistPlugin extends Plugin
$action->elementStart('li');
$this->checkboxAndText($action,
'blacklisthomepage',
// TRANS: Checkbox with text label in the delete user form.
// TRANS: Checkbox label in the blacklist user form.
_m('Add this homepage pattern to blacklist'),
'blacklisthomepagepattern',
$this->patternizeHomepage($profile->homepage));
@ -496,7 +497,7 @@ class BlacklistPlugin extends Plugin
if (!empty($homepage)) {
if (!$this->_checkUrl($homepage)) {
// TRANS: Exception thrown trying to post a notice while having set a blocked homepage URL. %s is the blocked URL.
$msg = sprintf(_m("Users from \"%s\" blocked."),
$msg = sprintf(_m("Users from \"%s\" are blocked."),
$homepage);
throw new ClientException($msg);
}
@ -507,7 +508,7 @@ class BlacklistPlugin extends Plugin
if (!empty($nickname)) {
if (!$this->_checkNickname($nickname)) {
// TRANS: Exception thrown trying to post a notice while having a blocked nickname. %s is the blocked nickname.
$msg = sprintf(_m("Posts from nickname \"%s\" disallowed."),
$msg = sprintf(_m("Notices from nickname \"%s\" disallowed."),
$nickname);
throw new ClientException($msg);
}
@ -531,7 +532,7 @@ class BlacklistPlugin extends Plugin
if (!$this->_checkUrl($url)) {
// TRANS: Client exception thrown trying to subscribe to a person with a blocked homepage or site URL. %s is the blocked URL.
$msg = sprintf(_m("Users from \"%s\" blocked."),
$msg = sprintf(_m("Users from \"%s\" are blocked."),
$url);
throw new ClientException($msg);
}
@ -542,7 +543,7 @@ class BlacklistPlugin extends Plugin
if (!empty($nickname)) {
if (!$this->_checkNickname($nickname)) {
// TRANS: Client exception thrown trying to subscribe to a person with a blocked nickname. %s is the blocked nickname.
$msg = sprintf(_m("Can't subscribe to nickname \"%s\"."),
$msg = sprintf(_m("Cannot subscribe to nickname \"%s\"."),
$nickname);
throw new ClientException($msg);
}

View File

@ -49,7 +49,8 @@ class BlacklistadminpanelAction extends AdminPanelAction
*/
function title()
{
return _m('Blacklist');
// TRANS: Title of blacklist plugin administration panel.
return _m('TITLE','Blacklist');
}
/**
@ -59,6 +60,7 @@ class BlacklistadminpanelAction extends AdminPanelAction
*/
function getInstructions()
{
// TRANS: Instructions for blacklist plugin administration panel.
return _m('Blacklisted URLs and nicknames');
}
@ -171,17 +173,21 @@ class BlacklistAdminPanelForm extends Form
$nickPatterns = Nickname_blacklist::getPatterns();
// TRANS: Field label in blacklist plugin administration panel.
$this->out->textarea('blacklist-nicknames', _m('Nicknames'),
implode("\r\n", $nickPatterns),
_m('Patterns of nicknames to block, one per line'));
// TRANS: Field title in blacklist plugin administration panel.
_m('Patterns of nicknames to block, one per line.'));
$this->out->elementEnd('li');
$urlPatterns = Homepage_blacklist::getPatterns();
$this->out->elementStart('li');
// TRANS: Field label in blacklist plugin administration panel.
$this->out->textarea('blacklist-urls', _m('URLs'),
implode("\r\n", $urlPatterns),
_m('Patterns of URLs to block, one per line'));
// TRANS: Field title in blacklist plugin administration panel.
_m('Patterns of URLs to block, one per line.'));
$this->out->elementEnd('li');
$this->out->elementEnd('ul');
@ -195,9 +201,11 @@ class BlacklistAdminPanelForm extends Form
function formActions()
{
$this->out->submit('submit',
_m('Save'),
// TRANS: Button text in blacklist plugin administration panel to save settings.
_m('BUTTON','Save'),
'submit',
null,
_m('Save site settings'));
// TRANS: Button title in blacklist plugin administration panel to save settings.
_m('Save site settings.'));
}
}

View File

@ -124,6 +124,7 @@ class BlankAdPlugin extends UAPPlugin
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:BlankAdPlugin',
'rawdescription' =>
// TRANS: Plugin description.
_m('Plugin for testing ad layout.'));
return true;
}

View File

@ -82,13 +82,19 @@ class BlogspamNetPlugin extends Plugin
} else {
common_debug("Blogspamnet results = " . $response);
if (preg_match('/^ERROR(:(.*))?$/', $response, $match)) {
throw new ServerException(sprintf(_m("Error from %1$s: %2$s"), $this->baseUrl, $match[2]), 500);
// TRANS: Server exception thrown when blogspam.net returns error status.
// TRANS: %1$s is the base URL, %2$s is the error (unknown contents; no period).
throw new ServerException(sprintf(_m('Error from %1$s: %2$s'), $this->baseUrl, $match[2]), 500);
} else if (preg_match('/^SPAM(:(.*))?$/', $response, $match)) {
throw new ClientException(sprintf(_m("Spam checker results: %s"), $match[2]), 400);
// TRANS: Server exception thrown when blogspam.net returns spam status.
// TRANS: Does not end with period because of unknown contents for %s (spam match).
throw new ClientException(sprintf(_m('Spam checker results: %s'), $match[2]), 400);
} else if (preg_match('/^OK$/', $response)) {
// don't do anything
} else {
throw new ServerException(sprintf(_m("Unexpected response from %1$s: %2$s"), $this->baseUrl, $response), 500);
// TRANS: Server exception thrown when blogspam.net returns an unexpected status.
// TRANS: %1$s is the base URL, %2$s is the response (unknown contents; no period).
throw new ServerException(sprintf(_m('Unexpected response from %1$s: %2$s'), $this->baseUrl, $response), 500);
}
}
return true;
@ -149,6 +155,7 @@ class BlogspamNetPlugin extends Plugin
'author' => 'Evan Prodromou, Brion Vibber',
'homepage' => 'http://status.net/wiki/Plugin:BlogspamNet',
'rawdescription' =>
// TRANS: Plugin description.
_m('Plugin to check submitted notices with blogspam.net.'));
return true;
}

View File

@ -42,7 +42,6 @@ if (!defined('STATUSNET')) {
*
* @see DB_DataObject
*/
class Bookmark extends Memcached_DataObject
{
public $__table = 'bookmark'; // table name
@ -65,7 +64,6 @@ class Bookmark extends Memcached_DataObject
* @return User_greeting_count object found, or null for no hits
*
*/
function staticGet($k, $v=null)
{
return Memcached_DataObject::staticGet('Bookmark', $k, $v);
@ -83,7 +81,6 @@ class Bookmark extends Memcached_DataObject
* @return Bookmark object found, or null for no hits
*
*/
function pkeyGet($kv)
{
return Memcached_DataObject::pkeyGet('Bookmark', $kv);
@ -97,7 +94,6 @@ class Bookmark extends Memcached_DataObject
*
* @return array array of column definitions
*/
function table()
{
return array('id' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
@ -106,7 +102,7 @@ class Bookmark extends Memcached_DataObject
'title' => DB_DATAOBJECT_STR,
'description' => DB_DATAOBJECT_STR,
'uri' => DB_DATAOBJECT_STR,
'created' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE +
'created' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE +
DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL);
}
@ -115,7 +111,6 @@ class Bookmark extends Memcached_DataObject
*
* @return array list of key field names
*/
function keys()
{
return array_keys($this->keyTypes());
@ -126,7 +121,6 @@ class Bookmark extends Memcached_DataObject
*
* @return array associative array of key definitions
*/
function keyTypes()
{
return array('id' => 'K',
@ -138,7 +132,6 @@ class Bookmark extends Memcached_DataObject
*
* @return array magic three-false array that stops auto-incrementing.
*/
function sequenceKey()
{
return array(false, false, false);
@ -146,12 +139,11 @@ class Bookmark extends Memcached_DataObject
/**
* Get a bookmark based on a notice
*
*
* @param Notice $notice Notice to check for
*
* @return Bookmark found bookmark or null
*/
function getByNotice($notice)
{
return self::staticGet('uri', $notice->uri);
@ -165,11 +157,10 @@ class Bookmark extends Memcached_DataObject
*
* @return Bookmark bookmark found or null
*/
static function getByURL($profile, $url)
{
$nb = new Bookmark();
$nb->profile_id = $profile->id;
$nb->url = $url;
@ -192,13 +183,13 @@ class Bookmark extends Memcached_DataObject
*
* @return Notice saved notice
*/
static function saveNew($profile, $title, $url, $rawtags, $description,
$options=null)
{
$nb = self::getByURL($profile, $url);
if (!empty($nb)) {
// TRANS: Client exception thrown when trying to save a new bookmark that already exists.
throw new ClientException(_m('Bookmark already exists.'));
}
@ -209,6 +200,7 @@ class Bookmark extends Memcached_DataObject
if (array_key_exists('uri', $options)) {
$other = Bookmark::staticGet('uri', $options['uri']);
if (!empty($other)) {
// TRANS: Client exception thrown when trying to save a new bookmark that already exists.
throw new ClientException(_m('Bookmark already exists.'));
}
}
@ -281,15 +273,15 @@ class Bookmark extends Memcached_DataObject
try {
$user = User::staticGet('id', $profile->id);
$shortUrl = File_redirection::makeShort($url,
$shortUrl = File_redirection::makeShort($url,
empty($user) ? null : $user);
} catch (Exception $e) {
// Don't let this stop us.
$shortUrl = $url;
}
// @todo FIXME: i18n documentation.
// TRANS: %1$s is a title, %2$s is a short URL, %3$s is a description,
// TRANS: Bookmark content.
// TRANS: %1$s is a title, %2$s is a short URL, %3$s is the bookmark description,
// TRANS: %4$s is space separated list of hash tags.
$content = sprintf(_m('"%1$s" %2$s %3$s %4$s'),
$title,
@ -297,6 +289,9 @@ class Bookmark extends Memcached_DataObject
$description,
implode(' ', $hashtags));
// TRANS: Rendered bookmark content.
// TRANS: %1$s is a URL, %2$s the bookmark title, %3$s is the bookmark description,
// TRANS: %4$s is space separated list of hash tags.
$rendered = sprintf(_m('<span class="xfolkentry">'.
'<a class="taggedlink" href="%1$s">%2$s</a> '.
'<span class="description">%3$s</span> '.

View File

@ -43,7 +43,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class BookmarkPlugin extends MicroAppPlugin
{
const VERSION = '0.1';
@ -60,7 +59,6 @@ class BookmarkPlugin extends MicroAppPlugin
*
* @return boolean hook value
*/
function onUserRightsCheck($profile, $right, &$result)
{
if ($right == self::IMPORTDELICIOUS) {
@ -78,7 +76,6 @@ class BookmarkPlugin extends MicroAppPlugin
*
* @return boolean hook value; true means continue processing, false means stop.
*/
function onCheckSchema()
{
$schema = Schema::get();
@ -127,7 +124,6 @@ class BookmarkPlugin extends MicroAppPlugin
*
* @return boolean hook value
*/
function onEndShowStyles($action)
{
$action->cssLink($this->path('bookmark.css'));
@ -141,7 +137,6 @@ class BookmarkPlugin extends MicroAppPlugin
*
* @return boolean hook value; true means continue processing, false means stop.
*/
function onAutoload($cls)
{
$dir = dirname(__FILE__);
@ -175,7 +170,6 @@ class BookmarkPlugin extends MicroAppPlugin
*
* @return boolean hook value; true means continue processing, false means stop.
*/
function onRouterInitialized($m)
{
$m->connect('main/bookmark/new',
@ -204,10 +198,9 @@ class BookmarkPlugin extends MicroAppPlugin
* Add our two queue handlers to the queue manager
*
* @param QueueManager $qm current queue manager
*
*
* @return boolean hook value
*/
function onEndInitializeQueueManager($qm)
{
$qm->connect('dlcsback', 'DeliciousBackupImporter');
@ -219,10 +212,9 @@ class BookmarkPlugin extends MicroAppPlugin
* Plugin version data
*
* @param array &$versions array of version data
*
*
* @return value
*/
function onPluginVersion(&$versions)
{
$versions[] = array('name' => 'Sample',
@ -230,6 +222,7 @@ class BookmarkPlugin extends MicroAppPlugin
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:Bookmark',
'rawdescription' =>
// TRANS: Plugin description.
_m('Simple extension for supporting bookmarks.'));
return true;
}
@ -242,7 +235,6 @@ class BookmarkPlugin extends MicroAppPlugin
*
* @return boolean hook value
*/
function onStartLoadDoc(&$title, &$output)
{
if ($title == 'bookmarklet') {
@ -256,8 +248,6 @@ class BookmarkPlugin extends MicroAppPlugin
return true;
}
/**
* Show a link to our delicious import page on profile settings form
*
@ -265,15 +255,15 @@ class BookmarkPlugin extends MicroAppPlugin
*
* @return boolean hook value
*/
function onEndProfileSettingsActions($action)
{
$user = common_current_user();
if (!empty($user) && $user->hasRight(self::IMPORTDELICIOUS)) {
$action->elementStart('li');
$action->element('a',
array('href' => common_local_url('importdelicious')),
// TRANS: Link text in proile leading to import form.
_m('Import del.icio.us bookmarks'));
$action->elementEnd('li');
}
@ -294,7 +284,11 @@ class BookmarkPlugin extends MicroAppPlugin
$nb = Bookmark::getByNotice($nli->notice);
if (!empty($nb)) {
$id = (empty($nli->repeat)) ? $nli->notice->id : $nli->repeat->id;
$nli->out->elementStart('li', array('class' => 'hentry notice bookmark',
$class = 'hentry notice bookmark';
if ($nli->notice->scope != 0 && $nli->notice->scope != 1) {
$class .= ' limited-scope';
}
$nli->out->elementStart('li', array('class' => $class,
'id' => 'notice-' . $id));
Event::handle('EndOpenNoticeListItemElement', array($nli));
return false;
@ -310,7 +304,6 @@ class BookmarkPlugin extends MicroAppPlugin
*
* @return Notice resulting notice.
*/
static private function _postRemoteBookmark(Ostatus_profile $author,
Activity $activity)
{
@ -320,7 +313,7 @@ class BookmarkPlugin extends MicroAppPlugin
'url' => $bookmark->link,
'is_local' => Notice::REMOTE_OMB,
'source' => 'ostatus');
return self::_postBookmark($author->localProfile(), $activity, $options);
}
@ -331,7 +324,6 @@ class BookmarkPlugin extends MicroAppPlugin
*
* @return true if it's a Post of a Bookmark, else false
*/
static private function _isPostBookmark($activity)
{
return ($activity->verb == ActivityVerb::POST &&
@ -347,10 +339,9 @@ class BookmarkPlugin extends MicroAppPlugin
* When a notice is deleted, delete the related Bookmark
*
* @param Notice $notice Notice being deleted
*
*
* @return boolean hook value
*/
function deleteRelated($notice)
{
$nb = Bookmark::getByNotice($notice);
@ -371,7 +362,6 @@ class BookmarkPlugin extends MicroAppPlugin
*
* @return Notice resulting notice
*/
function saveNoticeFromActivity($activity, $profile, $options=array())
{
$bookmark = $activity->objects[0];
@ -379,6 +369,7 @@ class BookmarkPlugin extends MicroAppPlugin
$relLinkEls = ActivityUtils::getLinks($bookmark->element, 'related');
if (count($relLinkEls) < 1) {
// TRANS: Client exception thrown when a bookmark is formatted incorrectly.
throw new ClientException(_m('Expected exactly 1 link '.
'rel=related in a Bookmark.'));
}
@ -472,6 +463,7 @@ class BookmarkPlugin extends MicroAppPlugin
$attachments = $notice->attachments();
if (count($attachments) != 1) {
// TRANS: Server exception thrown when a bookmark has multiple attachments.
throw new ServerException(_m('Bookmark notice with the '.
'wrong number of attachments.'));
}
@ -486,7 +478,7 @@ class BookmarkPlugin extends MicroAppPlugin
}
$object->extra[] = array('link', $attrs, null);
// Attributes of the thumbnail, if any
$thumbnail = $target->getThumbnail();
@ -526,7 +518,8 @@ class BookmarkPlugin extends MicroAppPlugin
if (count($atts) < 1) {
// Something wrong; let default code deal with it.
throw new Exception("That can't be right.");
// TRANS: Exception thrown when a bookmark has no attachments.
throw new Exception(_m('Bookmark has no attachments.'));
}
$att = $atts[0];
@ -558,21 +551,23 @@ class BookmarkPlugin extends MicroAppPlugin
if (!empty($replies) || !empty($tags)) {
$out->elementStart('ul', array('class' => 'bookmark-tags'));
foreach ($replies as $reply) {
$other = Profile::staticGet('id', $reply);
$out->elementStart('li');
$out->element('a', array('rel' => 'tag',
'href' => $other->profileurl,
'title' => $other->getBestName()),
sprintf('for:%s', $other->nickname));
$out->elementEnd('li');
$out->text(' ');
if (!empty($other)) {
$out->elementStart('li');
$out->element('a', array('rel' => 'tag',
'href' => $other->profileurl,
'title' => $other->getBestName()),
sprintf('for:%s', $other->nickname));
$out->elementEnd('li');
$out->text(' ');
}
}
foreach ($tags as $tag) {
$out->elementStart('li');
$out->element('a',
$out->element('a',
array('rel' => 'tag',
'href' => Notice_tag::url($tag)),
$tag);
@ -608,7 +603,7 @@ class BookmarkPlugin extends MicroAppPlugin
$avatar = $profile->getAvatar(AVATAR_MINI_SIZE);
$out->element('img',
$out->element('img',
array('src' => ($avatar) ?
$avatar->displayUrl() :
Avatar::defaultImage(AVATAR_MINI_SIZE),
@ -620,7 +615,7 @@ class BookmarkPlugin extends MicroAppPlugin
$out->raw('&#160;'); // avoid &nbsp; for AJAX XML compatibility
$out->elementStart('span', 'vcard author'); // hack for belongsOnTimeline; JS needs to be able to find the author
$out->element('a',
$out->element('a',
array('class' => 'url',
'href' => $profile->profileurl,
'title' => $profile->getBestName()),
@ -640,6 +635,7 @@ class BookmarkPlugin extends MicroAppPlugin
function appTitle()
{
return _m('Bookmark');
// TRANS: Application title.
return _m('TITLE','Bookmark');
}
}

View File

@ -4,7 +4,7 @@
* Copyright (C) 2010, StatusNet, Inc.
*
* Form for adding a new bookmark
*
*
* PHP version 5
*
* This program is free software: you can redistribute it and/or modify
@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class BookmarkForm extends Form
{
private $_title = null;
@ -63,7 +62,6 @@ class BookmarkForm extends Form
*
* @return void
*/
function __construct($out=null, $title=null, $url=null, $tags=null,
$description=null)
{
@ -80,7 +78,6 @@ class BookmarkForm extends Form
*
* @return int ID of the form
*/
function id()
{
return 'form_new_bookmark';
@ -91,7 +88,6 @@ class BookmarkForm extends Form
*
* @return string class of the form
*/
function formClass()
{
return 'form_settings ajax-notice';
@ -102,7 +98,6 @@ class BookmarkForm extends Form
*
* @return string URL of the action
*/
function action()
{
return common_local_url('newbookmark');
@ -113,7 +108,6 @@ class BookmarkForm extends Form
*
* @return void
*/
function formData()
{
$this->out->elementStart('fieldset', array('id' => 'new_bookmark_data'));
@ -121,33 +115,47 @@ class BookmarkForm extends Form
$this->li();
$this->out->input('title',
// TRANS: Field label on form for adding a new bookmark.
_m('LABEL','Title'),
$this->_title,
_m('Title of the bookmark'));
// TRANS: Field title on form for adding a new bookmark.
_m('Title of the bookmark.'));
$this->unli();
$this->li();
$this->out->input('url',
// TRANS: Field label on form for adding a new bookmark.
_m('LABEL','URL'),
$this->_url,
_m('URL to bookmark'));
$this->_url,
// TRANS: Field title on form for adding a new bookmark.
_m('URL to bookmark.'));
$this->unli();
$this->li();
$this->out->input('tags',
// TRANS: Field label on form for adding a new bookmark.
_m('LABEL','Tags'),
$this->_tags,
_m('Comma- or space-separated list of tags'));
$this->_tags,
// TRANS: Field title on form for adding a new bookmark.
_m('Comma- or space-separated list of tags.'));
$this->unli();
$this->li();
$this->out->input('description',
// TRANS: Field label on form for adding a new bookmark.
_m('LABEL','Description'),
$this->_description,
_m('Description of the URL'));
$this->_description,
// TRANS: Field title on form for adding a new bookmark.
_m('Description of the URL.'));
$this->unli();
$this->out->elementEnd('ul');
$toWidget = new ToSelector($this->out,
common_current_user(),
null);
$toWidget->show();
$this->out->elementEnd('fieldset');
}
@ -159,6 +167,7 @@ class BookmarkForm extends Form
function formActions()
{
// TRANS: Button text for action to save a new bookmark.
$this->out->submit('submit', _m('BUTTON', 'Save'));
}
}

View File

@ -49,13 +49,12 @@ class BookmarkpopupAction extends NewbookmarkAction
*
* @return void
*/
function showTitle()
{
// TRANS: Title for mini-posting window loaded from bookmarklet.
// TRANS: %s is the StatusNet site name.
$this->element('title',
null, sprintf(_m('Bookmark on %s'),
$this->element('title',
// TRANS: Title for mini-posting window loaded from bookmarklet.
// TRANS: %s is the StatusNet site name.
null, sprintf(_m('Bookmark on %s'),
common_config('site', 'name')));
}
@ -66,7 +65,6 @@ class BookmarkpopupAction extends NewbookmarkAction
*
* @return void
*/
function showHeader()
{
$this->elementStart('div', array('id' => 'header'));
@ -86,10 +84,9 @@ class BookmarkpopupAction extends NewbookmarkAction
/**
* Hide the core section of the page
*
*
* @return void
*/
function showCore()
{
}
@ -99,7 +96,6 @@ class BookmarkpopupAction extends NewbookmarkAction
*
* @return void
*/
function showFooter()
{
}

View File

@ -4,7 +4,7 @@
* Copyright (C) 2010, StatusNet, Inc.
*
* Importer class for Delicious.com backups
*
*
* PHP version 5
*
* This program is free software: you can redistribute it and/or modify
@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class DeliciousBackupImporter extends QueueHandler
{
/**
@ -52,7 +51,6 @@ class DeliciousBackupImporter extends QueueHandler
*
* @return string transport string
*/
function transport()
{
return 'dlcsback';
@ -72,7 +70,6 @@ class DeliciousBackupImporter extends QueueHandler
*
* @return boolean success value
*/
function handle($data)
{
list($user, $body) = $data;
@ -82,7 +79,8 @@ class DeliciousBackupImporter extends QueueHandler
$dls = $doc->getElementsByTagName('dl');
if ($dls->length != 1) {
throw new ClientException(_m("Bad import file."));
// TRANS: Client exception thrown when a file upload is incorrect.
throw new ClientException(_m('Bad import file.'));
}
$dl = $dls->item(0);
@ -123,7 +121,7 @@ class DeliciousBackupImporter extends QueueHandler
common_log(LOG_INFO, 'Skipping the <p> in the <dl>.');
break;
default:
common_log(LOG_WARNING,
common_log(LOG_WARNING,
"Unexpected element $child->tagName ".
" found in import.");
}
@ -146,12 +144,12 @@ class DeliciousBackupImporter extends QueueHandler
/**
* Import a single bookmark
*
*
* Takes a <dt>/<dd> pair. The <dt> has a single
* <a> in it with some non-standard attributes.
*
*
* A <dt><dt><dd> sequence will appear as a <dt> with
* anothe <dt> as a child. We handle this case recursively.
* anothe <dt> as a child. We handle this case recursively.
*
* @param User $user User to import data as
* @param DOMElement $dt <dt> element
@ -159,12 +157,12 @@ class DeliciousBackupImporter extends QueueHandler
*
* @return Notice imported notice
*/
function importBookmark($user, $dt, $dd = null)
{
$as = $dt->getElementsByTagName('a');
if ($as->length == 0) {
// TRANS: Client exception thrown when a bookmark in an import file is incorrectly formatted.
throw new ClientException(_m("No <A> tag in a <DT>."));
}
@ -173,6 +171,7 @@ class DeliciousBackupImporter extends QueueHandler
$private = $a->getAttribute('private');
if ($private != 0) {
// TRANS: Client exception thrown when a bookmark in an import file is private.
throw new ClientException(_m('Skipping private bookmark.'));
}
@ -306,5 +305,4 @@ class DeliciousBackupImporter extends QueueHandler
$this->fixListItem($node);
}
}
}

View File

@ -4,7 +4,7 @@
* Copyright (C) 2010, StatusNet, Inc.
*
* Importer class for Delicious.com bookmarks
*
*
* PHP version 5
*
* This program is free software: you can redistribute it and/or modify
@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class DeliciousBookmarkImporter extends QueueHandler
{
/**
@ -52,7 +51,6 @@ class DeliciousBookmarkImporter extends QueueHandler
*
* @return string 'dlcsbkmk'
*/
function transport()
{
return 'dlcsbkmk';
@ -60,12 +58,11 @@ class DeliciousBookmarkImporter extends QueueHandler
/**
* Handle the data
*
*
* @param array $data associative array of user & bookmark info from DeliciousBackupImporter::importBookmark()
*
* @return boolean success value
*/
function handle($data)
{
$profile = Profile::staticGet('id', $data['profile_id']);

View File

@ -4,7 +4,7 @@
* Copyright (C) 2010 StatusNet, Inc.
*
* Import a bookmarks file as notices
*
*
* PHP version 5
*
* This program is free software: you can redistribute it and/or modify
@ -46,7 +46,7 @@ require_once INSTALLDIR.'/scripts/commandline.inc';
/**
* Get the bookmarks file as a string
*
*
* Uses the -f or --file parameter to open and read a
* a bookmarks file
*
@ -63,19 +63,25 @@ function getBookmarksFile()
}
if (!file_exists($filename)) {
throw new Exception("No such file '$filename'.");
// TRANS: Exception thrown when a file upload cannot be found.
// TRANS: %s is the file that could not be found.
throw new Exception(sprintf(_m('No such file "%s".'),$filename));
}
if (!is_file($filename)) {
throw new Exception("Not a regular file: '$filename'.");
// TRANS: Exception thrown when a file upload is incorrect.
// TRANS: %s is the irregular file.
throw new Exception(sprintf(_m('Not a regular file: "%s".'),$filename));
}
if (!is_readable($filename)) {
throw new Exception("File '$filename' not readable.");
// TRANS: Exception thrown when a file upload is not readable.
// TRANS: %s is the file that could not be read.
throw new Exception(sprintf(_m('File "%s" not readable.'),$filename));
}
// TRANS: %s is the filename that contains a backup for a user.
printfv(_m("Getting backup from file \"%s\".")."\n", $filename);
printfv(_m('Getting backup from file "%s".')."\n", $filename);
$html = file_get_contents($filename);
@ -87,7 +93,7 @@ try {
$html = getBookmarksFile();
$qm = QueueManager::get();
$qm->enqueue(array($user, $html), 'dlcsback');
} catch (Exception $e) {

View File

@ -4,7 +4,7 @@
* Copyright (C) 2010, StatusNet, Inc.
*
* Import del.icio.us bookmarks backups
*
*
* PHP version 5
*
* This program is free software: you can redistribute it and/or modify
@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class ImportdeliciousAction extends Action
{
protected $success = false;
@ -55,9 +54,9 @@ class ImportdeliciousAction extends Action
*
* @return string page title
*/
function title()
{
// TRANS: Title for page to import del.icio.us bookmark backups on.
return _m("Import del.icio.us bookmarks");
}
@ -68,7 +67,6 @@ class ImportdeliciousAction extends Action
*
* @return boolean true
*/
function prepare($argarray)
{
parent::prepare($argarray);
@ -76,12 +74,14 @@ class ImportdeliciousAction extends Action
$cur = common_current_user();
if (empty($cur)) {
// TRANS: Client exception thrown when trying to import bookmarks without being logged in.
throw new ClientException(_m('Only logged-in users can '.
'import del.icio.us backups.'),
403);
}
if (!$cur->hasRight(BookmarkPlugin::IMPORTDELICIOUS)) {
// TRANS: Client exception thrown when trying to import bookmarks without having the rights to do so.
throw new ClientException(_m('You may not restore your account.'), 403);
}
@ -95,7 +95,6 @@ class ImportdeliciousAction extends Action
*
* @return void
*/
function handle($argarray=null)
{
parent::handle($argarray);
@ -110,17 +109,17 @@ class ImportdeliciousAction extends Action
/**
* Queue a file for importation
*
*
* Uses the DeliciousBackupImporter class; may take a long time!
*
* @return void
*/
function importDelicious()
{
$this->checkSessionToken();
if (!isset($_FILES[ImportDeliciousForm::FILEINPUT]['error'])) {
// TRANS: Client exception thrown when trying to import bookmarks and upload fails.
throw new ClientException(_m('No uploaded file.'));
}
@ -134,36 +133,37 @@ class ImportdeliciousAction extends Action
return;
case UPLOAD_ERR_FORM_SIZE:
throw new ClientException(
// TRANS: Client exception.
// TRANS: Client exception thrown when an uploaded file is too large.
_m('The uploaded file exceeds the MAX_FILE_SIZE directive' .
' that was specified in the HTML form.'));
return;
case UPLOAD_ERR_PARTIAL:
@unlink($_FILES[ImportDeliciousForm::FILEINPUT]['tmp_name']);
// TRANS: Client exception.
// TRANS: Client exception thrown when a file was only partially uploaded.
throw new ClientException(_m('The uploaded file was only' .
' partially uploaded.'));
return;
case UPLOAD_ERR_NO_FILE:
// No file; probably just a non-AJAX submission.
// TRANS: Client exception thrown when a file upload has failed.
throw new ClientException(_m('No uploaded file.'));
return;
case UPLOAD_ERR_NO_TMP_DIR:
// TRANS: Client exception thrown when a temporary folder is not present
// TRANS: Client exception thrown when a temporary folder is not present.
throw new ClientException(_m('Missing a temporary folder.'));
return;
case UPLOAD_ERR_CANT_WRITE:
// TRANS: Client exception thrown when writing to disk is not possible
// TRANS: Client exception thrown when writing to disk is not possible.
throw new ClientException(_m('Failed to write file to disk.'));
return;
case UPLOAD_ERR_EXTENSION:
// TRANS: Client exception thrown when a file upload has been stopped
// TRANS: Client exception thrown when a file upload has been stopped.
throw new ClientException(_m('File upload stopped by extension.'));
return;
default:
common_log(LOG_ERR, __METHOD__ . ": Unknown upload error " .
$_FILES[ImportDeliciousForm::FILEINPUT]['error']);
// TRANS: Client exception thrown when a file upload operation has failed
// TRANS: Client exception thrown when a file upload operation has failed.
throw new ClientException(_m('System error uploading file.'));
return;
}
@ -172,18 +172,24 @@ class ImportdeliciousAction extends Action
try {
if (!file_exists($filename)) {
throw new ServerException("No such file '$filename'.");
// TRANS: Server exception thrown when a file upload cannot be found.
// TRANS: %s is the file that could not be found.
throw new ServerException(sprintf(_m('No such file "%s".'),$filename));
}
if (!is_file($filename)) {
throw new ServerException("Not a regular file: '$filename'.");
// TRANS: Server exception thrown when a file upload is incorrect.
// TRANS: %s is the irregular file.
throw new ServerException(sprintf(_m('Not a regular file: "%s".'),$filename));
}
if (!is_readable($filename)) {
throw new ServerException("File '$filename' not readable.");
// TRANS: Server exception thrown when a file upload is not readable.
// TRANS: %s is the file that could not be read.
throw new ServerException(sprintf(_m('File "%s" not readable.'),$filename));
}
common_debug(sprintf(_m("Getting backup from file '%s'."), $filename));
common_debug(sprintf("Getting backup from file '%s'.", $filename));
$html = file_get_contents($filename);
@ -214,14 +220,15 @@ class ImportdeliciousAction extends Action
*
* @return void
*/
function showContent()
{
if ($this->success) {
$this->element('p', null,
// TRANS: Success message after importing bookmarks.
_m('Bookmarks have been imported. Your bookmarks should now appear in search and your profile page.'));
} else if ($this->inprogress) {
$this->element('p', null,
// TRANS: Busy message for importing bookmarks.
_m('Bookmarks are being imported. Please wait a few minutes for results.'));
} else {
$form = new ImportDeliciousForm($this);
@ -238,7 +245,6 @@ class ImportdeliciousAction extends Action
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return !$this->isPost();
@ -255,21 +261,19 @@ class ImportdeliciousAction extends Action
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class ImportDeliciousForm extends Form
{
const FILEINPUT = 'deliciousbackupfile';
/**
* Constructor
*
*
* Set the encoding type, since this is a file upload.
*
* @param HTMLOutputter $out output channel
*
* @return ImportDeliciousForm this
*/
function __construct($out=null)
{
parent::__construct($out);
@ -281,7 +285,6 @@ class ImportDeliciousForm extends Form
*
* @return string the form's class
*/
function formClass()
{
return 'form_import_delicious';
@ -292,7 +295,6 @@ class ImportDeliciousForm extends Form
*
* @return string the form's action URL
*/
function action()
{
return common_local_url('importdelicious');
@ -300,19 +302,19 @@ class ImportDeliciousForm extends Form
/**
* Output form data
*
*
* Really, just instructions for doing a backup.
*
* @return void
*/
function formData()
{
$this->out->elementStart('p', 'instructions');
// TRANS: Form instructions for importing bookmarks.
$this->out->raw(_m('You can upload a backed-up '.
'delicious.com bookmarks file.'));
$this->out->elementEnd('p');
$this->out->elementStart('ul', 'form_data');
@ -328,7 +330,7 @@ class ImportDeliciousForm extends Form
/**
* Buttons for the form
*
*
* In this case, a single submit button
*
* @return void
@ -337,9 +339,11 @@ class ImportDeliciousForm extends Form
function formActions()
{
$this->out->submit('submit',
// TRANS: Button text on form to import bookmarks.
_m('BUTTON', 'Upload'),
'submit',
null,
_m('Upload the file'));
// TRANS: Button title on form to import bookmarks.
_m('Upload the file.'));
}
}

View File

@ -4,7 +4,7 @@
* Copyright (C) 2010, StatusNet, Inc.
*
* Add a new bookmark
*
*
* PHP version 5
*
* This program is free software: you can redistribute it and/or modify
@ -43,7 +43,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class NewbookmarkAction extends Action
{
protected $user = null;
@ -59,9 +58,9 @@ class NewbookmarkAction extends Action
*
* @return string Action title
*/
function title()
{
// TRANS: Title for action to create a new bookmark.
return _m('New bookmark');
}
@ -72,7 +71,6 @@ class NewbookmarkAction extends Action
*
* @return boolean true
*/
function prepare($argarray)
{
parent::prepare($argarray);
@ -80,7 +78,8 @@ class NewbookmarkAction extends Action
$this->user = common_current_user();
if (empty($this->user)) {
throw new ClientException(_m("Must be logged in to post a bookmark."),
// TRANS: Client exception thrown when trying to create a new bookmark while not logged in.
throw new ClientException(_m('Must be logged in to post a bookmark.'),
403);
}
@ -103,7 +102,6 @@ class NewbookmarkAction extends Action
*
* @return void
*/
function handle($argarray=null)
{
parent::handle($argarray);
@ -122,7 +120,6 @@ class NewbookmarkAction extends Action
*
* @return void
*/
function newBookmark()
{
if ($this->boolean('ajax')) {
@ -130,19 +127,25 @@ class NewbookmarkAction extends Action
}
try {
if (empty($this->title)) {
// TRANS: Client exception thrown when trying to create a new bookmark without a title.
throw new ClientException(_m('Bookmark must have a title.'));
}
if (empty($this->url)) {
// TRANS: Client exception thrown when trying to create a new bookmark without a URL.
throw new ClientException(_m('Bookmark must have an URL.'));
}
$options = array();
ToSelector::fillOptions($this, $options);
$saved = Bookmark::saveNew($this->user->getProfile(),
$this->title,
$this->url,
$this->tags,
$this->description);
$this->title,
$this->url,
$this->tags,
$this->description,
$options);
} catch (ClientException $ce) {
$this->error = $ce->getMessage();
@ -155,8 +158,8 @@ class NewbookmarkAction extends Action
$this->xw->startDocument('1.0', 'UTF-8');
$this->elementStart('html');
$this->elementStart('head');
// TRANS: Page title after sending a notice.
$this->element('title', null, _m('Notice posted'));
// TRANS: Page title after posting a bookmark.
$this->element('title', null, _m('Bookmark posted'));
$this->elementEnd('head');
$this->elementStart('body');
$this->showNotice($saved);
@ -188,7 +191,6 @@ class NewbookmarkAction extends Action
*
* @return void
*/
function showContent()
{
if (!empty($this->error)) {
@ -215,7 +217,6 @@ class NewbookmarkAction extends Action
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
@ -226,4 +227,3 @@ class NewbookmarkAction extends Action
}
}
}

View File

@ -4,7 +4,7 @@
* Copyright (C) 2010, StatusNet, Inc.
*
* Notice stream of notices with a given attachment
*
*
* PHP version 5
*
* This program is free software: you can redistribute it and/or modify
@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class NoticebyurlAction extends Action
{
protected $url = null;
@ -59,15 +58,15 @@ class NoticebyurlAction extends Action
*
* @return boolean true
*/
function prepare($argarray)
{
parent::prepare($argarray);
$this->file = File::staticGet('id', $this->trimmed('id'));
if (empty($this->file)) {
throw new ClientException(_m('Unknown URL'));
// TRANS: Client exception thrown when an unknown URL is provided.
throw new ClientException(_m('Unknown URL.'));
}
$pageArg = $this->trimmed('page');
@ -85,13 +84,16 @@ class NoticebyurlAction extends Action
*
* @return string page title
*/
function title()
{
if ($this->page == 1) {
return sprintf(_m("Notices linking to %s"), $this->file->url);
// TRANS: Title of notice stream of notices with a given attachment (first page).
// TRANS: %s is the URL.
return sprintf(_m('Notices linking to %s'), $this->file->url);
} else {
return sprintf(_m("Notices linking to %1$s, page %2$d"),
// TRANS: Title of notice stream of notices with a given attachment (all but first page).
// TRANS: %1$s is the URL, %2$s is the page number.
return sprintf(_m('Notices linking to %1$s, page %2$d'),
$this->file->url,
$this->page);
}
@ -104,7 +106,6 @@ class NoticebyurlAction extends Action
*
* @return void
*/
function handle($argarray=null)
{
$this->showPage();
@ -117,7 +118,6 @@ class NoticebyurlAction extends Action
*
* @return void
*/
function showContent()
{
$nl = new NoticeList($this->notices, $this);
@ -142,7 +142,6 @@ class NoticebyurlAction extends Action
*
* @return boolean is read only action?
*/
function isReadOnly($args)
{
return true;
@ -169,7 +168,6 @@ class NoticebyurlAction extends Action
*
* @return string etag http header
*/
function etag()
{
return null;

View File

@ -50,7 +50,6 @@ class ShowbookmarkAction extends ShownoticeAction
function getNotice()
{
$this->id = $this->trimmed('id');
$this->bookmark = Bookmark::staticGet('id', $this->id);

View File

@ -103,6 +103,7 @@ class CacheLogPlugin extends Plugin
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:CacheLog',
'description' =>
// TRANS: Plugin description.
_m('Log reads and writes to the cache.'));
return true;
}

View File

@ -125,12 +125,15 @@ class CasAuthenticationPlugin extends AuthenticationPlugin
function onInitializePlugin(){
parent::onInitializePlugin();
if(!isset($this->server)){
// TRANS: Exception thrown when the CAS Authentication plugin has been configured incorrectly.
throw new Exception(_m("Specifying a server is required."));
}
if(!isset($this->port)){
// TRANS: Exception thrown when the CAS Authentication plugin has been configured incorrectly.
throw new Exception(_m("Specifying a port is required."));
}
if(!isset($this->path)){
// TRANS: Exception thrown when the CAS Authentication plugin has been configured incorrectly.
throw new Exception(_m("Specifying a path is required."));
}
//These values need to be accessible to a action object

View File

@ -25,6 +25,7 @@ class CasloginAction extends Action
{
parent::handle($args);
if (common_is_real_login()) {
// TRANS: Client error displayed when trying to log in while already logged on.
$this->clientError(_m('Already logged in.'));
} else {
global $casSettings;
@ -36,12 +37,14 @@ class CasloginAction extends Action
$casTempPassword = common_good_rand(16);
$user = common_check_user(phpCAS::getUser(), $casTempPassword);
if (!$user) {
// TRANS: Server error displayed when trying to log in with incorrect username or password.
$this->serverError(_m('Incorrect username or password.'));
return;
}
// success!
if (!common_set_user($user)) {
// TRANS: Server error displayed when login fails in CAS authentication plugin.
$this->serverError(_m('Error setting user. You are probably not authorized.'));
return;
}

View File

@ -73,6 +73,7 @@ class ClientSideShortenPlugin extends Plugin
'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:ClientSideShorten',
'rawdescription' =>
// TRANS: Plugin description.
_m('ClientSideShorten causes the web interface\'s notice form to automatically shorten URLs as they entered, and before the notice is submitted.'));
return true;
}

View File

@ -1,4 +1,5 @@
ClientSideShorten causes the web interface's notice form to automatically shorten urls as they entered, and before the notice is submitted.
ClientSideShorten causes the web interface's notice form to automatically
shorten URLs as they entered, and before the notice is submitted.
Installation
============

View File

@ -16,7 +16,7 @@
function delayed () {
if (!execAsap)
func.apply(obj, args);
timeout = null;
timeout = null;
};
if (timeout)
@ -24,7 +24,7 @@
else if (execAsap)
func.apply(obj, args);
timeout = setTimeout(delayed, threshold || 100);
timeout = setTimeout(delayed, threshold || 100);
};
}
jQuery.fn[sr] = function(fn){ return fn ? this.bind('keypress', debounce(fn, 1000)) : this.trigger(sr); };

View File

@ -52,7 +52,8 @@ class ShortenAction extends Action
$this->users=array();
$this->text = $this->arg('text');
if(is_null($this->text)){
throw new ClientException(_m('\'text\' argument must be specified.'));
// TRANS: Client exception thrown when a text argument is not present.
throw new ClientException(_m('"text" argument must be specified.'));
}
return true;
}

View File

@ -1,6 +1,5 @@
<?php
/*
*
* Phomet: a php comet client
*
* Copyright (C) 2008 Morgan 'ARR!' Allen <morganrallen@gmail.com> http://morglog.alleycatracing.com

View File

@ -1,6 +1,4 @@
// update the local timeline from a Comet server
//
var CometUpdate = function()
{
var _server;
@ -27,4 +25,3 @@ var CometUpdate = function()
}
}
}();

View File

@ -261,6 +261,7 @@ class DirectionDetectorPlugin extends Plugin {
'version' => DIRECTIONDETECTORPLUGIN_VERSION,
'author' => 'Behrooz Shabani',
'homepage' => $url,
// TRANS: Plugin description.
'rawdescription' => _m('Shows notices with right-to-left content in correct direction.')
);
return true;

View File

@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
*/
class DirectoryPlugin extends Plugin
{
private $dir = null;
/**
@ -165,8 +164,10 @@ class DirectoryPlugin extends Plugin
$nav->out->menuItem(
common_local_url('userdirectory'),
_m('Directory'),
_m('User Directory'),
// TRANS: Menu item text for user directory.
_m('MENU','Directory'),
// TRANS: Menu item title for user directory.
_m('User Directory.'),
$actionName == 'userdirectory',
'nav_directory'
);
@ -184,6 +185,7 @@ class DirectoryPlugin extends Plugin
'version' => STATUSNET_VERSION,
'author' => 'Zach Copley',
'homepage' => 'http://status.net/wiki/Plugin:Directory',
// TRANS: Plugin description.
'rawdescription' => _m('Add a user directory.')
);

View File

@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/
*/
class DiskCachePlugin extends Plugin
{
var $root = '/tmp';
@ -64,7 +63,6 @@ class DiskCachePlugin extends Plugin
*
* @return boolean hook success
*/
function onStartCacheGet(&$key, &$value)
{
$filename = $this->keyToFilename($key);
@ -91,7 +89,6 @@ class DiskCachePlugin extends Plugin
*
* @return boolean hook success
*/
function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
{
$filename = $this->keyToFilename($key);
@ -152,7 +149,6 @@ class DiskCachePlugin extends Plugin
*
* @return boolean hook success
*/
function onStartCacheDelete(&$key, &$success)
{
$filename = $this->keyToFilename($key);
@ -172,6 +168,7 @@ class DiskCachePlugin extends Plugin
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:DiskCache',
'rawdescription' =>
// TRANS: Plugin description.
_m('Plugin to implement cache interface with disk files.'));
return true;
}

View File

@ -140,6 +140,7 @@ ENDOFSCRIPT;
$action->elementStart('noscript');
// TRANS: User notification that JavaScript is required for Disqus comment display.
// TRANS: This message contains Markdown links in the form [description](link).
$noScriptMsg = sprintf(_m("Please enable JavaScript to view the [comments powered by Disqus](http://disqus.com/?ref_noscript=%s)."), $this->shortname);
$output = common_markup_to_html($noScriptMsg);
$action->raw($output);

View File

@ -215,7 +215,6 @@ class Happening extends Managed_DataObject
function getRSVP($profile)
{
common_log(LOG_DEBUG, "Finding RSVP for " . $profile->id . ', ' . $this->id);
return RSVP::pkeyGet(array('profile_id' => $profile->id,
'event_id' => $this->id));
}

View File

@ -138,8 +138,6 @@ class RSVP extends Managed_DataObject
function saveNew($profile, $event, $verb, $options=array())
{
common_debug("RSVP::saveNew({$profile->id}, {$event->id}, '$verb', 'some options');");
if (array_key_exists('uri', $options)) {
$other = RSVP::staticGet('uri', $options['uri']);
if (!empty($other)) {
@ -161,8 +159,6 @@ class RSVP extends Managed_DataObject
$rsvp->event_id = $event->id;
$rsvp->response = self::codeFor($verb);
common_debug("Got value {$rsvp->response} for verb {$verb}");
if (array_key_exists('created', $options)) {
$rsvp->created = $options['created'];
} else {
@ -178,6 +174,8 @@ class RSVP extends Managed_DataObject
$rsvp->insert();
self::blow('rsvp:for-event:%s', $event->id);
// XXX: come up with something sexier
$content = $rsvp->asString();
@ -256,18 +254,39 @@ class RSVP extends Managed_DataObject
static function forEvent($event)
{
$keypart = sprintf('rsvp:for-event:%s', $event->id);
$idstr = self::cacheGet($keypart);
if ($idstr !== false) {
$ids = explode(',', $idstr);
} else {
$ids = array();
$rsvp = new RSVP();
$rsvp->selectAdd();
$rsvp->selectAdd('id');
$rsvp->event_id = $event->id;
if ($rsvp->find()) {
while ($rsvp->fetch()) {
$ids[] = $rsvp->id;
}
}
self::cacheSet($keypart, implode(',', $ids));
}
$rsvps = array(RSVP::POSITIVE => array(),
RSVP::NEGATIVE => array(),
RSVP::POSSIBLE => array());
$rsvp = new RSVP();
$rsvp->event_id = $event->id;
if ($rsvp->find()) {
while ($rsvp->fetch()) {
foreach ($ids as $id) {
$rsvp = RSVP::staticGet('id', $id);
if (!empty($rsvp)) {
$verb = self::verbFor($rsvp->response);
$rsvps[$verb][] = clone($rsvp);
$rsvps[$verb][] = $rsvp;
}
}
@ -375,4 +394,10 @@ class RSVP extends Managed_DataObject
$profile->getBestName(),
$eventTitle);
}
function delete()
{
self::blow('rsvp:for-event:%s', $event->id);
parent::delete();
}
}

View File

@ -147,14 +147,13 @@ class EventForm extends Form
_m('Description of the event.'));
$this->unli();
$this->li();
$this->out->elementEnd('ul');
$toWidget = new ToSelector($this->out,
common_current_user(),
null);
$toWidget->show();
$this->unli();
$this->out->elementEnd('ul');
$this->out->elementEnd('fieldset');
}

View File

@ -20,11 +20,17 @@
define('INSTALLDIR', realpath(dirname(__FILE__) . '/../../..'));
$longoptions = array('unsub');
$shortoptions = 'u';
$helptext = <<<END_OF_HELP
resub-feed.php [options] http://example.com/atom-feed-url
Reinitialize the PuSH subscription for the given feed. This may help get
things restarted if we and the hub have gotten our states out of sync.
Options:
-u --unsub Unsubscribe instead of subscribing.
END_OF_HELP;
@ -48,8 +54,14 @@ print "Old state:\n";
showSub($sub);
print "\n";
print "Pinging hub $sub->huburi with new subscription for $sub->uri\n";
$ok = $sub->subscribe();
if (have_option('u') || have_option('--unsub')) {
print "Pinging hub $sub->huburi with unsubscription for $sub->uri\n";
$ok = $sub->unsubscribe();
} else {
print "Pinging hub $sub->huburi with new subscription for $sub->uri\n";
$ok = $sub->subscribe();
}
if ($ok) {
print "ok\n";

View File

@ -138,10 +138,19 @@ class NewPollAction extends Action
throw new ClientException(_m('Poll must have at least two options.'));
}
// Notice options; distinct from choices for the poll
$options = array();
// Does the heavy-lifting for getting "To:" information
ToSelector::fillOptions($this, $options);
$saved = Poll::saveNew($this->user->getProfile(),
$this->question,
$this->options);
$this->question,
$this->options,
$options);
} catch (ClientException $ce) {
$this->error = $ce->getMessage();
$this->showPage();

View File

@ -131,6 +131,12 @@ class NewpollForm extends Form
}
$this->out->elementEnd('ul');
$toWidget = new ToSelector($this->out,
common_current_user(),
null);
$toWidget->show();
$this->out->elementEnd('fieldset');
}

View File

@ -205,7 +205,7 @@ class QnAPlugin extends MicroAppPlugin
$questionObj = $activity->objects[0];
if ($questinoObj->type != QnA_Question::OBJECT_TYPE) {
if ($questionObj->type != QnA_Question::OBJECT_TYPE) {
throw new Exception('Wrong type for object.');
}
@ -295,9 +295,13 @@ class QnAPlugin extends MicroAppPlugin
{
case QnA_Question::OBJECT_TYPE:
$id = (empty($nli->repeat)) ? $nli->notice->id : $nli->repeat->id;
$class = 'hentry notice question';
if ($nli->notice->scope != 0 && $nli->notice->scope != 1) {
$class .= ' limited-scope';
}
$nli->out->elementStart(
'li', array(
'class' => 'hentry notice question',
'class' => $class,
'id' => 'notice-' . $id
)
);
@ -309,7 +313,7 @@ class QnAPlugin extends MicroAppPlugin
$cls = array('hentry', 'notice', 'answer');
$answer = QnA_Answer::staticGet('uri', $notice->uri);
$answer = QnA_Answer::staticGet('uri', $nli->notice->uri);
if (!empty($answer) && !empty($answer->best)) {
$cls[] = 'best';

View File

@ -155,13 +155,39 @@ class QnanewanswerAction extends Action
$answer = $this->question->getAnswer($profile);
header('Content-Type: text/xml;charset=utf-8');
$this->xw->startDocument('1.0', 'UTF-8');
$this->elementStart('html');
$this->elementStart('head');
// TRANS: Page title after sending an answer.
$this->element('title', null, _m('Answers'));
$this->elementEnd('head');
$this->elementStart('body');
$this->raw($answer->asHTML());
$nli = new NoticeListItem($notice, $this);
$nli->show();
//$this->raw($answer->asHTML());
/*
$question = $this->question;
$nli = new NoticeListItem($notice, $this);
$nli->showNotice();
$this->elementStart('div', array('class' => 'entry-content answer-content'));
if (!empty($answer)) {
$form = new QnashowanswerForm($this, $answer);
$form->show();
} else {
$this->text(_m('Answer data is missing.'));
}
$this->elementEnd('div');
// @fixme
//$this->elementStart('div', array('class' => 'entry-content'));
*/
$this->elementEnd('body');
$this->elementEnd('html');
} else {

View File

@ -88,7 +88,6 @@ class QnanewquestionAction extends Action
}
$this->title = $this->trimmed('title');
common_debug("TITLE = " . $this->title);
$this->description = $this->trimmed('description');
return true;
@ -130,10 +129,17 @@ class QnanewquestionAction extends Action
throw new ClientException(_m('Question must have a title.'));
}
// Notice options
$options = array();
// Does the heavy-lifting for getting "To:" information
ToSelector::fillOptions($this, $options);
$saved = QnA_Question::saveNew(
$this->user->getProfile(),
$this->title,
$this->description
$this->description,
$options
);
} catch (ClientException $ce) {
$this->error = $ce->getMessage();

View File

@ -97,7 +97,49 @@ class QnashowquestionAction extends ShownoticeAction
function showContent()
{
$this->elementStart('div', 'qna-full-question');
$this->raw($this->question->asHTML());
$answer = $this->question->getAnswers();
$this->elementStart('div', 'qna-full-question-answers');
$answerIds = array();
// @fixme use a filtered stream!
if (!empty($answer)) {
while ($answer->fetch()) {
$answerIds[] = $answer->getNotice()->id;
}
}
if (count($answerIds) > 0) {
$notice = new Notice();
$notice->query(
sprintf(
'SELECT notice.* FROM notice WHERE notice.id IN (%s)',
implode(',', $answerIds)
)
);
$nli = new NoticeList($notice, $this);
$nli->show();
}
$user = common_current_user();
if (!empty($user)) {
$profile = $user->getProfile();
$answer = QnA_Question::getAnswer($profile);
if (empty($answer)) {
$form = new QnanewanswerForm($this, $this->question, false);
$form->show();
}
}
$this->elementEnd('div');
$this->elementEnd('div');
}
/**
@ -111,9 +153,11 @@ class QnashowquestionAction extends ShownoticeAction
{
// TRANS: Page title for a question.
// TRANS: %1$s is the nickname of the user who asked the question, %2$s is the question.
return sprintf(_m('%1$s\'s question: %2$s'),
$this->user->nickname,
$this->question->title);
return sprintf(
_m('%1$s\'s question: %2$s'),
$this->user->nickname,
$this->question->title
);
}
/**

View File

@ -155,6 +155,11 @@ class QnA_Answer extends Managed_DataObject
return Notice::staticGet('uri', $this->uri);
}
static function fromNotice($notice)
{
return QnA_Answer::staticGet('uri', $notice->uri);
}
function bestUrl()
{
return $this->getNotice()->bestUrl();

View File

@ -189,9 +189,11 @@ class QnA_Question extends Managed_DataObject
function countAnswers()
{
$a = new QnA_Answer();
$a = new QnA_Answer();
$a->question_id = $this->id;
return $a-count();
return $a->count();
}
static function fromNotice($notice)
@ -221,6 +223,14 @@ class QnA_Question extends Managed_DataObject
$out->elementEnd('span');
}
$cnt = $question->countAnswers();
if (!empty($cnt)) {
$out->elementStart('span', 'answer-count');
$out->text(sprintf(_m('%s answers'), $cnt));
$out->elementEnd('span');
}
if (!empty($question->closed)) {
$out->elementStart('span', 'question-closed');
$out->text(_m('This question is closed.'));

View File

@ -47,6 +47,7 @@ if (!defined('STATUSNET')) {
class QnanewanswerForm extends Form
{
protected $question;
protected $showQuestion;
/**
* Construct a new answer form
@ -56,10 +57,11 @@ class QnanewanswerForm extends Form
*
* @return void
*/
function __construct(HTMLOutputter $out, QnA_Question $question)
function __construct(HTMLOutputter $out, QnA_Question $question, $showQuestion = true)
{
parent::__construct($out);
$this->question = $question;
$this->showQuestion = $showQuestion;
}
/**
@ -103,9 +105,10 @@ class QnanewanswerForm extends Form
$out = $this->out;
$id = "question-" . $question->id;
$out->raw($this->question->asHTML());
if ($this->showQuestion) {
$out->raw($this->question->asHTML());
}
$out->element('p', 'answer', 'Your answer');
$out->hidden('id', $id);
$out->textarea('answer', 'answer');
}
@ -118,7 +121,7 @@ class QnanewanswerForm extends Form
function formActions()
{
// TRANS: Button text for submitting a poll response.
$this->out->submit('submit', _m('BUTTON', 'Submit'));
$this->out->submit('submit', _m('BUTTON', 'Answer'));
}
}

View File

@ -121,6 +121,12 @@ class QnanewquestionForm extends Form
$this->unli();
$this->out->elementEnd('ul');
$toWidget = new ToSelector(
$this->out,
common_current_user(),
null
);
$toWidget->show();
$this->out->elementEnd('fieldset');
}

View File

@ -46,14 +46,14 @@ require_once INSTALLDIR . '/lib/form.php';
class QnashowanswerForm extends Form
{
/**
* The answer to revise
* The answer to show
*/
var $answer = null;
protected $answer = null;
/**
* The question this is an answer to
*/
var $question = null;
protected $question = null;
/**
* Constructor
@ -65,8 +65,8 @@ class QnashowanswerForm extends Form
{
parent::__construct($out);
$this->answer = $answer;
$this->question = $answer->getQuestion();
$this->answer = $answer;
$this->question = $answer->getQuestion();
}
/**
@ -76,7 +76,7 @@ class QnashowanswerForm extends Form
*/
function id()
{
return 'revise-' . $this->answer->id;
return 'show-' . $this->answer->id;
}
/**
@ -109,8 +109,8 @@ class QnashowanswerForm extends Form
*/
function formLegend()
{
// TRANS: Form legend for revising the answer.
$this->out->element('legend', null, _('Revise your answer'));
// TRANS: Form legend for showing the answer.
$this->out->element('legend', null, _('Answer'));
}
/**
@ -122,9 +122,9 @@ class QnashowanswerForm extends Form
{
$this->out->hidden(
'id',
'revise-' . $this->answer->id
'answer-' . $this->answer->id
);
$this->out->raw($this->answer->asHTML());
}
@ -155,6 +155,13 @@ class QnashowanswerForm extends Form
}
}
/*
* @fixme: Revise is disabled until we figure out the
* Ostatus bits This comment is just a reminder
* that the UI for this works.
*/
/*
if ($user->id == $this->answer->profile_id) {
$this->out->submit(
'revise',
@ -166,6 +173,7 @@ class QnashowanswerForm extends Form
_('Revise your answer')
);
}
*/
}
}
@ -176,6 +184,6 @@ class QnashowanswerForm extends Form
*/
function formClass()
{
return 'form_revise ajax';
return 'form_show ajax';
}
}

View File

@ -118,7 +118,7 @@ class QnashowquestionForm extends Form
'question-' . $this->question->id
);
$this->out->raw($this->question->asHTML());
$this->out->raw($this->question->asHTML());
}
/**

View File

@ -0,0 +1,83 @@
<?php
/*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2011, StatusNet, Inc.
*
* 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/>.
*/
if (!defined('STATUSNET')) {
exit(1);
}
/**
* Check DB queries for filesorts and such and log em.
*
* @package SQLStatsPlugin
* @maintainer Evan Prodromou <brion@status.net>
*/
class SQLStatsPlugin extends Plugin
{
protected $queryCount = 0;
protected $queryStart = 0;
protected $queryTimes = array();
protected $queries = array();
function onPluginVersion(&$versions)
{
$versions[] = array('name' => 'SQLStats',
'version' => STATUSNET_VERSION,
'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:SQLStats',
'rawdescription' =>
_m('Debug tool to watch for poorly indexed DB queries.'));
return true;
}
function onStartDBQuery($obj, $query, &$result)
{
$this->queryStart = microtime(true);
return true;
}
function onEndDBQuery($obj, $query, &$result)
{
$endTime = microtime(true);
$this->queryTimes[] = round(($endTime - $this->queryStart) * 1000);
$this->queries[] = trim(preg_replace('/\s/', ' ', $query));
$this->queryStart = 0;
return true;
}
function cleanup()
{
$this->log(LOG_INFO, sprintf('%d queries this hit (total = %d, avg = %d, max = %d, min = %d)',
count($this->queryTimes),
array_sum($this->queryTimes),
array_sum($this->queryTimes)/count($this->queryTimes),
max($this->queryTimes),
min($this->queryTimes)));
$verbose = common_config('sqlstats', 'verbose');
if ($verbose) {
foreach ($this->queries as $query) {
$this->log(LOG_INFO, $query);
}
}
}
}

View File

@ -120,6 +120,7 @@ class SearchSub extends Managed_DataObject
$ts->profile_id = $profile->id;
$ts->created = common_sql_now();
$ts->insert();
self::blow('searchsub:by_profile:%d', $profile->id);
return $ts;
}
@ -135,6 +136,34 @@ class SearchSub extends Managed_DataObject
'profile_id' => $profile->id));
if ($ts) {
$ts->delete();
self::blow('searchsub:by_profile:%d', $profile->id);
}
}
static function forProfile(Profile $profile)
{
$searches = array();
$keypart = sprintf('searchsub:by_profile:%d', $profile->id);
$searchstring = self::cacheGet($keypart);
if ($searchstring !== false && !empty($searchstring)) {
$searches = explode(',', $searchstring);
} else {
$searchsub = new SearchSub();
$searchsub->profile_id = $profile->id;
if ($searchsub->find()) {
while ($searchsub->fetch()) {
if (!empty($searchsub->search)) {
$searches[] = $searchsub->search;
}
}
}
self::cacheSet($keypart, implode(',', $searches));
}
return $searches;
}
}

View File

@ -80,6 +80,7 @@ class SearchSubPlugin extends Plugin
case 'SearchunsubAction':
case 'SearchsubsAction':
case 'SearchSubForm':
case 'SearchSubMenu':
case 'SearchUnsubForm':
case 'SearchSubTrackCommand':
case 'SearchSubTrackOffCommand':
@ -318,4 +319,19 @@ class SearchSubPlugin extends Plugin
// TRANS: Help message for IM/SMS command "tracking"
$commands["tracking"] = _m('COMMANDHELP', "List all your search subscriptions.");
}
function onEndDefaultLocalNav($menu, $user)
{
$user = common_current_user();
$searches = SearchSub::forProfile($user->getProfile());
if (!empty($searches) && count($searches) > 0) {
$searchSubMenu = new SearchSubMenu($menu->out, $user, $searches);
$menu->submenu(_m('Searches'), $searchSubMenu);
}
return true;
}
}

View File

@ -0,0 +1,78 @@
<?php
/**
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2011, StatusNet, Inc.
*
* Menu to show searches you're subscribed to
*
* PHP version 5
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Menu
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2011 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
// This check helps protect against security problems;
// your code file can't be executed directly from the web.
exit(1);
}
/**
* Class comment
*
* @category General
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2011 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class SearchSubMenu extends Menu
{
protected $user;
protected $searches;
function __construct($out, $user, $searches)
{
parent::__construct($out);
$this->user = $user;
$this->searches = $searches;
}
function show()
{
$this->out->elementStart('ul', array('class' => 'nav'));
foreach ($this->searches as $search) {
if (!empty($search)) {
$this->out->menuItem(common_local_url('noticesearch',
array('q' => $search)),
sprintf('"%s"', $search),
sprintf(_('Notices including %s'), $search),
$this->actionName == 'noticesearch' && $this->action->arg('q') == $search,
'nav_streams_search_'.$search);
}
}
$this->out->elementEnd('ul');
}
}

View File

@ -120,6 +120,7 @@ class TagSub extends Managed_DataObject
$ts->profile_id = $profile->id;
$ts->created = common_sql_now();
$ts->insert();
self::blow('tagsub:by_profile:%d', $profile->id);
return $ts;
}
@ -135,6 +136,34 @@ class TagSub extends Managed_DataObject
'profile_id' => $profile->id));
if ($ts) {
$ts->delete();
self::blow('tagsub:by_profile:%d', $profile->id);
}
}
static function forProfile(Profile $profile)
{
$tags = array();
$keypart = sprintf('tagsub:by_profile:%d', $profile->id);
$tagstring = self::cacheGet($keypart);
if ($tagstring !== false && !empty($tagstring)) {
$tags = explode(',', $tagstring);
} else {
$tagsub = new TagSub();
$tagsub->profile_id = $profile->id;
if ($tagsub->find()) {
while ($tagsub->fetch()) {
if (!empty($tagsub->tag)) {
$tags[] = $tagsub->tag;
}
}
}
self::cacheSet($keypart, implode(',', $tags));
}
return $tags;
}
}

View File

@ -80,6 +80,7 @@ class TagSubPlugin extends Plugin
case 'TagunsubAction':
case 'TagsubsAction':
case 'TagSubForm':
case 'TagSubMenu':
case 'TagUnsubForm':
include_once $dir.'/'.strtolower($cls).'.php';
return false;
@ -239,4 +240,19 @@ class TagSubPlugin extends Plugin
}
return true;
}
function onEndDefaultLocalNav($menu, $user)
{
$user = common_current_user();
$tags = TagSub::forProfile($user->getProfile());
if (!empty($tags) && count($tags) > 0) {
$tagSubMenu = new TagSubMenu($menu->out, $user, $tags);
$menu->submenu(_m('Tags'), $tagSubMenu);
}
return true;
}
}

View File

@ -0,0 +1,78 @@
<?php
/**
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2011, StatusNet, Inc.
*
* Menu to show tags you're subscribed to
*
* PHP version 5
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Menu
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2011 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
if (!defined('STATUSNET')) {
// This check helps protect against security problems;
// your code file can't be executed directly from the web.
exit(1);
}
/**
* Class comment
*
* @category General
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @copyright 2011 StatusNet, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/
*/
class TagSubMenu extends Menu
{
protected $user;
protected $tags;
function __construct($out, $user, $tags)
{
parent::__construct($out);
$this->user = $user;
$this->tags = $tags;
}
function show()
{
$this->out->elementStart('ul', array('class' => 'nav'));
foreach ($this->tags as $tag) {
if (!empty($tag)) {
$this->out->menuItem(common_local_url('tag',
array('tag' => $tag)),
sprintf('#%s', $tag),
sprintf(_('Notices tagged with %s'), $tag),
$this->actionName == 'tag' && $this->action->arg('tag') == $tag,
'nav_streams_tag_'.$tag);
}
}
$this->out->elementEnd('ul');
}
}

View File

@ -1,2 +1,6 @@
Default avatars are modified from an image by Francesco 'Architetto' Rollandin.
http://www.openclipart.org/detail/34957
Icons by Mark James
http://www.famfamfam.com/lab/icons/silk/
http://creativecommons.org/licenses/by/2.5/ Creative Commons Attribution 2.5 License

View File

@ -286,7 +286,7 @@ address {
padding-bottom: 15px;
}
#input_form_status {
#input_form_status, #input_form_direct {
padding-bottom: 45px;
}
@ -333,6 +333,10 @@ address {
font-size: 1.2em;
}
#form_notice-direct.form_notice textarea {
width: 498px;
}
.form_notice label.notice_data-attach {
top: 0px;
right: 0px;
@ -355,6 +359,11 @@ address {
z-index: 99;
}
#form_notice-direct.form_notice .count {
top: 80px;
right: 10px;
}
.form_notice #notice_action-submit {
position: absolute;
top: 100%;
@ -397,6 +406,52 @@ address {
margin-bottom: 10px !important;
}
.to-selector {
padding-top: 15px;
z-index: 99;
}
.form_settings label[for=notice_to] {
margin-left: 100px;
margin-right: 5px;
}
.checkbox-wrapper {
padding: 2px;
clear: left;
display: block;
margin-left: 26%;
}
.form_notice .checkbox-wrapper {
display: inline;
margin-left: 10px;
}
.form_settings .checkbox-wrapper label.checkbox {
margin-left: 0px;
margin-top: 6px;
line-height: 1.2em;
left: -3px;
}
.checkbox-wrapper #notice_private {
display:none;
}
.checkbox-wrapper.unchecked label.checkbox {
padding-left: 20px;
background: url(../images/lock_open.png) no-repeat 0px 0px;
opacity: 0.6;
}
.checkbox-wrapper.checked label.checkbox {
padding-left: 20px;
background: url(../images/lock.png) no-repeat 0px 0px;
color: red;
opacity: 1;
}
#aside_primary {
width: 218px;
float: left;
@ -1246,37 +1301,63 @@ table.profile_list tr.alt {
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FB6104', endColorstr='#fc8035',GradientType=0 );
}
/* Limited-scope specific styles */
.limited-scope .entry-content .timestamp {
padding-left: 20px;
position: relative;
}
.limited-scope .entry-content .timestamp:before {
content: url(../images/lock.png);
position: absolute;
top: -2px;
left: 0px;
}
/* QnA specific styles */
#content .question .entry-title {
#content .question .entry-title, #content .qna-full-question .entry-title {
min-height: 1px;
}
.question div.question-description {
font-size: 1em;
line-height: 1.36em;
margin-top: 0px;
opacity: 1;
}
.question fieldset {
.question div.answer-content, .qna-full-question div.answer-content {
opacity: 1;
}
.question .answer-count, .qna-full-question .answer-count {
display: block;
clear: left;
}
.question .answer-count:before, .qna-full-question .answer-count:before {
content: '(';
}
.question .answer-count:after, .qna-full-question .answer-count:after {
content: ')';
}
.question fieldset, .qna-full-question fieldset {
margin: 0px;
}
.question fieldset legend {
.question fieldset legend, .qna-full-question fieldset legend {
display: none;
}
.question p.answer {
margin-top: 4px;
margin-bottom: 4px;
font-style: italic;
}
.question label[for=answer] {
.question label[for=answer], .qna-full-question label[for=answer] {
display: none;
}
.question textarea {
.question textarea, .qna-full-question textarea {
width: 100%;
height: 42px;
padding: 6px 10px 18px 10px;
@ -1288,18 +1369,48 @@ table.profile_list tr.alt {
-moz-box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.2);
-webkit-box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.2);
font-size: 1.2em;
margin-top: 15px;
margin-bottom: 10px;
}
.question #answer-form input.submit {
.qna-full-question textarea {
width: 473px;
}
.question-description input.submit, .answer-content input.submit {
height: auto;
padding: 0px 10px;
margin-left: 0px;
margin-bottom: 10px;
margin: 6px 0px 10px 0px;
color:#fff;
font-weight: bold;
text-transform: uppercase;
font-size: 1.1em;
text-shadow: 0px -1px 0px rgba(0, 0, 0, 0.2);
border: 1px solid #d7621c;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
background: #FB6104;
background: -moz-linear-gradient(top, #ff9d63 , #FB6104);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff9d63), color-stop(100%,#FB6104));
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff9d63', endColorstr='#FB6104',GradientType=0 );
}
.question .question-description input.submit:hover, .question .answer-content input.submit:hover {
text-shadow: 0px -1px 0px rgba(0, 0, 0, 0.6);
background: #ff9d63;
background: -moz-linear-gradient(top, #FB6104 , #fc8035);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#FB6104), color-stop(100%,#fc8035));
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FB6104', endColorstr='#fc8035',GradientType=0 );
}
.question .question-description #answer-form input.submit {
margin-top: 0px;
}
.question p.best {
background: url(../images/rosette.png) no-repeat top left;
padding-left: 20px;
}
}/*end of @media screen, projection, tv*/

BIN
theme/neo/images/lock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 B

Some files were not shown because too many files have changed in this diff Show More