Work in progress: subscription approval policy field in place on user, hooked up to settings. Queue not 100% tidied up, no UI for queue or management yet.
This commit is contained in:
parent
11b40ddb1b
commit
df5def8ce4
|
@ -152,9 +152,9 @@ class ApprovegroupAction extends Action
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ($this->approve) {
|
if ($this->approve) {
|
||||||
$this->profile->completeJoinGroup($this->group);
|
$this->request->complete();
|
||||||
} elseif ($this->cancel) {
|
} elseif ($this->cancel) {
|
||||||
$this->profile->cancelJoinGroup($this->group);
|
$this->request->abort();
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
common_log(LOG_ERROR, "Exception canceling group sub: " . $e->getMessage());
|
common_log(LOG_ERROR, "Exception canceling group sub: " . $e->getMessage());
|
||||||
|
|
|
@ -139,7 +139,7 @@ class CancelgroupAction extends Action
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->profile->cancelJoinGroup($this->group);
|
$this->request->abort();
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
common_log(LOG_ERROR, "Exception canceling group sub: " . $e->getMessage());
|
common_log(LOG_ERROR, "Exception canceling group sub: " . $e->getMessage());
|
||||||
// TRANS: Server error displayed when cancelling a queued group join request fails.
|
// TRANS: Server error displayed when cancelling a queued group join request fails.
|
||||||
|
|
|
@ -192,6 +192,17 @@ class ProfilesettingsAction extends SettingsAction
|
||||||
($this->arg('autosubscribe')) ?
|
($this->arg('autosubscribe')) ?
|
||||||
$this->boolean('autosubscribe') : $user->autosubscribe);
|
$this->boolean('autosubscribe') : $user->autosubscribe);
|
||||||
$this->elementEnd('li');
|
$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');
|
$this->elementEnd('ul');
|
||||||
// TRANS: Button to save input in profile settings.
|
// TRANS: Button to save input in profile settings.
|
||||||
|
@ -234,6 +245,7 @@ class ProfilesettingsAction extends SettingsAction
|
||||||
$bio = $this->trimmed('bio');
|
$bio = $this->trimmed('bio');
|
||||||
$location = $this->trimmed('location');
|
$location = $this->trimmed('location');
|
||||||
$autosubscribe = $this->boolean('autosubscribe');
|
$autosubscribe = $this->boolean('autosubscribe');
|
||||||
|
$subscribe_policy = $this->trimmed('subscribe_policy');
|
||||||
$language = $this->trimmed('language');
|
$language = $this->trimmed('language');
|
||||||
$timezone = $this->trimmed('timezone');
|
$timezone = $this->trimmed('timezone');
|
||||||
$tagstring = $this->trimmed('tags');
|
$tagstring = $this->trimmed('tags');
|
||||||
|
@ -333,11 +345,12 @@ class ProfilesettingsAction extends SettingsAction
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: XOR
|
// XXX: XOR
|
||||||
if ($user->autosubscribe ^ $autosubscribe) {
|
if (($user->autosubscribe ^ $autosubscribe) || $user->subscribe_policy != $subscribe_policy) {
|
||||||
|
|
||||||
$original = clone($user);
|
$original = clone($user);
|
||||||
|
|
||||||
$user->autosubscribe = $autosubscribe;
|
$user->autosubscribe = $autosubscribe;
|
||||||
|
$user->subscribe_policy = $subscribe_policy;
|
||||||
|
|
||||||
$result = $user->update($original);
|
$result = $user->update($original);
|
||||||
|
|
||||||
|
@ -345,7 +358,7 @@ class ProfilesettingsAction extends SettingsAction
|
||||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||||
// TRANS: Server error thrown when user profile settings could not be updated to
|
// TRANS: Server error thrown when user profile settings could not be updated to
|
||||||
// TRANS: automatically subscribe to any subscriber.
|
// 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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,71 @@ class Group_join_queue extends Managed_DataObject
|
||||||
return $rq;
|
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
|
* Send notifications via email etc to group administrators about
|
||||||
* this exciting new pending moderation queue item!
|
* this exciting new pending moderation queue item!
|
||||||
|
|
|
@ -297,49 +297,6 @@ class Profile extends Memcached_DataObject
|
||||||
return $join;
|
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.
|
* 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)
|
function getSubscriptions($offset=0, $limit=null)
|
||||||
{
|
{
|
||||||
$subs = Subscription::bySubscriber($this->id,
|
$subs = Subscription::bySubscriber($this->id,
|
||||||
|
|
|
@ -27,6 +27,7 @@ require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
||||||
class Subscription extends Memcached_DataObject
|
class Subscription extends Memcached_DataObject
|
||||||
{
|
{
|
||||||
const CACHE_WINDOW = 201;
|
const CACHE_WINDOW = 201;
|
||||||
|
const FORCE = true;
|
||||||
|
|
||||||
###START_AUTOCODE
|
###START_AUTOCODE
|
||||||
/* the code below is auto generated do not remove the above tag */
|
/* the code below is auto generated do not remove the above tag */
|
||||||
|
@ -58,11 +59,12 @@ class Subscription extends Memcached_DataObject
|
||||||
*
|
*
|
||||||
* @param Profile $subscriber party to receive new notices
|
* @param Profile $subscriber party to receive new notices
|
||||||
* @param Profile $other party sending notices; publisher
|
* @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?
|
// @fixme should we enforce this as profiles in callers instead?
|
||||||
if ($subscriber instanceof User) {
|
if ($subscriber instanceof User) {
|
||||||
|
@ -88,6 +90,11 @@ class Subscription extends Memcached_DataObject
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Event::handle('StartSubscribe', array($subscriber, $other))) {
|
if (Event::handle('StartSubscribe', array($subscriber, $other))) {
|
||||||
|
$otherUser = User::staticGet('id', $other->id);
|
||||||
|
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 = self::saveNew($subscriber->id, $other->id);
|
||||||
$sub->notify();
|
$sub->notify();
|
||||||
|
|
||||||
|
@ -99,8 +106,6 @@ class Subscription extends Memcached_DataObject
|
||||||
$subscriber->blowSubscriptionCount();
|
$subscriber->blowSubscriptionCount();
|
||||||
$other->blowSubscriberCount();
|
$other->blowSubscriberCount();
|
||||||
|
|
||||||
$otherUser = User::staticGet('id', $other->id);
|
|
||||||
|
|
||||||
if (!empty($otherUser) &&
|
if (!empty($otherUser) &&
|
||||||
$otherUser->autosubscribe &&
|
$otherUser->autosubscribe &&
|
||||||
!self::exists($other, $subscriber) &&
|
!self::exists($other, $subscriber) &&
|
||||||
|
@ -112,6 +117,7 @@ class Subscription extends Memcached_DataObject
|
||||||
common_log(LOG_ERR, "Exception during autosubscribe of {$other->nickname} to profile {$subscriber->id}: {$e->getMessage()}");
|
common_log(LOG_ERR, "Exception during autosubscribe of {$other->nickname} to profile {$subscriber->id}: {$e->getMessage()}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Event::handle('EndSubscribe', array($subscriber, $other));
|
Event::handle('EndSubscribe', array($subscriber, $other));
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,35 @@ class Subscription_queue extends Managed_DataObject
|
||||||
return $rq;
|
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
|
* Send notifications via email etc to group administrators about
|
||||||
* this exciting new pending moderation queue item!
|
* this exciting new pending moderation queue item!
|
||||||
|
|
|
@ -30,6 +30,9 @@ require_once 'Validate.php';
|
||||||
|
|
||||||
class User extends Memcached_DataObject
|
class User extends Memcached_DataObject
|
||||||
{
|
{
|
||||||
|
const SUBSCRIBE_POLICY_OPEN = 0;
|
||||||
|
const SUBSCRIBE_POLICY_MODERATE = 1;
|
||||||
|
|
||||||
###START_AUTOCODE
|
###START_AUTOCODE
|
||||||
/* the code below is auto generated do not remove the above tag */
|
/* the code below is auto generated do not remove the above tag */
|
||||||
|
|
||||||
|
@ -55,6 +58,7 @@ class User extends Memcached_DataObject
|
||||||
public $smsemail; // varchar(255)
|
public $smsemail; // varchar(255)
|
||||||
public $uri; // varchar(255) unique_key
|
public $uri; // varchar(255) unique_key
|
||||||
public $autosubscribe; // tinyint(1)
|
public $autosubscribe; // tinyint(1)
|
||||||
|
public $subscribe_policy; // tinyint(1)
|
||||||
public $urlshorteningservice; // varchar(50) default_ur1.ca
|
public $urlshorteningservice; // varchar(50) default_ur1.ca
|
||||||
public $inboxed; // tinyint(1)
|
public $inboxed; // tinyint(1)
|
||||||
public $design_id; // int(4)
|
public $design_id; // int(4)
|
||||||
|
|
|
@ -590,6 +590,7 @@ smsreplies = 17
|
||||||
smsemail = 2
|
smsemail = 2
|
||||||
uri = 2
|
uri = 2
|
||||||
autosubscribe = 17
|
autosubscribe = 17
|
||||||
|
subscribe_policy = 17
|
||||||
urlshorteningservice = 2
|
urlshorteningservice = 2
|
||||||
inboxed = 17
|
inboxed = 17
|
||||||
design_id = 1
|
design_id = 1
|
||||||
|
|
|
@ -118,6 +118,7 @@ $schema['user'] = array(
|
||||||
'smsemail' => array('type' => 'varchar', 'length' => 255, 'description' => 'built from sms and carrier'),
|
'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'),
|
'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'),
|
'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'),
|
'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?'),
|
'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'),
|
'design_id' => array('type' => 'int', 'description' => 'id of a design'),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user