* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
+if (!defined('GNUSOCIAL')) { exit(1); }
/**
* Table Definition for subscription
*/
-require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
-
class Subscription extends Managed_DataObject
{
const CACHE_WINDOW = 201;
const FORCE = true;
- ###START_AUTOCODE
- /* the code below is auto generated do not remove the above tag */
-
public $__table = 'subscription'; // table name
public $subscriber; // int(4) primary_key not_null
public $subscribed; // int(4) primary_key not_null
public $jabber; // tinyint(1) default_1
public $sms; // tinyint(1) default_1
- public $token; // varchar(255)
- public $secret; // varchar(255)
- public $uri; // varchar(255)
+ public $token; // varchar(191) not 255 because utf8mb4 takes more space
+ public $secret; // varchar(191) not 255 because utf8mb4 takes more space
+ public $uri; // varchar(191) not 255 because utf8mb4 takes more space
public $created; // datetime() not_null
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
'subscribed' => array('type' => 'int', 'not null' => true, 'description' => 'profile being listened to'),
'jabber' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'deliver jabber messages'),
'sms' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'deliver sms messages'),
- 'token' => array('type' => 'varchar', 'length' => 255, 'description' => 'authorization token'),
- 'secret' => array('type' => 'varchar', 'length' => 255, 'description' => 'token secret'),
- 'uri' => array('type' => 'varchar', 'length' => 255, 'description' => 'universally unique identifier'),
+ 'token' => array('type' => 'varchar', 'length' => 191, 'description' => 'authorization token'),
+ 'secret' => array('type' => 'varchar', 'length' => 191, 'description' => 'token secret'),
+ 'uri' => array('type' => 'varchar', 'length' => 191, 'description' => 'universally unique identifier'),
'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
),
if (self::exists($subscriber, $other)) {
// TRANS: Exception thrown when trying to subscribe while already subscribed.
- throw new Exception(_('Already subscribed!'));
+ throw new AlreadyFulfilledException(_('Already subscribed!'));
}
if ($other->hasBlocked($subscriber)) {
}
if (Event::handle('StartSubscribe', array($subscriber, $other))) {
- $otherUser = User::getKV('id', $other->id);
- if ($otherUser && $otherUser->subscribe_policy == User::SUBSCRIBE_POLICY_MODERATE && !$force) {
- $sub = Subscription_queue::saveNew($subscriber, $other);
- $sub->notify();
+ // unless subscription is forced, the user policy for subscription approvals is tested
+ if (!$force && $other->requiresSubscriptionApproval($subscriber)) {
+ try {
+ $sub = Subscription_queue::saveNew($subscriber, $other);
+ $sub->notify();
+ } catch (AlreadyFulfilledException $e) {
+ $sub = Subscription_queue::getSubQueue($subscriber, $other);
+ }
} else {
- $sub = self::saveNew($subscriber->id, $other->id);
+ $otherUser = User::getKV('id', $other->id);
+ $sub = self::saveNew($subscriber, $other);
$sub->notify();
self::blow('user:notices_with_friends:%d', $subscriber->id);
$subscriber->blowSubscriptionCount();
$other->blowSubscriberCount();
- if (!empty($otherUser) &&
+ if ($otherUser instanceof User &&
$otherUser->autosubscribe &&
!self::exists($other, $subscriber) &&
!$subscriber->hasBlocked($other)) {
try {
self::start($other, $subscriber);
+ } catch (AlreadyFulfilledException $e) {
+ // This shouldn't happen due to !self::exists above
+ common_debug('Tried to autosubscribe a user to its new subscriber.');
} catch (Exception $e) {
common_log(LOG_ERR, "Exception during autosubscribe of {$other->nickname} to profile {$subscriber->id}: {$e->getMessage()}");
}
}
}
- Event::handle('EndSubscribe', array($subscriber, $other));
+ if ($sub instanceof Subscription) { // i.e. not Subscription_queue
+ Event::handle('EndSubscribe', array($subscriber, $other));
+ }
}
return $sub;
}
+ static function ensureStart(Profile $subscriber, Profile $other, $force=false)
+ {
+ try {
+ $sub = self::start($subscriber, $other, $force);
+ } catch (AlreadyFulfilledException $e) {
+ return self::getSubscription($subscriber, $other);
+ }
+ return $sub;
+ }
+
/**
* Low-level subscription save.
* Outside callers should use Subscription::start()
*/
- protected function saveNew($subscriber_id, $other_id)
+ protected static function saveNew(Profile $subscriber, Profile $other)
{
$sub = new Subscription();
- $sub->subscriber = $subscriber_id;
- $sub->subscribed = $other_id;
+ $sub->subscriber = $subscriber->getID();
+ $sub->subscribed = $other->getID();
$sub->jabber = 1;
$sub->sms = 1;
$sub->created = common_sql_now();
- $sub->uri = self::newURI($sub->subscriber,
- $sub->subscribed,
+ $sub->uri = self::newUri($subscriber,
+ $other,
$sub->created);
$result = $sub->insert();
- if (!$result) {
+ if ($result===false) {
common_log_db_error($sub, 'INSERT', __FILE__);
// TRANS: Exception thrown when a subscription could not be stored on the server.
throw new Exception(_('Could not save subscription.'));
{
$subscribedUser = User::getKV('id', $this->subscribed);
- if (!empty($subscribedUser)) {
+ if ($subscribedUser instanceof User) {
$subscriber = Profile::getKV('id', $this->subscriber);
{
if (!self::exists($subscriber, $other)) {
// TRANS: Exception thrown when trying to unsibscribe without a subscription.
- throw new Exception(_('Not subscribed!'));
+ throw new AlreadyFulfilledException(_('Not subscribed!'));
}
// Don't allow deleting self subs
static function exists(Profile $subscriber, Profile $other)
{
- $sub = Subscription::pkeyGet(array('subscriber' => $subscriber->id,
- 'subscribed' => $other->id));
- return (empty($sub)) ? false : true;
+ try {
+ $sub = self::getSubscription($subscriber, $other);
+ } catch (NoResultException $e) {
+ return false;
+ }
+
+ return true;
}
- function asActivity()
+ static function getSubscription(Profile $subscriber, Profile $other)
{
- $subscriber = Profile::getKV('id', $this->subscriber);
- $subscribed = Profile::getKV('id', $this->subscribed);
-
- if (empty($subscriber)) {
- throw new Exception(sprintf(_('No profile for the subscriber: %d'), $this->subscriber));
+ // This is essentially a pkeyGet but we have an object to return in NoResultException
+ $sub = new Subscription();
+ $sub->subscriber = $subscriber->id;
+ $sub->subscribed = $other->id;
+ if (!$sub->find(true)) {
+ throw new NoResultException($sub);
}
+ return $sub;
+ }
- if (empty($subscribed)) {
- throw new Exception(sprintf(_('No profile for the subscribed: %d'), $this->subscribed));
- }
+ public function getSubscriber()
+ {
+ return Profile::getByID($this->subscriber);
+ }
+
+ public function getSubscribed()
+ {
+ return Profile::getByID($this->subscribed);
+ }
+
+ function asActivity()
+ {
+ $subscriber = $this->getSubscriber();
+ $subscribed = $this->getSubscribed();
$act = new Activity();
// XXX: rationalize this with the URL
- $act->id = $this->getURI();
+ $act->id = $this->getUri();
$act->time = strtotime($this->created);
// TRANS: Activity title when subscribing to another person.
$subscriber->getBestName(),
$subscribed->getBestName());
- $act->actor = ActivityObject::fromProfile($subscriber);
- $act->objects[] = ActivityObject::fromProfile($subscribed);
+ $act->actor = $subscriber->asActivityObject();
+ $act->objects[] = $subscribed->asActivityObject();
$url = common_local_url('AtomPubShowSubscription',
array('subscriber' => $subscriber->id,
$ids = $sub->fetchAll($get_type);
// If we're simultaneously filling up cache, remember to slice
- if ($offset === 0 && $querylimit === self::CACHE_WINDOW) {
+ if ($queryoffset === 0 && $querylimit === self::CACHE_WINDOW) {
self::cacheSet($cacheKey, $ids);
return array_slice($ids, $offset, $limit);
}
return parent::update($dataObject);
}
- function getURI()
- {
- if (!empty($this->uri)) {
- return $this->uri;
- } else {
- return self::newURI($this->subscriber, $this->subscribed, $this->created);
- }
- }
-
- static function newURI($subscriber_id, $subscribed_id, $created)
+ public function getUri()
{
- return TagURI::mint('follow:%d:%d:%s',
- $subscriber_id,
- $subscribed_id,
- common_date_iso8601($created));
+ return $this->uri ?: self::newUri($this->getSubscriber(), $this->getSubscribed(), $this->created);
}
}