]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Working subscription approval!
authorBrion Vibber <brion@pobox.com>
Tue, 29 Mar 2011 00:06:02 +0000 (17:06 -0700)
committerBrion Vibber <brion@pobox.com>
Tue, 29 Mar 2011 00:08:04 +0000 (17:08 -0700)
13 files changed:
actions/approvegroup.php
actions/approvesub.php [new file with mode: 0644]
actions/cancelgroup.php
actions/cancelsubscription.php [new file with mode: 0644]
actions/groupqueue.php
actions/subqueue.php [new file with mode: 0644]
classes/Profile.php
classes/Subscription.php
classes/Subscription_queue.php
lib/approvesubform.php [new file with mode: 0644]
lib/cancelsubscriptionform.php [new file with mode: 0644]
lib/router.php
lib/subgroupnav.php

index 95338a4af3c5556f87ca6e84c4671135e2152c18..55a0a6c3fd88528cb705661c1ccde7dda9361f60 100644 (file)
@@ -157,7 +157,7 @@ class ApprovegroupAction extends Action
                 $this->request->abort();
             }
         } catch (Exception $e) {
-            common_log(LOG_ERROR, "Exception canceling group sub: " . $e->getMessage());
+            common_log(LOG_ERR, "Exception canceling group sub: " . $e->getMessage());
             // TRANS: Server error displayed when cancelling a queued group join request fails.
             // TRANS: %1$s is the leaving user's nickname, $2$s is the group nickname for which the leave failed.
             $this->serverError(sprintf(_('Could not cancel request for user %1$s to join group %2$s.'),
diff --git a/actions/approvesub.php b/actions/approvesub.php
new file mode 100644 (file)
index 0000000..d30da25
--- /dev/null
@@ -0,0 +1,145 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Leave a group
+ *
+ * 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   StatusNet
+ * @author    Evan Prodromou <evan@status.net>
+ * @copyright 2008-2009 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link      http://status.net/
+ */
+
+if (!defined('STATUSNET') && !defined('LACONICA')) {
+    exit(1);
+}
+
+/**
+ * Leave a group
+ *
+ * This is the action for leaving a group. It works more or less like the subscribe action
+ * for users.
+ *
+ * @category Group
+ * @package  StatusNet
+ * @author   Evan Prodromou <evan@status.net>
+ * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link     http://status.net/
+ */
+class ApprovesubAction extends Action
+{
+    var $profile = null;
+
+    /**
+     * Prepare to run
+     */
+    function prepare($args)
+    {
+        parent::prepare($args);
+
+        $cur = common_current_user();
+        if (empty($cur)) {
+            // TRANS: Client error displayed trying to approve group membership while not logged in.
+            $this->clientError(_('Must be logged in.'), 403);
+            return false;
+        }
+        if ($this->arg('profile_id')) {
+            $this->profile = Profile::staticGet('id', $this->arg('profile_id'));
+        } else {
+            // TRANS: Client error displayed trying to approve subscriptionswithout specifying a profile to approve.
+            $this->clientError(_('Must specify a profile.'));
+            return false;
+        }
+
+        $this->request = Subscription_queue::pkeyGet(array('subscriber' => $this->profile->id,
+                                                           'subscribed' => $cur->id));
+
+        if (empty($this->request)) {
+            // TRANS: Client error displayed trying to approve subscription for a non-existing request.
+            $this->clientError(sprintf(_('%s is not in the moderation queue for your subscriptions.'), $this->profile->nickname), 403);
+        }
+
+        $this->approve = (bool)$this->arg('approve');
+        $this->cancel = (bool)$this->arg('cancel');
+        if (!$this->approve && !$this->cancel) {
+            // TRANS: Client error displayed trying to approve/deny subscription.
+            $this->clientError(_('Internal error: received neither cancel nor abort.'));
+        }
+        if ($this->approve && $this->cancel) {
+            // TRANS: Client error displayed trying to approve/deny  subscription
+            $this->clientError(_('Internal error: received both cancel and abort.'));
+        }
+        return true;
+    }
+
+    /**
+     * Handle the request
+     *
+     * On POST, add the current user to the group
+     *
+     * @param array $args unused
+     *
+     * @return void
+     */
+    function handle($args)
+    {
+        parent::handle($args);
+        $cur = common_current_user();
+
+        try {
+            if ($this->approve) {
+                $this->request->complete();
+            } elseif ($this->cancel) {
+                $this->request->abort();
+            }
+        } catch (Exception $e) {
+            common_log(LOG_ERR, "Exception canceling sub: " . $e->getMessage());
+            // TRANS: Server error displayed when cancelling a queued subscription request fails.
+            // TRANS: %1$s is the leaving user's nickname, $2$s is the nickname for which the leave failed.
+            $this->serverError(sprintf(_('Could not cancel or approve request for user %1$s to join group %2$s.'),
+                                       $this->profile->nickname, $cur->nickname));
+            return;
+        }
+
+        if ($this->boolean('ajax')) {
+            $this->startHTML('text/xml;charset=utf-8');
+            $this->elementStart('head');
+            // TRANS: Title for subscription approval ajax return
+            // TRANS: %1$s is the approved user's nickname
+            $this->element('title', null, sprintf(_m('TITLE','%1$s\'s request'),
+                                                  $this->profile->nickname));
+            $this->elementEnd('head');
+            $this->elementStart('body');
+            if ($this->approve) {
+                // TRANS: Message on page for user after approving a subscription request.
+                $this->element('p', 'success', _('Subscription approved.'));
+            } elseif ($this->cancel) {
+                // TRANS: Message on page for user after rejecting a subscription request.
+                $this->element('p', 'success', _('Subscription canceled.'));
+            }
+            $this->elementEnd('body');
+            $this->elementEnd('html');
+        } else {
+            common_redirect(common_local_url('subqueue', array('nickname' =>
+                                                               $cur->nickname)),
+                            303);
+        }
+    }
+}
index 15eb2b5dc398a60492c63f74dd83789ed2bb5153..3074e3ffa3141db4fb47f851a0dbc92f76fc6eea 100644 (file)
@@ -141,7 +141,7 @@ class CancelgroupAction extends Action
         try {
             $this->request->abort();
         } catch (Exception $e) {
-            common_log(LOG_ERROR, "Exception canceling group sub: " . $e->getMessage());
+            common_log(LOG_ERR, "Exception canceling group sub: " . $e->getMessage());
             // TRANS: Server error displayed when cancelling a queued group join request fails.
             // TRANS: %1$s is the leaving user's nickname, $2$s is the group nickname for which the leave failed.
             $this->serverError(sprintf(_('Could not cancel request for user %1$s to join group %2$s.'),
diff --git a/actions/cancelsubscription.php b/actions/cancelsubscription.php
new file mode 100644 (file)
index 0000000..367fbfa
--- /dev/null
@@ -0,0 +1,119 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Leave a group
+ *
+ * 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   StatusNet
+ * @author    Evan Prodromou <evan@status.net>
+ * @copyright 2008-2009 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link      http://status.net/
+ */
+
+if (!defined('STATUSNET') && !defined('LACONICA')) {
+    exit(1);
+}
+
+/**
+ * Leave a group
+ *
+ * This is the action for leaving a group. It works more or less like the subscribe action
+ * for users.
+ *
+ * @category Group
+ * @package  StatusNet
+ * @author   Evan Prodromou <evan@status.net>
+ * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link     http://status.net/
+ */
+class CancelsubscriptionAction extends Action
+{
+
+    function handle($args)
+    {
+        parent::handle($args);
+        if ($this->boolean('ajax')) {
+            StatusNet::setApi(true);
+        }
+        if (!common_logged_in()) {
+            $this->clientError(_('Not logged in.'));
+            return;
+        }
+
+        $user = common_current_user();
+
+        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
+            common_redirect(common_local_url('subscriptions',
+                                             array('nickname' => $user->nickname)));
+            return;
+        }
+
+        /* Use a session token for CSRF protection. */
+
+        $token = $this->trimmed('token');
+
+        if (!$token || $token != common_session_token()) {
+            $this->clientError(_('There was a problem with your session token. ' .
+                                 'Try again, please.'));
+            return;
+        }
+
+        $other_id = $this->arg('unsubscribeto');
+
+        if (!$other_id) {
+            $this->clientError(_('No profile ID in request.'));
+            return;
+        }
+
+        $other = Profile::staticGet('id', $other_id);
+
+        if (!$other) {
+            $this->clientError(_('No profile with that ID.'));
+            return;
+        }
+
+        $this->request = Subscription_queue::pkeyGet(array('subscriber' => $user->id,
+                                                           'subscribed' => $other->id));
+
+        if (empty($this->request)) {
+            // TRANS: Client error displayed when trying to approve a non-existing group join request.
+            // TRANS: %s is a user nickname.
+            $this->clientError(sprintf(_('%s is not in the moderation queue for this group.'), $this->profile->nickname), 403);
+        }
+
+        $this->request->abort();
+
+        if ($this->boolean('ajax')) {
+            $this->startHTML('text/xml;charset=utf-8');
+            $this->elementStart('head');
+            $this->element('title', null, _('Unsubscribed'));
+            $this->elementEnd('head');
+            $this->elementStart('body');
+            $subscribe = new SubscribeForm($this, $other);
+            $subscribe->show();
+            $this->elementEnd('body');
+            $this->elementEnd('html');
+        } else {
+            common_redirect(common_local_url('subscriptions',
+                                             array('nickname' => $user->nickname)),
+                            303);
+        }
+    }
+}
index dca0ff7bd5be824740fc7c41130124496011807d..c6f54d57d7d52a2ed62d1ea50ed433129692c8b4 100644 (file)
@@ -156,7 +156,7 @@ class GroupqueueAction extends GroupDesignAction
         $members->free();
 
         $this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
-                          $this->page, 'groupmembers',
+                          $this->page, 'groupqueue',
                           array('nickname' => $this->group->nickname));
     }
 }
diff --git a/actions/subqueue.php b/actions/subqueue.php
new file mode 100644 (file)
index 0000000..38bc16e
--- /dev/null
@@ -0,0 +1,142 @@
+<?php
+/**
+ * StatusNet, 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   StatusNet
+ * @author    Evan Prodromou <evan@status.net>
+ * @copyright 2008-2009 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link      http://status.net/
+ */
+
+if (!defined('STATUSNET') && !defined('LACONICA')) {
+    exit(1);
+}
+
+require_once(INSTALLDIR.'/lib/profilelist.php');
+
+/**
+ * List of group members
+ *
+ * @category Group
+ * @package  StatusNet
+ * @author   Evan Prodromou <evan@status.net>
+ * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link     http://status.net/
+ */
+class SubqueueAction extends GalleryAction
+{
+    var $page = null;
+
+    function isReadOnly($args)
+    {
+        return true;
+    }
+
+    // @todo FIXME: most of this belongs in a base class, sounds common to most group actions?
+    function prepare($args)
+    {
+        parent::prepare($args);
+
+        $cur = common_current_user();
+        if (!$cur || $cur->id != $this->profile->id) {
+            // TRANS: Client error displayed when trying to approve group applicants without being a group administrator.
+            $this->clientError(_('You may only approve your own pending subscriptions.'));
+            return false;
+        }
+        return true;
+    }
+
+    function title()
+    {
+        if ($this->page == 1) {
+            // TRANS: Title of the first page showing pending subscribers still awaiting approval.
+            // TRANS: %s is the name of the user.
+            return sprintf(_('%s subscribers awaiting approval'),
+                           $this->profile->nickname);
+        } else {
+            // TRANS: Title of all but the first page showing pending subscribersmembers still awaiting approval.
+            // TRANS: %1$s is the name of the user, %2$d is the page number of the members list.
+            return sprintf(_('%1$s subscribers awaiting approval, page %2$d'),
+                           $this->profile->nickname,
+                           $this->page);
+        }
+    }
+
+    function showPageNotice()
+    {
+        $this->element('p', 'instructions',
+                       // TRANS: Page notice for group members page.
+                       _('A list of users awaiting approval to subscribe to you.'));
+    }
+
+
+    function showContent()
+    {
+        $offset = ($this->page-1) * PROFILES_PER_PAGE;
+        $limit =  PROFILES_PER_PAGE + 1;
+
+        $cnt = 0;
+
+        $members = $this->profile->getRequests($offset, $limit);
+
+        if ($members) {
+            // @fixme change!
+            $member_list = new SubQueueList($members, $this);
+            $cnt = $member_list->show();
+        }
+
+        $members->free();
+
+        $this->pagination($this->page > 1, $cnt > PROFILES_PER_PAGE,
+                          $this->page, 'subqueue',
+                          array('nickname' => $this->profile->nickname)); // urgh
+    }
+}
+
+class SubQueueList extends ProfileList
+{
+    function newListItem($profile)
+    {
+        return new SubQueueListItem($profile, $this->action);
+    }
+}
+
+class SubQueueListItem extends ProfileListItem
+{
+    function showActions()
+    {
+        $this->startActions();
+        if (Event::handle('StartProfileListItemActionElements', array($this))) {
+            $this->showApproveButtons();
+            Event::handle('EndProfileListItemActionElements', array($this));
+        }
+        $this->endActions();
+    }
+
+    function showApproveButtons()
+    {
+        $this->out->elementStart('li', 'entity_approval');
+        $form = new ApproveSubForm($this->out, $this->profile);
+        $form->show();
+        $this->out->elementEnd('li');
+    }
+}
index 94e709b5084c83979e141d33286d00b235858262..3d989dd974a75c46a5587de7bc00d800ac6e93b8 100644 (file)
@@ -356,6 +356,36 @@ class Profile extends Memcached_DataObject
         return new ArrayWrapper($profiles);
     }
 
+    /**
+     * Get pending subscribers, who have not yet been approved.
+     *
+     * @param int $offset
+     * @param int $limit
+     * @return Profile
+     */
+    function getRequests($offset=0, $limit=null)
+    {
+        $qry =
+          'SELECT profile.* ' .
+          'FROM profile JOIN subscription_queue '.
+          'ON profile.id = subscription_queue.subscriber ' .
+          'WHERE subscription_queue.subscribed = %d ' .
+          'ORDER BY subscription_queue.created DESC ';
+
+        if ($limit != null) {
+            if (common_config('db','type') == 'pgsql') {
+                $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
+            } else {
+                $qry .= ' LIMIT ' . $offset . ', ' . $limit;
+            }
+        }
+
+        $members = new Profile();
+
+        $members->query(sprintf($qry, $this->id));
+        return $members;
+    }
+
     function subscriptionCount()
     {
         $c = Cache::instance();
index 70d351a0f75af3ab3349c8c27346e34328c1acdb..438f1dfe50f879d1766f4ed055ea8f7a700f9711 100644 (file)
@@ -122,7 +122,7 @@ class Subscription extends Memcached_DataObject
             Event::handle('EndSubscribe', array($subscriber, $other));
         }
 
-        return true;
+        return $sub;
     }
 
     /**
index 3e254dfce1dcb732b97a5cbb490b1390c45d566e..41c0a54fa8f7be1cf1b914a64343a94653ac56da 100644 (file)
@@ -72,7 +72,7 @@ class Subscription_queue extends Managed_DataObject
     {
         $subscriber = Profile::staticGet('id', $this->subscriber);
         $subscribed = Profile::staticGet('id', $this->subscribed);
-        $sub = Subscription::start($subscriber, $other, Subscription::FORCE);
+        $sub = Subscription::start($subscriber, $subscribed, Subscription::FORCE);
         if ($sub) {
             $this->delete();
         }
@@ -82,7 +82,7 @@ class Subscription_queue extends Managed_DataObject
     /**
      * Cancel an outstanding subscription request to the other profile.
      */
