summaryrefslogtreecommitdiff
path: root/actions
diff options
context:
space:
mode:
Diffstat (limited to 'actions')
-rw-r--r--actions/api.php67
-rw-r--r--actions/attachment.php11
-rw-r--r--actions/attachment_ajax.php5
-rw-r--r--actions/attachment_thumbnail.php46
-rw-r--r--actions/conversation.php52
-rw-r--r--actions/disfavor.php2
-rw-r--r--actions/favor.php2
-rw-r--r--actions/file.php56
-rw-r--r--actions/groupdesignsettings.php65
-rw-r--r--actions/groupmembers.php9
-rw-r--r--actions/grouprss.php1
-rw-r--r--actions/groups.php1
-rw-r--r--actions/invite.php4
-rw-r--r--actions/newnotice.php64
-rw-r--r--actions/noticesearchrss.php13
-rw-r--r--actions/othersettings.php11
-rw-r--r--actions/peoplesearch.php44
-rw-r--r--actions/public.php14
-rw-r--r--actions/showfavorites.php2
-rw-r--r--actions/showgroup.php44
-rw-r--r--actions/shownotice.php21
-rw-r--r--actions/subscriptions.php5
-rw-r--r--actions/sup.php4
-rw-r--r--actions/twitapifriendships.php83
-rw-r--r--actions/twitapisearchatom.php28
-rw-r--r--actions/twitapisearchjson.php9
-rw-r--r--actions/twitapistatuses.php17
-rw-r--r--actions/twitapiusers.php11
-rw-r--r--actions/userdesignsettings.php109
29 files changed, 577 insertions, 223 deletions
diff --git a/actions/api.php b/actions/api.php
index 1fe5875ad..18c3b68d4 100644
--- a/actions/api.php
+++ b/actions/api.php
@@ -67,20 +67,22 @@ class ApiAction extends Action
$this->process_command();
} else {
# basic authentication failed
- common_log(LOG_WARNING, "Failed API auth attempt, nickname: $nickname.");
+ list($proxy, $ip) = common_client_ip();
+
+ common_log(LOG_WARNING, "Failed API auth attempt, nickname = $nickname, proxy = $proxy, ip = $ip.");
$this->show_basic_auth_error();
}
}
} else {
- # Caller might give us a username even if not required
- if (isset($_SERVER['PHP_AUTH_USER'])) {
- $user = User::staticGet('nickname', $_SERVER['PHP_AUTH_USER']);
- if ($user) {
- $this->user = $user;
- }
- # Twitter doesn't throw an error if the user isn't found
- }
+ // Caller might give us a username even if not required
+ if (isset($_SERVER['PHP_AUTH_USER'])) {
+ $user = User::staticGet('nickname', $_SERVER['PHP_AUTH_USER']);
+ if ($user) {
+ $this->user = $user;
+ }
+ # Twitter doesn't throw an error if the user isn't found
+ }
$this->process_command();
}
@@ -115,7 +117,7 @@ class ApiAction extends Action
}
}
- # Whitelist of API methods that don't need authentication
+ // Whitelist of API methods that don't need authentication
function requires_auth()
{
static $noauth = array( 'statuses/public_timeline',
@@ -133,28 +135,61 @@ class ApiAction extends Action
'statuses/replies',
'statuses/mentions',
'statuses/followers',
- 'favorites/favorites');
+ 'favorites/favorites',
+ 'friendships/show');
$fullname = "$this->api_action/$this->api_method";
// If the site is "private", all API methods except laconica/config
// need authentication
+
if (common_config('site', 'private')) {
return $fullname != 'laconica/config' || false;
}
+ // bareauth: only needs auth if without an argument or query param specifying user
+
if (in_array($fullname, $bareauth)) {
- # bareauth: only needs auth if without an argument or query param specifying user
- if ($this->api_arg || $this->arg('id') || is_numeric($this->arg('user_id')) || $this->arg('screen_name')) {
+
+ // Special case: friendships/show only needs auth if source_id or
+ // source_screen_name is not specified as a param
+
+ if ($fullname == 'friendships/show') {
+
+ $source_id = $this->arg('source_id');
+ $source_screen_name = $this->arg('source_screen_name');
+
+ if (empty($source_id) && empty($source_screen_name)) {
+ return true;
+ }
+
return false;
- } else {
+ }
+
+ // if all of these are empty, auth is required
+
+ $id = $this->arg('id');
+ $user_id = $this->arg('user_id');
+ $screen_name = $this->arg('screen_name');
+
+ if (empty($this->api_arg) &&
+ empty($id) &&
+ empty($user_id) &&
+ empty($screen_name)) {
return true;
+ } else {
+ return false;
}
+
} else if (in_array($fullname, $noauth)) {
- # noauth: never needs auth
+
+ // noauth: never needs auth
+
return false;
} else {
- # everybody else needs auth
+
+ // everybody else needs auth
+
return true;
}
}
diff --git a/actions/attachment.php b/actions/attachment.php
index e4dc0e054..ee4cd9640 100644
--- a/actions/attachment.php
+++ b/actions/attachment.php
@@ -111,7 +111,16 @@ class AttachmentAction extends Action
function handle($args)
{
parent::handle($args);
- $this->showPage();
+
+ if (empty($this->attachment->filename)) {
+
+ // if it's not a local file, gtfo
+
+ common_redirect($this->attachment->url, 303);
+
+ } else {
+ $this->showPage();
+ }
}
/**
diff --git a/actions/attachment_ajax.php b/actions/attachment_ajax.php
index 5d6773010..4caa159f3 100644
--- a/actions/attachment_ajax.php
+++ b/actions/attachment_ajax.php
@@ -58,6 +58,11 @@ class Attachment_ajaxAction extends AttachmentAction
}
}
+ function handle($args)
+ {
+ $this->showPage();
+ }
+
/**
* Show core.
*
diff --git a/actions/attachment_thumbnail.php b/actions/attachment_thumbnail.php
index b4070e747..248d16e38 100644
--- a/actions/attachment_thumbnail.php
+++ b/actions/attachment_thumbnail.php
@@ -45,6 +45,12 @@ require_once INSTALLDIR.'/actions/attachment.php';
class Attachment_thumbnailAction extends AttachmentAction
{
+
+ function handle($args)
+ {
+ $this->showPage();
+ }
+
/**
* Show page, a template method.
*
@@ -74,45 +80,5 @@ class Attachment_thumbnailAction extends AttachmentAction
$this->element('img', array('src' => $file_thumbnail->url, 'alt' => 'Thumbnail'));
}
- /**
- * Last-modified date for page
- *
- * When was the content of this page last modified? Based on notice,
- * profile, avatar.
- *
- * @return int last-modified date as unix timestamp
- */
-/*
- function lastModified()
- {
- return max(strtotime($this->notice->created),
- strtotime($this->profile->modified),
- ($this->avatar) ? strtotime($this->avatar->modified) : 0);
- }
-*/
-
- /**
- * An entity tag for this page
- *
- * Shows the ETag for the page, based on the notice ID and timestamps
- * for the notice, profile, and avatar. It's weak, since we change
- * the date text "one hour ago", etc.
- *
- * @return string etag
- */
-/*
- function etag()
- {
- $avtime = ($this->avatar) ?
- strtotime($this->avatar->modified) : 0;
-
- return 'W/"' . implode(':', array($this->arg('action'),
- common_language(),
- $this->notice->id,
- strtotime($this->notice->created),
- strtotime($this->profile->modified),
- $avtime)) . '"';
- }
-*/
}
diff --git a/actions/conversation.php b/actions/conversation.php
index d3fc5b6a9..0eb0d86d6 100644
--- a/actions/conversation.php
+++ b/actions/conversation.php
@@ -31,6 +31,9 @@ if (!defined('LACONICA')) {
exit(1);
}
+// XXX: not sure how to do paging yet,
+// so set a 60-notice limit
+
require_once INSTALLDIR.'/lib/noticelist.php';
/**
@@ -63,6 +66,7 @@ class ConversationAction extends Action
if (empty($this->id)) {
return false;
}
+ $this->id = $this->id+0;
$this->page = $this->trimmed('page');
if (empty($this->page)) {
$this->page = 1;
@@ -106,27 +110,12 @@ class ConversationAction extends Action
function showContent()
{
- // FIXME this needs to be a tree, not a list
-
- $qry = 'SELECT * FROM notice WHERE conversation = %s ';
-
- $offset = ($this->page-1) * NOTICES_PER_PAGE;
- $limit = NOTICES_PER_PAGE + 1;
-
- $txt = sprintf($qry, $this->id);
-
- $notices = Notice::getStream($txt,
- 'notice:conversation:'.$this->id,
- $offset, $limit);
+ $notices = Notice::conversationStream($this->id, null, null);
$ct = new ConversationTree($notices, $this);
$cnt = $ct->show();
-
- $this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
- $this->page, 'conversation', array('id' => $this->id));
}
-
}
/**
@@ -154,8 +143,25 @@ class ConversationTree extends NoticeList
function show()
{
- $cnt = 0;
+ $cnt = $this->_buildTree();
+
+ $this->out->elementStart('div', array('id' =>'notices_primary'));
+ $this->out->element('h2', null, _('Notices'));
+ $this->out->elementStart('ol', array('class' => 'notices xoxo'));
+ if (array_key_exists('root', $this->tree)) {
+ $rootid = $this->tree['root'][0];
+ $this->showNoticePlus($rootid);
+ }
+
+ $this->out->elementEnd('ol');
+ $this->out->elementEnd('div');
+
+ return $cnt;
+ }
+
+ function _buildTree()
+ {
$this->tree = array();
$this->table = array();
@@ -177,18 +183,6 @@ class ConversationTree extends NoticeList
}
}
- $this->out->elementStart('div', array('id' =>'notices_primary'));
- $this->out->element('h2', null, _('Notices'));
- $this->out->elementStart('ol', array('class' => 'notices xoxo'));
-
- if (array_key_exists('root', $this->tree)) {
- $rootid = $this->tree['root'][0];
- $this->showNoticePlus($rootid);
- }
-
- $this->out->elementEnd('ol');
- $this->out->elementEnd('div');
-
return $cnt;
}
diff --git a/actions/disfavor.php b/actions/disfavor.php
index 740f7de93..02e01d6e0 100644
--- a/actions/disfavor.php
+++ b/actions/disfavor.php
@@ -75,7 +75,7 @@ class DisfavorAction extends Action
return;
}
$fave = new Fave();
- $fave->user_id = $this->id;
+ $fave->user_id = $user->id;
$fave->notice_id = $notice->id;
if (!$fave->find(true)) {
$this->clientError(_('This notice is not a favorite!'));
diff --git a/actions/favor.php b/actions/favor.php
index ec86b17e6..fe51e34a2 100644
--- a/actions/favor.php
+++ b/actions/favor.php
@@ -12,8 +12,6 @@
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*
-
-/*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, 2009, Control Yourself, Inc.
*
diff --git a/actions/file.php b/actions/file.php
index bb245c4a7..8310e48df 100644
--- a/actions/file.php
+++ b/actions/file.php
@@ -21,20 +21,52 @@ if (!defined('LACONICA')) { exit(1); }
require_once(INSTALLDIR.'/actions/shownotice.php');
-class FileAction extends ShowNoticeAction
+class FileAction extends Action
{
- function showPage() {
- $source_url = common_local_url('file', array('notice' => $this->notice->id));
- $query = "select file_redirection.url as url from file join file_redirection on file.id = file_redirection.file_id where file.url = '$source_url'";
- $file = new File_redirection;
- $file->query($query);
- $file->fetch();
- if (empty($file->url)) {
- die('nothing attached here');
- } else {
- header("Location: {$file->url}");
- die();
+ var $id = null;
+ var $filerec = null;
+
+ function prepare($args)
+ {
+ parent::prepare($args);
+ $this->id = $this->trimmed('notice');
+ if (empty($this->id)) {
+ $this->clientError(_('No notice id'));
+ }
+ $notice = Notice::staticGet('id', $this->id);
+ if (empty($notice)) {
+ $this->clientError(_('No notice'));
+ }
+ $atts = $notice->attachments();
+ if (empty($atts)) {
+ $this->clientError(_('No attachments'));
}
+ foreach ($atts as $att) {
+ if (!empty($att->filename)) {
+ $this->filerec = $att;
+ break;
+ }
+ }
+ if (empty($this->filerec)) {
+ $this->clientError(_('No uploaded attachments'));
+ }
+ return true;
}
+
+ function handle() {
+ common_redirect($this->filerec->url);
+ }
+
+ /**
+ * Is this action read-only?
+ *
+ * @return boolean true
+ */
+
+ function isReadOnly($args)
+ {
+ return true;
+ }
+
}
diff --git a/actions/groupdesignsettings.php b/actions/groupdesignsettings.php
index 7270bc8f7..bb01243c6 100644
--- a/actions/groupdesignsettings.php
+++ b/actions/groupdesignsettings.php
@@ -34,19 +34,37 @@ if (!defined('LACONICA')) {
require_once INSTALLDIR . '/lib/designsettings.php';
+/**
+ * Set a group's design
+ *
+ * Saves a design for a given group
+ *
+ * @category Settings
+ * @package Laconica
+ * @author Zach Copley <zach@controlyourself.ca>
+ * @author Sarven Capadisli <csarven@controlyourself.ca>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://laconi.ca/
+ */
+
class GroupDesignSettingsAction extends DesignSettingsAction
{
var $group = null;
/**
- * Prepare to run
+ * Sets the right action for the form, and passes request args into
+ * the base action
+ *
+ * @param array $args misc. arguments
+ *
+ * @return boolean true
*/
function prepare($args)
{
parent::prepare($args);
- if (!common_config('inboxes','enabled')) {
+ if (!common_config('inboxes', 'enabled')) {
$this->serverError(_('Inboxes must be enabled for groups to work'));
return false;
}
@@ -57,7 +75,7 @@ class GroupDesignSettingsAction extends DesignSettingsAction
}
$nickname_arg = $this->trimmed('nickname');
- $nickname = common_canonical_nickname($nickname_arg);
+ $nickname = common_canonical_nickname($nickname_arg);
// Permanent redirect on non-canonical nickname
@@ -158,7 +176,8 @@ class GroupDesignSettingsAction extends DesignSettingsAction
* @return Design
*/
- function getWorkingDesign() {
+ function getWorkingDesign()
+ {
$design = null;
@@ -238,7 +257,6 @@ class GroupDesignSettingsAction extends DesignSettingsAction
$design->sidebarcolor = $sbcolor->intValue();
$design->textcolor = $tcolor->intValue();
$design->linkcolor = $lcolor->intValue();
- $design->backgroundimage = $filepath;
$design->setDisposition($on, $off, $tile);
@@ -263,7 +281,6 @@ class GroupDesignSettingsAction extends DesignSettingsAction
$design->sidebarcolor = $sbcolor->intValue();
$design->textcolor = $tcolor->intValue();
$design->linkcolor = $lcolor->intValue();
- $design->backgroundimage = $filepath;
$design->setDisposition($on, $off, $tile);
@@ -275,9 +292,9 @@ class GroupDesignSettingsAction extends DesignSettingsAction
return;
}
- $original = clone($this->group);
+ $original = clone($this->group);
$this->group->design_id = $id;
- $result = $this->group->update($original);
+ $result = $this->group->update($original);
if (empty($result)) {
common_log_db_error($original, 'UPDATE', __FILE__);
@@ -295,36 +312,4 @@ class GroupDesignSettingsAction extends DesignSettingsAction
$this->showForm(_('Design preferences saved.'), true);
}
- /**
- * Handle input and output a page (overrided)
- *
- * @param array $args $_REQUEST arguments
- *
- * @return void
- */
-
- function handle($args)
- {
- parent::handle($args);
- if (!common_logged_in()) {
- $this->clientError(_('Not logged in.'));
- return;
- } else if (!common_is_real_login()) {
- // Cookie theft means that automatic logins can't
- // change important settings or see private info, and
- // _all_ our settings are important
- common_set_returnto($this->selfUrl());
- $user = common_current_user();
- if ($user->hasOpenID()) {
- common_redirect(common_local_url('openidlogin'), 303);
- } else {
- common_redirect(common_local_url('login'), 303);
- }
- } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
- $this->handlePost();
- } else {
- $this->showForm();
- }
- }
-
}
diff --git a/actions/groupmembers.php b/actions/groupmembers.php
index d132cdf96..14256526a 100644
--- a/actions/groupmembers.php
+++ b/actions/groupmembers.php
@@ -167,6 +167,15 @@ class GroupMemberListItem extends ProfileListItem
$this->group = $group;
}
+ function showFullName()
+ {
+ parent::showFullName();
+ if ($this->profile->isAdmin($this->group)) {
+ $this->out->text(' ');
+ $this->out->element('span', 'role', _('Admin'));
+ }
+ }
+
function showActions()
{
$this->startActions();
diff --git a/actions/grouprss.php b/actions/grouprss.php
index 0b7280a11..2bdcaafb2 100644
--- a/actions/grouprss.php
+++ b/actions/grouprss.php
@@ -116,6 +116,7 @@ class groupRssAction extends Rss10Action
return null;
}
+ $notices = array();
$notice = $group->getNotices(0, ($limit == 0) ? NOTICES_PER_PAGE : $limit);
while ($notice->fetch()) {
diff --git a/actions/groups.php b/actions/groups.php
index b49d80f37..3d62843ed 100644
--- a/actions/groups.php
+++ b/actions/groups.php
@@ -115,6 +115,7 @@ class GroupsAction extends Action
$groups->orderBy('created DESC');
$groups->limit($offset, $limit);
+ $cnt = 0;
if ($groups->find()) {
$gl = new GroupList($groups, null, $this);
$cnt = $gl->show();
diff --git a/actions/invite.php b/actions/invite.php
index 5dcc83652..bdea4807d 100644
--- a/actions/invite.php
+++ b/actions/invite.php
@@ -35,7 +35,9 @@ class InviteAction extends CurrentUserDesignAction
function handle($args)
{
parent::handle($args);
- if (!common_logged_in()) {
+ if (!common_config('invite', 'enabled')) {
+ $this->clientError(_('Invites have been disabled.'));
+ } else if (!common_logged_in()) {
$this->clientError(sprintf(_('You must be logged in to invite other users to use %s'),
common_config('site', 'name')));
return;
diff --git a/actions/newnotice.php b/actions/newnotice.php
index 4a2c369f0..5f44a32a9 100644
--- a/actions/newnotice.php
+++ b/actions/newnotice.php
@@ -229,13 +229,25 @@ class NewnoticeAction extends Action
if (empty($filename)) {
$this->clientError(_('Couldn\'t save file.'));
}
- $fileurl = File::url($filename);
+
+ $fileRecord = $this->storeFile($filename, $mimetype);
+
+ $fileurl = common_local_url('attachment',
+ array('attachment' => $fileRecord->id));
+
+ // not sure this is necessary -- Zach
+ $this->maybeAddRedir($fileRecord->id, $fileurl);
+
$short_fileurl = common_shorten_url($fileurl);
$content_shortened .= ' ' . $short_fileurl;
+
if (mb_strlen($content_shortened) > 140) {
$this->deleteFile($filename);
$this->clientError(_('Max notice size is 140 chars, including attachment URL.'));
}
+
+ // Also, not sure this is necessary -- Zach
+ $this->maybeAddRedir($fileRecord->id, $short_fileurl);
}
$notice = Notice::saveNew($user->id, $content_shortened, 'web', 1,
@@ -249,7 +261,7 @@ class NewnoticeAction extends Action
}
if (isset($mimetype)) {
- $this->attachFile($notice, $filename, $mimetype, $short_fileurl);
+ $this->attachFile($notice, $fileRecord);
}
common_broadcast_notice($notice);
@@ -304,12 +316,12 @@ class NewnoticeAction extends Action
@unlink($filepath);
}
- function attachFile($notice, $filename, $mimetype, $short)
- {
+ function storeFile($filename, $mimetype) {
+
$file = new File;
$file->filename = $filename;
- $file->url = common_local_url('file', array('notice' => $notice->id));
+ $file->url = File::url($filename);
$filepath = File::path($filename);
@@ -324,28 +336,40 @@ class NewnoticeAction extends Action
$this->clientError(_('There was a database error while saving your file. Please try again.'));
}
- $file_redir = new File_redirection;
- $file_redir->url = File::url($filename);
- $file_redir->file_id = $file_id;
+ return $file;
+ }
- $result = $file_redir->insert();
+ function rememberFile($file, $short)
+ {
+ $this->maybeAddRedir($file->id, $short);
+ }
- if (!$result) {
- common_log_db_error($file_redir, "INSERT", __FILE__);
- $this->clientError(_('There was a database error while saving your file. Please try again.'));
- }
+ function maybeAddRedir($file_id, $url)
+ {
+ $file_redir = File_redirection::staticGet('url', $url);
- $f2p = new File_to_post;
- $f2p->file_id = $file_id;
- $f2p->post_id = $notice->id;
- $f2p->insert();
+ if (empty($file_redir)) {
+ $file_redir = new File_redirection;
+ $file_redir->url = $url;
+ $file_redir->file_id = $file_id;
- if (!$result) {
- common_log_db_error($f2p, "INSERT", __FILE__);
- $this->clientError(_('There was a database error while saving your file. Please try again.'));
+ $result = $file_redir->insert();
+
+ if (!$result) {
+ common_log_db_error($file_redir, "INSERT", __FILE__);
+ $this->clientError(_('There was a database error while saving your file. Please try again.'));
+ }
}
}
+ function attachFile($notice, $filerec)
+ {
+ File_to_post::processNew($filerec->id, $notice->id);
+
+ $this->maybeAddRedir($filerec->id,
+ common_local_url('file', array('notice' => $notice->id)));
+ }
+
/**
* Show an Ajax-y error message
*
diff --git a/actions/noticesearchrss.php b/actions/noticesearchrss.php
index c1bf3bf5f..2a4b2060d 100644
--- a/actions/noticesearchrss.php
+++ b/actions/noticesearchrss.php
@@ -67,11 +67,16 @@ class NoticesearchrssAction extends Rss10Action
if (!$limit) $limit = 20;
$search_engine->limit(0, $limit, true);
- $search_engine->query($q);
- $notice->find();
+ if (false === $search_engine->query($q)) {
+ $cnt = 0;
+ } else {
+ $cnt = $notice->find();
+ }
- while ($notice->fetch()) {
- $notices[] = clone($notice);
+ if ($cnt > 0) {
+ while ($notice->fetch()) {
+ $notices[] = clone($notice);
+ }
}
return $notices;
diff --git a/actions/othersettings.php b/actions/othersettings.php
index b542233ca..1277f8052 100644
--- a/actions/othersettings.php
+++ b/actions/othersettings.php
@@ -83,14 +83,12 @@ class OthersettingsAction extends AccountSettingsAction
{
$user = common_current_user();
-
$this->elementStart('form', array('method' => 'post',
'id' => 'form_settings_other',
'class' => 'form_settings',
'action' =>
common_local_url('othersettings')));
$this->elementStart('fieldset');
- $this->element('legend', null, _('URL Auto-shortening'));
$this->hidden('token', common_session_token());
// I18N
@@ -109,10 +107,14 @@ class OthersettingsAction extends AccountSettingsAction
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
- $this->dropdown('urlshorteningservice', _('Service'),
+ $this->dropdown('urlshorteningservice', _('Shorten URLs with'),
$services, _('Automatic shortening service to use.'),
false, $user->urlshorteningservice);
$this->elementEnd('li');
+ $this->elementStart('li');
+ $this->checkbox('viewdesigns', _('View profile designs'),
+ $user->viewdesigns, _('Show or hide profile designs.'));
+ $this->elementEnd('li');
$this->elementEnd('ul');
$this->submit('save', _('Save'));
$this->elementEnd('fieldset');
@@ -145,6 +147,8 @@ class OthersettingsAction extends AccountSettingsAction
return;
}
+ $viewdesigns = $this->boolean('viewdesigns');
+
$user = common_current_user();
assert(!is_null($user)); // should already be checked
@@ -154,6 +158,7 @@ class OthersettingsAction extends AccountSettingsAction
$original = clone($user);
$user->urlshorteningservice = $urlshorteningservice;
+ $user->viewdesigns = $viewdesigns;
$result = $user->update($original);
diff --git a/actions/peoplesearch.php b/actions/peoplesearch.php
index c61e0e273..60ddb6a82 100644
--- a/actions/peoplesearch.php
+++ b/actions/peoplesearch.php
@@ -87,3 +87,47 @@ class PeoplesearchAction extends SearchAction
}
}
+/**
+ * People search results class
+ *
+ * Derivative of ProfileList with specialization for highlighting search terms.
+ *
+ * @category Widget
+ * @package Laconica
+ * @author Evan Prodromou <evan@controlyourself.ca>
+ * @author Robin Millette <millette@controlyourself.ca>
+ * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
+ * @link http://laconi.ca/
+ *
+ * @see PeoplesearchAction
+ */
+
+class PeopleSearchResults extends ProfileList
+{
+ var $terms = null;
+ var $pattern = null;
+
+ function __construct($profile, $terms, $action)
+ {
+ parent::__construct($profile, $action);
+
+ $this->terms = array_map('preg_quote',
+ array_map('htmlspecialchars', $terms));
+
+ $this->pattern = '/('.implode('|',$terms).')/i';
+ }
+
+ function newProfileItem($profile)
+ {
+ return new PeopleSearchResultItem($profile, $this->action);
+ }
+}
+
+class PeopleSearchResultItem extends ProfileListItem
+{
+ function highlight($text)
+ {
+ return preg_replace($this->pattern, '<strong>\\1</strong>', htmlspecialchars($text));
+ }
+}
+
diff --git a/actions/public.php b/actions/public.php
index 27153f131..ef9ef0d1a 100644
--- a/actions/public.php
+++ b/actions/public.php
@@ -35,6 +35,10 @@ require_once INSTALLDIR.'/lib/publicgroupnav.php';
require_once INSTALLDIR.'/lib/noticelist.php';
require_once INSTALLDIR.'/lib/feedlist.php';
+// Farther than any human will go
+
+define('MAX_PUBLIC_PAGE', 100);
+
/**
* Action for displaying the public stream
*
@@ -74,6 +78,10 @@ class PublicAction extends Action
parent::prepare($args);
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
+ if ($this->page > MAX_PUBLIC_PAGE) {
+ $this->clientError(sprintf(_("Beyond the page limit (%s)"), MAX_PUBLIC_PAGE));
+ }
+
common_set_returnto($this->selfUrl());
return true;
@@ -174,8 +182,10 @@ class PublicAction extends Action
$message .= _('Be the first to post!');
}
else {
- $message .= _('Why not [register an account](%%action.register%%) and be the first to post!');
- }
+ if (! (common_config('site','closed') || common_config('site','inviteonly'))) {
+ $message .= _('Why not [register an account](%%action.register%%) and be the first to post!');
+ }
+ }
$this->elementStart('div', 'guide');
$this->raw(common_markup_to_html($message));
diff --git a/actions/showfavorites.php b/actions/showfavorites.php
index b723924a5..8efe9d30a 100644
--- a/actions/showfavorites.php
+++ b/actions/showfavorites.php
@@ -45,7 +45,7 @@ require_once INSTALLDIR.'/lib/feedlist.php';
* @link http://laconi.ca/
*/
-class ShowfavoritesAction extends CurrentUserDesignAction
+class ShowfavoritesAction extends OwnerDesignAction
{
/** User we're getting the faves of */
var $user = null;
diff --git a/actions/showgroup.php b/actions/showgroup.php
index b6a0f4844..ce11d574e 100644
--- a/actions/showgroup.php
+++ b/actions/showgroup.php
@@ -331,6 +331,7 @@ class ShowgroupAction extends GroupDesignAction
{
$this->showMembers();
$this->showStatistics();
+ $this->showAdmins();
$cloud = new GroupTagCloudSection($this, $this->group);
$cloud->show();
}
@@ -370,6 +371,18 @@ class ShowgroupAction extends GroupDesignAction
}
/**
+ * Show list of admins
+ *
+ * @return void
+ */
+
+ function showAdmins()
+ {
+ $adminSection = new GroupAdminSection($this, $this->group);
+ $adminSection->show();
+ }
+
+ /**
* Show some statistics
*
* @return void
@@ -423,3 +436,34 @@ class ShowgroupAction extends GroupDesignAction
$this->elementEnd('div');
}
}
+
+class GroupAdminSection extends ProfileSection
+{
+ var $group;
+
+ function __construct($out, $group)
+ {
+ parent::__construct($out);
+ $this->group = $group;
+ }
+
+ function getProfiles()
+ {
+ return $this->group->getAdmins();
+ }
+
+ function title()
+ {
+ return _('Admins');
+ }
+
+ function divId()
+ {
+ return 'group_admins';
+ }
+
+ function moreUrl()
+ {
+ return null;
+ }
+} \ No newline at end of file
diff --git a/actions/shownotice.php b/actions/shownotice.php
index 0d89af5ac..1ec38a76b 100644
--- a/actions/shownotice.php
+++ b/actions/shownotice.php
@@ -45,7 +45,7 @@ require_once INSTALLDIR.'/lib/feedlist.php';
* @link http://laconi.ca/
*/
-class ShownoticeAction extends Action
+class ShownoticeAction extends OwnerDesignAction
{
/**
* Notice object to show
@@ -83,18 +83,25 @@ class ShownoticeAction extends Action
$this->notice = Notice::staticGet($id);
- if (!$this->notice) {
+ if (empty($this->notice)) {
$this->clientError(_('No such notice.'), 404);
return false;
}
$this->profile = $this->notice->getProfile();
- if (!$this->profile) {
+ if (empty($this->profile)) {
$this->serverError(_('Notice has no profile'), 500);
return false;
}
+ $this->user = User::staticGet('id', $this->profile->id);
+
+ if (empty($this->user)) {
+ $this->serverError(_('Not a local notice'), 500);
+ return false;
+ }
+
$this->avatar = $this->profile->getAvatar(AVATAR_PROFILE_SIZE);
return true;
@@ -158,8 +165,14 @@ class ShownoticeAction extends Action
function title()
{
+ if (!empty($this->profile->fullname)) {
+ $base = $this->profile->fullname . ' (' . $this->user->nickname . ') ';
+ } else {
+ $base = $this->user->nickname;
+ }
+
return sprintf(_('%1$s\'s status on %2$s'),
- $this->profile->nickname,
+ $base,
common_exact_date($this->notice->created));
}
diff --git a/actions/subscriptions.php b/actions/subscriptions.php
index 4124abea4..42bdae10f 100644
--- a/actions/subscriptions.php
+++ b/actions/subscriptions.php
@@ -159,7 +159,10 @@ class SubscriptionsListItem extends SubscriptionListItem
$this->showBio();
$this->showTags();
// Relevant portion!
- $this->showOwnerControls();
+ $cur = common_current_user();
+ if (!empty($cur) && $cur->id == $this->owner->id) {
+ $this->showOwnerControls();
+ }
$this->endProfile();
}
diff --git a/actions/sup.php b/actions/sup.php
index e446a7b0d..a5b665562 100644
--- a/actions/sup.php
+++ b/actions/sup.php
@@ -63,11 +63,13 @@ class SupAction extends Action
# XXX: cache this. Depends on how big this protocol becomes;
# Re-doing this query every 15 seconds isn't the end of the world.
+ $divider = common_sql_date(time() - $seconds);
+
$notice->query('SELECT profile_id, max(id) AS max_id ' .
'FROM notice ' .
((common_config('db','type') == 'pgsql') ?
'WHERE extract(epoch from created) > (extract(epoch from now()) - ' . $seconds . ') ' :
- 'WHERE created > (now() - ' . $seconds . ') ' ) .
+ 'WHERE created > "'.$divider.'" ' ) .
'GROUP BY profile_id');
$updates = array();
diff --git a/actions/twitapifriendships.php b/actions/twitapifriendships.php
index 29eb4cc0f..5fb55e9ff 100644
--- a/actions/twitapifriendships.php
+++ b/actions/twitapifriendships.php
@@ -160,4 +160,85 @@ class TwitapifriendshipsAction extends TwitterapiAction
}
-} \ No newline at end of file
+ function show($args, $apidata)
+ {
+ parent::handle($args);
+
+ if (!in_array($apidata['content-type'], array('xml', 'json'))) {
+ $this->clientError(_('API method not found!'), $code = 404);
+ return;
+ }
+
+ $source_id = (int)$this->trimmed('source_id');
+ $source_screen_name = $this->trimmed('source_screen_name');
+
+ // If the source is not specified for an unauthenticated request,
+ // the method will return an HTTP 403.
+
+ if (empty($source_id) && empty($source_screen_name)) {
+ if (empty($apidata['user'])) {
+ $this->clientError(_('Could not determine source user.'),
+ $code = 403);
+ return;
+ }
+ }
+
+ $source = null;
+
+ if (!empty($source_id)) {
+ $source = User::staticGet($source_id);
+ } elseif (!empty($source_screen_name)) {
+ $source = User::staticGet('nickname', $source_screen_name);
+ } else {
+ $source = $apidata['user'];
+ }
+
+ // If a source or target is specified but does not exist,
+ // the method will return an HTTP 404.
+
+ if (empty($source)) {
+ $this->clientError(_('Could not determine source user.'),
+ $code = 404);
+ return;
+ }
+
+ $target_id = (int)$this->trimmed('target_id');
+ $target_screen_name = $this->trimmed('target_screen_name');
+
+ $target = null;
+
+ if (!empty($target_id)) {
+ $target = User::staticGet($target_id);
+ } elseif (!empty($target_screen_name)) {
+ $target = User::staticGet('nickname', $target_screen_name);
+ } else {
+ $this->clientError(_('Target user not specified.'),
+ $code = 403);
+ return;
+ }
+
+ if (empty($target)) {
+ $this->clientError(_('Could not find target user.'),
+ $code = 404);
+ return;
+ }
+
+ $result = $this->twitter_relationship_array($source, $target);
+
+ switch ($apidata['content-type']) {
+ case 'xml':
+ $this->init_document('xml');
+ $this->show_twitter_xml_relationship($result[relationship]);
+ $this->end_document('xml');
+ break;
+ case 'json':
+ $this->init_document('json');
+ print json_encode($result);
+ $this->end_document('json');
+ break;
+ default:
+ break;
+ }
+ }
+
+}
diff --git a/actions/twitapisearchatom.php b/actions/twitapisearchatom.php
index eb9ab5d8e..3678213c3 100644
--- a/actions/twitapisearchatom.php
+++ b/actions/twitapisearchatom.php
@@ -165,24 +165,30 @@ class TwitapisearchatomAction extends TwitterapiAction
$search_engine->set_sort_mode('chron');
$search_engine->limit(($this->page - 1) * $this->rpp,
$this->rpp + 1, true);
- $search_engine->query($q);
- $this->cnt = $notice->find();
+ if (false === $search_engine->query($q)) {
+ $this->cnt = 0;
+ } else {
+ $this->cnt = $notice->find();
+ }
$cnt = 0;
+ $this->max_id = 0;
- while ($notice->fetch()) {
+ if ($this->cnt > 0) {
+ while ($notice->fetch()) {
- ++$cnt;
+ ++$cnt;
- if (!$this->max_id) {
- $this->max_id = $notice->id;
- }
+ if (!$this->max_id) {
+ $this->max_id = $notice->id;
+ }
- if ($cnt > $this->rpp) {
- break;
- }
+ if ($cnt > $this->rpp) {
+ break;
+ }
- $notices[] = clone($notice);
+ $notices[] = clone($notice);
+ }
}
return $notices;
diff --git a/actions/twitapisearchjson.php b/actions/twitapisearchjson.php
index b0e3be687..27a717bfc 100644
--- a/actions/twitapisearchjson.php
+++ b/actions/twitapisearchjson.php
@@ -124,8 +124,11 @@ class TwitapisearchjsonAction extends TwitterapiAction
$search_engine = $notice->getSearchEngine('identica_notices');
$search_engine->set_sort_mode('chron');
$search_engine->limit(($this->page - 1) * $this->rpp, $this->rpp + 1, true);
- $search_engine->query($q);
- $cnt = $notice->find();
+ if (false === $search_engine->query($q)) {
+ $cnt = 0;
+ } else {
+ $cnt = $notice->find();
+ }
// TODO: since_id, lang, geocode
@@ -146,4 +149,4 @@ class TwitapisearchjsonAction extends TwitterapiAction
{
return true;
}
-} \ No newline at end of file
+}
diff --git a/actions/twitapistatuses.php b/actions/twitapistatuses.php
index e1fbc5c76..c9943698d 100644
--- a/actions/twitapistatuses.php
+++ b/actions/twitapistatuses.php
@@ -78,8 +78,6 @@ class TwitapistatusesAction extends TwitterapiAction
$this->auth_user = $apidata['user'];
$user = $this->get_user($apidata['api_arg'], $apidata);
- common_debug("auth user = " . $this->auth_user->nickname);
-
if (empty($user)) {
$this->clientError(_('No such user!'), 404,
$apidata['content-type']);
@@ -375,9 +373,19 @@ class TwitapistatusesAction extends TwitterapiAction
return;
}
+ // 'id' is an undocumented parameter in Twitter's API. Several
+ // clients make use of it, so we support it too.
+
+ // show.json?id=12345 takes precedence over /show/12345.json
+
$this->auth_user = $apidata['user'];
- $notice_id = $apidata['api_arg'];
- $notice = Notice::staticGet($notice_id);
+ $notice_id = $this->trimmed('id');
+
+ if (empty($notice_id)) {
+ $notice_id = $apidata['api_arg'];
+ }
+
+ $notice = Notice::staticGet((int)$notice_id);
if ($notice) {
if ($apidata['content-type'] == 'xml') {
@@ -391,7 +399,6 @@ class TwitapistatusesAction extends TwitterapiAction
$this->clientError(_('No status with that ID found.'),
404, $apidata['content-type']);
}
-
}
function destroy($args, $apidata)
diff --git a/actions/twitapiusers.php b/actions/twitapiusers.php
index 4057b63e7..e9fcccbde 100644
--- a/actions/twitapiusers.php
+++ b/actions/twitapiusers.php
@@ -37,24 +37,17 @@ class TwitapiusersAction extends TwitterapiAction
$user = null;
$email = $this->arg('email');
- $user_id = $this->arg('user_id');
// XXX: email field deprecated in Twitter's API
- // XXX: Also: need to add screen_name param
-
if ($email) {
$user = User::staticGet('email', $email);
- } elseif ($user_id) {
- $user = $this->get_user($user_id);
- } elseif (isset($apidata['api_arg'])) {
+ } else {
$user = $this->get_user($apidata['api_arg']);
- } elseif (isset($apidata['user'])) {
- $user = $apidata['user'];
}
if (empty($user)) {
- $this->client_error(_('Not found.'), 404, $apidata['content-type']);
+ $this->clientError(_('Not found.'), 404, $apidata['content-type']);
return;
}
diff --git a/actions/userdesignsettings.php b/actions/userdesignsettings.php
index d6088aa9d..d7949951a 100644
--- a/actions/userdesignsettings.php
+++ b/actions/userdesignsettings.php
@@ -34,16 +34,37 @@ if (!defined('LACONICA')) {
require_once INSTALLDIR . '/lib/designsettings.php';
+/**
+ * Set a user's design
+ *
+ * Saves a design for a given user
+ *
+ * @category Settings
+ * @package Laconica
+ * @author Zach Copley <zach@controlyourself.ca>
+ * @author Sarven Capadisli <csarven@controlyourself.ca>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://laconi.ca/
+ */
+
class UserDesignSettingsAction extends DesignSettingsAction
{
-
+ /**
+ * Sets the right action for the form, and passes request args into
+ * the base action
+ *
+ * @param array $args misc. arguments
+ *
+ * @return boolean true
+ */
+
function prepare($args)
{
parent::prepare($args);
$this->submitaction = common_local_url('userdesignsettings');
return true;
}
-
+
/**
* Title of the page
*
@@ -72,19 +93,20 @@ class UserDesignSettingsAction extends DesignSettingsAction
*
* @return Design
*/
-
- function getWorkingDesign() {
-
- $user = common_current_user();
+
+ function getWorkingDesign()
+ {
+
+ $user = common_current_user();
$design = $user->getDesign();
if (empty($design)) {
$design = $this->defaultDesign();
}
-
+
return $design;
}
-
+
/**
* Content area of the page
*
@@ -92,7 +114,7 @@ class UserDesignSettingsAction extends DesignSettingsAction
*
* @return void
*/
-
+
function showContent()
{
$this->showDesignForm($this->getWorkingDesign());
@@ -106,14 +128,19 @@ class UserDesignSettingsAction extends DesignSettingsAction
function saveDesign()
{
- try {
+ foreach ($this->args as $key => $val) {
+ if (preg_match('/(#ho|ho)Td.*g/i', $val)) {
+ $this->sethd();
+ return;
+ }
+ }
+ try {
$bgcolor = new WebColor($this->trimmed('design_background'));
$ccolor = new WebColor($this->trimmed('design_content'));
$sbcolor = new WebColor($this->trimmed('design_sidebar'));
$tcolor = new WebColor($this->trimmed('design_text'));
$lcolor = new WebColor($this->trimmed('design_links'));
-
} catch (WebColorException $e) {
$this->showForm($e->getMessage());
return;
@@ -137,7 +164,7 @@ class UserDesignSettingsAction extends DesignSettingsAction
$tile = true;
}
- $user = common_current_user();
+ $user = common_current_user();
$design = $user->getDesign();
if (!empty($design)) {
@@ -149,7 +176,6 @@ class UserDesignSettingsAction extends DesignSettingsAction
$design->sidebarcolor = $sbcolor->intValue();
$design->textcolor = $tcolor->intValue();
$design->linkcolor = $lcolor->intValue();
- $design->backgroundimage = $filepath;
$design->setDisposition($on, $off, $tile);
@@ -174,7 +200,6 @@ class UserDesignSettingsAction extends DesignSettingsAction
$design->sidebarcolor = $sbcolor->intValue();
$design->textcolor = $tcolor->intValue();
$design->linkcolor = $lcolor->intValue();
- $design->backgroundimage = $filepath;
$design->setDisposition($on, $off, $tile);
@@ -186,9 +211,9 @@ class UserDesignSettingsAction extends DesignSettingsAction
return;
}
- $original = clone($user);
+ $original = clone($user);
$user->design_id = $id;
- $result = $user->update($original);
+ $result = $user->update($original);
if (empty($result)) {
common_log_db_error($original, 'UPDATE', __FILE__);
@@ -205,4 +230,56 @@ class UserDesignSettingsAction extends DesignSettingsAction
$this->showForm(_('Design preferences saved.'), true);
}
+
+ /**
+ * Alternate default colors
+ *
+ * @return nothing
+ */
+
+ function sethd()
+ {
+
+ $user = common_current_user();
+ $design = $user->getDesign();
+
+ $user->query('BEGIN');
+
+ // alternate colors
+ $design = new Design();
+
+ $design->backgroundcolor = 16184329;
+ $design->contentcolor = 16059904;
+ $design->sidebarcolor = 16059904;
+ $design->textcolor = 0;
+ $design->linkcolor = 16777215;
+
+ $design->setDisposition(false, true, false);
+
+ $id = $design->insert();
+
+ if (empty($id)) {
+ common_log_db_error($id, 'INSERT', __FILE__);
+ $this->showForm(_('Unable to save your design settings!'));
+ return;
+ }
+
+ $original = clone($user);
+ $user->design_id = $id;
+ $result = $user->update($original);
+
+ if (empty($result)) {
+ common_log_db_error($original, 'UPDATE', __FILE__);
+ $this->showForm(_('Unable to save your design settings!'));
+ $user->query('ROLLBACK');
+ return;
+ }
+
+ $user->query('COMMIT');
+
+ $this->saveBackgroundImage($design);
+
+ $this->showForm(_('Enjoy your hotdog!'), true);
+ }
+
}