Merge branch '0.8.x' into group-rss-empty

This commit is contained in:
Jeffery To 2009-06-26 15:30:24 +08:00
commit 899aad747a
223 changed files with 7766 additions and 2102 deletions

2
.gitignore vendored
View File

@ -1,4 +1,5 @@
avatar/* avatar/*
background/*
files/* files/*
file/* file/*
_darcs/* _darcs/*
@ -22,3 +23,4 @@ config-*.php
good-config.php good-config.php
lac08.log lac08.log
php.log php.log
config.php.*

63
README
View File

@ -178,8 +178,9 @@ and the URLs are listed here for your convenience.
- Facebook library. Used for the Facebook application. - Facebook library. Used for the Facebook application.
- PEAR Services_oEmbed. Used for some multimedia integration. - PEAR Services_oEmbed. Used for some multimedia integration.
- PEAR HTTP_Request is an oEmbed dependency. - PEAR HTTP_Request is an oEmbed dependency.
- PEAR Validat is an oEmbed dependency.e - PEAR Validate is an oEmbed dependency.
- PEAR Net_URL is an oEmbed dependency.2 - PEAR Net_URL2 is an oEmbed dependency.
- Console_GetOpt for parsing command-line options.
A design goal of Laconica is that the basic Web functionality should A design goal of Laconica is that the basic Web functionality should
work on even the most restrictive commercial hosting services. work on even the most restrictive commercial hosting services.
@ -1008,6 +1009,12 @@ avatar
For configuring avatar access. For configuring avatar access.
dir: Directory to look for avatar files and to put them into.
Defaults to avatar subdirectory of install directory; if
you change it, make sure to change path, too.
path: Path to avatars. Defaults to path for avatar subdirectory,
but you can change it if you wish. Note that this will
be included with the avatar server, too.
server: If set, defines another server where avatars are stored in the server: If set, defines another server where avatars are stored in the
root directory. Note that the 'avatar' subdir still has to be root directory. Note that the 'avatar' subdir still has to be
writeable. You'd typically use this to split HTTP requests on writeable. You'd typically use this to split HTTP requests on
@ -1033,9 +1040,16 @@ theme
----- -----
server: Like avatars, you can speed up page loading by pointing the server: Like avatars, you can speed up page loading by pointing the
theme file lookup to another server (virtual or real). The theme file lookup to another server (virtual or real).
theme server's root path should map to the Laconica "theme" Defaults to NULL, meaning to use the site server.
subdirectory. Defaults to NULL. dir: Directory where theme files are stored. Used to determine
whether to show parts of a theme file. Defaults to the theme
subdirectory of the install directory.
path: Path part of theme URLs, before the theme name. Relative to the
theme server. It may make sense to change this path when upgrading,
(using version numbers as the path) to make sure that all files are
reloaded by caching clients or proxies. Defaults to null,
which means to use the site path + '/theme'.
xmpp xmpp
---- ----
@ -1100,6 +1114,13 @@ database data in memcached <http://www.danga.com/memcached/>.
enabled: Set to true to enable. Default false. enabled: Set to true to enable. Default false.
server: a string with the hostname of the memcached server. Can also server: a string with the hostname of the memcached server. Can also
be an array of hostnames, if you've got more than one server. be an array of hostnames, if you've got more than one server.
base: memcached uses key-value pairs to store data. We build long,
funny-looking keys to make sure we don't have any conflicts. The
base of the key is usually a simplified version of the site name
(like "Identi.ca" => "identica"), but you can overwrite this if
you need to. You can safely ignore it if you only have one
Laconica site using your memcached server.
port: Port to connect to; defaults to 11211.
sphinx sphinx
------ ------
@ -1196,7 +1217,6 @@ reporturl: URL to post statistics to. Defaults to Laconica developers'
set 'run' to 'never' than to set this value to something set 'run' to 'never' than to set this value to something
nonsensical. nonsensical.
attachments attachments
----------- -----------
@ -1211,6 +1231,11 @@ supported: an array of mime types you accept to store and distribute,
like 'image/gif', 'video/mpeg', 'audio/mpeg', etc. Make sure you like 'image/gif', 'video/mpeg', 'audio/mpeg', etc. Make sure you
setup your server to properly reckognize the types you want to setup your server to properly reckognize the types you want to
support. support.
uploads: false to disable uploading files with notices (true by default).
filecommand: The required MIME_Type library may need to use the 'file'
command. It tries the one in the Web server's path, but if
you're having problems with uploads, try setting this to the
correct value. Note: 'file' must accept '-b' and '-i' options.
For quotas, be sure you've set the upload_max_filesize and post_max_size For quotas, be sure you've set the upload_max_filesize and post_max_size
in php.ini to be large enough to handle your upload. In httpd.conf in php.ini to be large enough to handle your upload. In httpd.conf
@ -1226,6 +1251,32 @@ user_quota: total size in bytes a user can store on this server. Each user
monthly_quota: total size permitted in the current month. This is the total monthly_quota: total size permitted in the current month. This is the total
size in bytes that a user can upload each month. size in bytes that a user can upload each month.
group
-----
Options for group functionality.
maxaliases: maximum number of aliases a group can have. Default 3. Set
to 0 or less to prevent aliases in a group.
oohembed
--------
oEmbed endpoint for multimedia attachments (links in posts).
endpoint: oohembed endpoint using http://oohembed.com/ software.
search
------
Some stuff for search.
type: type of search. Ignored if PostgreSQL or Sphinx are enabled. Can either
be 'fulltext' (default) or 'like'. The former is faster and more efficient
but requires the lame old MyISAM engine for MySQL. The latter
will work with InnoDB but could be miserably slow on large
systems. We'll probably add another type sometime in the future,
with our own indexing system (maybe like MediaWiki's).
Troubleshooting Troubleshooting
=============== ===============

View File

@ -12,7 +12,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -98,7 +98,13 @@ class AllAction extends ProfileAction
function showContent() function showContent()
{ {
$notice = $this->user->noticesWithFriends(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); $cur = common_current_user();
if (!empty($cur) && $cur->id == $this->user->id) {
$notice = $this->user->noticeInbox(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
} else {
$notice = $this->user->noticesWithFriends(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
}
$nl = new NoticeList($notice, $this); $nl = new NoticeList($notice, $this);

View File

@ -13,7 +13,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -81,6 +81,14 @@ class AllrssAction extends Rss10Action
*/ */
function getNotices($limit=0) function getNotices($limit=0)
{ {
$cur = common_current_user();
if (!empty($cur) && $cur->id == $user->id) {
$notice = $this->user->noticeInbox(0, $limit);
} else {
$notice = $this->user->noticesWithFriends(0, $limit);
}
$user = $this->user; $user = $this->user;
$notice = $user->noticesWithFriends(0, $limit); $notice = $user->noticesWithFriends(0, $limit);
$notices = array(); $notices = array();

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -98,48 +98,6 @@ class AttachmentAction extends Action
return $a->title(); return $a->title();
} }
/**
* 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)) . '"';
}
*/
/** /**
* Handle input * Handle input
* *

View File

@ -74,46 +74,5 @@ class Attachment_ajaxAction extends AttachmentAction
} }
$this->elementEnd('div'); $this->elementEnd('div');
} }
/**
* 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)) . '"';
}
*/
} }

View File

@ -12,7 +12,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -12,7 +12,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -125,16 +125,18 @@ class BlockAction extends Action
function areYouSureForm() function areYouSureForm()
{ {
$id = $this->profile->id; $id = $this->profile->id;
$this->elementStart('form', array('id' => 'block-' . $id,
'method' => 'post',
'class' => 'form_settings form_entity_block',
'action' => common_local_url('block')));
$this->elementStart('fieldset');
$this->hidden('token', common_session_token());
$this->element('legend', _('Block user'));
$this->element('p', null, $this->element('p', null,
_('Are you sure you want to block this user? '. _('Are you sure you want to block this user? '.
'Afterwards, they will be unsubscribed from you, '. 'Afterwards, they will be unsubscribed from you, '.
'unable to subscribe to you in the future, and '. 'unable to subscribe to you in the future, and '.
'you will not be notified of any @-replies from them.')); 'you will not be notified of any @-replies from them.'));
$this->elementStart('form', array('id' => 'block-' . $id,
'method' => 'post',
'class' => 'block',
'action' => common_local_url('block')));
$this->hidden('token', common_session_token());
$this->element('input', array('id' => 'blockto-' . $id, $this->element('input', array('id' => 'blockto-' . $id,
'name' => 'blockto', 'name' => 'blockto',
'type' => 'hidden', 'type' => 'hidden',
@ -144,8 +146,9 @@ class BlockAction extends Action
$this->hidden($k, $v); $this->hidden($k, $v);
} }
} }
$this->submit('no', _('No')); $this->submit('form_action-no', _('No'), 'submit form_action-primary', 'no', _("Do not block this user from this group"));
$this->submit('yes', _('Yes')); $this->submit('form_action-yes', _('Yes'), 'submit form_action-secondary', 'yes', _('Block this user from this group'));
$this->elementEnd('fieldset');
$this->elementEnd('form'); $this->elementEnd('form');
} }
@ -180,7 +183,7 @@ class BlockAction extends Action
if ($action) { if ($action) {
common_redirect(common_local_url($action, $args), 303); common_redirect(common_local_url($action, $args), 303);
} else { } else {
common_redirect(common_local_url('subscriptions', common_redirect(common_local_url('subscribers',
array('nickname' => $cur->nickname)), array('nickname' => $cur->nickname)),
303); 303);
} }

View File

@ -0,0 +1,315 @@
<?php
/**
* Laconica, the distributed open-source microblogging tool
*
* List of group members
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Group
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @copyright 2008-2009 Control Yourself, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://laconi.ca/
*/
if (!defined('LACONICA')) {
exit(1);
}
/**
* List of profiles blocked from this group
*
* @category Group
* @package Laconica
* @author Evan Prodromou <evan@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 BlockedfromgroupAction extends GroupDesignAction
{
var $page = null;
function isReadOnly($args)
{
return true;
}
function prepare($args)
{
parent::prepare($args);
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
$nickname_arg = $this->arg('nickname');
$nickname = common_canonical_nickname($nickname_arg);
// Permanent redirect on non-canonical nickname
if ($nickname_arg != $nickname) {
$args = array('nickname' => $nickname);
if ($this->page != 1) {
$args['page'] = $this->page;
}
common_redirect(common_local_url('blockedfromgroup', $args), 301);
return false;
}
if (!$nickname) {
$this->clientError(_('No nickname'), 404);
return false;
}
$this->group = User_group::staticGet('nickname', $nickname);
if (!$this->group) {
$this->clientError(_('No such group'), 404);
return false;
}
return true;
}
function title()
{
if ($this->page == 1) {
return sprintf(_('%s blocked profiles'),
$this->group->nickname);
} else {
return sprintf(_('%s blocked profiles, page %d'),
$this->group->nickname,
$this->page);
}
}
function handle($args)
{
parent::handle($args);
$this->showPage();
}
function showPageNotice()
{
$this->element('p', 'instructions',
_('A list of the users blocked from joining this group.'));
}
function showLocalNav()
{
$nav = new GroupNav($this, $this->group);
$nav->show();
}
function showContent()
{
$offset = ($this->page-1) * PROFILES_PER_PAGE;
$limit = PROFILES_PER_PAGE + 1;
$cnt = 0;
$blocked = $this->group->getBlocked($offset, $limit);
if ($blocked) {
$blocked_list = new GroupBlockList($blocked, $this->group, $this);
$cnt = $blocked_list->show();
}
$blocked->free();
$this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
$this->page, 'blockedfromgroup',
array('nickname' => $this->group->nickname));
}
}
class GroupBlockList extends ProfileList
{
var $group = null;
function __construct($profile, $group, $action)
{
parent::__construct($profile, $action);
$this->group = $group;
}
function newListItem($profile)
{
return new GroupBlockListItem($profile, $this->group, $this->action);
}
}
class GroupBlockListItem extends ProfileListItem
{
var $group = null;
function __construct($profile, $group, $action)
{
parent::__construct($profile, $action);
$this->group = $group;
}
function showActions()
{
$this->startActions();
$this->showGroupUnblockForm();
$this->endActions();
}
function showGroupUnblockForm()
{
$user = common_current_user();
if (!empty($user) && $user->id != $this->profile->id && $user->isAdmin($this->group)) {
$this->out->elementStart('li', 'entity_block');
$bf = new GroupUnblockForm($this->out, $this->profile, $this->group,
array('action' => 'blockedfromgroup',
'nickname' => $this->group->nickname));
$bf->show();
$this->out->elementEnd('li');
}
}
}
/**
* Form for unblocking a user from a group
*
* @category Form
* @package Laconica
* @author Evan Prodromou <evan@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/
*
* @see UnblockForm
*/
class GroupUnblockForm extends Form
{
/**
* Profile of user to block
*/
var $profile = null;
/**
* Group to block the user from
*/
var $group = null;
/**
* Return-to args
*/
var $args = null;
/**
* Constructor
*
* @param HTMLOutputter $out output channel
* @param Profile $profile profile of user to block
* @param User_group $group group to block user from
* @param array $args return-to args
*/
function __construct($out=null, $profile=null, $group=null, $args=null)
{
parent::__construct($out);
$this->profile = $profile;
$this->group = $group;
$this->args = $args;
}
/**
* ID of the form
*
* @return int ID of the form
*/
function id()
{
// This should be unique for the page.
return 'unblock-' . $this->profile->id;
}
/**
* class of the form
*
* @return string class of the form
*/
function formClass()
{
return 'form_group_unblock';
}
/**
* Action of the form
*
* @return string URL of the action
*/
function action()
{
return common_local_url('groupunblock');
}
/**
* Legend of the Form
*
* @return void
*/
function formLegend()
{
$this->out->element('legend', null, _('Unblock user from group'));
}
/**
* Data elements of the form
*
* @return void
*/
function formData()
{
$this->out->hidden('unblockto-' . $this->profile->id,
$this->profile->id,
'unblockto');
$this->out->hidden('unblockgroup-' . $this->group->id,
$this->group->id,
'unblockgroup');
if ($this->args) {
foreach ($this->args as $k => $v) {
$this->out->hidden('returnto-' . $k, $v);
}
}
}
/**
* Action elements
*
* @return void
*/
function formActions()
{
$this->out->submit('submit', _('Unblock'), 'submit', null, _('Unblock this user'));
}
}

