diff options
Diffstat (limited to 'actions')
-rw-r--r-- | actions/block.php | 2 | ||||
-rw-r--r-- | actions/blockedfromgroup.php | 315 | ||||
-rw-r--r-- | actions/editgroup.php | 59 | ||||
-rw-r--r-- | actions/groupblock.php | 215 | ||||
-rw-r--r-- | actions/groupmembers.php | 325 | ||||
-rw-r--r-- | actions/groupunblock.php | 149 | ||||
-rw-r--r-- | actions/joingroup.php | 5 | ||||
-rw-r--r-- | actions/makeadmin.php | 166 | ||||
-rw-r--r-- | actions/newgroup.php | 51 | ||||
-rw-r--r-- | actions/showgroup.php | 15 | ||||
-rw-r--r-- | actions/showstream.php | 8 | ||||
-rw-r--r-- | actions/subscribers.php | 32 | ||||
-rw-r--r-- | actions/subscriptions.php | 34 | ||||
-rw-r--r-- | actions/unblock.php | 2 |
14 files changed, 1354 insertions, 24 deletions
diff --git a/actions/block.php b/actions/block.php index 34f991dc6..0efee5932 100644 --- a/actions/block.php +++ b/actions/block.php @@ -180,7 +180,7 @@ class BlockAction extends Action if ($action) { common_redirect(common_local_url($action, $args), 303); } else { - common_redirect(common_local_url('subscriptions', + common_redirect(common_local_url('subscribers', array('nickname' => $cur->nickname)), 303); } diff --git a/actions/blockedfromgroup.php b/actions/blockedfromgroup.php new file mode 100644 index 000000000..541ebcfd9 --- /dev/null +++ b/actions/blockedfromgroup.php @@ -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 Action +{ + 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')); + } +} diff --git a/actions/editgroup.php b/actions/editgroup.php index 39dad0465..29a7bce43 100644 --- a/actions/editgroup.php +++ b/actions/editgroup.php @@ -171,6 +171,7 @@ class EditgroupAction extends Action $homepage = $this->trimmed('homepage'); $description = $this->trimmed('description'); $location = $this->trimmed('location'); + $aliasstring = $this->trimmed('aliases'); if (!Validate::string($nickname, array('min_length' => 1, 'max_length' => 64, @@ -201,6 +202,39 @@ class EditgroupAction extends Action 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); $this->group->nickname = $nickname; @@ -217,6 +251,14 @@ class EditgroupAction extends Action $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) { common_redirect(common_local_url('editgroup', array('nickname' => $nickname)), @@ -229,9 +271,20 @@ class EditgroupAction extends Action function nicknameExists($nickname) { $group = User_group::staticGet('nickname', $nickname); - return (!is_null($group) && - $group != false && - $group->id != $this->group->id); + + if (!empty($group) && + $group->id != $this->group->id) { + return true; + } + + $alias = Group_alias::staticGet('alias', $nickname); + + if (!empty($alias) && + $alias->group_id != $this->group->id) { + return true; + } + + return false; } } diff --git a/actions/groupblock.php b/actions/groupblock.php new file mode 100644 index 000000000..93662da79 --- /dev/null +++ b/actions/groupblock.php @@ -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, Controlez-Vous, 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); + } + } +} + diff --git a/actions/groupmembers.php b/actions/groupmembers.php index 21e5ebbaa..abfad3f0d 100644 --- a/actions/groupmembers.php +++ b/actions/groupmembers.php @@ -127,7 +127,7 @@ class GroupmembersAction extends Action $members = $this->group->getMembers($offset, $limit); if ($members) { - $member_list = new ProfileList($members, null, $this); + $member_list = new GroupMemberList($members, $this->group, $this); $cnt = $member_list->show(); } @@ -138,3 +138,326 @@ class GroupmembersAction extends Action 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')); + } +} diff --git a/actions/groupunblock.php b/actions/groupunblock.php new file mode 100644 index 000000000..a0bcb01f9 --- /dev/null +++ b/actions/groupunblock.php @@ -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, Controlez-Vous, 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); + } + } +} + diff --git a/actions/joingroup.php b/actions/joingroup.php index a5d82ddc7..0e4f96eaf 100644 --- a/actions/joingroup.php +++ b/actions/joingroup.php @@ -96,6 +96,11 @@ class JoingroupAction extends Action 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; } diff --git a/actions/makeadmin.php b/actions/makeadmin.php new file mode 100644 index 000000000..899c23ae4 --- /dev/null +++ b/actions/makeadmin.php @@ -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, Controlez-Vous, 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); + } + } +} diff --git a/actions/newgroup.php b/actions/newgroup.php index 67cd6b2f1..0289e77c2 100644 --- a/actions/newgroup.php +++ b/actions/newgroup.php @@ -123,6 +123,7 @@ class NewgroupAction extends Action $homepage = $this->trimmed('homepage'); $description = $this->trimmed('description'); $location = $this->trimmed('location'); + $aliasstring = $this->trimmed('aliases'); if (!Validate::string($nickname, array('min_length' => 1, 'max_length' => 64, @@ -153,6 +154,37 @@ class NewgroupAction extends Action 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(); // Checked in prepare() above @@ -177,6 +209,12 @@ class NewgroupAction extends Action $this->serverError(_('Could not create group.')); } + $result = $group->setAliases($aliases); + + if (!$result) { + $this->serverError(_('Could not create aliases.')); + } + $member = new Group_member(); $member->group_id = $group->id; @@ -199,7 +237,18 @@ class NewgroupAction extends Action function nicknameExists($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; } } diff --git a/actions/showgroup.php b/actions/showgroup.php index 29b6fa1e6..357f579d8 100644 --- a/actions/showgroup.php +++ b/actions/showgroup.php @@ -272,6 +272,17 @@ class ShowgroupAction extends Action $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->elementStart('div', 'entity_actions'); @@ -283,7 +294,7 @@ class ShowgroupAction extends Action if ($cur->isMember($this->group)) { $lf = new LeaveForm($this, $this->group); $lf->show(); - } else { + } else if (!Group_block::isBlocked($this->group, $cur->getProfile())) { $jf = new JoinForm($this, $this->group); $jf->show(); } @@ -344,7 +355,7 @@ class ShowgroupAction extends Action $this->element('h2', null, _('Members')); - $pml = new ProfileMiniList($member, null, $this); + $pml = new ProfileMiniList($member, $this); $cnt = $pml->show(); if ($cnt == 0) { $this->element('p', null, _('(None)')); diff --git a/actions/showstream.php b/actions/showstream.php index e2f4e24d4..72316b259 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -320,10 +320,14 @@ class ShowstreamAction extends ProfileAction $blocked = $cur->hasBlocked($this->profile); $this->elementStart('li', 'entity_block'); if ($blocked) { - $ubf = new UnblockForm($this, $this->profile); + $ubf = new UnblockForm($this, $this->profile, + array('action' => 'showstream', + 'nickname' => $this->profile->nickname)); $ubf->show(); } else { - $bf = new BlockForm($this, $this->profile); + $bf = new BlockForm($this, $this->profile, + array('action' => 'showstream', + 'nickname' => $this->profile->nickname)); $bf->show(); } $this->elementEnd('li'); diff --git a/actions/subscribers.php b/actions/subscribers.php index 4482de9a7..66ac00fb1 100644 --- a/actions/subscribers.php +++ b/actions/subscribers.php @@ -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, - array('action' => 'subscribers', - 'nickname' => $this->owner->nickname)); - $bf->show(); + return new SubscribersListItem($profile, $this->owner, $this->action); } +} - function isReadOnly($args) +class SubscribersListItem extends SubscriptionListItem +{ + 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(); + } } } diff --git a/actions/subscriptions.php b/actions/subscriptions.php index 095b18ad8..4124abea4 100644 --- a/actions/subscriptions.php +++ b/actions/subscriptions.php @@ -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, - 'subscribed' => $profile->id)); + 'subscribed' => $this->profile->id)); if (!$sub) { return; } - $this->out->elementStart('form', array('id' => 'subedit-' . $profile->id, + $this->out->elementStart('form', array('id' => 'subedit-' . $this->profile->id, 'method' => 'post', 'class' => 'form_subscription_edit', 'action' => common_local_url('subedit'))); $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('sms', _('SMS'), $sub->sms); $this->out->submit('save', _('Save')); diff --git a/actions/unblock.php b/actions/unblock.php index 8573b2a87..6e671c9dd 100644 --- a/actions/unblock.php +++ b/actions/unblock.php @@ -118,7 +118,7 @@ class UnblockAction extends Action if ($action) { common_redirect(common_local_url($action, $args), 303); } else { - common_redirect(common_local_url('subscriptions', + common_redirect(common_local_url('subscribers', array('nickname' => $cur->nickname)), 303); } |