]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Work in progress: subscription approval policy field in place on user, hooked up...
authorBrion Vibber <brion@pobox.com>
Mon, 28 Mar 2011 22:13:59 +0000 (15:13 -0700)
committerBrion Vibber <brion@pobox.com>
Mon, 28 Mar 2011 22:13:59 +0000 (15:13 -0700)
actions/approvegroup.php
actions/cancelgroup.php
actions/profilesettings.php
classes/Group_join_queue.php
classes/Profile.php
classes/Subscription.php
classes/Subscription_queue.php
classes/User.php
classes/statusnet.ini
db/core.php

index 5039cfae6bcf34964c6ea0c9160f1169e03600ae..95338a4af3c5556f87ca6e84c4671135e2152c18 100644 (file)
@@ -152,9 +152,9 @@ class ApprovegroupAction extends Action
 
         try {
             if ($this->approve) {
-                $this->profile->completeJoinGroup($this->group);
+                $this->request->complete();
             } elseif ($this->cancel) {
-                $this->profile->cancelJoinGroup($this->group);
+                $this->request->abort();
             }
         } catch (Exception $e) {
             common_log(LOG_ERROR, "Exception canceling group sub: " . $e->getMessage());
index 57df1a10a7b955470f97485998ed29440efdc3fe..15eb2b5dc398a60492c63f74dd83789ed2bb5153 100644 (file)
@@ -139,7 +139,7 @@ class CancelgroupAction extends Action
         parent::handle($args);
 
         try {
-            $this->profile->cancelJoinGroup($this->group);
+            $this->request->abort();
         } catch (Exception $e) {
             common_log(LOG_ERROR, "Exception canceling group sub: " . $e->getMessage());
             // TRANS: Server error displayed when cancelling a queued group join request fails.
index e1d686ca292678cf2790683aea0fbd4266fc3f24..7aa987f3a5bf4020103f07894a336db95bd7df7d 100644 (file)
@@ -192,6 +192,17 @@ class ProfilesettingsAction extends SettingsAction
                             ($this->arg('autosubscribe')) ?
                             $this->boolean('autosubscribe') : $user->autosubscribe);
             $this->elementEnd('li');
+            $this->elementStart('li');
+            $this->dropdown('subscribe_policy',
+                            // TRANS: Dropdown field label on profile settings, for what policies to apply when someone else tries to subscribe to your updates.
+                            _('Subscription policy'),
+                            array(User::SUBSCRIBE_POLICY_OPEN     => _('Let anyone follow me'),
+                                  User::SUBSCRIBE_POLICY_MODERATE => _('Ask me first')),
+                            // TRANS: Dropdown field title on group edit form.
+                            _('Whether other users need your permission to follow your updates.'),
+                            false,
+                            (empty($user->subscribe_policy)) ? User::SUBSCRIBE_POLICY_OPEN : $user->subscribe_policy);
+            $this->elementEnd('li');
         }
         $this->elementEnd('ul');
         // TRANS: Button to save input in profile settings.
@@ -234,6 +245,7 @@ class ProfilesettingsAction extends SettingsAction
             $bio = $this->trimmed('bio');
             $location = $this->trimmed('location');
             $autosubscribe = $this->boolean('autosubscribe');
+            $subscribe_policy = $this->trimmed('subscribe_policy');
             $language = $this->trimmed('language');
             $timezone = $this->trimmed('timezone');
             $tagstring = $this->trimmed('tags');
@@ -333,11 +345,12 @@ class ProfilesettingsAction extends SettingsAction
             }
 
             // XXX: XOR
-            if ($user->autosubscribe ^ $autosubscribe) {
+            if (($user->autosubscribe ^ $autosubscribe) || $user->subscribe_policy != $subscribe_policy) {
 
                 $original = clone($user);
 
                 $user->autosubscribe = $autosubscribe;
+                $user->subscribe_policy = $subscribe_policy;
 
                 $result = $user->update($original);
 
@@ -345,7 +358,7 @@ class ProfilesettingsAction extends SettingsAction
                     common_log_db_error($user, 'UPDATE', __FILE__);
                     // TRANS: Server error thrown when user profile settings could not be updated to
                     // TRANS: automatically subscribe to any subscriber.
-                    $this->serverError(_('Could not update user for autosubscribe.'));
+                    $this->serverError(_('Could not update user for autosubscribe or subscribe_policy.'));
                     return;
                 }
             }