View File

@ -63,6 +63,7 @@ class ConversationAction extends Action
if (empty($this->id)) { if (empty($this->id)) {
return false; return false;
} }
$this->id = $this->id+0;
$this->page = $this->trimmed('page'); $this->page = $this->trimmed('page');
if (empty($this->page)) { if (empty($this->page)) {
$this->page = 1; $this->page = 1;
@ -106,18 +107,10 @@ class ConversationAction extends Action
function showContent() 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; $offset = ($this->page-1) * NOTICES_PER_PAGE;
$limit = NOTICES_PER_PAGE + 1; $limit = NOTICES_PER_PAGE + 1;
$txt = sprintf($qry, $this->id); $notices = Notice::conversationStream($this->id, $offset, $limit);
$notices = Notice::getStream($txt,
'notice:conversation:'.$this->id,
$offset, $limit);
$ct = new ConversationTree($notices, $this); $ct = new ConversationTree($notices, $this);
@ -126,7 +119,6 @@ class ConversationAction extends Action
$this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE, $this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
$this->page, 'conversation', array('id' => $this->id)); $this->page, 'conversation', array('id' => $this->id));
} }
} }
/** /**
@ -217,6 +209,8 @@ class ConversationTree extends NoticeList
$this->out->elementStart('ol', array('class' => 'notices')); $this->out->elementStart('ol', array('class' => 'notices'));
sort($children);
foreach ($children as $child) { foreach ($children as $child) {
$this->showNoticePlus($child); $this->showNoticePlus($child);
} }

View File

@ -1,264 +0,0 @@
<?php
/**
* Laconica, the distributed open-source microblogging tool
*
* Change user password
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Settings
* @package Laconica
* @author Sarven Capadisli <csarven@controlyourself.ca>
* @copyright 2008-2009 Control Yourself, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://laconi.ca/
*/
if (!defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR.'/lib/accountsettingsaction.php';
class DesignsettingsAction extends AccountSettingsAction
{
/**
* Title of the page
*
* @return string Title of the page
*/
function title()
{
return _('Profile design');
}
/**
* Instructions for use
*
* @return instructions for use
*/
function getInstructions()
{
return _('Customize the way your profile looks with a background image and a colour palette of your choice.');
}
/**
* Content area of the page
*
* Shows a form for changing the password
*
* @return void
*/
function showContent()
{
$user = common_current_user();
$this->elementStart('form', array('method' => 'post',
'id' => 'form_settings_design',
'class' => 'form_settings',
'action' =>
common_local_url('designsettings')));
$this->elementStart('fieldset');
$this->hidden('token', common_session_token());
$this->elementStart('fieldset', array('id' => 'settings_design_background-image'));
$this->element('legend', null, _('Change background image'));
$this->elementStart('ul', 'form_data');
$this->elementStart('li');
$this->element('label', array('for' => 'design_background-image_file'),
_('Upload file'));
$this->element('input', array('name' => 'design_background-image_file',
'type' => 'file',
'id' => 'design_background-image_file'));
$this->element('p', 'form_guide', _('You can upload your personal background image. The maximum file size is 2Mb.'));
$this->element('input', array('name' => 'MAX_FILE_SIZE',
'type' => 'hidden',
'id' => 'MAX_FILE_SIZE',
'value' => ImageFile::maxFileSizeInt()));
$this->elementEnd('li');
$this->elementEnd('ul');
$this->elementEnd('fieldset');
$this->elementStart('fieldset', array('id' => 'settings_design_color'));
$this->element('legend', null, _('Change colours'));
$this->elementStart('ul', 'form_data');
//This is a JSON object in the DB field. Here for testing. Remove later.
$userSwatch = '{"body":{"background-color":"#F0F2F5"},
"#content":{"background-color":"#FFFFFF"},
"#aside_primary":{"background-color":"#CEE1E9"},
"html body":{"color":"#000000"},
"a":{"color":"#002E6E"}}';
//Default theme swatch -- Where should this be stored?
$defaultSwatch = array('body' => array('background-color' => '#F0F2F5'),
'#content' => array('background-color' => '#FFFFFF'),
'#aside_primary' => array('background-color' => '#CEE1E9'),
'html body' => array('color' => '#000000'),
'a' => array('color' => '#002E6E'));
$userSwatch = ($userSwatch) ? json_decode($userSwatch, true) : $defaultSwatch;
$s = 0;
$labelSwatch = array('Background',
'Content',
'Sidebar',
'Text',
'Links');
foreach($userSwatch as $propertyvalue => $value) {
$foo = array_values($value);
$this->elementStart('li');
$this->element('label', array('for' => 'swatch-'.$s), _($labelSwatch[$s]));
$this->element('input', array('name' => 'swatch-'.$s, //prefer swatch[$s] ?
'type' => 'text',
'id' => 'swatch-'.$s,
'class' => 'swatch',
'maxlength' => '7',
'size' => '7',
'value' => $foo[0]));
$this->elementEnd('li');
$s++;
}
$this->elementEnd('ul');
$this->elementEnd('fieldset');
$this->element('input', array('id' => 'settings_design_reset',
'type' => 'reset',
'value' => 'Reset',
'class' => 'submit form_action-primary',
'title' => _('Reset back to default')));
$this->submit('save', _('Save'), 'submit form_action-secondary', 'save', _('Save design'));
/*TODO: Check submitted form values:
json_encode(form values)
if submitted Swatch == DefaultSwatch, don't store in DB.
else store in BD
*/
$this->elementEnd('fieldset');
$this->elementEnd('form');
}
/**
* Handle a post
*
* Validate input and save changes. Reload the form with a success
* or error message.
*
* @return void
*/
function handlePost()
{
/*
// CSRF protection
$token = $this->trimmed('token');
if (!$token || $token != common_session_token()) {
$this->showForm(_('There was a problem with your session token. '.
'Try again, please.'));
return;
}
$user = common_current_user();
assert(!is_null($user)); // should already be checked
// FIXME: scrub input
$newpassword = $this->arg('newpassword');
$confirm = $this->arg('confirm');
# Some validation
if (strlen($newpassword) < 6) {
$this->showForm(_('Password must be 6 or more characters.'));
return;
} else if (0 != strcmp($newpassword, $confirm)) {
$this->showForm(_('Passwords don\'t match.'));
return;
}
if ($user->password) {
$oldpassword = $this->arg('oldpassword');
if (!common_check_user($user->nickname, $oldpassword)) {
$this->showForm(_('Incorrect old password'));
return;
}
}
$original = clone($user);
$user->password = common_munge_password($newpassword, $user->id);
$val = $user->validate();
if ($val !== true) {
$this->showForm(_('Error saving user; invalid.'));
return;
}
if (!$user->update($original)) {
$this->serverError(_('Can\'t save new password.'));
return;
}
$this->showForm(_('Password saved.'), true);
*/
}
/**
* Add the Farbtastic stylesheet
*
* @return void
*/
function showStylesheets()
{
parent::showStylesheets();
$farbtasticStyle =
common_path('theme/base/css/farbtastic.css?version='.LACONICA_VERSION);
$this->element('link', array('rel' => 'stylesheet',
'type' => 'text/css',
'href' => $farbtasticStyle,
'media' => 'screen, projection, tv'));
}
/**
* Add the Farbtastic scripts
*
* @return void
*/
function showScripts()
{
parent::showScripts();
$farbtasticPack = common_path('js/farbtastic/farbtastic.js');
$farbtasticGo = common_path('js/farbtastic/farbtastic.go.js');
$this->element('script', array('type' => 'text/javascript',
'src' => $farbtasticPack));
$this->element('script', array('type' => 'text/javascript',
'src' => $farbtasticGo));
}
}

View File

