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. 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 - $notice Notice
- &$ni: in/out array mapping profile IDs to constants: NOTICE_INBOX_SOURCE_SUB etc - &$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 null (default) means to use the site-wide text limits. 0
means no limit. 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 search
------ ------

View File

@ -89,7 +89,7 @@ class ApiGroupListAllAction extends ApiPrivateAuthAction
$taguribase = TagURI::base(); $taguribase = TagURI::base();
$id = "tag:$taguribase:Groups"; $id = "tag:$taguribase:Groups";
$link = common_local_url('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); $subtitle = sprintf(_("groups on %s"), $sitename);
switch($this->format) { switch($this->format) {

View File

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

View File

@ -74,4 +74,23 @@ class Conversation extends Memcached_DataObject
return $conv; 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.php';
require_once INSTALLDIR.'/classes/File_oembed.php'; require_once INSTALLDIR.'/classes/File_oembed.php';
define('USER_AGENT', 'StatusNet user agent / file probe');
/** /**
* Table Definition for file_redirection * 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 public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */ /* 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 */ /* the code above is auto generated do not remove the tag below */
###END_AUTOCODE ###END_AUTOCODE

View File

@ -35,7 +35,7 @@ class Login_token extends Memcached_DataObject
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */ /* 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 */ /* the code above is auto generated do not remove the tag below */
###END_AUTOCODE ###END_AUTOCODE

View File

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

View File

@ -211,31 +211,16 @@ class Profile extends Memcached_DataObject
function isMember($group) function isMember($group)
{ {
$mem = new Group_member(); $gm = Group_member::pkeyGet(array('profile_id' => $this->id,
'group_id' => $group->id));
$mem->group_id = $group->id; return (!empty($gm));
$mem->profile_id = $this->id;
if ($mem->find()) {
return true;
} else {
return false;
}
} }
function isAdmin($group) function isAdmin($group)
{ {
$mem = new Group_member(); $gm = Group_member::pkeyGet(array('profile_id' => $this->id,
'group_id' => $group->id));
$mem->group_id = $group->id; return (!empty($gm) && $gm->is_admin);
$mem->profile_id = $this->id;
$mem->is_admin = 1;
if ($mem->find()) {
return true;
} else {
return false;
}
} }
function isPendingMember($group) function isPendingMember($group)
@ -245,30 +230,40 @@ class Profile extends Memcached_DataObject
return !empty($request); return !empty($request);
} }
function getGroups($offset=0, $limit=null) function getGroups($offset=0, $limit=PROFILES_PER_PAGE)
{ {
$qry = $ids = array();
'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 ';
if ($offset>0 && !is_null($limit)) { $keypart = sprintf('profile:groups:%d', $this->id);
if ($offset) {
if (common_config('db','type') == 'pgsql') { $idstring = self::cacheGet($keypart);
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
} else { if ($idstring !== false) {
$qry .= ' LIMIT ' . $offset . ', ' . $limit; $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(); return new ArrayWrapper($groups);
$cnt = $groups->query(sprintf($qry, $this->id));
return $groups;
} }
function isTagged($peopletag) function isTagged($peopletag)
@ -463,6 +458,7 @@ class Profile extends Memcached_DataObject
} else { } else {
if (Event::handle('StartJoinGroup', array($group, $this))) { if (Event::handle('StartJoinGroup', array($group, $this))) {
$join = Group_member::join($group->id, $this->id); $join = Group_member::join($group->id, $this->id);
self::blow('profile:groups:%d', $this->id);
Event::handle('EndJoinGroup', array($group, $this)); Event::handle('EndJoinGroup', array($group, $this));
} }
} }
@ -482,6 +478,7 @@ class Profile extends Memcached_DataObject
{ {
if (Event::handle('StartLeaveGroup', array($group, $this))) { if (Event::handle('StartLeaveGroup', array($group, $this))) {
Group_member::leave($group->id, $this->id); Group_member::leave($group->id, $this->id);
self::blow('profile:groups:%d', $this->id);
Event::handle('EndLeaveGroup', array($group, $this)); Event::handle('EndLeaveGroup', array($group, $this));
} }
} }

View File

@ -31,7 +31,9 @@ class User_group extends Memcached_DataObject
public $force_scope; // tinyint public $force_scope; // tinyint
/* Static get */ /* 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 */ /* the code above is auto generated do not remove the tag below */
###END_AUTOCODE ###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(){ $(document).ready(function(){
SN.Init.AjaxForms(); SN.Init.AjaxForms();
SN.Init.UploadForms(); SN.Init.UploadForms();
SN.Init.CheckBoxes();
if ($('.'+SN.C.S.FormNotice).length > 0) { if ($('.'+SN.C.S.FormNotice).length > 0) {
SN.Init.NoticeForm(); SN.Init.NoticeForm();
} }
@ -1661,3 +1681,4 @@ $(document).ready(function(){
SN.Init.PeopleTags(); 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 ($activity->objects[0]->id == $author->id) {
if (!$this->trusted) { if (!$this->trusted) {
// TRANS: Client exception thrown when trying to force a subscription for an untrusted user. // 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; $other = $activity->actor;
@ -113,8 +113,8 @@ class ActivityImporter extends QueueHandler
if (!empty($otherUser)) { if (!empty($otherUser)) {
$otherProfile = $otherUser->getProfile(); $otherProfile = $otherUser->getProfile();
} else { } else {
// TRANS: Client exception thrown when trying to for a 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.")); throw new Exception(_('Cannot force remote user to subscribe.'));
} }
// XXX: don't do this for untrusted input! // XXX: don't do this for untrusted input!
@ -129,13 +129,13 @@ class ActivityImporter extends QueueHandler
if (empty($otherProfile)) { if (empty($otherProfile)) {
// TRANS: Client exception thrown when trying to subscribe to an unknown profile. // 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); Subscription::start($profile, $otherProfile);
} else { } else {
// TRANS: Client exception thrown when trying to import an event not related to the importing user. // 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]); $oprofile = Ostatus_profile::ensureActivityObjectProfile($activity->objects[0]);
if (!$oprofile->isGroup()) { if (!$oprofile->isGroup()) {
// TRANS: Client exception thrown when trying to join a remote group that is not a group. // 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(); $group = $oprofile->localGroup();
} }
@ -201,7 +201,7 @@ class ActivityImporter extends QueueHandler
} }
} else { } else {
// TRANS: Client exception thrown when trying to overwrite the author information for a non-trusted user during import. // 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? // @fixme fetch from $sourceUrl?
// TRANS: Client exception thrown when trying to import a notice without content. // TRANS: Client exception thrown when trying to import a notice without content.
// TRANS: %s is the notice URI. // 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 // 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) function moveActivity($act, $sink, $user, $remote)
{ {
if (empty($user)) { 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)); throw new Exception(sprintf(_('No such user "%s".'),$act->actor->id));
} }

View File

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

View File

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

View File

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

View File

@ -20,7 +20,7 @@
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
define('STATUSNET_BASE_VERSION', '1.0.0'); 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('STATUSNET_VERSION', STATUSNET_BASE_VERSION . STATUSNET_LIFECYCLE);
define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility define('LACONICA_VERSION', STATUSNET_VERSION); // compatibility

View File

@ -202,10 +202,12 @@ class GroupEditForm extends Form
$this->out->elementEnd('li'); $this->out->elementEnd('li');
} }
$this->out->elementStart('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') : ($this->out->arg('private')) ? $this->out->arg('private') :
((!empty($this->group)) ? $this->group->isPrivate() : false), ((!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'); $this->out->elementEnd('li');
Event::handle('EndGroupEditFormData', array($this)); 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( protected static $apiMap = array(
'flickr.com' => 'http://www.flickr.com/services/oembed/', 'flickr.com' => 'http://www.flickr.com/services/oembed/',
'yfrog.com' => 'http://www.yfrog.com/api/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( protected static $functionMap = array(
'twitpic.com' => 'oEmbedHelper::twitPic', 'twitpic.com' => 'oEmbedHelper::twitPic',
@ -74,30 +81,59 @@ class oEmbedHelper
$host = substr($host, 4); $host = substr($host, 4);
} }
// Blacklist: systems with no oEmbed API of their own, which are common_log(LOG_INFO, 'Checking for oEmbed data for ' . $url);
// 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);
}
// Whitelist: known API endpoints for sites that don't provide discovery... // You can fiddle with the order of discovery -- either skipping
if (array_key_exists($host, self::$apiMap)) { // some types or re-ordering them.
$api = self::$apiMap[$host];
} else { $order = common_config('oembed', 'order');
try {
$api = self::discover($url); foreach ($order as $method) {
} catch (Exception $e) {
// Discovery failed... fall back to oohembed if enabled. switch ($method) {
$oohembed = common_config('oohembed', 'endpoint'); case 'built-in':
if ($oohembed) { common_log(LOG_INFO, 'Considering built-in oEmbed methods...');
$api = $oohembed; // Blacklist: systems with no oEmbed API of their own, which are
} else { // either missing from or broken on oohembed.com's proxy.
throw $e; // 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); return self::getObjectFrom($api, $url, $params);
} }

View File

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

View File

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

View File

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

View File

@ -60,7 +60,6 @@ class APCPlugin extends Plugin
* *
* @return boolean hook success * @return boolean hook success
*/ */
function onStartCacheGet(&$key, &$value) function onStartCacheGet(&$key, &$value)
{ {
$value = apc_fetch($key); $value = apc_fetch($key);
@ -79,7 +78,6 @@ class APCPlugin extends Plugin
* *
* @return boolean hook success * @return boolean hook success
*/ */
function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success) function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
{ {
$success = apc_store($key, $value, ((is_null($expiry)) ? 0 : $expiry)); $success = apc_store($key, $value, ((is_null($expiry)) ? 0 : $expiry));
@ -97,7 +95,6 @@ class APCPlugin extends Plugin
* *
* @return boolean hook success * @return boolean hook success
*/ */
function onStartCacheDelete(&$key, &$success) function onStartCacheDelete(&$key, &$success)
{ {
$success = apc_delete($key); $success = apc_delete($key);
@ -112,6 +109,7 @@ class APCPlugin extends Plugin
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:APC', 'homepage' => 'http://status.net/wiki/Plugin:APC',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description.
_m('Use the <a href="http://pecl.php.net/package/apc">APC</a> variable cache to cache query results.')); _m('Use the <a href="http://pecl.php.net/package/apc">APC</a> variable cache to cache query results.'));
return true; 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 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class AccountManagementControlDocumentAction extends Action class AccountManagementControlDocumentAction extends Action
{ {
/** /**
@ -50,7 +49,6 @@ class AccountManagementControlDocumentAction extends Action
* *
* @return void * @return void
*/ */
function handle($args) function handle($args)
{ {
parent::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 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class AccountManagementSessionStatusAction extends Action class AccountManagementSessionStatusAction extends Action
{ {
/** /**
@ -50,7 +49,6 @@ class AccountManagementSessionStatusAction extends Action
* *
* @return void * @return void
*/ */
function handle($args) function handle($args)
{ {
parent::handle($args); parent::handle($args);

View File

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

View File

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

View File

@ -49,6 +49,7 @@ class AdsenseadminpanelAction extends AdminPanelAction
*/ */
function title() function title()
{ {
// TRANS: Title of AdSense administrator panel.
return _m('TITLE', 'AdSense'); return _m('TITLE', 'AdSense');
} }
@ -59,6 +60,7 @@ class AdsenseadminpanelAction extends AdminPanelAction
*/ */
function getInstructions() function getInstructions()
{ {
// TRANS: Instructions for AdSense administrator panel.
return _m('AdSense settings for this StatusNet site'); return _m('AdSense settings for this StatusNet site');
} }
@ -161,38 +163,50 @@ class AdsenseAdminPanelForm extends AdminForm
$this->out->elementStart('ul', 'form_data'); $this->out->elementStart('ul', 'form_data');
$this->li(); $this->li();
$this->input('client', $this->input('client',
// TRANS: Field label in AdSense administration panel.
_m('Client ID'), _m('Client ID'),
_m('Google client ID'), // TRANS: Field title in AdSense administration panel.
_m('Google client ID.'),
'adsense'); 'adsense');
$this->unli(); $this->unli();
$this->li(); $this->li();
$this->input('adScript', $this->input('adScript',
// TRANS: Field label in AdSense administration panel.
_m('Ad script URL'), _m('Ad script URL'),
_m('Script URL (advanced)'), // TRANS: Field title in AdSense administration panel.
_m('Script URL (advanced).'),
'adsense'); 'adsense');
$this->unli(); $this->unli();
$this->li(); $this->li();
$this->input('mediumRectangle', $this->input('mediumRectangle',
// TRANS: Field label in AdSense administration panel.
_m('Medium rectangle'), _m('Medium rectangle'),
_m('Medium rectangle slot code'), // TRANS: Field title in AdSense administration panel.
_m('Medium rectangle slot code.'),
'adsense'); 'adsense');
$this->unli(); $this->unli();
$this->li(); $this->li();
$this->input('rectangle', $this->input('rectangle',
// TRANS: Field label in AdSense administration panel.
_m('Rectangle'), _m('Rectangle'),
_m('Rectangle slot code'), // TRANS: Field title in AdSense administration panel.
_m('Rectangle slot code.'),
'adsense'); 'adsense');
$this->unli(); $this->unli();
$this->li(); $this->li();
$this->input('leaderboard', $this->input('leaderboard',
// TRANS: Field label in AdSense administration panel.
_m('Leaderboard'), _m('Leaderboard'),
_m('Leaderboard slot code'), // TRANS: Field title in AdSense administration panel.
_m('Leaderboard slot code.'),
'adsense'); 'adsense');
$this->unli(); $this->unli();
$this->li(); $this->li();
$this->input('wideSkyscraper', $this->input('wideSkyscraper',
// TRANS: Field label in AdSense administration panel.
_m('Skyscraper'), _m('Skyscraper'),
_m('Wide skyscraper slot code'), // TRANS: Field title in AdSense administration panel.
_m('Wide skyscraper slot code.'),
'adsense'); 'adsense');
$this->unli(); $this->unli();
$this->out->elementEnd('ul'); $this->out->elementEnd('ul');
@ -205,6 +219,9 @@ class AdsenseAdminPanelForm extends AdminForm
*/ */
function formActions() 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 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class AimPlugin extends ImPlugin class AimPlugin extends ImPlugin
{ {
public $user = null; public $user = null;
@ -57,6 +56,7 @@ class AimPlugin extends ImPlugin
function getDisplayName() function getDisplayName()
{ {
// TRANS: Display name.
return _m('AIM'); return _m('AIM');
} }
@ -145,10 +145,12 @@ class AimPlugin extends ImPlugin
function initialize(){ function initialize(){
if(!isset($this->user)){ 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)){ 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); $this->fake_aim = new Fake_Aim($this->user,$this->password,4);
@ -162,8 +164,8 @@ class AimPlugin extends ImPlugin
'author' => 'Craig Andrews', 'author' => 'Craig Andrews',
'homepage' => 'http://status.net/wiki/Plugin:AIM', 'homepage' => 'http://status.net/wiki/Plugin:AIM',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description.
_m('The AIM plugin allows users to send and receive notices over the AIM network.')); _m('The AIM plugin allows users to send and receive notices over the AIM network.'));
return true; 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); $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 * 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. * for each site being handled by the current process that has XMPP enabled.
*/ */
class AimManager extends ImManager class AimManager extends ImManager
{ {
public $conn = null; public $conn = null;
/** /**
* Initialize connection to server. * Initialize connection to server.
@ -77,6 +75,8 @@ class AimManager extends ImManager
$this->conn->registerHandler("IMIn",array($this,"handle_aim_message")); $this->conn->registerHandler("IMIn",array($this,"handle_aim_message"));
$this->conn->myServer="toc.oscar.aol.com"; $this->conn->myServer="toc.oscar.aol.com";
$this->conn->signon(); $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); $this->conn->setProfile(_m('Send me a message to post a notice'),false);
} }
return $this->conn; 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 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class AnonymousFavePlugin extends Plugin class AnonymousFavePlugin extends Plugin
{ {
// Array of users who should not have anon faving. The default is // Array of users who should not have anon faving. The default is
// that anonymous faving is allowed for all users. // that anonymous faving is allowed for all users.
public $restricted = array(); public $restricted = array();
@ -237,7 +235,7 @@ class AnonymousFavePlugin extends Plugin
if (!$id) { if (!$id) {
// TRANS: Server exception. // 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 // Stick the Profile ID into the nickname
@ -248,7 +246,7 @@ class AnonymousFavePlugin extends Plugin
if (!$result) { if (!$result) {
// TRANS: Server exception. // 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( common_log(
@ -327,5 +325,4 @@ class AnonymousFavePlugin extends Plugin
return true; return true;
} }
} }

View File

@ -152,7 +152,7 @@ class Fave_tally extends Memcached_DataObject
$msg = sprintf( $msg = sprintf(
// TRANS: Server exception. // TRANS: Server exception.
// TRANS: %d is the notice ID (number). // 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 $noticeID
); );
throw new ServerException($msg); throw new ServerException($msg);
@ -181,7 +181,7 @@ class Fave_tally extends Memcached_DataObject
$msg = sprintf( $msg = sprintf(
// TRANS: Server exception. // TRANS: Server exception.
// TRANS: %d is the notice ID (number). // 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 $noticeID
); );
throw new ServerException($msg); throw new ServerException($msg);
@ -212,7 +212,7 @@ class Fave_tally extends Memcached_DataObject
$msg = sprintf( $msg = sprintf(
// TRANS: Server exception. // TRANS: Server exception.
// TRANS: %d is the notice ID (number). // 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 $noticeID
); );
throw new ServerException($msg); throw new ServerException($msg);

View File

@ -57,7 +57,7 @@ class AnonFavorAction extends RedirectingAction
if (empty($profile) || $_SERVER['REQUEST_METHOD'] != 'POST') { if (empty($profile) || $_SERVER['REQUEST_METHOD'] != 'POST') {
// TRANS: Client error. // 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; return;
} }

View File

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

View File

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

View File

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

View File

@ -94,7 +94,8 @@ class AutocompleteAction extends Action
$cur = common_current_user(); $cur = common_current_user();
if (!$cur) { 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->groups=array();
$this->users=array(); $this->users=array();

View File

@ -42,7 +42,7 @@ if (!defined('STATUSNET')) {
class AwesomenessPlugin extends Plugin class AwesomenessPlugin extends Plugin
{ {
const VERSION = '0.0.42'; const VERSION = '0.0.42';
public function onPluginVersion(&$versions) public function onPluginVersion(&$versions)
{ {
@ -72,22 +72,22 @@ class AwesomenessPlugin extends Plugin
$action->elementStart('div', array('id' => 'cornify_section', $action->elementStart('div', array('id' => 'cornify_section',
'class' => 'section')); 'class' => 'section'));
$action->raw( $action->raw(
<<<EOT <<<EOT
<a href="http://www.cornify.com" onclick="cornify_add();return false;"> <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" /> <img src="http://www.cornify.com/assets/cornify.gif" width="61" height="16" border="0" alt="Cornify" />
</a> </a>
<script type="text/javascript">(function() { <script type="text/javascript">(function() {
var js = document.createElement('script'); var js = document.createElement('script');
js.type = 'text/javascript'; js.type = 'text/javascript';
js.async = true; js.async = true;
js.src = 'http://www.cornify.com/js/cornify.js'; js.src = 'http://www.cornify.com/js/cornify.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(js); (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(js);
})();</script> })();</script>
EOT EOT
); );
$action->elementEnd('div'); $action->elementEnd('div');
} }
/** /**
@ -102,7 +102,7 @@ EOT
*/ */
function onStartSaveNewNoticeWeb($action, $user, &$content, &$options) function onStartSaveNewNoticeWeb($action, $user, &$content, &$options)
{ {
$content = htmlspecialchars($content); $content = htmlspecialchars($content);
$options['rendered'] = preg_replace("/(^|\s|-)((?:awesome|awesomeness)[\?!\.\,]?)(\s|$)/i", " <b>$2</b> ", $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(){ function onInitializePlugin(){
parent::onInitializePlugin(); parent::onInitializePlugin();
if(!isset($this->serviceUrl)){ 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', 'author' => 'Craig Andrews, Brion Vibber',
'homepage' => 'http://status.net/wiki/Plugin:BitlyUrl', 'homepage' => 'http://status.net/wiki/Plugin:BitlyUrl',
'rawdescription' => '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.'), sprintf(_m('Uses <a href="http://%1$s/">%1$s</a> URL-shortener service.'),
$this->shortenerName)); $this->shortenerName));
@ -211,8 +213,10 @@ class BitlyUrlPlugin extends UrlShortenerPlugin
$action_name = $nav->action->trimmed('action'); $action_name = $nav->action->trimmed('action');
$nav->out->menuItem(common_local_url('bitlyadminpanel'), $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'),
_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', $action_name == 'bitlyadminpanel',
'nav_bitly_admin_panel'); '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 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class BitlyadminpanelAction extends AdminPanelAction class BitlyadminpanelAction extends AdminPanelAction
{ {
/** /**
@ -48,9 +47,9 @@ class BitlyadminpanelAction extends AdminPanelAction
* *
* @return string page title * @return string page title
*/ */
function title() function title()
{ {
// TRANS: Title of administration panel.
return _m('bit.ly URL shortening'); return _m('bit.ly URL shortening');
} }
@ -59,9 +58,10 @@ class BitlyadminpanelAction extends AdminPanelAction
* *
* @return string instructions * @return string instructions
*/ */
function getInstructions() 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 ' . return _m('URL shortening with bit.ly requires ' .
'[a bit.ly account and API key](http://bit.ly/a/your_api_key). ' . '[a bit.ly account and API key](http://bit.ly/a/your_api_key). ' .
'This verifies that this is an authorized account, and ' . 'This verifies that this is an authorized account, and ' .
@ -73,7 +73,6 @@ class BitlyadminpanelAction extends AdminPanelAction
* *
* @return void * @return void
*/ */
function showForm() function showForm()
{ {
$form = new BitlyAdminPanelForm($this); $form = new BitlyAdminPanelForm($this);
@ -86,7 +85,6 @@ class BitlyadminpanelAction extends AdminPanelAction
* *
* @return void * @return void
*/ */
function saveSettings() function saveSettings()
{ {
static $settings = array( static $settings = array(
@ -129,13 +127,15 @@ class BitlyadminpanelAction extends AdminPanelAction
if (mb_strlen($values['bitly']['default_apikey']) > 255) { if (mb_strlen($values['bitly']['default_apikey']) > 255) {
$this->clientError( $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) { if (mb_strlen($values['bitly']['default_apikey']) > 255) {
$this->clientError( $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 * @return int ID of the form
*/ */
function id() function id()
{ {
return 'bitlyadminpanel'; return 'bitlyadminpanel';
@ -159,7 +158,6 @@ class BitlyAdminPanelForm extends AdminForm
* *
* @return string class of the form * @return string class of the form
*/ */
function formClass() function formClass()
{ {
return 'form_settings'; return 'form_settings';
@ -170,7 +168,6 @@ class BitlyAdminPanelForm extends AdminForm
* *
* @return string URL of the action * @return string URL of the action
*/ */
function action() function action()
{ {
return common_local_url('bitlyadminpanel'); return common_local_url('bitlyadminpanel');
@ -181,14 +178,14 @@ class BitlyAdminPanelForm extends AdminForm
* *
* @return void * @return void
*/ */
function formData() function formData()
{ {
$this->out->elementStart( $this->out->elementStart(
'fieldset', 'fieldset',
array('id' => 'settings_bitly') 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? // Do we have global defaults to fall back on?
$login = $apiKey = false; $login = $apiKey = false;
@ -196,9 +193,11 @@ class BitlyAdminPanelForm extends AdminForm
$haveGlobalDefaults = ($login && $apiKey); $haveGlobalDefaults = ($login && $apiKey);
if ($login && $apiKey) { if ($login && $apiKey) {
$this->out->element('p', 'form_guide', $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.')); _m('Leave these empty to use global default credentials.'));
} else { } else {
$this->out->element('p', 'form_guide', $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.')); _m('If you leave these empty, bit.ly will be unavailable to users.'));
} }
$this->out->elementStart('ul', 'form_data'); $this->out->elementStart('ul', 'form_data');
@ -206,6 +205,7 @@ class BitlyAdminPanelForm extends AdminForm
$this->li(); $this->li();
$this->input( $this->input(
'default_login', 'default_login',
// TRANS: Field label in administration panel for bit.ly URL shortening.
_m('Login name'), _m('Login name'),
null, null,
'bitly' 'bitly'
@ -215,6 +215,7 @@ class BitlyAdminPanelForm extends AdminForm
$this->li(); $this->li();
$this->input( $this->input(
'default_apikey', 'default_apikey',
// TRANS: Field label in administration panel for bit.ly URL shortening.
_m('API key'), _m('API key'),
null, null,
'bitly' 'bitly'
@ -230,13 +231,14 @@ class BitlyAdminPanelForm extends AdminForm
* *
* @return void * @return void
*/ */
function formActions() function formActions()
{ {
$this->out->submit('submit', $this->out->submit('submit',
// TRANS: Button text to save setting in administration panel for bit.ly URL shortening.
_m('BUTTON','Save'), _m('BUTTON','Save'),
'submit', 'submit',
null, null,
// TRANS: Button title to save setting in administration panel for bit.ly URL shortening.
_m('Save bit.ly settings')); _m('Save bit.ly settings'));
} }
} }

View File

@ -126,7 +126,7 @@ class BlacklistPlugin extends Plugin
} else if (is_string($config)) { } else if (is_string($config)) {
return explode("\r\n", $config); return explode("\r\n", $config);
} else { } 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' => 'homepage' =>
'http://status.net/wiki/Plugin:Blacklist', 'http://status.net/wiki/Plugin:Blacklist',
'description' => 'description' =>
// TRANS: Plugin description.
_m('Keeps a blacklist of forbidden nickname '. _m('Keeps a blacklist of forbidden nickname '.
'and URL patterns.')); 'and URL patterns.'));
return true; return true;
@ -380,7 +381,7 @@ class BlacklistPlugin extends Plugin
// TRANS: Menu item in admin panel. // TRANS: Menu item in admin panel.
_m('MENU','Blacklist'), _m('MENU','Blacklist'),
// TRANS: Tooltip for menu item in admin panel. // TRANS: Tooltip for menu item in admin panel.
_m('TOOLTIP','Blacklist configuration'), _m('TOOLTIP','Blacklist configuration.'),
$action_name == 'blacklistadminpanel', $action_name == 'blacklistadminpanel',
'nav_blacklist_admin_panel'); 'nav_blacklist_admin_panel');
} }
@ -406,7 +407,7 @@ class BlacklistPlugin extends Plugin
$action->elementStart('li'); $action->elementStart('li');
$this->checkboxAndText($action, $this->checkboxAndText($action,
'blacklistnickname', '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'), _m('Add this nickname pattern to blacklist'),
'blacklistnicknamepattern', 'blacklistnicknamepattern',
$this->patternizeNickname($user->nickname)); $this->patternizeNickname($user->nickname));
@ -416,7 +417,7 @@ class BlacklistPlugin extends Plugin
$action->elementStart('li'); $action->elementStart('li');
$this->checkboxAndText($action, $this->checkboxAndText($action,
'blacklisthomepage', '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'), _m('Add this homepage pattern to blacklist'),
'blacklisthomepagepattern', 'blacklisthomepagepattern',
$this->patternizeHomepage($profile->homepage)); $this->patternizeHomepage($profile->homepage));
@ -496,7 +497,7 @@ class BlacklistPlugin extends Plugin
if (!empty($homepage)) { if (!empty($homepage)) {
if (!$this->_checkUrl($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. // 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); $homepage);
throw new ClientException($msg); throw new ClientException($msg);
} }
@ -507,7 +508,7 @@ class BlacklistPlugin extends Plugin
if (!empty($nickname)) { if (!empty($nickname)) {
if (!$this->_checkNickname($nickname)) { if (!$this->_checkNickname($nickname)) {
// TRANS: Exception thrown trying to post a notice while having a blocked nickname. %s is the blocked 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); $nickname);
throw new ClientException($msg); throw new ClientException($msg);
} }
@ -531,7 +532,7 @@ class BlacklistPlugin extends Plugin
if (!$this->_checkUrl($url)) { 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. // 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); $url);
throw new ClientException($msg); throw new ClientException($msg);
} }
@ -542,7 +543,7 @@ class BlacklistPlugin extends Plugin
if (!empty($nickname)) { if (!empty($nickname)) {
if (!$this->_checkNickname($nickname)) { if (!$this->_checkNickname($nickname)) {
// TRANS: Client exception thrown trying to subscribe to a person with a blocked nickname. %s is the blocked 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); $nickname);
throw new ClientException($msg); throw new ClientException($msg);
} }

View File

@ -49,7 +49,8 @@ class BlacklistadminpanelAction extends AdminPanelAction
*/ */
function title() 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() function getInstructions()
{ {
// TRANS: Instructions for blacklist plugin administration panel.
return _m('Blacklisted URLs and nicknames'); return _m('Blacklisted URLs and nicknames');
} }
@ -171,17 +173,21 @@ class BlacklistAdminPanelForm extends Form
$nickPatterns = Nickname_blacklist::getPatterns(); $nickPatterns = Nickname_blacklist::getPatterns();
// TRANS: Field label in blacklist plugin administration panel.
$this->out->textarea('blacklist-nicknames', _m('Nicknames'), $this->out->textarea('blacklist-nicknames', _m('Nicknames'),
implode("\r\n", $nickPatterns), 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'); $this->out->elementEnd('li');
$urlPatterns = Homepage_blacklist::getPatterns(); $urlPatterns = Homepage_blacklist::getPatterns();
$this->out->elementStart('li'); $this->out->elementStart('li');
// TRANS: Field label in blacklist plugin administration panel.
$this->out->textarea('blacklist-urls', _m('URLs'), $this->out->textarea('blacklist-urls', _m('URLs'),
implode("\r\n", $urlPatterns), 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('li');
$this->out->elementEnd('ul'); $this->out->elementEnd('ul');
@ -195,9 +201,11 @@ class BlacklistAdminPanelForm extends Form
function formActions() function formActions()
{ {
$this->out->submit('submit', $this->out->submit('submit',
_m('Save'), // TRANS: Button text in blacklist plugin administration panel to save settings.
_m('BUTTON','Save'),
'submit', 'submit',
null, 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', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:BlankAdPlugin', 'homepage' => 'http://status.net/wiki/Plugin:BlankAdPlugin',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description.
_m('Plugin for testing ad layout.')); _m('Plugin for testing ad layout.'));
return true; return true;
} }

View File

@ -82,13 +82,19 @@ class BlogspamNetPlugin extends Plugin
} else { } else {
common_debug("Blogspamnet results = " . $response); common_debug("Blogspamnet results = " . $response);
if (preg_match('/^ERROR(:(.*))?$/', $response, $match)) { 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)) { } 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)) { } else if (preg_match('/^OK$/', $response)) {
// don't do anything // don't do anything
} else { } 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; return true;
@ -149,6 +155,7 @@ class BlogspamNetPlugin extends Plugin
'author' => 'Evan Prodromou, Brion Vibber', 'author' => 'Evan Prodromou, Brion Vibber',
'homepage' => 'http://status.net/wiki/Plugin:BlogspamNet', 'homepage' => 'http://status.net/wiki/Plugin:BlogspamNet',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description.
_m('Plugin to check submitted notices with blogspam.net.')); _m('Plugin to check submitted notices with blogspam.net.'));
return true; return true;
} }

View File

@ -42,7 +42,6 @@ if (!defined('STATUSNET')) {
* *
* @see DB_DataObject * @see DB_DataObject
*/ */
class Bookmark extends Memcached_DataObject class Bookmark extends Memcached_DataObject
{ {
public $__table = 'bookmark'; // table name 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 * @return User_greeting_count object found, or null for no hits
* *
*/ */
function staticGet($k, $v=null) function staticGet($k, $v=null)
{ {
return Memcached_DataObject::staticGet('Bookmark', $k, $v); 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 * @return Bookmark object found, or null for no hits
* *
*/ */
function pkeyGet($kv) function pkeyGet($kv)
{ {
return Memcached_DataObject::pkeyGet('Bookmark', $kv); return Memcached_DataObject::pkeyGet('Bookmark', $kv);
@ -97,7 +94,6 @@ class Bookmark extends Memcached_DataObject
* *
* @return array array of column definitions * @return array array of column definitions
*/ */
function table() function table()
{ {
return array('id' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL, return array('id' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL,
@ -115,7 +111,6 @@ class Bookmark extends Memcached_DataObject
* *
* @return array list of key field names * @return array list of key field names
*/ */
function keys() function keys()
{ {
return array_keys($this->keyTypes()); return array_keys($this->keyTypes());
@ -126,7 +121,6 @@ class Bookmark extends Memcached_DataObject
* *
* @return array associative array of key definitions * @return array associative array of key definitions
*/ */
function keyTypes() function keyTypes()
{ {
return array('id' => 'K', return array('id' => 'K',
@ -138,7 +132,6 @@ class Bookmark extends Memcached_DataObject
* *
* @return array magic three-false array that stops auto-incrementing. * @return array magic three-false array that stops auto-incrementing.
*/ */
function sequenceKey() function sequenceKey()
{ {
return array(false, false, false); return array(false, false, false);
@ -151,7 +144,6 @@ class Bookmark extends Memcached_DataObject
* *
* @return Bookmark found bookmark or null * @return Bookmark found bookmark or null
*/ */
function getByNotice($notice) function getByNotice($notice)
{ {
return self::staticGet('uri', $notice->uri); return self::staticGet('uri', $notice->uri);
@ -165,7 +157,6 @@ class Bookmark extends Memcached_DataObject
* *
* @return Bookmark bookmark found or null * @return Bookmark bookmark found or null
*/ */
static function getByURL($profile, $url) static function getByURL($profile, $url)
{ {
$nb = new Bookmark(); $nb = new Bookmark();
@ -192,13 +183,13 @@ class Bookmark extends Memcached_DataObject
* *
* @return Notice saved notice * @return Notice saved notice
*/ */
static function saveNew($profile, $title, $url, $rawtags, $description, static function saveNew($profile, $title, $url, $rawtags, $description,
$options=null) $options=null)
{ {
$nb = self::getByURL($profile, $url); $nb = self::getByURL($profile, $url);
if (!empty($nb)) { if (!empty($nb)) {
// TRANS: Client exception thrown when trying to save a new bookmark that already exists.
throw new ClientException(_m('Bookmark already exists.')); throw new ClientException(_m('Bookmark already exists.'));
} }
@ -209,6 +200,7 @@ class Bookmark extends Memcached_DataObject
if (array_key_exists('uri', $options)) { if (array_key_exists('uri', $options)) {
$other = Bookmark::staticGet('uri', $options['uri']); $other = Bookmark::staticGet('uri', $options['uri']);
if (!empty($other)) { if (!empty($other)) {
// TRANS: Client exception thrown when trying to save a new bookmark that already exists.
throw new ClientException(_m('Bookmark already exists.')); throw new ClientException(_m('Bookmark already exists.'));
} }
} }
@ -288,8 +280,8 @@ class Bookmark extends Memcached_DataObject
$shortUrl = $url; $shortUrl = $url;
} }
// @todo FIXME: i18n documentation. // TRANS: Bookmark content.
// TRANS: %1$s is a title, %2$s is a short URL, %3$s is a description, // 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. // TRANS: %4$s is space separated list of hash tags.
$content = sprintf(_m('"%1$s" %2$s %3$s %4$s'), $content = sprintf(_m('"%1$s" %2$s %3$s %4$s'),
$title, $title,
@ -297,6 +289,9 @@ class Bookmark extends Memcached_DataObject
$description, $description,
implode(' ', $hashtags)); 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">'. $rendered = sprintf(_m('<span class="xfolkentry">'.
'<a class="taggedlink" href="%1$s">%2$s</a> '. '<a class="taggedlink" href="%1$s">%2$s</a> '.
'<span class="description">%3$s</span> '. '<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 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class BookmarkPlugin extends MicroAppPlugin class BookmarkPlugin extends MicroAppPlugin
{ {
const VERSION = '0.1'; const VERSION = '0.1';
@ -60,7 +59,6 @@ class BookmarkPlugin extends MicroAppPlugin
* *
* @return boolean hook value * @return boolean hook value
*/ */
function onUserRightsCheck($profile, $right, &$result) function onUserRightsCheck($profile, $right, &$result)
{ {
if ($right == self::IMPORTDELICIOUS) { if ($right == self::IMPORTDELICIOUS) {
@ -78,7 +76,6 @@ class BookmarkPlugin extends MicroAppPlugin
* *
* @return boolean hook value; true means continue processing, false means stop. * @return boolean hook value; true means continue processing, false means stop.
*/ */
function onCheckSchema() function onCheckSchema()
{ {
$schema = Schema::get(); $schema = Schema::get();
@ -127,7 +124,6 @@ class BookmarkPlugin extends MicroAppPlugin
* *
* @return boolean hook value * @return boolean hook value
*/ */
function onEndShowStyles($action) function onEndShowStyles($action)
{ {
$action->cssLink($this->path('bookmark.css')); $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. * @return boolean hook value; true means continue processing, false means stop.
*/ */
function onAutoload($cls) function onAutoload($cls)
{ {
$dir = dirname(__FILE__); $dir = dirname(__FILE__);
@ -175,7 +170,6 @@ class BookmarkPlugin extends MicroAppPlugin
* *
* @return boolean hook value; true means continue processing, false means stop. * @return boolean hook value; true means continue processing, false means stop.
*/ */
function onRouterInitialized($m) function onRouterInitialized($m)
{ {
$m->connect('main/bookmark/new', $m->connect('main/bookmark/new',
@ -207,7 +201,6 @@ class BookmarkPlugin extends MicroAppPlugin
* *
* @return boolean hook value * @return boolean hook value
*/ */
function onEndInitializeQueueManager($qm) function onEndInitializeQueueManager($qm)
{ {
$qm->connect('dlcsback', 'DeliciousBackupImporter'); $qm->connect('dlcsback', 'DeliciousBackupImporter');
@ -222,7 +215,6 @@ class BookmarkPlugin extends MicroAppPlugin
* *
* @return value * @return value
*/ */
function onPluginVersion(&$versions) function onPluginVersion(&$versions)
{ {
$versions[] = array('name' => 'Sample', $versions[] = array('name' => 'Sample',
@ -230,6 +222,7 @@ class BookmarkPlugin extends MicroAppPlugin
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:Bookmark', 'homepage' => 'http://status.net/wiki/Plugin:Bookmark',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description.
_m('Simple extension for supporting bookmarks.')); _m('Simple extension for supporting bookmarks.'));
return true; return true;
} }
@ -242,7 +235,6 @@ class BookmarkPlugin extends MicroAppPlugin
* *
* @return boolean hook value * @return boolean hook value
*/ */
function onStartLoadDoc(&$title, &$output) function onStartLoadDoc(&$title, &$output)
{ {
if ($title == 'bookmarklet') { if ($title == 'bookmarklet') {
@ -256,8 +248,6 @@ class BookmarkPlugin extends MicroAppPlugin
return true; return true;
} }
/** /**
* Show a link to our delicious import page on profile settings form * Show a link to our delicious import page on profile settings form
* *
@ -265,7 +255,6 @@ class BookmarkPlugin extends MicroAppPlugin
* *
* @return boolean hook value * @return boolean hook value
*/ */
function onEndProfileSettingsActions($action) function onEndProfileSettingsActions($action)
{ {
$user = common_current_user(); $user = common_current_user();
@ -274,6 +263,7 @@ class BookmarkPlugin extends MicroAppPlugin
$action->elementStart('li'); $action->elementStart('li');
$action->element('a', $action->element('a',
array('href' => common_local_url('importdelicious')), array('href' => common_local_url('importdelicious')),
// TRANS: Link text in proile leading to import form.
_m('Import del.icio.us bookmarks')); _m('Import del.icio.us bookmarks'));
$action->elementEnd('li'); $action->elementEnd('li');
} }
@ -294,7 +284,11 @@ class BookmarkPlugin extends MicroAppPlugin
$nb = Bookmark::getByNotice($nli->notice); $nb = Bookmark::getByNotice($nli->notice);
if (!empty($nb)) { if (!empty($nb)) {
$id = (empty($nli->repeat)) ? $nli->notice->id : $nli->repeat->id; $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)); 'id' => 'notice-' . $id));
Event::handle('EndOpenNoticeListItemElement', array($nli)); Event::handle('EndOpenNoticeListItemElement', array($nli));
return false; return false;
@ -310,7 +304,6 @@ class BookmarkPlugin extends MicroAppPlugin
* *
* @return Notice resulting notice. * @return Notice resulting notice.
*/ */
static private function _postRemoteBookmark(Ostatus_profile $author, static private function _postRemoteBookmark(Ostatus_profile $author,
Activity $activity) Activity $activity)
{ {
@ -331,7 +324,6 @@ class BookmarkPlugin extends MicroAppPlugin
* *
* @return true if it's a Post of a Bookmark, else false * @return true if it's a Post of a Bookmark, else false
*/ */
static private function _isPostBookmark($activity) static private function _isPostBookmark($activity)
{ {
return ($activity->verb == ActivityVerb::POST && return ($activity->verb == ActivityVerb::POST &&
@ -350,7 +342,6 @@ class BookmarkPlugin extends MicroAppPlugin
* *
* @return boolean hook value * @return boolean hook value
*/ */
function deleteRelated($notice) function deleteRelated($notice)
{ {
$nb = Bookmark::getByNotice($notice); $nb = Bookmark::getByNotice($notice);
@ -371,7 +362,6 @@ class BookmarkPlugin extends MicroAppPlugin
* *
* @return Notice resulting notice * @return Notice resulting notice
*/ */
function saveNoticeFromActivity($activity, $profile, $options=array()) function saveNoticeFromActivity($activity, $profile, $options=array())
{ {
$bookmark = $activity->objects[0]; $bookmark = $activity->objects[0];
@ -379,6 +369,7 @@ class BookmarkPlugin extends MicroAppPlugin
$relLinkEls = ActivityUtils::getLinks($bookmark->element, 'related'); $relLinkEls = ActivityUtils::getLinks($bookmark->element, 'related');
if (count($relLinkEls) < 1) { if (count($relLinkEls) < 1) {
// TRANS: Client exception thrown when a bookmark is formatted incorrectly.
throw new ClientException(_m('Expected exactly 1 link '. throw new ClientException(_m('Expected exactly 1 link '.
'rel=related in a Bookmark.')); 'rel=related in a Bookmark.'));
} }
@ -472,6 +463,7 @@ class BookmarkPlugin extends MicroAppPlugin
$attachments = $notice->attachments(); $attachments = $notice->attachments();
if (count($attachments) != 1) { if (count($attachments) != 1) {
// TRANS: Server exception thrown when a bookmark has multiple attachments.
throw new ServerException(_m('Bookmark notice with the '. throw new ServerException(_m('Bookmark notice with the '.
'wrong number of attachments.')); 'wrong number of attachments.'));
} }
@ -526,7 +518,8 @@ class BookmarkPlugin extends MicroAppPlugin
if (count($atts) < 1) { if (count($atts) < 1) {
// Something wrong; let default code deal with it. // 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]; $att = $atts[0];
@ -561,13 +554,15 @@ class BookmarkPlugin extends MicroAppPlugin
foreach ($replies as $reply) { foreach ($replies as $reply) {
$other = Profile::staticGet('id', $reply); $other = Profile::staticGet('id', $reply);
$out->elementStart('li'); if (!empty($other)) {
$out->element('a', array('rel' => 'tag', $out->elementStart('li');
'href' => $other->profileurl, $out->element('a', array('rel' => 'tag',
'title' => $other->getBestName()), 'href' => $other->profileurl,
sprintf('for:%s', $other->nickname)); 'title' => $other->getBestName()),
$out->elementEnd('li'); sprintf('for:%s', $other->nickname));
$out->text(' '); $out->elementEnd('li');
$out->text(' ');
}
} }
foreach ($tags as $tag) { foreach ($tags as $tag) {
@ -640,6 +635,7 @@ class BookmarkPlugin extends MicroAppPlugin
function appTitle() function appTitle()
{ {
return _m('Bookmark'); // TRANS: Application title.
return _m('TITLE','Bookmark');
} }
} }

View File

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

View File

@ -49,12 +49,11 @@ class BookmarkpopupAction extends NewbookmarkAction
* *
* @return void * @return void
*/ */
function showTitle() function showTitle()
{ {
// TRANS: Title for mini-posting window loaded from bookmarklet.
// TRANS: %s is the StatusNet site name.
$this->element('title', $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'), null, sprintf(_m('Bookmark on %s'),
common_config('site', 'name'))); common_config('site', 'name')));
} }
@ -66,7 +65,6 @@ class BookmarkpopupAction extends NewbookmarkAction
* *
* @return void * @return void
*/ */
function showHeader() function showHeader()
{ {
$this->elementStart('div', array('id' => 'header')); $this->elementStart('div', array('id' => 'header'));
@ -89,7 +87,6 @@ class BookmarkpopupAction extends NewbookmarkAction
* *
* @return void * @return void
*/ */
function showCore() function showCore()
{ {
} }
@ -99,7 +96,6 @@ class BookmarkpopupAction extends NewbookmarkAction
* *
* @return void * @return void
*/ */
function showFooter() function showFooter()
{ {
} }

View File

@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class DeliciousBackupImporter extends QueueHandler class DeliciousBackupImporter extends QueueHandler
{ {
/** /**
@ -52,7 +51,6 @@ class DeliciousBackupImporter extends QueueHandler
* *
* @return string transport string * @return string transport string
*/ */
function transport() function transport()
{ {
return 'dlcsback'; return 'dlcsback';
@ -72,7 +70,6 @@ class DeliciousBackupImporter extends QueueHandler
* *
* @return boolean success value * @return boolean success value
*/ */
function handle($data) function handle($data)
{ {
list($user, $body) = $data; list($user, $body) = $data;
@ -82,7 +79,8 @@ class DeliciousBackupImporter extends QueueHandler
$dls = $doc->getElementsByTagName('dl'); $dls = $doc->getElementsByTagName('dl');
if ($dls->length != 1) { 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); $dl = $dls->item(0);
@ -159,12 +157,12 @@ class DeliciousBackupImporter extends QueueHandler
* *
* @return Notice imported notice * @return Notice imported notice
*/ */
function importBookmark($user, $dt, $dd = null) function importBookmark($user, $dt, $dd = null)
{ {
$as = $dt->getElementsByTagName('a'); $as = $dt->getElementsByTagName('a');
if ($as->length == 0) { 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>.")); throw new ClientException(_m("No <A> tag in a <DT>."));
} }
@ -173,6 +171,7 @@ class DeliciousBackupImporter extends QueueHandler
$private = $a->getAttribute('private'); $private = $a->getAttribute('private');
if ($private != 0) { if ($private != 0) {
// TRANS: Client exception thrown when a bookmark in an import file is private.
throw new ClientException(_m('Skipping private bookmark.')); throw new ClientException(_m('Skipping private bookmark.'));
} }
@ -306,5 +305,4 @@ class DeliciousBackupImporter extends QueueHandler
$this->fixListItem($node); $this->fixListItem($node);
} }
} }
} }

View File

@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class DeliciousBookmarkImporter extends QueueHandler class DeliciousBookmarkImporter extends QueueHandler
{ {
/** /**
@ -52,7 +51,6 @@ class DeliciousBookmarkImporter extends QueueHandler
* *
* @return string 'dlcsbkmk' * @return string 'dlcsbkmk'
*/ */
function transport() function transport()
{ {
return 'dlcsbkmk'; return 'dlcsbkmk';
@ -65,7 +63,6 @@ class DeliciousBookmarkImporter extends QueueHandler
* *
* @return boolean success value * @return boolean success value
*/ */
function handle($data) function handle($data)
{ {
$profile = Profile::staticGet('id', $data['profile_id']); $profile = Profile::staticGet('id', $data['profile_id']);

View File

@ -63,19 +63,25 @@ function getBookmarksFile()
} }
if (!file_exists($filename)) { 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)) { 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)) { 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. // 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); $html = file_get_contents($filename);

View File

@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class ImportdeliciousAction extends Action class ImportdeliciousAction extends Action
{ {
protected $success = false; protected $success = false;
@ -55,9 +54,9 @@ class ImportdeliciousAction extends Action
* *
* @return string page title * @return string page title
*/ */
function title() function title()
{ {
// TRANS: Title for page to import del.icio.us bookmark backups on.
return _m("Import del.icio.us bookmarks"); return _m("Import del.icio.us bookmarks");
} }
@ -68,7 +67,6 @@ class ImportdeliciousAction extends Action
* *
* @return boolean true * @return boolean true
*/ */
function prepare($argarray) function prepare($argarray)
{ {
parent::prepare($argarray); parent::prepare($argarray);
@ -76,12 +74,14 @@ class ImportdeliciousAction extends Action
$cur = common_current_user(); $cur = common_current_user();
if (empty($cur)) { 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 '. throw new ClientException(_m('Only logged-in users can '.
'import del.icio.us backups.'), 'import del.icio.us backups.'),
403); 403);
} }
if (!$cur->hasRight(BookmarkPlugin::IMPORTDELICIOUS)) { 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); throw new ClientException(_m('You may not restore your account.'), 403);
} }
@ -95,7 +95,6 @@ class ImportdeliciousAction extends Action
* *
* @return void * @return void
*/ */
function handle($argarray=null) function handle($argarray=null)
{ {
parent::handle($argarray); parent::handle($argarray);
@ -115,12 +114,12 @@ class ImportdeliciousAction extends Action
* *
* @return void * @return void
*/ */
function importDelicious() function importDelicious()
{ {
$this->checkSessionToken(); $this->checkSessionToken();
if (!isset($_FILES[ImportDeliciousForm::FILEINPUT]['error'])) { 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.')); throw new ClientException(_m('No uploaded file.'));
} }
@ -134,36 +133,37 @@ class ImportdeliciousAction extends Action
return; return;
case UPLOAD_ERR_FORM_SIZE: case UPLOAD_ERR_FORM_SIZE:
throw new ClientException( 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' . _m('The uploaded file exceeds the MAX_FILE_SIZE directive' .
' that was specified in the HTML form.')); ' that was specified in the HTML form.'));
return; return;
case UPLOAD_ERR_PARTIAL: case UPLOAD_ERR_PARTIAL:
@unlink($_FILES[ImportDeliciousForm::FILEINPUT]['tmp_name']); @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' . throw new ClientException(_m('The uploaded file was only' .
' partially uploaded.')); ' partially uploaded.'));
return; return;
case UPLOAD_ERR_NO_FILE: case UPLOAD_ERR_NO_FILE:
// No file; probably just a non-AJAX submission. // 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.')); throw new ClientException(_m('No uploaded file.'));
return; return;
case UPLOAD_ERR_NO_TMP_DIR: 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.')); throw new ClientException(_m('Missing a temporary folder.'));
return; return;
case UPLOAD_ERR_CANT_WRITE: 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.')); throw new ClientException(_m('Failed to write file to disk.'));
return; return;
case UPLOAD_ERR_EXTENSION: 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.')); throw new ClientException(_m('File upload stopped by extension.'));
return; return;
default: default:
common_log(LOG_ERR, __METHOD__ . ": Unknown upload error " . common_log(LOG_ERR, __METHOD__ . ": Unknown upload error " .
$_FILES[ImportDeliciousForm::FILEINPUT]['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.')); throw new ClientException(_m('System error uploading file.'));
return; return;
} }
@ -172,18 +172,24 @@ class ImportdeliciousAction extends Action
try { try {
if (!file_exists($filename)) { 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)) { 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)) { 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); $html = file_get_contents($filename);
@ -214,14 +220,15 @@ class ImportdeliciousAction extends Action
* *
* @return void * @return void
*/ */
function showContent() function showContent()
{ {
if ($this->success) { if ($this->success) {
$this->element('p', null, $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.')); _m('Bookmarks have been imported. Your bookmarks should now appear in search and your profile page.'));
} else if ($this->inprogress) { } else if ($this->inprogress) {
$this->element('p', null, $this->element('p', null,
// TRANS: Busy message for importing bookmarks.
_m('Bookmarks are being imported. Please wait a few minutes for results.')); _m('Bookmarks are being imported. Please wait a few minutes for results.'));
} else { } else {
$form = new ImportDeliciousForm($this); $form = new ImportDeliciousForm($this);
@ -238,7 +245,6 @@ class ImportdeliciousAction extends Action
* *
* @return boolean is read only action? * @return boolean is read only action?
*/ */
function isReadOnly($args) function isReadOnly($args)
{ {
return !$this->isPost(); return !$this->isPost();
@ -255,7 +261,6 @@ class ImportdeliciousAction extends Action
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class ImportDeliciousForm extends Form class ImportDeliciousForm extends Form
{ {
const FILEINPUT = 'deliciousbackupfile'; const FILEINPUT = 'deliciousbackupfile';
@ -269,7 +274,6 @@ class ImportDeliciousForm extends Form
* *
* @return ImportDeliciousForm this * @return ImportDeliciousForm this
*/ */
function __construct($out=null) function __construct($out=null)
{ {
parent::__construct($out); parent::__construct($out);
@ -281,7 +285,6 @@ class ImportDeliciousForm extends Form
* *
* @return string the form's class * @return string the form's class
*/ */
function formClass() function formClass()
{ {
return 'form_import_delicious'; return 'form_import_delicious';
@ -292,7 +295,6 @@ class ImportDeliciousForm extends Form
* *
* @return string the form's action URL * @return string the form's action URL
*/ */
function action() function action()
{ {
return common_local_url('importdelicious'); return common_local_url('importdelicious');
@ -305,11 +307,11 @@ class ImportDeliciousForm extends Form
* *
* @return void * @return void
*/ */
function formData() function formData()
{ {
$this->out->elementStart('p', 'instructions'); $this->out->elementStart('p', 'instructions');
// TRANS: Form instructions for importing bookmarks.
$this->out->raw(_m('You can upload a backed-up '. $this->out->raw(_m('You can upload a backed-up '.
'delicious.com bookmarks file.')); 'delicious.com bookmarks file.'));
@ -337,9 +339,11 @@ class ImportDeliciousForm extends Form
function formActions() function formActions()
{ {
$this->out->submit('submit', $this->out->submit('submit',
// TRANS: Button text on form to import bookmarks.
_m('BUTTON', 'Upload'), _m('BUTTON', 'Upload'),
'submit', 'submit',
null, null,
_m('Upload the file')); // TRANS: Button title on form to import bookmarks.
_m('Upload the file.'));
} }
} }

View File

@ -43,7 +43,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class NewbookmarkAction extends Action class NewbookmarkAction extends Action
{ {
protected $user = null; protected $user = null;
@ -59,9 +58,9 @@ class NewbookmarkAction extends Action
* *
* @return string Action title * @return string Action title
*/ */
function title() function title()
{ {
// TRANS: Title for action to create a new bookmark.
return _m('New bookmark'); return _m('New bookmark');
} }
@ -72,7 +71,6 @@ class NewbookmarkAction extends Action
* *
* @return boolean true * @return boolean true
*/ */
function prepare($argarray) function prepare($argarray)
{ {
parent::prepare($argarray); parent::prepare($argarray);
@ -80,7 +78,8 @@ class NewbookmarkAction extends Action
$this->user = common_current_user(); $this->user = common_current_user();
if (empty($this->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); 403);
} }
@ -103,7 +102,6 @@ class NewbookmarkAction extends Action
* *
* @return void * @return void
*/ */
function handle($argarray=null) function handle($argarray=null)
{ {
parent::handle($argarray); parent::handle($argarray);
@ -122,7 +120,6 @@ class NewbookmarkAction extends Action
* *
* @return void * @return void
*/ */
function newBookmark() function newBookmark()
{ {
if ($this->boolean('ajax')) { if ($this->boolean('ajax')) {
@ -130,19 +127,25 @@ class NewbookmarkAction extends Action
} }
try { try {
if (empty($this->title)) { 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.')); throw new ClientException(_m('Bookmark must have a title.'));
} }
if (empty($this->url)) { 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.')); throw new ClientException(_m('Bookmark must have an URL.'));
} }
$options = array();
ToSelector::fillOptions($this, $options);
$saved = Bookmark::saveNew($this->user->getProfile(), $saved = Bookmark::saveNew($this->user->getProfile(),
$this->title, $this->title,
$this->url, $this->url,
$this->tags, $this->tags,
$this->description); $this->description,
$options);
} catch (ClientException $ce) { } catch (ClientException $ce) {
$this->error = $ce->getMessage(); $this->error = $ce->getMessage();
@ -155,8 +158,8 @@ class NewbookmarkAction extends Action
$this->xw->startDocument('1.0', 'UTF-8'); $this->xw->startDocument('1.0', 'UTF-8');
$this->elementStart('html'); $this->elementStart('html');
$this->elementStart('head'); $this->elementStart('head');
// TRANS: Page title after sending a notice. // TRANS: Page title after posting a bookmark.
$this->element('title', null, _m('Notice posted')); $this->element('title', null, _m('Bookmark posted'));
$this->elementEnd('head'); $this->elementEnd('head');
$this->elementStart('body'); $this->elementStart('body');
$this->showNotice($saved); $this->showNotice($saved);
@ -188,7 +191,6 @@ class NewbookmarkAction extends Action
* *
* @return void * @return void
*/ */
function showContent() function showContent()
{ {
if (!empty($this->error)) { if (!empty($this->error)) {
@ -215,7 +217,6 @@ class NewbookmarkAction extends Action
* *
* @return boolean is read only action? * @return boolean is read only action?
*/ */
function isReadOnly($args) function isReadOnly($args)
{ {
if ($_SERVER['REQUEST_METHOD'] == 'GET' || if ($_SERVER['REQUEST_METHOD'] == 'GET' ||
@ -226,4 +227,3 @@ class NewbookmarkAction extends Action
} }
} }
} }

View File

@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class NoticebyurlAction extends Action class NoticebyurlAction extends Action
{ {
protected $url = null; protected $url = null;
@ -59,7 +58,6 @@ class NoticebyurlAction extends Action
* *
* @return boolean true * @return boolean true
*/ */
function prepare($argarray) function prepare($argarray)
{ {
parent::prepare($argarray); parent::prepare($argarray);
@ -67,7 +65,8 @@ class NoticebyurlAction extends Action
$this->file = File::staticGet('id', $this->trimmed('id')); $this->file = File::staticGet('id', $this->trimmed('id'));
if (empty($this->file)) { 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'); $pageArg = $this->trimmed('page');
@ -85,13 +84,16 @@ class NoticebyurlAction extends Action
* *
* @return string page title * @return string page title
*/ */
function title() function title()
{ {
if ($this->page == 1) { 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 { } 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->file->url,
$this->page); $this->page);
} }
@ -104,7 +106,6 @@ class NoticebyurlAction extends Action
* *
* @return void * @return void
*/ */
function handle($argarray=null) function handle($argarray=null)
{ {
$this->showPage(); $this->showPage();
@ -117,7 +118,6 @@ class NoticebyurlAction extends Action
* *
* @return void * @return void
*/ */
function showContent() function showContent()
{ {
$nl = new NoticeList($this->notices, $this); $nl = new NoticeList($this->notices, $this);
@ -142,7 +142,6 @@ class NoticebyurlAction extends Action
* *
* @return boolean is read only action? * @return boolean is read only action?
*/ */
function isReadOnly($args) function isReadOnly($args)
{ {
return true; return true;
@ -169,7 +168,6 @@ class NoticebyurlAction extends Action
* *
* @return string etag http header * @return string etag http header
*/ */
function etag() function etag()
{ {
return null; return null;

View File

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

View File

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

View File

@ -125,12 +125,15 @@ class CasAuthenticationPlugin extends AuthenticationPlugin
function onInitializePlugin(){ function onInitializePlugin(){
parent::onInitializePlugin(); parent::onInitializePlugin();
if(!isset($this->server)){ 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.")); throw new Exception(_m("Specifying a server is required."));
} }
if(!isset($this->port)){ 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.")); throw new Exception(_m("Specifying a port is required."));
} }
if(!isset($this->path)){ 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.")); throw new Exception(_m("Specifying a path is required."));
} }
//These values need to be accessible to a action object //These values need to be accessible to a action object

View File

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

View File

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

View File

@ -52,7 +52,8 @@ class ShortenAction extends Action
$this->users=array(); $this->users=array();
$this->text = $this->arg('text'); $this->text = $this->arg('text');
if(is_null($this->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; return true;
} }

View File

@ -1,6 +1,5 @@
<?php <?php
/* /*
*
* Phomet: a php comet client * Phomet: a php comet client
* *
* Copyright (C) 2008 Morgan 'ARR!' Allen <morganrallen@gmail.com> http://morglog.alleycatracing.com * 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 // update the local timeline from a Comet server
//
var CometUpdate = function() var CometUpdate = function()
{ {
var _server; var _server;
@ -27,4 +25,3 @@ var CometUpdate = function()
} }
} }
}(); }();

View File

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

View File

@ -44,7 +44,6 @@ if (!defined('STATUSNET')) {
*/ */
class DirectoryPlugin extends Plugin class DirectoryPlugin extends Plugin
{ {
private $dir = null; private $dir = null;
/** /**
@ -165,8 +164,10 @@ class DirectoryPlugin extends Plugin
$nav->out->menuItem( $nav->out->menuItem(
common_local_url('userdirectory'), common_local_url('userdirectory'),
_m('Directory'), // TRANS: Menu item text for user directory.
_m('User Directory'), _m('MENU','Directory'),
// TRANS: Menu item title for user directory.
_m('User Directory.'),
$actionName == 'userdirectory', $actionName == 'userdirectory',
'nav_directory' 'nav_directory'
); );
@ -184,6 +185,7 @@ class DirectoryPlugin extends Plugin
'version' => STATUSNET_VERSION, 'version' => STATUSNET_VERSION,
'author' => 'Zach Copley', 'author' => 'Zach Copley',
'homepage' => 'http://status.net/wiki/Plugin:Directory', 'homepage' => 'http://status.net/wiki/Plugin:Directory',
// TRANS: Plugin description.
'rawdescription' => _m('Add a user directory.') '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 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://status.net/ * @link http://status.net/
*/ */
class DiskCachePlugin extends Plugin class DiskCachePlugin extends Plugin
{ {
var $root = '/tmp'; var $root = '/tmp';
@ -64,7 +63,6 @@ class DiskCachePlugin extends Plugin
* *
* @return boolean hook success * @return boolean hook success
*/ */
function onStartCacheGet(&$key, &$value) function onStartCacheGet(&$key, &$value)
{ {
$filename = $this->keyToFilename($key); $filename = $this->keyToFilename($key);
@ -91,7 +89,6 @@ class DiskCachePlugin extends Plugin
* *
* @return boolean hook success * @return boolean hook success
*/ */
function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success) function onStartCacheSet(&$key, &$value, &$flag, &$expiry, &$success)
{ {
$filename = $this->keyToFilename($key); $filename = $this->keyToFilename($key);
@ -152,7 +149,6 @@ class DiskCachePlugin extends Plugin
* *
* @return boolean hook success * @return boolean hook success
*/ */
function onStartCacheDelete(&$key, &$success) function onStartCacheDelete(&$key, &$success)
{ {
$filename = $this->keyToFilename($key); $filename = $this->keyToFilename($key);
@ -172,6 +168,7 @@ class DiskCachePlugin extends Plugin
'author' => 'Evan Prodromou', 'author' => 'Evan Prodromou',
'homepage' => 'http://status.net/wiki/Plugin:DiskCache', 'homepage' => 'http://status.net/wiki/Plugin:DiskCache',
'rawdescription' => 'rawdescription' =>
// TRANS: Plugin description.
_m('Plugin to implement cache interface with disk files.')); _m('Plugin to implement cache interface with disk files.'));
return true; return true;
} }

View File

@ -140,6 +140,7 @@ ENDOFSCRIPT;
$action->elementStart('noscript'); $action->elementStart('noscript');
// TRANS: User notification that JavaScript is required for Disqus comment display. // 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); $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); $output = common_markup_to_html($noScriptMsg);
$action->raw($output); $action->raw($output);

View File

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

View File

@ -138,8 +138,6 @@ class RSVP extends Managed_DataObject
function saveNew($profile, $event, $verb, $options=array()) function saveNew($profile, $event, $verb, $options=array())
{ {
common_debug("RSVP::saveNew({$profile->id}, {$event->id}, '$verb', 'some options');");
if (array_key_exists('uri', $options)) { if (array_key_exists('uri', $options)) {
$other = RSVP::staticGet('uri', $options['uri']); $other = RSVP::staticGet('uri', $options['uri']);
if (!empty($other)) { if (!empty($other)) {
@ -161,8 +159,6 @@ class RSVP extends Managed_DataObject
$rsvp->event_id = $event->id; $rsvp->event_id = $event->id;
$rsvp->response = self::codeFor($verb); $rsvp->response = self::codeFor($verb);
common_debug("Got value {$rsvp->response} for verb {$verb}");
if (array_key_exists('created', $options)) { if (array_key_exists('created', $options)) {
$rsvp->created = $options['created']; $rsvp->created = $options['created'];
} else { } else {
@ -178,6 +174,8 @@ class RSVP extends Managed_DataObject
$rsvp->insert(); $rsvp->insert();
self::blow('rsvp:for-event:%s', $event->id);
// XXX: come up with something sexier // XXX: come up with something sexier
$content = $rsvp->asString(); $content = $rsvp->asString();
@ -256,18 +254,39 @@ class RSVP extends Managed_DataObject
static function forEvent($event) 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(), $rsvps = array(RSVP::POSITIVE => array(),
RSVP::NEGATIVE => array(), RSVP::NEGATIVE => array(),
RSVP::POSSIBLE => array()); RSVP::POSSIBLE => array());
$rsvp = new RSVP(); foreach ($ids as $id) {
$rsvp = RSVP::staticGet('id', $id);
$rsvp->event_id = $event->id; if (!empty($rsvp)) {
if ($rsvp->find()) {
while ($rsvp->fetch()) {
$verb = self::verbFor($rsvp->response); $verb = self::verbFor($rsvp->response);
$rsvps[$verb][] = clone($rsvp); $rsvps[$verb][] = $rsvp;
} }
} }
@ -375,4 +394,10 @@ class RSVP extends Managed_DataObject
$profile->getBestName(), $profile->getBestName(),
$eventTitle); $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.')); _m('Description of the event.'));
$this->unli(); $this->unli();
$this->li(); $this->out->elementEnd('ul');
$toWidget = new ToSelector($this->out, $toWidget = new ToSelector($this->out,
common_current_user(), common_current_user(),
null); null);
$toWidget->show(); $toWidget->show();
$this->unli();
$this->out->elementEnd('ul');
$this->out->elementEnd('fieldset'); $this->out->elementEnd('fieldset');
} }

View File

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

View File

@ -138,10 +138,19 @@ class NewPollAction extends Action
throw new ClientException(_m('Poll must have at least two options.')); 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(), $saved = Poll::saveNew($this->user->getProfile(),
$this->question, $this->question,
$this->options); $this->options,
$options);
} catch (ClientException $ce) { } catch (ClientException $ce) {
$this->error = $ce->getMessage(); $this->error = $ce->getMessage();
$this->showPage(); $this->showPage();

View File

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

View File

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

View File

@ -155,13 +155,39 @@ class QnanewanswerAction extends Action
$answer = $this->question->getAnswer($profile); $answer = $this->question->getAnswer($profile);
header('Content-Type: text/xml;charset=utf-8'); header('Content-Type: text/xml;charset=utf-8');
$this->xw->startDocument('1.0', 'UTF-8'); $this->xw->startDocument('1.0', 'UTF-8');
$this->elementStart('html'); $this->elementStart('html');
$this->elementStart('head'); $this->elementStart('head');
// TRANS: Page title after sending an answer. // TRANS: Page title after sending an answer.
$this->element('title', null, _m('Answers')); $this->element('title', null, _m('Answers'));
$this->elementEnd('head'); $this->elementEnd('head');
$this->elementStart('body'); $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('body');
$this->elementEnd('html'); $this->elementEnd('html');
} else { } else {

View File

@ -88,7 +88,6 @@ class QnanewquestionAction extends Action
} }
$this->title = $this->trimmed('title'); $this->title = $this->trimmed('title');
common_debug("TITLE = " . $this->title);
$this->description = $this->trimmed('description'); $this->description = $this->trimmed('description');
return true; return true;
@ -130,10 +129,17 @@ class QnanewquestionAction extends Action
throw new ClientException(_m('Question must have a title.')); 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( $saved = QnA_Question::saveNew(
$this->user->getProfile(), $this->user->getProfile(),
$this->title, $this->title,
$this->description $this->description,
$options
); );
} catch (ClientException $ce) { } catch (ClientException $ce) {
$this->error = $ce->getMessage(); $this->error = $ce->getMessage();

View File

@ -97,7 +97,49 @@ class QnashowquestionAction extends ShownoticeAction
function showContent() function showContent()
{ {
$this->elementStart('div', 'qna-full-question');
$this->raw($this->question->asHTML()); $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: Page title for a question.
// TRANS: %1$s is the nickname of the user who asked the question, %2$s is the 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'), return sprintf(
$this->user->nickname, _m('%1$s\'s question: %2$s'),
$this->question->title); $this->user->nickname,
$this->question->title
);
} }
/** /**

View File

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

View File

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

View File

@ -47,6 +47,7 @@ if (!defined('STATUSNET')) {
class QnanewanswerForm extends Form class QnanewanswerForm extends Form
{ {
protected $question; protected $question;
protected $showQuestion;
/** /**
* Construct a new answer form * Construct a new answer form
@ -56,10 +57,11 @@ class QnanewanswerForm extends Form
* *
* @return void * @return void
*/ */
function __construct(HTMLOutputter $out, QnA_Question $question) function __construct(HTMLOutputter $out, QnA_Question $question, $showQuestion = true)
{ {
parent::__construct($out); parent::__construct($out);
$this->question = $question; $this->question = $question;
$this->showQuestion = $showQuestion;
} }
/** /**
@ -103,9 +105,10 @@ class QnanewanswerForm extends Form
$out = $this->out; $out = $this->out;
$id = "question-" . $question->id; $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->hidden('id', $id);
$out->textarea('answer', 'answer'); $out->textarea('answer', 'answer');
} }
@ -118,7 +121,7 @@ class QnanewanswerForm extends Form
function formActions() function formActions()
{ {
// TRANS: Button text for submitting a poll response. // 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->unli();
$this->out->elementEnd('ul'); $this->out->elementEnd('ul');
$toWidget = new ToSelector(
$this->out,
common_current_user(),
null
);
$toWidget->show();
$this->out->elementEnd('fieldset'); $this->out->elementEnd('fieldset');
} }

View File

@ -46,14 +46,14 @@ require_once INSTALLDIR . '/lib/form.php';
class QnashowanswerForm extends Form 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 * The question this is an answer to
*/ */
var $question = null; protected $question = null;
/** /**
* Constructor * Constructor
@ -65,8 +65,8 @@ class QnashowanswerForm extends Form
{ {
parent::__construct($out); parent::__construct($out);
$this->answer = $answer; $this->answer = $answer;
$this->question = $answer->getQuestion(); $this->question = $answer->getQuestion();
} }
/** /**
@ -76,7 +76,7 @@ class QnashowanswerForm extends Form
*/ */
function id() function id()
{ {
return 'revise-' . $this->answer->id; return 'show-' . $this->answer->id;
} }
/** /**
@ -109,8 +109,8 @@ class QnashowanswerForm extends Form
*/ */
function formLegend() function formLegend()
{ {
// TRANS: Form legend for revising the answer. // TRANS: Form legend for showing the answer.
$this->out->element('legend', null, _('Revise your answer')); $this->out->element('legend', null, _('Answer'));
} }
/** /**
@ -122,7 +122,7 @@ class QnashowanswerForm extends Form
{ {
$this->out->hidden( $this->out->hidden(
'id', 'id',
'revise-' . $this->answer->id 'answer-' . $this->answer->id
); );
$this->out->raw($this->answer->asHTML()); $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) { if ($user->id == $this->answer->profile_id) {
$this->out->submit( $this->out->submit(
'revise', 'revise',
@ -166,6 +173,7 @@ class QnashowanswerForm extends Form
_('Revise your answer') _('Revise your answer')
); );
} }
*/
} }
} }
@ -176,6 +184,6 @@ class QnashowanswerForm extends Form
*/ */
function formClass() function formClass()
{ {
return 'form_revise ajax'; return 'form_show ajax';
} }
} }

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->profile_id = $profile->id;
$ts->created = common_sql_now(); $ts->created = common_sql_now();
$ts->insert(); $ts->insert();
self::blow('searchsub:by_profile:%d', $profile->id);
return $ts; return $ts;
} }
@ -135,6 +136,34 @@ class SearchSub extends Managed_DataObject
'profile_id' => $profile->id)); 'profile_id' => $profile->id));
if ($ts) { if ($ts) {
$ts->delete(); $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 'SearchunsubAction':
case 'SearchsubsAction': case 'SearchsubsAction':
case 'SearchSubForm': case 'SearchSubForm':
case 'SearchSubMenu':
case 'SearchUnsubForm': case 'SearchUnsubForm':
case 'SearchSubTrackCommand': case 'SearchSubTrackCommand':
case 'SearchSubTrackOffCommand': case 'SearchSubTrackOffCommand':
@ -318,4 +319,19 @@ class SearchSubPlugin extends Plugin
// TRANS: Help message for IM/SMS command "tracking" // TRANS: Help message for IM/SMS command "tracking"
$commands["tracking"] = _m('COMMANDHELP', "List all your search subscriptions."); $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->profile_id = $profile->id;
$ts->created = common_sql_now(); $ts->created = common_sql_now();
$ts->insert(); $ts->insert();
self::blow('tagsub:by_profile:%d', $profile->id);
return $ts; return $ts;
} }
@ -135,6 +136,34 @@ class TagSub extends Managed_DataObject
'profile_id' => $profile->id)); 'profile_id' => $profile->id));
if ($ts) { if ($ts) {
$ts->delete(); $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 'TagunsubAction':
case 'TagsubsAction': case 'TagsubsAction':
case 'TagSubForm': case 'TagSubForm':
case 'TagSubMenu':
case 'TagUnsubForm': case 'TagUnsubForm':
include_once $dir.'/'.strtolower($cls).'.php'; include_once $dir.'/'.strtolower($cls).'.php';
return false; return false;
@ -239,4 +240,19 @@ class TagSubPlugin extends Plugin
} }
return true; 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. Default avatars are modified from an image by Francesco 'Architetto' Rollandin.
http://www.openclipart.org/detail/34957 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; padding-bottom: 15px;
} }
#input_form_status { #input_form_status, #input_form_direct {
padding-bottom: 45px; padding-bottom: 45px;
} }
@ -333,6 +333,10 @@ address {
font-size: 1.2em; font-size: 1.2em;
} }
#form_notice-direct.form_notice textarea {
width: 498px;
}
.form_notice label.notice_data-attach { .form_notice label.notice_data-attach {
top: 0px; top: 0px;
right: 0px; right: 0px;
@ -355,6 +359,11 @@ address {
z-index: 99; z-index: 99;
} }
#form_notice-direct.form_notice .count {
top: 80px;
right: 10px;
}
.form_notice #notice_action-submit { .form_notice #notice_action-submit {
position: absolute; position: absolute;
top: 100%; top: 100%;
@ -397,6 +406,52 @@ address {
margin-bottom: 10px !important; 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 { #aside_primary {
width: 218px; width: 218px;
float: left; float: left;
@ -1246,37 +1301,63 @@ table.profile_list tr.alt {
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FB6104', endColorstr='#fc8035',GradientType=0 ); 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 */ /* QnA specific styles */
#content .question .entry-title { #content .question .entry-title, #content .qna-full-question .entry-title {
min-height: 1px; min-height: 1px;
} }
.question div.question-description { .question div.question-description {
font-size: 1em; font-size: 1em;
line-height: 1.36em; line-height: 1.36em;
margin-top: 0px;
opacity: 1; 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; margin: 0px;
} }
.question fieldset legend { .question fieldset legend, .qna-full-question fieldset legend {
display: none; display: none;
} }
.question p.answer { .question label[for=answer], .qna-full-question label[for=answer] {
margin-top: 4px;
margin-bottom: 4px;
font-style: italic;
}
.question label[for=answer] {
display: none; display: none;
} }
.question textarea { .question textarea, .qna-full-question textarea {
width: 100%; width: 100%;
height: 42px; height: 42px;
padding: 6px 10px 18px 10px; 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); -moz-box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.2);
-webkit-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; font-size: 1.2em;
margin-top: 15px;
margin-bottom: 10px; margin-bottom: 10px;
} }
.question #answer-form input.submit { .qna-full-question textarea {
width: 473px;
}
.question-description input.submit, .answer-content input.submit {
height: auto; height: auto;
padding: 0px 10px; padding: 0px 10px;
margin-left: 0px; margin: 6px 0px 10px 0px;
margin-bottom: 10px;
color:#fff; color:#fff;
font-weight: bold; font-weight: bold;
text-transform: uppercase; text-transform: uppercase;
font-size: 1.1em; 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*/ }/*end of @media screen, projection, tv*/

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B