-    public function abort($profile)
+    public function abort()
     {
         $subscriber = Profile::staticGet('id', $this->subscriber);
         $subscribed = Profile::staticGet('id', $this->subscribed);
diff --git a/lib/approvesubform.php b/lib/approvesubform.php
new file mode 100644 (file)
index 0000000..820f648
--- /dev/null
@@ -0,0 +1,114 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Form for leaving a group
+ *
+ * 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  Form
+ * @package   StatusNet
+ * @author    Evan Prodromou <evan@status.net>
+ * @author    Sarven Capadisli <csarven@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link      http://status.net/
+ */
+
+if (!defined('STATUSNET') && !defined('LACONICA')) {
+    exit(1);
+}
+
+require_once INSTALLDIR.'/lib/form.php';
+
+/**
+ * Form for leaving a group
+ *
+ * @category Form
+ * @package  StatusNet
+ * @author   Evan Prodromou <evan@status.net>
+ * @author   Sarven Capadisli <csarven@status.net>
+ * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link     http://status.net/
+ *
+ * @see      UnsubscribeForm
+ */
+class ApproveSubForm extends Form
+{
+    var $profile = null;
+
+    /**
+     * Constructor
+     *
+     * @param HTMLOutputter $out   output channel
+     * @param Profile       $profile user whose request to accept or drop
+     */
+    function __construct($out=null, $profile=null)
+    {
+        parent::__construct($out);
+
+        $this->profile = $profile;
+    }
+
+    /**
+     * ID of the form
+     *
+     * @return string ID of the form
+     */
+    function id()
+    {
+        return 'sub-queue-' . $this->profile->id;
+    }
+
+    /**
+     * class of the form
+     *
+     * @return string of the form class
+     */
+    function formClass()
+    {
+        return 'form_sub_queue ajax';
+    }
+
+    /**
+     * Action of the form
+     *
+     * @return string URL of the action
+     */
+    function action()
+    {
+        $params = array();
+        if ($this->profile) {
+            $params['profile_id'] = $this->profile->id;
+        }
+        return common_local_url('approvesub',
+                                array(), $params);
+    }
+
+    /**
+     * Action elements
+     *
+     * @return void
+     */
+
+    function formActions()
+    {
+        // TRANS: Submit button text to accept a subscription request on approve sub form.
+        $this->out->submit('approve', _m('BUTTON','Accept'));
+        // TRANS: Submit button text to reject a subscription request on approve sub form.
+        $this->out->submit('cancel', _m('BUTTON','Reject'));
+    }
+}
diff --git a/lib/cancelsubscriptionform.php b/lib/cancelsubscriptionform.php
new file mode 100644 (file)
index 0000000..1173152
--- /dev/null
@@ -0,0 +1,129 @@
+<?php
+/**
+ * StatusNet, the distributed open-source microblogging tool
+ *
+ * Form for leaving a group
+ *
+ * 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  Form
+ * @package   StatusNet
+ * @author    Evan Prodromou <evan@status.net>
+ * @author    Sarven Capadisli <csarven@status.net>
+ * @copyright 2009 StatusNet, Inc.
+ * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link      http://status.net/
+ */
+
+if (!defined('STATUSNET') && !defined('LACONICA')) {
+    exit(1);
+}
+
+require_once INSTALLDIR.'/lib/form.php';
+
+/**
+ * Form for leaving a group
+ *
+ * @category Form
+ * @package  StatusNet
+ * @author   Evan Prodromou <evan@status.net>
+ * @author   Sarven Capadisli <csarven@status.net>
+ * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link     http://status.net/
+ *
+ * @see      UnsubscribeForm
+ */
+
+class CancelSubscriptionForm extends Form
+{
+    /**
+     * user being subscribed to
+     */
+
+    var $profile = null;
+
+    /**
+     * Constructor
+     *
+     * @param HTMLOutputter $out   output channel
+     * @param Profile       $profile being subscribed to
+     */
+
+    function __construct($out=null, $profile=null)
+    {
+        parent::__construct($out);
+
+        $this->profile = $profile;
+    }
+
+    /**
+     * ID of the form
+     *
+     * @return string ID of the form
+     */
+
+    function id()
+    {
+        return 'subscription-cancel-' . $this->profile->id;
+    }
+
+    /**
+     * class of the form
+     *
+     * @return string of the form class
+     */
+
+    function formClass()
+    {
+        return 'form_unsubscribe ajax';
+    }
+
+    /**
+     * Action of the form
+     *
+     * @return string URL of the action
+     */
+
+    function action()
+    {
+        return common_local_url('cancelsubscription',
+                                array(),
+                                array('id' => $this->profile->id));
+    }
+
+    /**
+     * Data elements of the form
+     *
+     * @return void
+     */
+    function formData()
+    {
+        $this->out->hidden('unsubscribeto-' . $this->profile->id,
+                           $this->profile->id,
+                           'unsubscribeto');
+    }
+
+    /**
+     * Action elements
+     *
+     * @return void
+     */
+
+    function formActions()
+    {
+        $this->out->submit('submit', _('Cancel sub request'));
+    }
+}
index 2cbb1ad649702844fa59582b8610f106b36a4213..156bc10c7f1e2bb3950e8231f7d9f5a1c0db1347 100644 (file)
@@ -199,7 +199,7 @@ class Router
             // main stuff is repetitive
 
             $main = array('login', 'logout', 'register', 'subscribe',
-                          'unsubscribe', 'cancelsubscription',
+                          'unsubscribe', 'cancelsubscription', 'approvesub',
                           'confirmaddress', 'recoverpassword',
                           'invite', 'favor', 'disfavor', 'sup',
                           'block', 'unblock', 'subedit',
@@ -844,6 +844,10 @@ class Router
                                 array('tag' => self::REGEX_TAG));
                 }
 