@ -13,7 +13,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -13,7 +13,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -23,6 +23,7 @@
* @package Laconica * @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca> * @author Evan Prodromou <evan@controlyourself.ca>
* @author Sarven Capadisli <csarven@controlyourself.ca> * @author Sarven Capadisli <csarven@controlyourself.ca>
* @author Zach Copley <zach@controlyourself.ca>
* @copyright 2008-2009 Control Yourself, Inc. * @copyright 2008-2009 Control Yourself, Inc.
* @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://laconi.ca/ * @link http://laconi.ca/
@ -40,14 +41,15 @@ if (!defined('LACONICA')) {
* @category Group * @category Group
* @package Laconica * @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca> * @author Evan Prodromou <evan@controlyourself.ca>
* @author Zach Copley <zach@controlyourself.ca>
* @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://laconi.ca/ * @link http://laconi.ca/
*/ */
class EditgroupAction extends Action class EditgroupAction extends GroupDesignAction
{ {
var $msg; var $msg;
var $group = null;
function title() function title()
{ {
@ -171,6 +173,7 @@ class EditgroupAction extends Action
$homepage = $this->trimmed('homepage'); $homepage = $this->trimmed('homepage');
$description = $this->trimmed('description'); $description = $this->trimmed('description');
$location = $this->trimmed('location'); $location = $this->trimmed('location');
$aliasstring = $this->trimmed('aliases');
if (!Validate::string($nickname, array('min_length' => 1, if (!Validate::string($nickname, array('min_length' => 1,
'max_length' => 64, 'max_length' => 64,
@ -201,6 +204,39 @@ class EditgroupAction extends Action
return; return;
} }
if (!empty($aliasstring)) {
$aliases = array_map('common_canonical_nickname', array_unique(preg_split('/[\s,]+/', $aliasstring)));
} else {
$aliases = array();
}
if (count($aliases) > common_config('group', 'maxaliases')) {
$this->showForm(sprintf(_('Too many aliases! Maximum %d.'),
common_config('group', 'maxaliases')));
return;
}
foreach ($aliases as $alias) {
if (!Validate::string($alias, array('min_length' => 1,
'max_length' => 64,
'format' => NICKNAME_FMT))) {
$this->showForm(sprintf(_('Invalid alias: "%s"'), $alias));
return;
}
if ($this->nicknameExists($alias)) {
$this->showForm(sprintf(_('Alias "%s" already in use. Try another one.'),
$alias));
return;
}
// XXX assumes alphanum nicknames
if (strcmp($alias, $nickname) == 0) {
$this->showForm(_('Alias can\'t be the same as nickname.'));
return;
}
}
$this->group->query('BEGIN');
$orig = clone($this->group); $orig = clone($this->group);
$this->group->nickname = $nickname; $this->group->nickname = $nickname;
@ -217,6 +253,14 @@ class EditgroupAction extends Action
$this->serverError(_('Could not update group.')); $this->serverError(_('Could not update group.'));
} }
$result = $this->group->setAliases($aliases);
if (!$result) {
$this->serverError(_('Could not create aliases.'));
}
$this->group->query('COMMIT');
if ($this->group->nickname != $orig->nickname) { if ($this->group->nickname != $orig->nickname) {
common_redirect(common_local_url('editgroup', common_redirect(common_local_url('editgroup',
array('nickname' => $nickname)), array('nickname' => $nickname)),
@ -229,9 +273,20 @@ class EditgroupAction extends Action
function nicknameExists($nickname) function nicknameExists($nickname)
{ {
$group = User_group::staticGet('nickname', $nickname); $group = User_group::staticGet('nickname', $nickname);
return (!is_null($group) &&
$group != false && if (!empty($group) &&
$group->id != $this->group->id); $group->id != $this->group->id) {
return true;
}
$alias = Group_alias::staticGet('alias', $nickname);
if (!empty($alias) &&
$alias->group_id != $this->group->id) {
return true;
}
return false;
} }
} }

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -21,29 +21,28 @@ if (!defined('LACONICA')) { exit(1); }
require_once INSTALLDIR.'/lib/facebookaction.php'; require_once INSTALLDIR.'/lib/facebookaction.php';
class FacebookhomeAction extends FacebookAction class FacebookhomeAction extends FacebookAction
{ {
var $page = null; var $page = null;
function prepare($argarray) function prepare($argarray)
{ {
parent::prepare($argarray); parent::prepare($argarray);
$this->page = $this->trimmed('page'); $this->page = $this->trimmed('page');
if (!$this->page) { if (!$this->page) {
$this->page = 1; $this->page = 1;
} }
return true; return true;
} }
function handle($args) function handle($args)
{ {
parent::handle($args); parent::handle($args);
// If the user has opted not to initially allow the app to have // If the user has opted not to initially allow the app to have
// Facebook status update permission, store that preference. Only // Facebook status update permission, store that preference. Only
// promt the user the first time she uses the app // promt the user the first time she uses the app
@ -73,7 +72,7 @@ class FacebookhomeAction extends FacebookAction
$this->updateProfileBox($notice); $this->updateProfileBox($notice);
} }
if ($this->arg('status_submit') == 'Send') { if ($this->arg('status_submit') == 'Send') {
$this->saveNewNotice(); $this->saveNewNotice();
} }
@ -81,7 +80,7 @@ class FacebookhomeAction extends FacebookAction
// Facebook status update permission? Then show the main page // Facebook status update permission? Then show the main page
// of the app // of the app
$this->showPage(); $this->showPage();
} else { } else {
// User hasn't authenticated yet, prompt for creds // User hasn't authenticated yet, prompt for creds
@ -89,12 +88,12 @@ class FacebookhomeAction extends FacebookAction
} }
} }
function login() function login()
{ {
$this->showStylesheets(); $this->showStylesheets();
$nickname = common_canonical_nickname($this->trimmed('nickname')); $nickname = common_canonical_nickname($this->trimmed('nickname'));
$password = $this->arg('password'); $password = $this->arg('password');
@ -141,13 +140,12 @@ class FacebookhomeAction extends FacebookAction
$this->facebook->api_client->data_setUserPreference( $this->facebook->api_client->data_setUserPreference(
FACEBOOK_PROMPTED_UPDATE_PREF, 'false'); FACEBOOK_PROMPTED_UPDATE_PREF, 'false');
} }
function showNoticeForm() function showNoticeForm()
{ {
$post_action = "$this->app_uri/index.php"; $post_action = "$this->app_uri/index.php";
$notice_form = new FacebookNoticeForm($this, $post_action, null, $notice_form = new FacebookNoticeForm($this, $post_action, null,
$post_action, $this->user); $post_action, $this->user);
$notice_form->show(); $notice_form->show();
} }
@ -163,9 +161,8 @@ class FacebookhomeAction extends FacebookAction
function showContent() function showContent()
{ {
$notice = $this->user->noticesWithFriends(($this->page-1) * $notice = $this->user->noticeInbox(($this->page-1) * NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1);
$nl = new NoticeList($notice, $this); $nl = new NoticeList($notice, $this);
$cnt = $nl->show(); $cnt = $nl->show();
@ -176,7 +173,7 @@ class FacebookhomeAction extends FacebookAction
function showNoticeList($notice) function showNoticeList($notice)
{ {
$nl = new NoticeList($notice, $this); $nl = new NoticeList($notice, $this);
return $nl->show(); return $nl->show();
} }
@ -201,16 +198,16 @@ class FacebookhomeAction extends FacebookAction
$this->elementStart('ul', array('id' => 'fb-permissions-list')); $this->elementStart('ul', array('id' => 'fb-permissions-list'));
$this->elementStart('li', array('id' => 'fb-permissions-item')); $this->elementStart('li', array('id' => 'fb-permissions-item'));
$next = urlencode("$this->app_uri/index.php"); $next = urlencode("$this->app_uri/index.php");
$api_key = common_config('facebook', 'apikey'); $api_key = common_config('facebook', 'apikey');
$auth_url = 'http://www.facebook.com/authorize.php?api_key=' . $auth_url = 'http://www.facebook.com/authorize.php?api_key=' .
$api_key . '&v=1.0&ext_perm=status_update&next=' . $next . $api_key . '&v=1.0&ext_perm=status_update&next=' . $next .
'&next_cancel=' . $next . '&submit=skip'; '&next_cancel=' . $next . '&submit=skip';
$this->elementStart('span', array('class' => 'facebook-button')); $this->elementStart('span', array('class' => 'facebook-button'));
$this->element('a', array('href' => $auth_url), $this->element('a', array('href' => $auth_url),
sprintf(_('Okay, do it!'), $this->app_name)); sprintf(_('Okay, do it!'), $this->app_name));
$this->elementEnd('span'); $this->elementEnd('span');
@ -225,7 +222,7 @@ class FacebookhomeAction extends FacebookAction
$this->elementEnd('div'); $this->elementEnd('div');
} }
/** /**
* Generate pagination links * Generate pagination links
* *
@ -239,11 +236,11 @@ class FacebookhomeAction extends FacebookAction
*/ */
function pagination($have_before, $have_after, $page, $action, $args=null) function pagination($have_before, $have_after, $page, $action, $args=null)
{ {
// Does a little before-after block for next/prev page // Does a little before-after block for next/prev page
// XXX: Fix so this uses common_local_url() if possible. // XXX: Fix so this uses common_local_url() if possible.
if ($have_before || $have_after) { if ($have_before || $have_after) {
$this->elementStart('div', array('class' => 'pagination')); $this->elementStart('div', array('class' => 'pagination'));
$this->elementStart('dl', null); $this->elementStart('dl', null);
@ -254,7 +251,7 @@ class FacebookhomeAction extends FacebookAction
if ($have_before) { if ($have_before) {
$pargs = array('page' => $page-1); $pargs = array('page' => $page-1);
$newargs = $args ? array_merge($args, $pargs) : $pargs; $newargs = $args ? array_merge($args, $pargs) : $pargs;
$this->elementStart('li', array('class' => 'nav_prev')); $this->elementStart('li', array('class' => 'nav_prev'));
$this->element('a', array('href' => "$action?page=$newargs[page]", 'rel' => 'prev'), $this->element('a', array('href' => "$action?page=$newargs[page]", 'rel' => 'prev'),
_('After')); _('After'));
$this->elementEnd('li'); $this->elementEnd('li');
@ -274,6 +271,5 @@ class FacebookhomeAction extends FacebookAction
$this->elementEnd('div'); $this->elementEnd('div');
} }
} }
} }

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -15,7 +15,7 @@
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -13,7 +13,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -32,7 +32,7 @@ if (!defined('LACONICA')) {
exit(1); exit(1);
} }
require_once(INSTALLDIR.'/lib/profilelist.php'); require_once INSTALLDIR.'/lib/profilelist.php';
require_once INSTALLDIR.'/lib/publicgroupnav.php'; require_once INSTALLDIR.'/lib/publicgroupnav.php';
/** /**
@ -107,7 +107,6 @@ class FeaturedAction extends Action
$featured_nicks = common_config('nickname', 'featured'); $featured_nicks = common_config('nickname', 'featured');
if (count($featured_nicks) > 0) { if (count($featured_nicks) > 0) {
$quoted = array(); $quoted = array();
@ -136,7 +135,7 @@ class FeaturedAction extends Action
$cnt = $profile->find(); $cnt = $profile->find();
if ($cnt > 0) { if ($cnt > 0) {
$featured = new ProfileList($profile, null, $this); $featured = new ProfileList($profile, $this);
$featured->show(); $featured->show();
} }

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -21,20 +21,40 @@ if (!defined('LACONICA')) { exit(1); }
require_once(INSTALLDIR.'/actions/shownotice.php'); require_once(INSTALLDIR.'/actions/shownotice.php');
class FileAction extends ShowNoticeAction class FileAction extends Action
{ {
function showPage() { var $id = null;
$source_url = common_local_url('file', array('notice' => $this->notice->id)); var $filerec = null;
$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; function prepare($args)
$file->query($query); {
$file->fetch(); parent::prepare($args);
if (empty($file->url)) { $this->id = $this->trimmed('notice');
die('nothing attached here'); if (empty($this->id)) {
} else { $this->clientError(_('No notice id'));
header("Location: {$file->url}");
die();
} }
$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);
} }
} }

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

215
actions/groupblock.php Normal file
View File

@ -0,0 +1,215 @@
<?php
/**
* Block a user from a group action class.
*
* PHP version 5
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @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.
*
* 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('LACONICA')) {
exit(1);
}
/**
* Block a user from a group
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*/
class GroupblockAction extends Action
{
var $profile = null;
var $group = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
function prepare($args)
{
parent::prepare($args);
if (!common_logged_in()) {
$this->clientError(_('Not logged in.'));
return false;
}
$token = $this->trimmed('token');
if (empty($token) || $token != common_session_token()) {
$this->clientError(_('There was a problem with your session token. Try again, please.'));
return;
}
$id = $this->trimmed('blockto');
if (empty($id)) {
$this->clientError(_('No profile specified.'));
return false;
}
$this->profile = Profile::staticGet('id', $id);
if (empty($this->profile)) {
$this->clientError(_('No profile with that ID.'));
return false;
}
$group_id = $this->trimmed('blockgroup');
if (empty($group_id)) {
$this->clientError(_('No group specified.'));
return false;
}
$this->group = User_group::staticGet('id', $group_id);
if (empty($this->group)) {
$this->clientError(_('No such group.'));
return false;
}
$user = common_current_user();
if (!$user->isAdmin($this->group)) {
$this->clientError(_('Only an admin can block group members.'), 401);
return false;
}
if (Group_block::isBlocked($this->group, $this->profile)) {
$this->clientError(_('User is already blocked from group.'));
return false;
}
// XXX: could have proactive blocks, but we don't have UI for it.
if (!$this->profile->isMember($this->group)) {
$this->clientError(_('User is not a member of group.'));
return false;
}
return true;
}
/**
* Handle request
*
* Shows a page with list of favorite notices
*
* @param array $args $_REQUEST args; handled in prepare()
*
* @return void
*/
function handle($args)
{
parent::handle($args);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if ($this->arg('no')) {
common_redirect(common_local_url('groupmembers',
array('nickname' => $this->group->nickname)),
303);
} elseif ($this->arg('yes')) {
$this->blockProfile();
} elseif ($this->arg('blockto')) {
$this->showPage();
}
}
}
function showContent() {
$this->areYouSureForm();
}
function title() {
return _('Block user from group');
}
function showNoticeForm() {
// nop
}
/**
* Confirm with user.
*
* Shows a confirmation form.
*
* @return void
*/
function areYouSureForm()
{
$id = $this->profile->id;
$this->element('p', null,
sprintf(_('Are you sure you want to block user "%s" from the group "%s"? '.
'They will be removed from the group, unable to post, and '.
'unable to subscribe to the group in the future.'),
$this->profile->getBestName(),
$this->group->getBestName()));
$this->elementStart('form', array('id' => 'block-' . $id,
'method' => 'post',
'class' => 'block',
'action' => common_local_url('groupblock')));
$this->hidden('token', common_session_token());
$this->hidden('blockto-' . $this->profile->id,
$this->profile->id,
'blockto');
$this->hidden('blockgroup-' . $this->group->id,
$this->group->id,
'blockgroup');
foreach ($this->args as $k => $v) {
if (substr($k, 0, 9) == 'returnto-') {
$this->hidden($k, $v);
}
}
$this->submit('no', _('No'));
$this->submit('yes', _('Yes'));
$this->elementEnd('form');
}
/**
* Actually block a user.
*
* @return void
*/
function blockProfile()
{
$block = Group_block::blockProfile($this->group, $this->profile,
common_current_user());
if (empty($block)) {
$this->serverError(_("Database error blocking user from group."));
return false;
}
// Now, gotta figure where we go back to
foreach ($this->args as $k => $v) {
if ($k == 'returnto-action') {
$action = $v;
} elseif (substr($k, 0, 9) == 'returnto-') {
$args[substr($k, 9)] = $v;
}
}
if ($action) {
common_redirect(common_local_url($action, $args), 303);
} else {
common_redirect(common_local_url('groupmembers',
array('nickname' => $this->group->nickname)),
303);
}
}
}

View File

@ -0,0 +1,328 @@
<?php
/**
* Laconica, the distributed open-source microblogging tool
*
* Change user password
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Settings
* @package Laconica
* @author Sarven Capadisli <csarven@controlyourself.ca>
* @author Zach Copley <zach@controlyourself.ca>
* @copyright 2008-2009 Control Yourself, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://laconi.ca/
*/
if (!defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR . '/lib/designsettings.php';
class GroupDesignSettingsAction extends DesignSettingsAction
{
var $group = null;
/**
* Prepare to run
*/
function prepare($args)
{
parent::prepare($args);
if (!common_config('inboxes','enabled')) {
$this->serverError(_('Inboxes must be enabled for groups to work'));
return false;
}
if (!common_logged_in()) {
$this->clientError(_('You must be logged in to edit a group.'));
return false;
}
$nickname_arg = $this->trimmed('nickname');
$nickname = common_canonical_nickname($nickname_arg);
// Permanent redirect on non-canonical nickname
if ($nickname_arg != $nickname) {
$args = array('nickname' => $nickname);
common_redirect(common_local_url('groupdesignsettings', $args), 301);
return false;
}
if (!$nickname) {
$this->clientError(_('No nickname'), 404);
return false;
}
$groupid = $this->trimmed('groupid');
if ($groupid) {
$this->group = User_group::staticGet('id', $groupid);
} else {
$this->group = User_group::staticGet('nickname', $nickname);
}
if (!$this->group) {
$this->clientError(_('No such group'), 404);
return false;
}
$cur = common_current_user();
if (!$cur->isAdmin($this->group)) {
$this->clientError(_('You must be an admin to edit the group'), 403);
return false;
}
$this->submitaction = common_local_url('groupdesignsettings',
array('nickname' => $this->group->nickname));
return true;
}
/**
* A design for this action
*
* if the group attribute has been set, returns that group's
* design.
*
* @return Design a design object to use
*/
function getDesign()
{
if (empty($this->group)) {
return null;
}
return $this->group->getDesign();
}
/**
* Title of the page
*
* @return string Title of the page
*/
function title()
{
return _('Group design');
}
/**
* Instructions for use
*
* @return instructions for use
*/
function getInstructions()
{
return _('Customize the way your group looks ' .
'with a background image and a colour palette of your choice.');
}
/**
* Override to show group nav stuff
*
* @return nothing
*/
function showLocalNav()
{
$nav = new GroupNav($this, $this->group);
$nav->show();
}
/**
* Get the design we want to edit
*
* @return Design
*/
function getWorkingDesign() {
$design = null;
if (isset($this->group)) {
$design = $this->group->getDesign();
}
if (empty($design)) {
$design = $this->defaultDesign();
}
return $design;
}
/**
* Content area of the page
*
* Shows a form for changing the design
*
* @return void
*/
function showContent()
{
$this->showDesignForm($this->getWorkingDesign());
}
/**
* Save or update the group's design settings
*
* @return void
*/
function saveDesign()
{
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;
}
$onoff = $this->arg('design_background-image_onoff');
$on = false;
$off = false;
$tile = false;
if ($onoff == 'on') {
$on = true;
} else {
$off = true;
}
$repeat = $this->boolean('design_background-image_repeat');
if ($repeat) {
$tile = true;
}
$design = $this->group->getDesign();
if (!empty($design)) {
// update design
$original = clone($design);
$design->backgroundcolor = $bgcolor->intValue();
$design->contentcolor = $ccolor->intValue();
$design->sidebarcolor = $sbcolor->intValue();
$design->textcolor = $tcolor->intValue();
$design->linkcolor = $lcolor->intValue();
$design->setDisposition($on, $off, $tile);
$result = $design->update($original);
if ($result === false) {
common_log_db_error($design, 'UPDATE', __FILE__);
$this->showForm(_('Couldn\'t update your design.'));
return;
}
} else {
$this->group->query('BEGIN');
// save new design
$design = new Design();
$design->backgroundcolor = $bgcolor->intValue();
$design->contentcolor = $ccolor->intValue();
$design->sidebarcolor = $sbcolor->intValue();
$design->textcolor = $tcolor->intValue();
$design->linkcolor = $lcolor->intValue();
$design->setDisposition($on, $off, $tile);
$id = $design->insert();
if (empty($id)) {
common_log_db_error($id, 'INSERT', __FILE__);
$this->showForm(_('Unable to save your design settings!'));
return;
}
$original = clone($this->group);
$this->group->design_id = $id;
$result = $this->group->update($original);
if (empty($result)) {
common_log_db_error($original, 'UPDATE', __FILE__);
$this->showForm(_('Unable to save your design settings!'));
$this->group->query('ROLLBACK');
return;
}
$this->group->query('COMMIT');
}
$this->saveBackgroundImage($design);
$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();
}
}
}

View File

@ -50,7 +50,7 @@ define('MAX_ORIGINAL', 480);
* @link http://laconi.ca/ * @link http://laconi.ca/
*/ */
class GrouplogoAction extends Action class GrouplogoAction extends GroupDesignAction
{ {
var $mode = null; var $mode = null;
var $imagefile = null; var $imagefile = null;

View File

@ -44,7 +44,7 @@ require_once INSTALLDIR.'/lib/publicgroupnav.php';
* @link http://laconi.ca/ * @link http://laconi.ca/
*/ */
class GroupmembersAction extends Action class GroupmembersAction extends GroupDesignAction
{ {
var $page = null; var $page = null;
@ -127,7 +127,7 @@ class GroupmembersAction extends Action
$members = $this->group->getMembers($offset, $limit); $members = $this->group->getMembers($offset, $limit);
if ($members) { if ($members) {
$member_list = new ProfileList($members, null, $this); $member_list = new GroupMemberList($members, $this->group, $this);
$cnt = $member_list->show(); $cnt = $member_list->show();
} }
@ -138,3 +138,326 @@ class GroupmembersAction extends Action
array('nickname' => $this->group->nickname)); array('nickname' => $this->group->nickname));
} }
} }
class GroupMemberList extends ProfileList
{
var $group = null;
function __construct($profile, $group, $action)
{
parent::__construct($profile, $action);
$this->group = $group;
}
function newListItem($profile)
{
return new GroupMemberListItem($profile, $this->group, $this->action);
}
}
class GroupMemberListItem extends ProfileListItem
{
var $group = null;
function __construct($profile, $group, $action)
{
parent::__construct($profile, $action);
$this->group = $group;
}
function showActions()
{
$this->startActions();
$this->showSubscribeButton();
$this->showMakeAdminForm();
$this->showGroupBlockForm();
$this->endActions();
}
function showMakeAdminForm()
{
$user = common_current_user();
if (!empty($user) && $user->id != $this->profile->id && $user->isAdmin($this->group) &&
!$this->profile->isAdmin($this->group)) {
$this->out->elementStart('li', 'entity_make_admin');
$maf = new MakeAdminForm($this->out, $this->profile, $this->group,
array('action' => 'groupmembers',
'nickname' => $this->group->nickname));
$maf->show();
$this->out->elementEnd('li');
}
}
function showGroupBlockForm()
{
$user = common_current_user();
if (!empty($user) && $user->id != $this->profile->id && $user->isAdmin($this->group)) {
$this->out->elementStart('li', 'entity_block');
$bf = new GroupBlockForm($this->out, $this->profile, $this->group,
array('action' => 'groupmembers',
'nickname' => $this->group->nickname));
$bf->show();
$this->out->elementEnd('li');
}
}
}
/**
* Form for blocking a user from a group
*
* @category Form
* @package Laconica
* @author Evan Prodromou <evan@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/
*
* @see BlockForm
*/
class GroupBlockForm extends Form
{
/**
* Profile of user to block
*/
var $profile = null;
/**
* Group to block the user from
*/
var $group = null;
/**
* Return-to args
*/
var $args = null;
/**
* Constructor
*
* @param HTMLOutputter $out output channel
* @param Profile $profile profile of user to block
* @param User_group $group group to block user from
* @param array $args return-to args
*/
function __construct($out=null, $profile=null, $group=null, $args=null)
{
parent::__construct($out);
$this->profile = $profile;
$this->group = $group;
$this->args = $args;
}
/**
* ID of the form
*
* @return int ID of the form
*/
function id()
{
// This should be unique for the page.
return 'block-' . $this->profile->id;
}
/**
* class of the form
*
* @return string class of the form
*/
function formClass()
{
return 'form_group_block';
}
/**
* Action of the form
*
* @return string URL of the action
*/
function action()
{
return common_local_url('groupblock');
}
/**
* Legend of the Form
*
* @return void
*/
function formLegend()
{
$this->out->element('legend', null, _('Block user from group'));
}
/**
* Data elements of the form
*
* @return void
*/
function formData()
{
$this->out->hidden('blockto-' . $this->profile->id,
$this->profile->id,
'blockto');
$this->out->hidden('blockgroup-' . $this->group->id,
$this->group->id,
'blockgroup');
if ($this->args) {
foreach ($this->args as $k => $v) {
$this->out->hidden('returnto-' . $k, $v);
}
}
}
/**
* Action elements
*
* @return void
*/
function formActions()
{
$this->out->submit('submit', _('Block'), 'submit', null, _('Block this user'));
}
}
/**
* Form for making a user an admin for a group
*
* @category Form
* @package Laconica
* @author Evan Prodromou <evan@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 MakeAdminForm extends Form
{
/**
* Profile of user to block
*/
var $profile = null;
/**
* Group to block the user from
*/
var $group = null;
/**
* Return-to args
*/
var $args = null;
/**
* Constructor
*
* @param HTMLOutputter $out output channel
* @param Profile $profile profile of user to block
* @param User_group $group group to block user from
* @param array $args return-to args
*/
function __construct($out=null, $profile=null, $group=null, $args=null)
{
parent::__construct($out);
$this->profile = $profile;
$this->group = $group;
$this->args = $args;
}
/**
* ID of the form
*
* @return int ID of the form
*/
function id()
{
// This should be unique for the page.
return 'makeadmin-' . $this->profile->id;
}
/**
* class of the form
*
* @return string class of the form
*/
function formClass()
{
return 'form_make_admin';
}
/**
* Action of the form
*
* @return string URL of the action
*/
function action()
{
return common_local_url('makeadmin', array('nickname' => $this->group->nickname));
}
/**
* Legend of the Form
*
* @return void
*/
function formLegend()
{
$this->out->element('legend', null, _('Make user an admin of the group'));
}
/**
* Data elements of the form
*
* @return void
*/
function formData()
{
$this->out->hidden('profileid-' . $this->profile->id,
$this->profile->id,
'profileid');
$this->out->hidden('groupid-' . $this->group->id,
$this->group->id,
'groupid');
if ($this->args) {
foreach ($this->args as $k => $v) {
$this->out->hidden('returnto-' . $k, $v);
}
}
}
/**
* Action elements
*
* @return void
*/
function formActions()
{
$this->out->submit('submit', _('Make Admin'), 'submit', null, _('Make this user an admin'));
}
}

View File

@ -100,11 +100,13 @@ class GroupsAction extends Action
function showContent() function showContent()
{ {
$this->elementStart('p', array('id' => 'new_group')); if (common_logged_in()) {
$this->element('a', array('href' => common_local_url('newgroup'), $this->elementStart('p', array('id' => 'new_group'));
'class' => 'more'), $this->element('a', array('href' => common_local_url('newgroup'),
_('Create a new group')); 'class' => 'more'),
$this->elementEnd('p'); _('Create a new group'));
$this->elementEnd('p');
}
$offset = ($this->page-1) * GROUPS_PER_PAGE; $offset = ($this->page-1) * GROUPS_PER_PAGE;
$limit = GROUPS_PER_PAGE + 1; $limit = GROUPS_PER_PAGE + 1;

View File

@ -12,7 +12,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

149
actions/groupunblock.php Normal file
View File

@ -0,0 +1,149 @@
<?php
/**
* Block a user from a group action class.
*
* PHP version 5
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @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.
*
* 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('LACONICA')) {
exit(1);
}
/**
* Unlock a user from a group
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*/
class GroupunblockAction extends Action
{
var $profile = null;
var $group = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
function prepare($args)
{
parent::prepare($args);
if (!common_logged_in()) {
$this->clientError(_('Not logged in.'));
return false;
}
$token = $this->trimmed('token');
if (empty($token) || $token != common_session_token()) {
$this->clientError(_('There was a problem with your session token. Try again, please.'));
return;
}
$id = $this->trimmed('unblockto');
if (empty($id)) {
$this->clientError(_('No profile specified.'));
return false;
}
$this->profile = Profile::staticGet('id', $id);
if (empty($this->profile)) {
$this->clientError(_('No profile with that ID.'));
return false;
}
$group_id = $this->trimmed('unblockgroup');
if (empty($group_id)) {
$this->clientError(_('No group specified.'));
return false;
}
$this->group = User_group::staticGet('id', $group_id);
if (empty($this->group)) {
$this->clientError(_('No such group.'));
return false;
}
$user = common_current_user();
if (!$user->isAdmin($this->group)) {
$this->clientError(_('Only an admin can unblock group members.'), 401);
return false;
}
if (!Group_block::isBlocked($this->group, $this->profile)) {
$this->clientError(_('User is not blocked from group.'));
return false;
}
return true;
}
/**
* Handle request
*
* @param array $args $_REQUEST args; handled in prepare()
*
* @return void
*/
function handle($args)
{
parent::handle($args);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$this->unblockProfile();
}
}
/**
* Unblock a user.
*
* @return void
*/
function unblockProfile()
{
$result = Group_block::unblockProfile($this->group, $this->profile);
if (!$result) {
$this->serverError(_('Error removing the block.'));
return;
}
foreach ($this->args as $k => $v) {
if ($k == 'returnto-action') {
$action = $v;
} else if (substr($k, 0, 9) == 'returnto-') {
$args[substr($k, 9)] = $v;
}
}
if ($action) {
common_redirect(common_local_url($action, $args), 303);
} else {
common_redirect(common_local_url('blockedfromgroup',
array('nickname' => $this->group->nickname)),
303);
}
}
}

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -19,7 +19,7 @@
if (!defined('LACONICA')) { exit(1); } if (!defined('LACONICA')) { exit(1); }
class InviteAction extends Action class InviteAction extends CurrentUserDesignAction
{ {
var $mode = null; var $mode = null;
var $error = null; var $error = null;

View File

@ -96,6 +96,11 @@ class JoingroupAction extends Action
return false; return false;
} }
if (Group_block::isBlocked($this->group, $cur->getProfile())) {
$this->clientError(_('You have been blocked from that group by the admin.'), 403);
return false;
}
return true; return true;
} }

View File

@ -12,7 +12,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

166
actions/makeadmin.php Normal file
View File

@ -0,0 +1,166 @@
<?php
/**
* Make another user an admin of a group
*
* PHP version 5
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @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.
*
* 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('LACONICA')) {
exit(1);
}
/**
* Make another user an admin of a group
*
* @category Action
* @package Laconica
* @author Evan Prodromou <evan@controlyourself.ca>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://laconi.ca/
*/
class MakeadminAction extends Action
{
var $profile = null;
var $group = null;
/**
* Take arguments for running
*
* @param array $args $_REQUEST args
*
* @return boolean success flag
*/
function prepare($args)
{
parent::prepare($args);
if (!common_logged_in()) {
$this->clientError(_('Not logged in.'));
return false;
}
$token = $this->trimmed('token');
if (empty($token) || $token != common_session_token()) {
$this->clientError(_('There was a problem with your session token. Try again, please.'));
return;
}
$id = $this->trimmed('profileid');
if (empty($id)) {
$this->clientError(_('No profile specified.'));
return false;
}
$this->profile = Profile::staticGet('id', $id);
if (empty($this->profile)) {
$this->clientError(_('No profile with that ID.'));
return false;
}
$group_id = $this->trimmed('groupid');
if (empty($group_id)) {
$this->clientError(_('No group specified.'));
return false;
}
$this->group = User_group::staticGet('id', $group_id);
if (empty($this->group)) {
$this->clientError(_('No such group.'));
return false;
}
$user = common_current_user();
if (!$user->isAdmin($this->group)) {
$this->clientError(_('Only an admin can make another user an admin.'), 401);
return false;
}
if ($this->profile->isAdmin($this->group)) {
$this->clientError(sprintf(_('%s is already an admin for group "%s".'),
$this->profile->getBestName(),
$this->group->getBestName()),
401);
return false;
}
return true;
}
/**
* Handle request
*
* @param array $args $_REQUEST args; handled in prepare()
*
* @return void
*/
function handle($args)
{
parent::handle($args);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$this->makeAdmin();
}
}
/**
* Make user an admin
*
* @return void
*/
function makeAdmin()
{
$member = Group_member::pkeyGet(array('group_id' => $this->group->id,
'profile_id' => $this->profile->id));
if (empty($member)) {
$this->serverError(_('Can\'t get membership record for %s in group %s'),
$this->profile->getBestName(),
$this->group->getBestName());
}
$orig = clone($member);
$member->is_admin = 1;
$result = $member->update($orig);
if (!$result) {
common_log_db_error($member, 'UPDATE', __FILE__);
$this->serverError(_('Can\'t make %s an admin for group %s'),
$this->profile->getBestName(),
$this->group->getBestName());
}
foreach ($this->args as $k => $v) {
if ($k == 'returnto-action') {
$action = $v;
} else if (substr($k, 0, 9) == 'returnto-') {
$args[substr($k, 9)] = $v;
}
}
if ($action) {
common_redirect(common_local_url($action, $args), 303);
} else {
common_redirect(common_local_url('groupmembers',
array('nickname' => $this->group->nickname)),
303);
}
}
}

