]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Allow users to be unblocked from a group
authorEvan Prodromou <evan@controlyourself.ca>
Sun, 14 Jun 2009 23:17:44 +0000 (16:17 -0700)
committerEvan Prodromou <evan@controlyourself.ca>
Sun, 14 Jun 2009 23:17:44 +0000 (16:17 -0700)
List users who are blocked from joining a group. Add a form to let
them be unblocked. Add an action that removes the block. Includes
changes to group and groupblock classes.

actions/blockedfromgroup.php [new file with mode: 0644]
actions/groupunblock.php [new file with mode: 0644]
classes/Group_block.php
classes/User_group.php
lib/groupnav.php
lib/router.php

diff --git a/actions/blockedfromgroup.php b/actions/blockedfromgroup.php
new file mode 100644 (file)
index 0000000..1b7b317
--- /dev/null
@@ -0,0 +1,313 @@
+<?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)) {
+            $bf = new GroupUnblockForm($this->out, $this->profile, $this->group,
+                                       array('action' => 'blockedfromgroup',
+                                             'nickname' => $this->group->nickname));
+            $bf->show();
+        }
+    }
+}
+
+/**
+ * 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/groupunblock.php b/actions/groupunblock.php
new file mode 100644 (file)
index 0000000..a0bcb01
--- /dev/null
@@ -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);
+        }
+    }
+}
+
index d945fd57a922ec3ba788658c26107a8a069b768a..4c583d8e230e71e9a447b49004b067942e7a45a4 100644 (file)
@@ -92,4 +92,24 @@ class Group_block extends Memcached_DataObject
 
         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;
+    }
+
 }
index 1be34b60bd34ec96ac3dedd00acc4f6553445cd9..9f9977755be5e8182a1f20637f7c42e7bdb7b6b9 100644 (file)
@@ -125,6 +125,29 @@ class User_group extends Memcached_DataObject
         return $members;
     }
 
+    function getBlocked($offset=0, $limit=null)
+    {
+        $qry =
+          'SELECT profile.* ' .
+          'FROM profile JOIN group_block '.
+          'ON profile.id = group_block.blocked ' .
+          'WHERE group_block.group_id = %d ' .
+          'ORDER BY group_block.modified DESC ';
+
+        if ($limit != null) {
+            if (common_config('db','type') == 'pgsql') {
+                $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
+            } else {
+                $qry .= ' LIMIT ' . $offset . ', ' . $limit;
+            }
+        }
+
+        $blocked = new Profile();
+
+        $blocked->query(sprintf($qry, $this->id));
+        return $blocked;
+    }
+
     function setOriginal($filename)
     {
         $imagefile = new ImageFile($this->id, Avatar::path($filename));
index 90bdc10149b30cda2cb0aab8dca759d615e90c78..194247982cc6ae7e6b25c71fd816125902d9d66e 100644 (file)
@@ -95,6 +95,12 @@ class GroupNav extends Widget
         $cur = common_current_user();
 
         if ($cur && $cur->isAdmin($this->group)) {
+            $this->out->menuItem(common_local_url('blockedfromgroup', array('nickname' =>
+                                                                            $nickname)),
+                                 _('Blocked'),
+                                 sprintf(_('%s blocked users'), $nickname),
+                                 $action_name == 'blockedfromgroup',
+                                 'nav_group_blocked');
             $this->out->menuItem(common_local_url('editgroup', array('nickname' =>
                                                                      $nickname)),
                                  _('Admin'),
index 3d870e5651ea54c90291b20a62cea61a0f50748e..e10871bc08ab9271354faa34f36988d34507c8e0 100644 (file)
@@ -101,7 +101,8 @@ class Router
         $main = array('login', 'logout', 'register', 'subscribe',
                       'unsubscribe', 'confirmaddress', 'recoverpassword',
                       'invite', 'favor', 'disfavor', 'sup',
-                      'block', 'unblock', 'subedit', 'groupblock');
+                      'block', 'unblock', 'subedit',
+                      'groupblock', 'groupunblock');
 
         foreach ($main as $a) {
             $m->connect('main/'.$a, array('action' => $a));
@@ -228,6 +229,10 @@ class Router
                         array('nickname' => '[a-zA-Z0-9]+'));
         }
 
+        $m->connect('group/:nickname/blocked',
+                    array('action' => 'blockedfromgroup'),
+                    array('nickname' => '[a-zA-Z0-9]+'));
+
         $m->connect('group/:id/id',
                     array('action' => 'groupbyid'),
                     array('id' => '[0-9]+'));