index 48b36cae2deab5a8cc27a06c50cf98529fd2ac96..acf3a13957408ff4ac59db6cfdf0aab4594f2af1 100644 (file)
@@ -56,6 +56,71 @@ class Group_join_queue extends Managed_DataObject
         return $rq;
     }
 
+    function getMember()
+    {
+        $member = Profile::staticGet('id', $this->profile_id);
+
+        if (empty($member)) {
+            // TRANS: Exception thrown providing an invalid profile ID.
+            // TRANS: %s is the invalid profile ID.
+            throw new Exception(sprintf(_("Profile ID %s is invalid."),$this->profile_id));
+        }
+
+        return $member;
+    }
+
+    function getGroup()
+    {
+        $group  = User_group::staticGet('id', $this->group_id);
+
+        if (empty($group)) {
+            // TRANS: Exception thrown providing an invalid group ID.
+            // TRANS: %s is the invalid group ID.
+            throw new Exception(sprintf(_("Group ID %s is invalid."),$this->group_id));
+        }
+
+        return $group;
+    }
+
+    /**
+     * Abort the pending group join...
+     *
+     * @param User_group $group
+     */
+    function abort()
+    {
+        $profile = $this->getMember();
+        $group = $this->getGroup();
+        if ($request) {
+            if (Event::handle('StartCancelJoinGroup', array($profile, $group))) {
+                $this->delete();
+                Event::handle('EndCancelJoinGroup', array($profile, $group));
+            }
+        }
+    }
+
+    /**
+     * Complete a pending group join...
+     *
+     * @return Group_member object on success
+     */
+    function complete(User_group $group)
+    {
+        $join = null;
+        $profile = $this->getMember();
+        $group = $this->getGroup();
+        if (Event::handle('StartJoinGroup', array($profile, $group))) {
+            $join = Group_member::join($group->id, $profile->id);
+            $this->delete();
+            Event::handle('EndJoinGroup', array($profile, $group));
+        }
+        if (!$join) {
+            throw new Exception('Internal error: group join failed.');
+        }
+        $join->notify();
+        return $join;
+    }
+
     /**
      * Send notifications via email etc to group administrators about
      * this exciting new pending moderation queue item!
index 9a145a001843269517dfb5f494a257c4a7ea7b45..98fe9ede2facf0bcf7fc700291ed1e534f7cf84c 100644 (file)
@@ -297,49 +297,6 @@ class Profile extends Memcached_DataObject
         return $join;
     }
 
-    /**
-     * Cancel a pending group join...
-     *
-     * @param User_group $group
-     */
-    function cancelJoinGroup(User_group $group)
-    {
-        $request = Group_join_queue::pkeyGet(array('profile_id' => $this->id,
-                                                   'group_id' => $group->id));
-        if ($request) {
-            if (Event::handle('StartCancelJoinGroup', array($group, $this))) {
-                $request->delete();
-                Event::handle('EndCancelJoinGroup', array($group, $this));
-            }
-        }
-    }
-
-    /**
-     * Complete a pending group join on our end...
-     *
-     * @param User_group $group
-     */
-    function completeJoinGroup(User_group $group)
-    {
-        $join = null;
-        $request = Group_join_queue::pkeyGet(array('profile_id' => $this->id,
-                                                   'group_id' => $group->id));
-        if ($request) {
-            if (Event::handle('StartJoinGroup', array($group, $this))) {
-                $join = Group_member::join($group->id, $this->id);
-                $request->delete();
-                Event::handle('EndJoinGroup', array($group, $this));
-            }
-        } else {
-            // TRANS: Exception thrown trying to approve a non-existing group join request.
-            throw new Exception(_('Invalid group join approval: not pending.'));
-        }
-        if ($join) {
-            $join->notify();
-        }
-        return $join;
-    }
-
     /**
      * Leave a group that this profile is a member of.
      *
@@ -363,47 +320,6 @@ class Profile extends Memcached_DataObject
         }
     }
 
-    /**
-     * Request a subscription to another local or remote profile.
-     * This will result in either the subscription going through
-     * immediately, being queued for approval, or being rejected
-     * immediately.
-     *
-     * @param Profile $profile
-     * @return mixed: Subscription or Subscription_queue object on success
-     * @throws Exception of various types on invalid state
-     */
-    function subscribe($profile)
-    {
-        //
-    }
-
-    /**
-     * Cancel an outstanding subscription request to the other profile.
-     *
-     * @param Profile $profile
-     */
-    function cancelSubscribe($profile)
-    {
-        $request = Subscribe_join_queue::pkeyGet(array('subscriber' => $this->id,
-                                                       'subscribed' => $profile->id));
-        if ($request) {
-            if (Event::handle('StartCancelSubscription', array($this, $profile))) {
-                $request->delete();
-                Event::handle('EndCancelSubscription', array($this, $profile));
-            }
-        }
-    }
-
-    /**
-     *
-     * @param <type> $profile 
-     */
-    function completeSubscribe($profile)
-    {
-
-    }
-
     function getSubscriptions($offset=0, $limit=null)
     {
         $subs = Subscription::bySubscriber($this->id,
index 797e6fef1c30bf880bc4cef7ac61bc76f3deb738..70d351a0f75af3ab3349c8c27346e34328c1acdb 100644 (file)
@@ -27,6 +27,7 @@ require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
 class Subscription extends Memcached_DataObject
 {
     const CACHE_WINDOW = 201;
+    const FORCE = true;
 
     ###START_AUTOCODE
     /* the code below is auto generated do not remove the above tag */
@@ -58,11 +59,12 @@ class Subscription extends Memcached_DataObject
      *
      * @param Profile $subscriber party to receive new notices
      * @param Profile $other      party sending notices; publisher
+     * @param bool    $force      pass Subscription::FORCE to override local subscription approval
      *
-     * @return Subscription new subscription
+     * @return mixed Subscription or Subscription_queue: new subscription info
      */
 
-    static function start($subscriber, $other)
+    static function start($subscriber, $other, $force=false)
     {
         // @fixme should we enforce this as profiles in callers instead?
         if ($subscriber instanceof User) {
@@ -88,28 +90,32 @@ class Subscription extends Memcached_DataObject
         }
 
         if (Event::handle('StartSubscribe', array($subscriber, $other))) {
-            $sub = self::saveNew($subscriber->id, $other->id);
-            $sub->notify();
-
-            self::blow('user:notices_with_friends:%d', $subscriber->id);
-
-            self::blow('subscription:by-subscriber:'.$subscriber->id);
-            self::blow('subscription:by-subscribed:'.$other->id);
-
-            $subscriber->blowSubscriptionCount();
-            $other->blowSubscriberCount();
-
             $otherUser = User::staticGet('id', $other->id);
-
-            if (!empty($otherUser) &&
-                $otherUser->autosubscribe &&
-                !self::exists($other, $subscriber) &&
-                !$subscriber->hasBlocked($other)) {
-
-                try {
-                    self::start($other, $subscriber);
-                } catch (Exception $e) {
-                    common_log(LOG_ERR, "Exception during autosubscribe of {$other->nickname} to profile {$subscriber->id}: {$e->getMessage()}");
+            if ($otherUser && $otherUser->subscribe_policy == User::SUBSCRIBE_POLICY_MODERATE && !$force) {
+                $sub = Subscription_queue::saveNew($subscriber, $other);
+                $sub->notify();
+            } else {
+                $sub = self::saveNew($subscriber->id, $other->id);
+                $sub->notify();
+
+                self::blow('user:notices_with_friends:%d', $subscriber->id);
+
+                self::blow('subscription:by-subscriber:'.$subscriber->id);
+                self::blow('subscription:by-subscribed:'.$other->id);
+
+                $subscriber->blowSubscriptionCount();
+                $other->blowSubscriberCount();
+
+                if (!empty($otherUser) &&
+                    $otherUser->autosubscribe &&
+                    !self::exists($other, $subscriber) &&
+                    !$subscriber->hasBlocked($other)) {
+
+                    try {
+                        self::start($other, $subscriber);
+                    } catch (Exception $e) {
+                        common_log(LOG_ERR, "Exception during autosubscribe of {$other->nickname} to profile {$subscriber->id}: {$e->getMessage()}");
+                    }
                 }
             }
 
index 6bf4a681b2d56a522f51d770d495b90264bfb81c..e7572ae7258654ad6681e448cf01ad31f38d559f 100644 (file)
@@ -56,6 +56,35 @@ class Subscription_queue extends Managed_DataObject
         return $rq;
     }
 
+    /**
+     * Complete a pending subscription, as we've got approval of some sort.
+     *
+     * @return Subscription
+     */
+    public function complete()
+    {
+        $subscriber = Profile::staticGet('id', $this->subscriber);
+        $subscribed = Profile::staticGet('id', $this->subscribed);
+        $sub = Subscription::start($subscriber, $other, Subscription::FORCE);
+        if ($sub) {
+            $this->delete();
+        }
+        return $sub;
+    }
+
+    /**
+     * Cancel an outstanding subscription request to the other profile.
+     */
+    public function abort($profile)
+    {
+        $subscriber = Profile::staticGet('id', $this->subscriber);
+        $subscribed = Profile::staticGet('id', $this->subscribed);
+        if (Event::handle('StartCancelSubscription', array($subscriber, $subscribed))) {
+            $this->delete();
+            Event::handle('EndCancelSubscription', array($subscriber, $subscribed));
+        }
+    }
+
     /**
      * Send notifications via email etc to group administrators about
      * this exciting new pending moderation queue item!
index 1a3a7dfd72246d107103361f8f471cda441b35d6..5945456b1814b4002466049e5179526c526f6340 100644 (file)
@@ -30,6 +30,9 @@ require_once 'Validate.php';
 
 class User extends Memcached_DataObject
 {
+    const SUBSCRIBE_POLICY_OPEN = 0;
+    const SUBSCRIBE_POLICY_MODERATE = 1;
+
     ###START_AUTOCODE
     /* the code below is auto generated do not remove the above tag */
 
@@ -55,6 +58,7 @@ class User extends Memcached_DataObject
     public $smsemail;                        // varchar(255)
     public $uri;                             // varchar(255)  unique_key
     public $autosubscribe;                   // tinyint(1)
+    public $subscribe_policy;                // tinyint(1)
     public $urlshorteningservice;            // varchar(50)   default_ur1.ca
     public $inboxed;                         // tinyint(1)
     public $design_id;                       // int(4)
index f648fb3fbf183a30951ea091efd18155bc9d76dc..ab2c3d02ef60144a68f62f67babfe7af4097e286 100644 (file)
@@ -590,6 +590,7 @@ smsreplies = 17
 smsemail = 2
 uri = 2
 autosubscribe = 17
+subscribe_policy = 17
 urlshorteningservice = 2
 inboxed = 17
 design_id = 1
index dfba0f8cd4d11ee1caeaf68a9dab33b35b673e13..f44a85cad7efd2e16f3d8f45b8ec29db47d3fb2a 100644 (file)
@@ -118,6 +118,7 @@ $schema['user'] = array(
         'smsemail' => array('type' => 'varchar', 'length' => 255, 'description' => 'built from sms and carrier'),
         'uri' => array('type' => 'varchar', 'length' => 255, 'description' => 'universally unique identifier, usually a tag URI'),
         'autosubscribe' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'automatically subscribe to users who subscribe to us'),
+        'subscribe_policy' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => '0 = anybody can subscribe; 1 = require approval'),
         'urlshorteningservice' => array('type' => 'varchar', 'length' => 50, 'default' => 'internal', 'description' => 'service to use for auto-shortening URLs'),
         'inboxed' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'has an inbox been created for this user?'),
         'design_id' => array('type' => 'int', 'description' => 'id of a design'),