View File

@ -12,7 +12,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -123,6 +123,7 @@ class NewgroupAction extends Action
$homepage = $this->trimmed('homepage'); $homepage = $this->trimmed('homepage');
$description = $this->trimmed('description'); $description = $this->trimmed('description');
$location = $this->trimmed('location'); $location = $this->trimmed('location');
$aliasstring = $this->trimmed('aliases');
if (!Validate::string($nickname, array('min_length' => 1, if (!Validate::string($nickname, array('min_length' => 1,
'max_length' => 64, 'max_length' => 64,
@ -153,6 +154,37 @@ class NewgroupAction extends Action
return; return;
} }
if (!empty($aliasstring)) {
$aliases = array_map('common_canonical_nickname', array_unique(preg_split('/[\s,]+/', $aliasstring)));
} else {
$aliases = array();
}
if (count($aliases) > common_config('group', 'maxaliases')) {
$this->showForm(sprintf(_('Too many aliases! Maximum %d.'),
common_config('group', 'maxaliases')));
return;
}
foreach ($aliases as $alias) {
if (!Validate::string($alias, array('min_length' => 1,
'max_length' => 64,
'format' => NICKNAME_FMT))) {
$this->showForm(sprintf(_('Invalid alias: "%s"'), $alias));
return;
}
if ($this->nicknameExists($alias)) {
$this->showForm(sprintf(_('Alias "%s" already in use. Try another one.'),
$alias));
return;
}
// XXX assumes alphanum nicknames
if (strcmp($alias, $nickname) == 0) {
$this->showForm(_('Alias can\'t be the same as nickname.'));
return;
}
}
$cur = common_current_user(); $cur = common_current_user();
// Checked in prepare() above // Checked in prepare() above
@ -177,6 +209,12 @@ class NewgroupAction extends Action
$this->serverError(_('Could not create group.')); $this->serverError(_('Could not create group.'));
} }
$result = $group->setAliases($aliases);
if (!$result) {
$this->serverError(_('Could not create aliases.'));
}
$member = new Group_member(); $member = new Group_member();
$member->group_id = $group->id; $member->group_id = $group->id;
@ -199,7 +237,18 @@ class NewgroupAction extends Action
function nicknameExists($nickname) function nicknameExists($nickname)
{ {
$group = User_group::staticGet('nickname', $nickname); $group = User_group::staticGet('nickname', $nickname);
return (!is_null($group) && $group != false);
if (!empty($group)) {
return true;
}
$alias = Group_alias::staticGet('alias', $nickname);
if (!empty($alias)) {
return true;
}
return false;
} }
} }