+                $m->connect('subscribers/pending',
+                            array('action' => 'subqueue',
+                                  'nickname' => $nickname));
+
                 foreach (array('rss', 'groups') as $a) {
                     $m->connect($a,
                                 array('action' => 'user'.$a,
@@ -900,6 +904,9 @@ class Router
                                 array('action' => $a),
                                 array('nickname' => Nickname::DISPLAY_FMT));
                 }
+                $m->connect(':nickname/subscribers/pending',
+                            array('action' => 'subqueue'),
+                            array('nickname' => Nickname::DISPLAY_FMT));
 
                 foreach (array('subscriptions', 'subscribers') as $a) {
                     $m->connect(':nickname/'.$a.'/:tag',
index ee4b0a8dffc482242c94d0bccb92e8cfd2f10f26..b0ec364bff6806badc722d6e591fe37e7bc8d33e 100644 (file)
@@ -96,6 +96,20 @@ class SubGroupNav extends Menu
                                          $this->user->nickname),
                                  $action == 'subscribers',
                                  'nav_subscribers');
+            if ($cur && $cur->id == $this->user->id) {
+                // Possibly site admins should be able to get in here too
+                $pending = $this->countPendingSubs();
+                if ($pending || $cur->subscribe_policy == User::SUBSCRIBE_POLICY_MODERATE) {
+                    $this->out->menuItem(common_local_url('subqueue',
+                                                          array('nickname' =>
+                                                                $this->user->nickname)),
+                                         sprintf(_('Pending (%d)'), $pending),
+                                         sprintf(_('Approve pending subscription requests'),
+                                                 $this->user->nickname),
+                                         $action == 'subqueueaction',
+                                         'nav_subscribers');
+                }
+            }
             $this->out->menuItem(common_local_url('usergroups',
                                                   array('nickname' =>
                                                         $this->user->nickname)),
@@ -118,4 +132,11 @@ class SubGroupNav extends Menu
 
         $this->out->elementEnd('ul');
     }
+
+    function countPendingSubs()
+    {
+        $req = new Subscription_queue();
+        $req->subscribed = $this->user->id;
+        return $req->count();
+    }
 }