View File

@ -116,6 +116,9 @@ class NewnoticeAction extends Action
function getUploadedFileType() { function getUploadedFileType() {
require_once 'MIME/Type.php'; require_once 'MIME/Type.php';
$cmd = &PEAR::getStaticProperty('MIME_Type', 'fileCmd');
$cmd = common_config('attachments', 'filecommand');
$filetype = MIME_Type::autoDetect($_FILES['attach']['tmp_name']); $filetype = MIME_Type::autoDetect($_FILES['attach']['tmp_name']);
if (in_array($filetype, common_config('attachments', 'supported'))) { if (in_array($filetype, common_config('attachments', 'supported'))) {
return $filetype; return $filetype;
@ -221,17 +224,35 @@ class NewnoticeAction extends Action
} }
} }
if (isset($mimetype)) {
$filename = $this->saveFile($mimetype);
if (empty($filename)) {
$this->clientError(_('Couldn\'t save file.'));
}
$fileurl = File::url($filename);
$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.'));
}
$fileRecord = $this->rememberFile($filename, $mimetype, $short_fileurl);
}
$notice = Notice::saveNew($user->id, $content_shortened, 'web', 1, $notice = Notice::saveNew($user->id, $content_shortened, 'web', 1,
($replyto == 'false') ? null : $replyto); ($replyto == 'false') ? null : $replyto);
if (is_string($notice)) { if (is_string($notice)) {
if (isset($filename)) {
$this->deleteFile($filename);
}
$this->clientError($notice); $this->clientError($notice);
} }
if (isset($mimetype)) { if (isset($mimetype)) {
$this->storeFile($notice, $mimetype); $this->attachFile($notice, $fileRecord);
} }
$this->saveUrls($notice);
common_broadcast_notice($notice); common_broadcast_notice($notice);
if ($this->boolean('ajax')) { if ($this->boolean('ajax')) {
@ -257,49 +278,82 @@ class NewnoticeAction extends Action
} }
} }
function storeFile($notice, $mimetype) { function saveFile($mimetype) {
$filename = basename($_FILES['attach']['name']);
$destination = "file/{$notice->id}-$filename";
if (move_uploaded_file($_FILES['attach']['tmp_name'], INSTALLDIR . "/$destination")) {
$file = new File;
$file->url = common_local_url('file', array('notice' => $notice->id));
$file->size = filesize(INSTALLDIR . "/$destination");
$file->date = time();
$file->mimetype = $mimetype;
if ($file_id = $file->insert()) {
$file_redir = new File_redirection;
$file_redir->url = common_path($destination);
$file_redir->file_id = $file_id;
$file_redir->insert();
$f2p = new File_to_post; $cur = common_current_user();
$f2p->file_id = $file_id;
$f2p->post_id = $notice->id; if (empty($cur)) {
$f2p->insert(); $this->serverError(_('Somehow lost the login in saveFile'));
} else { }
$this->clientError(_('There was a database error while saving your file. Please try again.'));
} $basename = basename($_FILES['attach']['name']);
$filename = File::filename($cur->getProfile(), $basename, $mimetype);
$filepath = File::path($filename);
if (move_uploaded_file($_FILES['attach']['tmp_name'], $filepath)) {
return $filename;
} else { } else {
$this->clientError(_('File could not be moved to destination directory.')); $this->clientError(_('File could not be moved to destination directory.'));
} }
} }
/** save all urls in the notice to the db function deleteFile($filename)
* {
* follow redirects and save all available file information $filepath = File::path($filename);
* (mimetype, date, size, oembed, etc.) @unlink($filepath);
*
* @param class $notice Notice to pull URLs from
*
* @return void
*/
function saveUrls($notice, $uploaded = null) {
common_replace_urls_callback($notice->content, array($this, 'saveUrl'), $notice->id);
} }
function saveUrl($data) { function rememberFile($filename, $mimetype, $short)
list($url, $notice_id) = $data; {
$zzz = File::processNew($url, $notice_id); $file = new File;
$file->filename = $filename;
$file->url = File::url($filename);
$filepath = File::path($filename);
$file->size = filesize($filepath);
$file->date = time();
$file->mimetype = $mimetype;
$file_id = $file->insert();
if (!$file_id) {
common_log_db_error($file, "INSERT", __FILE__);
$this->clientError(_('There was a database error while saving your file. Please try again.'));
}
$this->maybeAddRedir($file_id, $short);
return $file;
}
function maybeAddRedir($file_id, $url)
{
$file_redir = File_redirection::staticGet('url', $url);
if (empty($file_redir)) {
$file_redir = new File_redirection;
$file_redir->url = $url;
$file_redir->file_id = $file_id;
$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)));
} }
/** /**

View File

@ -13,7 +13,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -12,7 +12,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -13,7 +13,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -13,7 +13,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -12,7 +12,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -124,7 +124,7 @@ class PeopletagAction extends Action
$profile->query(sprintf($qry, $this->tag, $lim)); $profile->query(sprintf($qry, $this->tag, $lim));
$pl = new ProfileList($profile, null, $this); $pl = new ProfileList($profile, $this);
$cnt = $pl->show(); $cnt = $pl->show();
$this->pagination($this->page > 1, $this->pagination($this->page > 1,

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -35,6 +35,10 @@ require_once INSTALLDIR.'/lib/publicgroupnav.php';
require_once INSTALLDIR.'/lib/noticelist.php'; require_once INSTALLDIR.'/lib/noticelist.php';
require_once INSTALLDIR.'/lib/feedlist.php'; require_once INSTALLDIR.'/lib/feedlist.php';
// Farther than any human will go
define('MAX_PUBLIC_PAGE', 100);
/** /**
* Action for displaying the public stream * Action for displaying the public stream
* *
@ -74,6 +78,10 @@ class PublicAction extends Action
parent::prepare($args); parent::prepare($args);
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1; $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()); common_set_returnto($this->selfUrl());
return true; return true;

View File

@ -13,7 +13,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -13,7 +13,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -45,9 +45,8 @@ require_once INSTALLDIR.'/lib/feedlist.php';
* @link http://laconi.ca/ * @link http://laconi.ca/
*/ */
class RepliesAction extends Action class RepliesAction extends OwnerDesignAction
{ {
var $user = null;
var $page = null; var $page = null;
/** /**

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -13,7 +13,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -45,7 +45,7 @@ require_once INSTALLDIR.'/lib/feedlist.php';
* @link http://laconi.ca/ * @link http://laconi.ca/
*/ */
class ShowfavoritesAction extends Action class ShowfavoritesAction extends CurrentUserDesignAction
{ {
/** User we're getting the faves of */ /** User we're getting the faves of */
var $user = null; var $user = null;
@ -191,10 +191,21 @@ class ShowfavoritesAction extends Action
function showContent() function showContent()
{ {
$notice = $this->user->favoriteNotices(($this->page-1)*NOTICES_PER_PAGE, $cur = common_current_user();
NOTICES_PER_PAGE + 1);
if (!$notice) { if (!empty($cur) && $cur->id == $this->user->id) {
// Show imported/gateway notices as well as local if
// the user is looking at his own favorites
$notice = $this->user->favoriteNotices(($this->page-1)*NOTICES_PER_PAGE,
NOTICES_PER_PAGE + 1, true);
} else {
$notice = $this->user->favoriteNotices(($this->page-1)*NOTICES_PER_PAGE,
NOTICES_PER_PAGE + 1, false);
}
if (empty($notice)) {
$this->serverError(_('Could not retrieve favorite notices.')); $this->serverError(_('Could not retrieve favorite notices.'));
return; return;
} }

View File

@ -47,10 +47,9 @@ define('MEMBERS_PER_SECTION', 27);
* @link http://laconi.ca/ * @link http://laconi.ca/
*/ */
class ShowgroupAction extends Action class ShowgroupAction extends GroupDesignAction
{ {
/** group we're viewing. */
var $group = null;
/** page we're viewing. */ /** page we're viewing. */
var $page = null; var $page = null;
@ -272,6 +271,17 @@ class ShowgroupAction extends Action
$this->elementEnd('dl'); $this->elementEnd('dl');
} }
if (common_config('group', 'maxaliases') > 0) {
$aliases = $this->group->getAliases();
if (!empty($aliases)) {
$this->elementStart('dl', 'entity_aliases');
$this->element('dt', null, _('Aliases'));
$this->element('dd', 'aliases', implode(' ', $aliases));
$this->elementEnd('dl');
}
}
$this->elementEnd('div'); $this->elementEnd('div');
$this->elementStart('div', 'entity_actions'); $this->elementStart('div', 'entity_actions');
@ -283,7 +293,7 @@ class ShowgroupAction extends Action
if ($cur->isMember($this->group)) { if ($cur->isMember($this->group)) {
$lf = new LeaveForm($this, $this->group); $lf = new LeaveForm($this, $this->group);
$lf->show(); $lf->show();
} else { } else if (!Group_block::isBlocked($this->group, $cur->getProfile())) {
$jf = new JoinForm($this, $this->group); $jf = new JoinForm($this, $this->group);
$jf->show(); $jf->show();
} }
@ -344,7 +354,7 @@ class ShowgroupAction extends Action
$this->element('h2', null, _('Members')); $this->element('h2', null, _('Members'));
$pml = new ProfileMiniList($member, null, $this); $pml = new ProfileMiniList($member, $this);
$cnt = $pml->show(); $cnt = $pml->show();
if ($cnt == 0) { if ($cnt == 0) {
$this->element('p', null, _('(None)')); $this->element('p', null, _('(None)'));

View File

@ -209,7 +209,7 @@ class ShownoticeAction extends Action
function showContent() function showContent()
{ {
$this->elementStart('ol', array('class' => 'notices xoxo')); $this->elementStart('ol', array('class' => 'notices xoxo'));
$nli = new NoticeListItem($this->notice, $this); $nli = new SingleNoticeItem($this->notice, $this);
$nli->show(); $nli->show();
$this->elementEnd('ol'); $this->elementEnd('ol');
} }
@ -264,3 +264,29 @@ class ShownoticeAction extends Action
} }
} }
} }
class SingleNoticeItem extends NoticeListItem
{
/**
* recipe function for displaying a single notice.
*
* We overload to show attachments.
*
* @return void
*/
function show()
{
$this->showStart();
$this->showNotice();
$this->showNoticeAttachments();
$this->showNoticeInfo();
$this->showNoticeOptions();
$this->showEnd();
}
function showNoticeAttachments() {
$al = new AttachmentList($this->notice, $this->out);
$al->show();
}
}

View File

@ -320,10 +320,14 @@ class ShowstreamAction extends ProfileAction
$blocked = $cur->hasBlocked($this->profile); $blocked = $cur->hasBlocked($this->profile);
$this->elementStart('li', 'entity_block'); $this->elementStart('li', 'entity_block');
if ($blocked) { if ($blocked) {
$ubf = new UnblockForm($this, $this->profile); $ubf = new UnblockForm($this, $this->profile,
array('action' => 'showstream',
'nickname' => $this->profile->nickname));
$ubf->show(); $ubf->show();
} else { } else {
$bf = new BlockForm($this, $this->profile); $bf = new BlockForm($this, $this->profile,
array('action' => 'showstream',
'nickname' => $this->profile->nickname));
$bf->show(); $bf->show();
} }
$this->elementEnd('li'); $this->elementEnd('li');
@ -366,7 +370,7 @@ class ShowstreamAction extends ProfileAction
{ {
$notice = empty($this->tag) $notice = empty($this->tag)
? $this->user->getNotices(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1) ? $this->user->getNotices(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1)
: $this->user->getTaggedNotices(($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1, 0, 0, null, $this->tag); : $this->user->getTaggedNotices($this->tag, ($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1, 0, 0, null);
$pnl = new ProfileNoticeList($notice, $this); $pnl = new ProfileNoticeList($notice, $this);
$cnt = $pnl->show(); $cnt = $pnl->show();

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -130,18 +130,34 @@ class SubscribersAction extends GalleryAction
} }
} }
class SubscribersList extends ProfileList class SubscribersList extends SubscriptionList
{ {
function showBlockForm() function newListItem($profile)
{ {
$bf = new BlockForm($this->out, $this->profile, return new SubscribersListItem($profile, $this->owner, $this->action);
array('action' => 'subscribers', }
'nickname' => $this->owner->nickname)); }
$bf->show();
} class SubscribersListItem extends SubscriptionListItem
{
function isReadOnly($args) function showActions()
{ {
return true; $this->startActions();
$this->showSubscribeButton();
// Relevant code!
$this->showBlockForm();
$this->endActions();
}
function showBlockForm()
{
$user = common_current_user();
if (!empty($user) && $this->owner->id == $user->id) {
$bf = new BlockForm($this->out, $this->profile,
array('action' => 'subscribers',
'nickname' => $this->owner->nickname));
$bf->show();
}
} }
} }

View File

@ -137,22 +137,46 @@ class SubscriptionsAction extends GalleryAction
} }
} }
class SubscriptionsList extends ProfileList // XXX SubscriptionsList and SubscriptionList are dangerously close
class SubscriptionsList extends SubscriptionList
{ {
function showOwnerControls($profile) function newListItem($profile)
{
return new SubscriptionsListItem($profile, $this->owner, $this->action);
}
}
class SubscriptionsListItem extends SubscriptionListItem
{
function showProfile()
{
$this->startProfile();
$this->showAvatar();
$this->showFullName();
$this->showLocation();
$this->showHomepage();
$this->showBio();
$this->showTags();
// Relevant portion!
$this->showOwnerControls();
$this->endProfile();
}
function showOwnerControls()
{ {
$sub = Subscription::pkeyGet(array('subscriber' => $this->owner->id, $sub = Subscription::pkeyGet(array('subscriber' => $this->owner->id,
'subscribed' => $profile->id)); 'subscribed' => $this->profile->id));
if (!$sub) { if (!$sub) {
return; return;
} }
$this->out->elementStart('form', array('id' => 'subedit-' . $profile->id, $this->out->elementStart('form', array('id' => 'subedit-' . $this->profile->id,
'method' => 'post', 'method' => 'post',
'class' => 'form_subscription_edit', 'class' => 'form_subscription_edit',
'action' => common_local_url('subedit'))); 'action' => common_local_url('subedit')));
$this->out->hidden('token', common_session_token()); $this->out->hidden('token', common_session_token());
$this->out->hidden('profile', $profile->id); $this->out->hidden('profile', $this->profile->id);
$this->out->checkbox('jabber', _('Jabber'), $sub->jabber); $this->out->checkbox('jabber', _('Jabber'), $sub->jabber);
$this->out->checkbox('sms', _('SMS'), $sub->sms); $this->out->checkbox('sms', _('SMS'), $sub->sms);
$this->out->submit('save', _('Save')); $this->out->submit('save', _('Save'));

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -34,6 +34,11 @@ class TwitapifavoritesAction extends TwitterapiAction
$user = $this->get_user($apidata['api_arg'], $apidata); $user = $this->get_user($apidata['api_arg'], $apidata);
if (empty($user)) { if (empty($user)) {
if ($apidata['content-type'] == 'xml') {
$this->show_single_xml_status($notice);
} elseif ($apidata['content-type'] == 'json') {
$this->show_single_json_status($notice);
}
$this->clientError('Not Found', 404, $apidata['content-type']); $this->clientError('Not Found', 404, $apidata['content-type']);
return; return;
} }
@ -56,7 +61,11 @@ class TwitapifavoritesAction extends TwitterapiAction
$since_id = (int)$this->arg('since_id', 0); $since_id = (int)$this->arg('since_id', 0);
$since = $this->arg('since'); $since = $this->arg('since');
$notice = $user->favoriteNotices(($page-1)*$count, $count); if (!empty($this->auth_user) && $this->auth_user->id == $user->id) {
$notice = $user->favoriteNotices(($page-1)*$count, $count, true);
} else {
$notice = $user->favoriteNotices(($page-1)*$count, $count, false);
}
switch($apidata['content-type']) { switch($apidata['content-type']) {
case 'xml': case 'xml':
@ -91,7 +100,6 @@ class TwitapifavoritesAction extends TwitterapiAction
// Check for RESTfulness // Check for RESTfulness
if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) { if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
// XXX: Twitter just prints the err msg, no XML / JSON.
$this->clientError(_('This method requires a POST or DELETE.'), $this->clientError(_('This method requires a POST or DELETE.'),
400, $apidata['content-type']); 400, $apidata['content-type']);
return; return;
@ -102,10 +110,9 @@ class TwitapifavoritesAction extends TwitterapiAction
return; return;
} }
$user = $apidata['user']; // Always the auth user $user = $apidata['user']; // Always the auth user
$notice_id = $apidata['api_arg']; $notice_id = $apidata['api_arg'];
$notice = Notice::staticGet($notice_id); $notice = Notice::staticGet($notice_id);
if (empty($notice)) { if (empty($notice)) {
$this->clientError(_('No status found with that ID.'), $this->clientError(_('No status found with that ID.'),
@ -115,7 +122,7 @@ class TwitapifavoritesAction extends TwitterapiAction
// XXX: Twitter lets you fave things repeatedly via api. // XXX: Twitter lets you fave things repeatedly via api.
if ($user->hasFave($notice)) { if ($user->hasFave($notice)) {
$this->clientError(_('This notice is already a favorite!'), $this->clientError(_('This status is already a favorite!'),
403, $apidata['content-type']); 403, $apidata['content-type']);
return; return;
} }
@ -123,7 +130,7 @@ class TwitapifavoritesAction extends TwitterapiAction
$fave = Fave::addNew($user, $notice); $fave = Fave::addNew($user, $notice);
if (empty($fave)) { if (empty($fave)) {
$this->serverError(_('Could not create favorite.')); $this->clientError(_('Could not create favorite.'));
return; return;
} }
@ -141,7 +148,55 @@ class TwitapifavoritesAction extends TwitterapiAction
function destroy($args, $apidata) function destroy($args, $apidata)
{ {
parent::handle($args); parent::handle($args);
$this->serverError(_('API method under construction.'), $code=501);
// Check for RESTfulness
if (!in_array($_SERVER['REQUEST_METHOD'], array('POST', 'DELETE'))) {
$this->clientError(_('This method requires a POST or DELETE.'),
400, $apidata['content-type']);
return;
}
if (!in_array($apidata['content-type'], array('xml', 'json'))) {
$this->clientError(_('API method not found!'), $code = 404);
return;
}
$user = $apidata['user']; // Always the auth user
$notice_id = $apidata['api_arg'];
$notice = Notice::staticGet($notice_id);
if (empty($notice)) {
$this->clientError(_('No status found with that ID.'),
404, $apidata['content-type']);
return;
}
$fave = new Fave();
$fave->user_id = $this->id;
$fave->notice_id = $notice->id;
if (!$fave->find(true)) {
$this->clientError(_('That status is not a favorite!'),
403, $apidata['content-type']);
return;
}
$result = $fave->delete();
if (!$result) {
common_log_db_error($fave, 'DELETE', __FILE__);
$this->clientError(_('Could not delete favorite.'), 404);
return;
}
$user->blowFavesCache();
if ($apidata['content-type'] == 'xml') {
$this->show_single_xml_status($notice);
} elseif ($apidata['content-type'] == 'json') {
$this->show_single_json_status($notice);
}
} }
// XXX: these two funcs swiped from faves. // XXX: these two funcs swiped from faves.

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -75,8 +75,8 @@ class TwitapistatusesAction extends TwitterapiAction
{ {
parent::handle($args); parent::handle($args);
$this->auth_user = $apidata['user'];
$user = $this->get_user($apidata['api_arg'], $apidata); $user = $this->get_user($apidata['api_arg'], $apidata);
$this->auth_user = $user;
if (empty($user)) { if (empty($user)) {
$this->clientError(_('No such user!'), 404, $this->clientError(_('No such user!'), 404,
@ -100,8 +100,13 @@ class TwitapistatusesAction extends TwitterapiAction
$since_id = (int)$this->arg('since_id', 0); $since_id = (int)$this->arg('since_id', 0);
$since = $this->arg('since'); $since = $this->arg('since');
$notice = $user->noticesWithFriends(($page-1)*$count, if (!empty($this->auth_user) && $this->auth_user->id == $user->id) {
$count, $since_id, $max_id,$since); $notice = $user->noticeInbox(($page-1)*$count,
$count, $since_id, $max_id, $since);
} else {
$notice = $user->noticesWithFriends(($page-1)*$count,
$count, $since_id, $max_id, $since);
}
switch($apidata['content-type']) { switch($apidata['content-type']) {
case 'xml': case 'xml':

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -58,7 +58,7 @@ class TwitapiusersAction extends TwitterapiAction
return; return;
} }
$twitter_user = $this->twitter_user_array($profile, true); $twitter_user = $this->twitter_user_array($user->getProfile(), true);
if ($apidata['content-type'] == 'xml') { if ($apidata['content-type'] == 'xml') {
$this->init_document('xml'); $this->init_document('xml');

View File

@ -12,7 +12,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -118,7 +118,7 @@ class UnblockAction extends Action
if ($action) { if ($action) {
common_redirect(common_local_url($action, $args), 303); common_redirect(common_local_url($action, $args), 303);
} else { } else {
common_redirect(common_local_url('subscriptions', common_redirect(common_local_url('subscribers',
array('nickname' => $cur->nickname)), array('nickname' => $cur->nickname)),
303); 303);
} }

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -13,7 +13,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -0,0 +1,206 @@
<?php
/**
* Laconica, the distributed open-source microblogging tool
*
* Change user password
*
* PHP version 5
*
* LICENCE: This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Settings
* @package Laconica
* @author Sarven Capadisli <csarven@controlyourself.ca>
* @author Zach Copley <zach@controlyourself.ca>
* @copyright 2008-2009 Control Yourself, Inc.
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
* @link http://laconi.ca/
*/
if (!defined('LACONICA')) {
exit(1);
}
require_once INSTALLDIR . '/lib/designsettings.php';
class UserDesignSettingsAction extends DesignSettingsAction
{
function prepare($args)
{
parent::prepare($args);
$this->submitaction = common_local_url('userdesignsettings');
return true;
}
/**
* Title of the page
*
* @return string Title of the page
*/
function title()
{
return _('Profile design');
}
/**
* Instructions for use
*
* @return instructions for use
*/
function getInstructions()
{
return _('Customize the way your profile looks ' .
'with a background image and a colour palette of your choice.');
}
/**
* Get the design we want to edit
*
* @return Design
*/
function getWorkingDesign() {
$user = common_current_user();
$design = $user->getDesign();
if (empty($design)) {
$design = $this->defaultDesign();
}
return $design;
}
/**
* Content area of the page
*
* Shows a form for changing the design
*
* @return void
*/
function showContent()
{
$this->showDesignForm($this->getWorkingDesign());
}
/**
* Save or update the user's design settings
*
* @return void
*/
function saveDesign()
{
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;
}
$onoff = $this->arg('design_background-image_onoff');
$on = false;
$off = false;
$tile = false;
if ($onoff == 'on') {
$on = true;
} else {
$off = true;
}
$repeat = $this->boolean('design_background-image_repeat');
if ($repeat) {
$tile = true;
}
$user = common_current_user();
$design = $user->getDesign();
if (!empty($design)) {
$original = clone($design);
$design->backgroundcolor = $bgcolor->intValue();
$design->contentcolor = $ccolor->intValue();
$design->sidebarcolor = $sbcolor->intValue();
$design->textcolor = $tcolor->intValue();
$design->linkcolor = $lcolor->intValue();
$design->setDisposition($on, $off, $tile);
$result = $design->update($original);
if ($result === false) {
common_log_db_error($design, 'UPDATE', __FILE__);
$this->showForm(_('Couldn\'t update your design.'));
return;
}
// update design
} else {
$user->query('BEGIN');
// save new design
$design = new Design();
$design->backgroundcolor = $bgcolor->intValue();
$design->contentcolor = $ccolor->intValue();
$design->sidebarcolor = $sbcolor->intValue();
$design->textcolor = $tcolor->intValue();
$design->linkcolor = $lcolor->intValue();
$design->setDisposition($on, $off, $tile);
$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(_('Design preferences saved.'), true);
}
}

View File

@ -46,9 +46,8 @@ require_once INSTALLDIR.'/lib/grouplist.php';
* @link http://laconi.ca/ * @link http://laconi.ca/
*/ */
class UsergroupsAction extends Action class UsergroupsAction extends OwnerDesignAction
{ {
var $user = null;
var $page = null; var $page = null;
var $profile = null; var $profile = null;

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

View File

@ -13,7 +13,7 @@
* @link http://laconi.ca/ * @link http://laconi.ca/
* *
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by

0
background/.gitignore vendored Normal file
View File

View File

@ -55,19 +55,43 @@ class Avatar extends Memcached_DataObject
static function path($filename) static function path($filename)
{ {
return INSTALLDIR . '/avatar/' . $filename; $dir = common_config('avatar', 'dir');
if ($dir[strlen($dir)-1] != '/') {
$dir .= '/';
}
return $dir . $filename;
} }
static function url($filename) static function url($filename)
{ {
return common_path('avatar/'.$filename); $path = common_config('avatar', 'path');
if ($path[strlen($path)-1] != '/') {
$path .= '/';
}
if ($path[0] != '/') {
$path = '/'.$path;
}
$server = common_config('avatar', 'server');
if (empty($server)) {
$server = common_config('site', 'server');
}
// XXX: protocol
return 'http://'.$server.$path.$filename;
} }
function displayUrl() function displayUrl()
{ {
$server = common_config('avatar', 'server'); $server = common_config('avatar', 'server');
if ($server) { if ($server) {
return 'http://'.$server.'/'.$this->filename; return Avatar::url($this->filename);
} else { } else {
return $this->url; return $this->url;
} }

155
classes/Design.php Normal file
View File

@ -0,0 +1,155 @@
<?php
/*
* Laconica - the distributed open-source microblogging tool
* Copyright (C) 2009, Control Yourself, 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('LACONICA')) {
exit(1);
}
define('BACKGROUND_ON', 1);
define('BACKGROUND_OFF', 2);
define('BACKGROUND_TILE', 4);
/**
* Table Definition for design
*/
require_once INSTALLDIR . '/classes/Memcached_DataObject.php';
require_once INSTALLDIR . '/lib/webcolor.php';
class Design extends Memcached_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'design'; // table name
public $id; // int(4) primary_key not_null
public $backgroundcolor; // int(4)
public $contentcolor; // int(4)
public $sidebarcolor; // int(4)
public $textcolor; // int(4)
public $linkcolor; // int(4)
public $backgroundimage; // varchar(255)
public $disposition; // tinyint(1) default_1
/* Static get */
function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Design',$k,$v); }
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
function showCSS($out)
{
try {
$bgcolor = new WebColor($this->backgroundcolor);
$ccolor = new WebColor($this->contentcolor);
$sbcolor = new WebColor($this->sidebarcolor);
$tcolor = new WebColor($this->textcolor);
$lcolor = new WebColor($this->linkcolor);
} catch (WebColorException $e) {
// This shouldn't happen
common_log(LOG_ERR, "Unable to create color for design $id.",
__FILE__);
}
$css = 'body { background-color: #' . $bgcolor->hexValue() . ' }' . "\n";
$css .= '#content, #site_nav_local_views .current a { background-color: #';
$css .= $ccolor->hexValue() . '} '."\n";
$css .= '#aside_primary { background-color: #'. $sbcolor->hexValue() . ' }' . "\n";
$css .= 'html body { color: #'. $tcolor->hexValue() . ' }'. "\n";
$css .= 'a { color: #' . $lcolor->hexValue() . ' }' . "\n";
if (!empty($this->backgroundimage) &&
$this->disposition & BACKGROUND_ON) {
$repeat = ($this->disposition & BACKGROUND_TILE) ?
'background-repeat:repeat;' :
'background-repeat:no-repeat;';
$css .= 'body { background-image:url(' .
Design::url($this->backgroundimage) .
'); ' . $repeat . ' }' . "\n";
}
$out->element('style', array('type' => 'text/css'), $css);
}
static function filename($id, $extension, $extra=null)
{
return $id . (($extra) ? ('-' . $extra) : '') . $extension;
}
static function path($filename)
{
$dir = common_config('background', 'dir');
if ($dir[strlen($dir)-1] != '/') {
$dir .= '/';
}
return $dir . $filename;
}
static function url($filename)
{
$path = common_config('background', 'path');
if ($path[strlen($path)-1] != '/') {
$path .= '/';
}
if ($path[0] != '/') {
$path = '/'.$path;
}
$server = common_config('background', 'server');
if (empty($server)) {
$server = common_config('site', 'server');
}
// XXX: protocol
return 'http://'.$server.$path.$filename;
}
function setDisposition($on, $off, $tile)
{
if ($on) {
$this->disposition |= BACKGROUND_ON;
} else {
$this->disposition &= ~BACKGROUND_ON;
}
if ($off) {
$this->disposition |= BACKGROUND_OFF;
} else {
$this->disposition &= ~BACKGROUND_OFF;
}
if ($tile) {
$this->disposition |= BACKGROUND_TILE;
} else {
$this->disposition &= ~BACKGROUND_TILE;
}
}
}

View File

@ -37,52 +37,62 @@ class Fave extends Memcached_DataObject
return Memcached_DataObject::pkeyGet('Fave', $kv); return Memcached_DataObject::pkeyGet('Fave', $kv);
} }
function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE) function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $own=false)
{ {
$ids = Notice::stream(array('Fave', '_streamDirect'), $ids = Notice::stream(array('Fave', '_streamDirect'),
array($user_id), array($user_id, $own),
'fave:ids_by_user:'.$user_id, ($own) ? 'fave:ids_by_user_own:'.$user_id :
'fave:by_user:'.$user_id,
$offset, $limit); $offset, $limit);
return $ids; return $ids;
} }
function _streamDirect($user_id, $offset, $limit, $since_id, $max_id, $since) function _streamDirect($user_id, $own, $offset, $limit, $since_id, $max_id, $since)
{ {
$fav = new Fave(); $fav = new Fave();
$qry = null;
$fav->user_id = $user_id; if ($own) {
$qry = 'SELECT fave.* FROM fave ';
$fav->selectAdd(); $qry .= 'WHERE fave.user_id = ' . $user_id . ' ';
$fav->selectAdd('notice_id'); } else {
$qry = 'SELECT fave.* FROM fave ';
$qry .= 'INNER JOIN notice ON fave.notice_id = notice.id ';
$qry .= 'WHERE fave.user_id = ' . $user_id . ' ';
$qry .= 'AND notice.is_local != ' . NOTICE_GATEWAY . ' ';
}
if ($since_id != 0) { if ($since_id != 0) {
$fav->whereAdd('notice_id > ' . $since_id); $qry .= 'AND notice_id > ' . $since_id . ' ';
} }
if ($max_id != 0) { if ($max_id != 0) {
$fav->whereAdd('notice_id <= ' . $max_id); $qry .= 'AND notice_id <= ' . $max_id . ' ';
} }
if (!is_null($since)) { if (!is_null($since)) {
$fav->whereAdd('modified > \'' . date('Y-m-d H:i:s', $since) . '\''); $qry .= 'AND modified > \'' . date('Y-m-d H:i:s', $since) . '\' ';
} }
// NOTE: we sort by fave time, not by notice time! // NOTE: we sort by fave time, not by notice time!
$fav->orderBy('modified DESC'); $qry .= 'ORDER BY modified DESC ';
if (!is_null($offset)) { if (!is_null($offset)) {
$fav->limit($offset, $limit); $qry .= "LIMIT $offset, $limit";
} }
$fav->query($qry);
$ids = array(); $ids = array();
if ($fav->find()) { while ($fav->fetch()) {
while ($fav->fetch()) { $ids[] = $fav->notice_id;
$ids[] = $fav->notice_id;
}
} }
$fav->free();
unset($fav);
return $ids; return $ids;
} }
} }

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -30,22 +30,24 @@ require_once INSTALLDIR.'/classes/File_to_post.php';
* Table Definition for file * Table Definition for file
*/ */
class File extends Memcached_DataObject class File extends Memcached_DataObject
{ {
###START_AUTOCODE ###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */ /* the code below is auto generated do not remove the above tag */
public $__table = 'file'; // table name public $__table = 'file'; // table name
public $id; // int(11) not_null primary_key group_by public $id; // int(4) primary_key not_null
public $url; // varchar(255) unique_key public $url; // varchar(255) unique_key
public $mimetype; // varchar(50) public $mimetype; // varchar(50)
public $size; // int(11) group_by public $size; // int(4)
public $title; // varchar(255) public $title; // varchar(255)
public $date; // int(11) group_by public $date; // int(4)
public $protected; // int(1) group_by public $protected; // int(4)
public $filename; // varchar(255)
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */ /* Static get */
function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('File',$k,$v); } function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('File',$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
@ -79,7 +81,6 @@ class File extends Memcached_DataObject
&& ('text/html' === substr($redir_data['type'], 0, 9)) && ('text/html' === substr($redir_data['type'], 0, 9))
&& ($oembed_data = File_oembed::_getOembed($given_url)) && ($oembed_data = File_oembed::_getOembed($given_url))
&& isset($oembed_data['json'])) { && isset($oembed_data['json'])) {
File_oembed::saveNew($oembed_data['json'], $file_id); File_oembed::saveNew($oembed_data['json'], $file_id);
} }
return $x; return $x;
@ -90,15 +91,15 @@ class File extends Memcached_DataObject
$given_url = File_redirection::_canonUrl($given_url); $given_url = File_redirection::_canonUrl($given_url);
if (empty($given_url)) return -1; // error, no url to process if (empty($given_url)) return -1; // error, no url to process
$file = File::staticGet('url', $given_url); $file = File::staticGet('url', $given_url);
if (empty($file->id)) { if (empty($file)) {
$file_redir = File_redirection::staticGet('url', $given_url); $file_redir = File_redirection::staticGet('url', $given_url);
if (empty($file_redir->id)) { if (empty($file_redir)) {
common_debug("processNew() '$given_url' not a known redirect.\n");
$redir_data = File_redirection::where($given_url); $redir_data = File_redirection::where($given_url);
$redir_url = $redir_data['url']; $redir_url = $redir_data['url'];
if ($redir_url === $given_url) { if ($redir_url === $given_url) {
$x = File::saveNew($redir_data, $given_url); $x = File::saveNew($redir_data, $given_url);
$file_id = $x->id; $file_id = $x->id;
} else { } else {
$x = File::processNew($redir_url, $notice_id); $x = File::processNew($redir_url, $notice_id);
$file_id = $x->id; $file_id = $x->id;
@ -116,7 +117,7 @@ class File extends Memcached_DataObject
$x = File::staticGet($file_id); $x = File::staticGet($file_id);
if (empty($x)) die('Impossible!'); if (empty($x)) die('Impossible!');
} }
File_to_post::processNew($file_id, $notice_id); File_to_post::processNew($file_id, $notice_id);
return $x; return $x;
} }
@ -124,8 +125,8 @@ class File extends Memcached_DataObject
function isRespectsQuota($user) { function isRespectsQuota($user) {
if ($_FILES['attach']['size'] > common_config('attachments', 'file_quota')) { if ($_FILES['attach']['size'] > common_config('attachments', 'file_quota')) {
return sprintf(_('No file may be larger than %d bytes ' . return sprintf(_('No file may be larger than %d bytes ' .
'and the file you sent was %d bytes. Try to upload a smaller version.'), 'and the file you sent was %d bytes. Try to upload a smaller version.'),
common_config('attachments', 'file_quota'), $_FILES['attach']['size']); common_config('attachments', 'file_quota'), $_FILES['attach']['size']);
} }
$query = "select sum(size) as total from file join file_to_post on file_to_post.file_id = file.id join notice on file_to_post.post_id = notice.id where profile_id = {$user->id} and file.url like '%/notice/%/file'"; $query = "select sum(size) as total from file join file_to_post on file_to_post.file_id = file.id join notice on file_to_post.post_id = notice.id where profile_id = {$user->id} and file.url like '%/notice/%/file'";
@ -145,5 +146,52 @@ class File extends Memcached_DataObject
} }
return true; return true;
} }
// where should the file go?
static function filename($profile, $basename, $mimetype)
{
require_once 'MIME/Type/Extension.php';
$mte = new MIME_Type_Extension();
$ext = $mte->getExtension($mimetype);
$nickname = $profile->nickname;
$datestamp = strftime('%Y%m%dT%H%M%S', time());
$random = strtolower(common_confirmation_code(32));
return "$nickname-$datestamp-$random.$ext";
}
static function path($filename)
{
$dir = common_config('attachments', 'dir');
if ($dir[strlen($dir)-1] != '/') {
$dir .= '/';
}
return $dir . $filename;
}
static function url($filename)
{
$path = common_config('attachments', 'path');
if ($path[strlen($path)-1] != '/') {
$path .= '/';
}
if ($path[0] != '/') {
$path = '/'.$path;
}
$server = common_config('attachments', 'server');
if (empty($server)) {
$server = common_config('site', 'server');
}
// XXX: protocol
return 'http://'.$server.$path.$filename;
}
} }

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -25,35 +25,39 @@ require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
* Table Definition for file_oembed * Table Definition for file_oembed
*/ */
class File_oembed extends Memcached_DataObject class File_oembed extends Memcached_DataObject
{ {
###START_AUTOCODE ###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */ /* the code below is auto generated do not remove the above tag */
public $__table = 'file_oembed'; // table name public $__table = 'file_oembed'; // table name
public $id; // int(11) not_null primary_key group_by public $file_id; // int(4) primary_key not_null
public $file_id; // int(11) unique_key group_by public $version; // varchar(20)
public $version; // varchar(20) public $type; // varchar(20)
public $type; // varchar(20) public $provider; // varchar(50)
public $provider; // varchar(50) public $provider_url; // varchar(255)
public $provider_url; // varchar(255) public $width; // int(4)
public $width; // int(11) group_by public $height; // int(4)
public $height; // int(11) group_by public $html; // text()
public $html; // blob(65535) blob public $title; // varchar(255)
public $title; // varchar(255) public $author_name; // varchar(50)
public $author_name; // varchar(50) public $author_url; // varchar(255)
public $author_url; // varchar(255) public $url; // varchar(255)
public $url; // varchar(255) public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */ /* Static get */
function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('File_oembed',$k,$v); } function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('File_oembed',$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
function sequenceKey()
{
return array(false, false, false);
}
function _getOembed($url, $maxwidth = 500, $maxheight = 400, $format = 'json') { function _getOembed($url, $maxwidth = 500, $maxheight = 400, $format = 'json') {
$cmd = 'http://oohembed.com/oohembed/?url=' . urlencode($url); $cmd = common_config('oohembed', 'endpoint') . '?url=' . urlencode($url);
if (is_int($maxwidth)) $cmd .= "&maxwidth=$maxwidth"; if (is_int($maxwidth)) $cmd .= "&maxwidth=$maxwidth";
if (is_int($maxheight)) $cmd .= "&maxheight=$maxheight"; if (is_int($maxheight)) $cmd .= "&maxheight=$maxheight";
if (is_string($format)) $cmd .= "&format=$format"; if (is_string($format)) $cmd .= "&format=$format";
@ -84,4 +88,3 @@ class File_oembed extends Memcached_DataObject
} }
} }

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -25,31 +25,28 @@ require_once INSTALLDIR.'/classes/File_oembed.php';
define('USER_AGENT', 'Laconica user agent / file probe'); define('USER_AGENT', 'Laconica user agent / file probe');
/** /**
* Table Definition for file_redirection * Table Definition for file_redirection
*/ */
class File_redirection extends Memcached_DataObject class File_redirection extends Memcached_DataObject
{ {
###START_AUTOCODE ###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */ /* the code below is auto generated do not remove the above tag */
public $__table = 'file_redirection'; // table name public $__table = 'file_redirection'; // table name
public $id; // int(11) not_null primary_key group_by public $url; // varchar(255) primary_key not_null
public $url; // varchar(255) unique_key public $file_id; // int(4)
public $file_id; // int(11) group_by public $redirections; // int(4)
public $redirections; // int(11) group_by public $httpcode; // int(4)
public $httpcode; // int(11) group_by public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */ /* Static get */
function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('File_redirection',$k,$v); } function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('File_redirection',$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
function _commonCurl($url, $redirs) { function _commonCurl($url, $redirs) {
$curlh = curl_init(); $curlh = curl_init();
curl_setopt($curlh, CURLOPT_URL, $url); curl_setopt($curlh, CURLOPT_URL, $url);
@ -69,24 +66,18 @@ class File_redirection extends Memcached_DataObject
// let's see if we know this... // let's see if we know this...
$a = File::staticGet('url', $short_url); $a = File::staticGet('url', $short_url);
if (empty($a->id)) {
$b = File_redirection::staticGet('url', $short_url); if (!empty($a)) {
if (empty($b->id)) {
// we'll have to figure it out
} else {
// this is a redirect to $b->file_id
$a = File::staticGet($b->file_id);
$url = $a->url;
}
} else {
// this is a direct link to $a->url // this is a direct link to $a->url
$url = $a->url; return $a->url;
} else {
$b = File_redirection::staticGet('url', $short_url);
if (!empty($b)) {
// this is a redirect to $b->file_id
$a = File::staticGet('id', $b->file_id);
return $a->url;
}
} }
if (isset($url)) {
return $url;
}
$curlh = File_redirection::_commonCurl($short_url, $redirs); $curlh = File_redirection::_commonCurl($short_url, $redirs);
// Don't include body in output // Don't include body in output
@ -123,83 +114,22 @@ class File_redirection extends Memcached_DataObject
} }
function makeShort($long_url) { function makeShort($long_url) {
$long_url = File_redirection::_canonUrl($long_url);
// do we already know this long_url and have a short redirection for it?
$file = new File;
$file_redir = new File_redirection;
$file->url = $long_url;
$file->joinAdd($file_redir);
$file->selectAdd('length(file_redirection.url) as len');
$file->limit(1);
$file->orderBy('len');
$file->find(true);
if (!empty($file->url) && (strlen($file->url) < strlen($long_url))) {
return $file->url;
}
// if yet unknown, we must find a short url according to user settings $canon = File_redirection::_canonUrl($long_url);
$short_url = File_redirection::_userMakeShort($long_url, common_current_user());
return $short_url; $short_url = File_redirection::_userMakeShort($canon);
// Did we get one? Is it shorter?
if (!empty($short_url) && mb_strlen($short_url) < mb_strlen($long_url)) {
return $short_url;
} else {
return $long_url;
}
} }
function _userMakeShort($long_url, $user) { function _userMakeShort($long_url) {
if (empty($user)) { $short_url = common_shorten_url($long_url);
// common current user does not find a user when called from the XMPP daemon if (!empty($short_url) && $short_url != $long_url) {
// therefore we'll set one here fix, so that XMPP given URLs may be shortened
$user->urlshorteningservice = 'ur1.ca';
}
$curlh = curl_init();
curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 20); // # seconds to wait
curl_setopt($curlh, CURLOPT_USERAGENT, 'Laconica');
curl_setopt($curlh, CURLOPT_RETURNTRANSFER, true);
switch($user->urlshorteningservice) {
case 'ur1.ca':
require_once INSTALLDIR.'/lib/Shorturl_api.php';
$short_url_service = new LilUrl;
$short_url = $short_url_service->shorten($long_url);
break;
case '2tu.us':
$short_url_service = new TightUrl;
require_once INSTALLDIR.'/lib/Shorturl_api.php';
$short_url = $short_url_service->shorten($long_url);
break;
case 'ptiturl.com':
require_once INSTALLDIR.'/lib/Shorturl_api.php';
$short_url_service = new PtitUrl;
$short_url = $short_url_service->shorten($long_url);
break;
case 'bit.ly':
curl_setopt($curlh, CURLOPT_URL, 'http://bit.ly/api?method=shorten&long_url='.urlencode($long_url));
$short_url = current(json_decode(curl_exec($curlh))->results)->hashUrl;
break;
case 'is.gd':
curl_setopt($curlh, CURLOPT_URL, 'http://is.gd/api.php?longurl='.urlencode($long_url));
$short_url = curl_exec($curlh);
break;
case 'snipr.com':
curl_setopt($curlh, CURLOPT_URL, 'http://snipr.com/site/snip?r=simple&link='.urlencode($long_url));
$short_url = curl_exec($curlh);
break;
case 'metamark.net':
curl_setopt($curlh, CURLOPT_URL, 'http://metamark.net/api/rest/simple?long_url='.urlencode($long_url));
$short_url = curl_exec($curlh);
break;
case 'tinyurl.com':
curl_setopt($curlh, CURLOPT_URL, 'http://tinyurl.com/api-create.php?url='.urlencode($long_url));
$short_url = curl_exec($curlh);
break;
default:
$short_url = false;
}
curl_close($curlh);
if ($short_url) {
$short_url = (string)$short_url; $short_url = (string)$short_url;
// store it // store it
$file = File::staticGet('url', $long_url); $file = File::staticGet('url', $long_url);
@ -222,7 +152,7 @@ class File_redirection extends Memcached_DataObject
} }
return $short_url; return $short_url;
} }
return $long_url; return null;
} }
function _canonUrl($in_url, $default_scheme = 'http://') { function _canonUrl($in_url, $default_scheme = 'http://') {

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -25,24 +25,29 @@ require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
* Table Definition for file_thumbnail * Table Definition for file_thumbnail
*/ */
class File_thumbnail extends Memcached_DataObject class File_thumbnail extends Memcached_DataObject
{ {
###START_AUTOCODE ###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */ /* the code below is auto generated do not remove the above tag */
public $__table = 'file_thumbnail'; // table name public $__table = 'file_thumbnail'; // table name
public $id; // int(11) not_null primary_key group_by public $file_id; // int(4) primary_key not_null
public $file_id; // int(11) unique_key group_by
public $url; // varchar(255) unique_key public $url; // varchar(255) unique_key
public $width; // int(11) group_by public $width; // int(4)
public $height; // int(11) group_by public $height; // int(4)
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */ /* Static get */
function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('File_thumbnail',$k,$v); } function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('File_thumbnail',$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
function sequenceKey()
{
return array(false, false, false);
}
function saveNew($data, $file_id) { function saveNew($data, $file_id) {
$tn = new File_thumbnail; $tn = new File_thumbnail;
$tn->file_id = $file_id; $tn->file_id = $file_id;

View File

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Laconica - a distributed open-source microblogging tool * Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, Controlez-Vous, Inc. * Copyright (C) 2008, 2009, Control Yourself, Inc.
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -25,18 +25,18 @@ require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
* Table Definition for file_to_post * Table Definition for file_to_post
*/ */
class File_to_post extends Memcached_DataObject class File_to_post extends Memcached_DataObject
{ {
###START_AUTOCODE ###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */ /* the code below is auto generated do not remove the above tag */
public $__table = 'file_to_post'; // table name public $__table = 'file_to_post'; // table name
public $id; // int(11) not_null primary_key group_by public $file_id; // int(4) primary_key not_null
public $file_id; // int(11) multiple_key group_by public $post_id; // int(4) primary_key not_null
public $post_id; // int(11) group_by public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */ /* Static get */
function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('File_to_post',$k,$v); } function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('File_to_post',$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
@ -44,17 +44,27 @@ class File_to_post extends Memcached_DataObject
function processNew($file_id, $notice_id) { function processNew($file_id, $notice_id) {
static $seen = array(); static $seen = array();
if (empty($seen[$notice_id]) || !in_array($file_id, $seen[$notice_id])) { if (empty($seen[$notice_id]) || !in_array($file_id, $seen[$notice_id])) {
$f2p = new File_to_post;
$f2p->file_id = $file_id; $f2p = File_to_post::pkeyGet(array('post_id' => $notice_id,
$f2p->post_id = $notice_id; 'file_id' => $file_id));
$f2p->insert(); if (empty($f2p)) {
$f2p = new File_to_post;
$f2p->file_id = $file_id;
$f2p->post_id = $notice_id;
$f2p->insert();
}
if (empty($seen[$notice_id])) { if (empty($seen[$notice_id])) {
$seen[$notice_id] = array($file_id); $seen[$notice_id] = array($file_id);
} else { } else {
$seen[$notice_id][] = $file_id; $seen[$notice_id][] = $file_id;
} }
} }
}
function &pkeyGet($kv)
{
return Memcached_DataObject::pkeyGet('File_to_post', $kv);
} }
} }

View File

@ -4,42 +4,41 @@
*/ */
require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
class Foreign_user extends Memcached_DataObject class Foreign_user extends Memcached_DataObject
{ {
###START_AUTOCODE ###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */ /* the code below is auto generated do not remove the above tag */
public $__table = 'foreign_user'; // table name public $__table = 'foreign_user'; // table name
public $id; // int(4) primary_key not_null public $id; // bigint(8) primary_key not_null
public $service; // int(4) primary_key not_null public $service; // int(4) primary_key not_null
public $uri; // varchar(255) unique_key not_null public $uri; // varchar(255) unique_key not_null
public $nickname; // varchar(255) public $nickname; // varchar(255)
public $created; // datetime() not_null public $created; // datetime() not_null
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) function staticGet($k,$v=NULL) { return Memcached_DataObject::staticGet('Foreign_user',$k,$v); }
{ return Memcached_DataObject::staticGet('Foreign_user',$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
// XXX: This only returns a 1->1 single obj mapping. Change? Or make // XXX: This only returns a 1->1 single obj mapping. Change? Or make
// a getForeignUsers() that returns more than one? --Zach // a getForeignUsers() that returns more than one? --Zach
static function getForeignUser($id, $service) { static function getForeignUser($id, $service) {
$fuser = new Foreign_user(); $fuser = new Foreign_user();
$fuser->whereAdd("service = $service"); $fuser->whereAdd("service = $service");
$fuser->whereAdd("id = $id"); $fuser->whereAdd("id = $id");
$fuser->limit(1); $fuser->limit(1);
if ($fuser->find()) { if ($fuser->find()) {
$fuser->fetch(); $fuser->fetch();
return $fuser; return $fuser;
} }
return null; return null;
} }
function updateKeys(&$orig) function updateKeys(&$orig)
{ {
$parts = array(); $parts = array();
@ -68,5 +67,4 @@ class Foreign_user extends Memcached_DataObject
return $result; return $result;
} }
} }

41
classes/Group_alias.php Normal file
View File

@ -0,0 +1,41 @@
<?php
/**
* Table Definition for group_alias
*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2009, Control Yourself, 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('LACONICA')) { exit(1); }
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
class Group_alias extends Memcached_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'group_alias'; // table name
public $alias; // varchar(64) primary_key not_null
public $group_id; // int(4) not_null
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */
function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('Group_alias',$k,$v); }
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
}

115
classes/Group_block.php Normal file
View File

@ -0,0 +1,115 @@
<?php
/**
* Table Definition for group_block
*
* Laconica - a distributed open-source microblogging tool
* Copyright (C) 2008, 2009, Control Yourself, 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('LACONICA')) { exit(1); }
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
class Group_block extends Memcached_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'group_block'; // table name
public $group_id; // int(4) primary_key not_null
public $blocked; // int(4) primary_key not_null
public $blocker; // int(4) not_null
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */
function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('Group_block',$k,$v); }
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
function &pkeyGet($kv)
{
return Memcached_DataObject::pkeyGet('Group_block', $kv);
}
static function isBlocked($group, $profile)
{
$block = Group_block::pkeyGet(array('group_id' => $group->id,
'blocked' => $profile->id));
return !empty($block);
}
static function blockProfile($group, $profile, $blocker)
{
// Insert the block
$block = new Group_block();
$block->query('BEGIN');
$block->group_id = $group->id;
$block->blocked = $profile->id;
$block->blocker = $blocker->id;
$result = $block->insert();
if (!$result) {
common_log_db_error($block, 'INSERT', __FILE__);
return null;
}
// Delete membership if any
$member = new Group_member();
$member->group_id = $group->id;
$member->profile_id = $profile->id;
if ($member->find(true)) {
$result = $member->delete();
if (!$result) {
common_log_db_error($member, 'DELETE', __FILE__);
return null;
}
}
// Commit, since both have been done
$block->query('COMMIT');
return $block;
}
static function unblockProfile($group, $profile)
{
$block = Group_block::pkeyGet(array('group_id' => $group->id,
'blocked' => $profile->id));
if (empty($block)) {
return null;
}
$result = $block->delete();
if (!$result) {
common_log_db_error($block, 'DELETE', __FILE__);
return null;
}
return true;
}
}

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