]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
More modern coding, stuff related to subscriptions
authorMikael Nordfeldth <mmn@hethane.se>
Mon, 5 May 2014 21:57:41 +0000 (23:57 +0200)
committerMikael Nordfeldth <mmn@hethane.se>
Mon, 5 May 2014 21:58:05 +0000 (23:58 +0200)
Also trying to use the newly implemented AlreadyFulfilledException

classes/Subscription.php
classes/Subscription_queue.php
plugins/OStatus/actions/salmon.php [deleted file]
plugins/OStatus/actions/usersalmon.php
plugins/OStatus/lib/salmonaction.php [new file with mode: 0644]

index 4f27537f278ff205260c71c36e7a2b215eb72adf..12f4e86f10bf3009ee93a3f9af0bbf6dfcecf1ae 100644 (file)
  * 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
@@ -88,7 +83,7 @@ class Subscription extends Managed_DataObject
 
         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)) {
@@ -98,7 +93,7 @@ class Subscription extends Managed_DataObject
 
         if (Event::handle('StartSubscribe', array($subscriber, $other))) {
             $otherUser = User::getKV('id', $other->id);
-            if ($otherUser && $otherUser->subscribe_policy == User::SUBSCRIBE_POLICY_MODERATE && !$force) {
+            if ($otherUser instanceof User && $otherUser->subscribe_policy == User::SUBSCRIBE_POLICY_MODERATE && !$force) {
                 $sub = Subscription_queue::saveNew($subscriber, $other);
                 $sub->notify();
             } else {
@@ -113,13 +108,16 @@ class Subscription extends Managed_DataObject
                 $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()}");
                     }
@@ -151,7 +149,7 @@ class Subscription extends Managed_DataObject
 
         $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.'));
@@ -173,7 +171,7 @@ class Subscription extends Managed_DataObject
     {
         $subscribedUser = User::getKV('id', $this->subscribed);
 
-        if (!empty($subscribedUser)) {
+        if ($subscribedUser instanceof User) {
 
             $subscriber = Profile::getKV('id', $this->subscriber);
 
@@ -189,7 +187,7 @@ class Subscription extends Managed_DataObject
     {
         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
@@ -234,7 +232,7 @@ class Subscription extends Managed_DataObject
     {
         $sub = Subscription::pkeyGet(array('subscriber' => $subscriber->id,
                                            'subscribed' => $other->id));
-        return (empty($sub)) ? false : true;
+        return ($sub instanceof Subscription);
     }
 
     function asActivity()
@@ -242,12 +240,12 @@ class Subscription extends Managed_DataObject
         $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));
+        if (!$subscriber instanceof Profile) {
+            throw new NoProfileException($this->subscriber);
         }
 
-        if (empty($subscribed)) {
-            throw new Exception(sprintf(_('No profile for the subscribed: %d'), $this->subscribed));
+        if (!$subscribed instanceof Profile) {
+            throw new NoProfileException($this->subscribed);
         }
 
         $act = new Activity();
index ea0e906d43fca01c1208eeafc1508fc556d135ab..405eca93fd0f7309ffdd6c5e78b1375c2918120e 100644 (file)
@@ -1,22 +1,18 @@
 <?php
+
+if (!defined('GNUSOCIAL')) { exit(1); }
+
 /**
  * Table Definition for subscription_queue
  */
-require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
 
 class Subscription_queue extends Managed_DataObject
 {
-    ###START_AUTOCODE
-    /* the code below is auto generated do not remove the above tag */
-
     public $__table = 'subscription_queue';       // table name
     public $subscriber;
     public $subscribed;
     public $created;
 
-    /* the code above is auto generated do not remove the tag below */
-    ###END_AUTOCODE
-
     public static function schemaDef()
     {
         return array(
@@ -48,11 +44,11 @@ class Subscription_queue extends Managed_DataObject
         return $rq;
     }
 
-    function exists($subscriber, $other)
+    public function exists(Profile $subscriber, Profile $other)
     {
         $sub = Subscription_queue::pkeyGet(array('subscriber' => $subscriber->id,
                                                  'subscribed' => $other->id));
-        return (empty($sub)) ? false : true;
+        return ($sub instanceof Subscription_queue);
     }
 
     /**
@@ -64,9 +60,11 @@ class Subscription_queue extends Managed_DataObject
     {
         $subscriber = Profile::getKV('id', $this->subscriber);
         $subscribed = Profile::getKV('id', $this->subscribed);
-        $sub = Subscription::start($subscriber, $subscribed, Subscription::FORCE);
-        if ($sub) {
+        try {
+            $sub = Subscription::start($subscriber, $subscribed, Subscription::FORCE);
             $this->delete();
+        } catch (AlreadyFulfilledException $e) {
+            common_debug('Tried to start a subscription which already existed.');
         }
         return $sub;
     }
diff --git a/plugins/OStatus/actions/salmon.php b/plugins/OStatus/actions/salmon.php
deleted file mode 100644 (file)
index 2a6fc15..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-<?php
-/*
- * StatusNet - the distributed open-source microblogging tool
- * Copyright (C) 2010, StatusNet, 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/>.
- */
-
-/**
- * @package OStatusPlugin
- * @author James Walker <james@status.net>
- */
-
-if (!defined('GNUSOCIAL')) { exit(1); }
-
-class SalmonAction extends Action
-{
-    var $xml      = null;
-    var $activity = null;
-    var $target   = null;
-
-    protected function prepare(array $args=array())
-    {
-        StatusNet::setApi(true); // Send smaller error pages
-
-        parent::prepare($args);
-
-        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
-            // TRANS: Client error. POST is a HTTP command. It should not be translated.
-            $this->clientError(_m('This method requires a POST.'));
-        }
-
-        if (empty($_SERVER['CONTENT_TYPE']) || $_SERVER['CONTENT_TYPE'] != 'application/magic-envelope+xml') {
-            // TRANS: Client error. Do not translate "application/magic-envelope+xml".
-            $this->clientError(_m('Salmon requires "application/magic-envelope+xml".'));
-        }
-
-        $xml = file_get_contents('php://input');
-
-        // Check the signature
-        $salmon = new Salmon;
-        if (!$salmon->verifyMagicEnv($xml)) {
-            common_log(LOG_DEBUG, "Salmon signature verification failed.");
-            // TRANS: Client error.
-            $this->clientError(_m('Salmon signature verification failed.'));
-        } else {
-            $magic_env = new MagicEnvelope();
-            $env = $magic_env->parse($xml);
-            $xml = $magic_env->unfold($env);
-        }
-
-        $dom = DOMDocument::loadXML($xml);
-        if ($dom->documentElement->namespaceURI != Activity::ATOM ||
-            $dom->documentElement->localName != 'entry') {
-            common_log(LOG_DEBUG, "Got invalid Salmon post: $xml");
-            // TRANS: Client error.
-            $this->clientError(_m('Salmon post must be an Atom entry.'));
-        }
-
-        $this->activity = new Activity($dom->documentElement);
-        return true;
-    }
-
-    /**
-     * Check the posted activity type and break out to appropriate processing.
-     */
-
-    protected function handle()
-    {
-        parent::handle();
-
-        common_log(LOG_DEBUG, "Got a " . $this->activity->verb);
-        if (Event::handle('StartHandleSalmonTarget', array($this->activity, $this->target)) &&
-            Event::handle('StartHandleSalmon', array($this->activity))) {
-            switch ($this->activity->verb)
-            {
-            case ActivityVerb::POST:
-                $this->handlePost();
-                break;
-            case ActivityVerb::SHARE:
-                $this->handleShare();
-                break;
-            case ActivityVerb::FAVORITE:
-                $this->handleFavorite();
-                break;
-            case ActivityVerb::UNFAVORITE:
-                $this->handleUnfavorite();
-                break;
-            case ActivityVerb::FOLLOW:
-            case ActivityVerb::FRIEND:
-                $this->handleFollow();
-                break;
-            case ActivityVerb::UNFOLLOW:
-                $this->handleUnfollow();
-                break;
-            case ActivityVerb::JOIN:
-                $this->handleJoin();
-                break;
-            case ActivityVerb::LEAVE:
-                $this->handleLeave();
-                break;
-            case ActivityVerb::TAG:
-                $this->handleTag();
-                break;
-            case ActivityVerb::UNTAG:
-                $this->handleUntag();
-                break;
-            case ActivityVerb::UPDATE_PROFILE:
-                $this->handleUpdateProfile();
-                break;
-            default:
-                // TRANS: Client exception.
-                throw new ClientException(_m('Unrecognized activity type.'));
-            }
-            Event::handle('EndHandleSalmon', array($this->activity));
-            Event::handle('EndHandleSalmonTarget', array($this->activity, $this->target));
-        }
-    }
-
-    function handlePost()
-    {
-        // TRANS: Client exception.
-        throw new ClientException(_m('This target does not understand posts.'));
-    }
-
-    function handleFollow()
-    {
-        // TRANS: Client exception.
-        throw new ClientException(_m('This target does not understand follows.'));
-    }
-
-    function handleUnfollow()
-    {
-        // TRANS: Client exception.
-        throw new ClientException(_m('This target does not understand unfollows.'));
-    }
-
-    function handleFavorite()
-    {
-        // TRANS: Client exception.
-        throw new ClientException(_m('This target does not understand favorites.'));
-    }
-
-    function handleUnfavorite()
-    {
-        // TRANS: Client exception.
-        throw new ClientException(_m('This target does not understand unfavorites.'));
-    }
-
-    function handleShare()
-    {
-        // TRANS: Client exception.
-        throw new ClientException(_m('This target does not understand share events.'));
-    }
-
-    function handleJoin()
-    {
-        // TRANS: Client exception.
-        throw new ClientException(_m('This target does not understand joins.'));
-    }
-
-    function handleLeave()
-    {
-        // TRANS: Client exception.
-        throw new ClientException(_m('This target does not understand leave events.'));
-    }
-
-    function handleTag()
-    {
-        // TRANS: Client exception.
-        throw new ClientException(_m('This target does not understand list events.'));
-    }
-
-    function handleUntag()
-    {
-        // TRANS: Client exception.
-        throw new ClientException(_m('This target does not understand unlist events.'));
-    }
-
-    /**
-     * Remote user sent us an update to their profile.
-     * If we already know them, accept the updates.
-     */
-    function handleUpdateProfile()
-    {
-        $oprofile = Ostatus_profile::getActorProfile($this->activity);
-        if ($oprofile) {
-            common_log(LOG_INFO, "Got a profile-update ping from $oprofile->uri");
-            $oprofile->updateFromActivityObject($this->activity->actor);
-        } else {
-            common_log(LOG_INFO, "Ignoring profile-update ping from unknown " . $this->activity->actor->id);
-        }
-    }
-
-    /**
-     * @return Ostatus_profile
-     */
-    function ensureProfile()
-    {
-        $actor = $this->activity->actor;
-        if (empty($actor->id)) {
-            common_log(LOG_ERR, "broken actor: " . var_export($actor, true));
-            common_log(LOG_ERR, "activity with no actor: " . var_export($this->activity, true));
-            // TRANS: Exception.
-            throw new Exception(_m('Received a salmon slap from unidentified actor.'));
-        }
-
-        return Ostatus_profile::ensureActivityObjectProfile($actor);
-    }
-
-    function saveNotice()
-    {
-        $oprofile = $this->ensureProfile();
-        return $oprofile->processPost($this->activity, 'salmon');
-    }
-}
index 40577a7d6e1688d7acb707d15baee9fa03d7ffdc..550c034e4921f8870a93cfaff178f8d2448bda2a 100644 (file)
@@ -134,7 +134,11 @@ class UsersalmonAction extends SalmonAction
         $oprofile = $this->ensureProfile();
         if ($oprofile instanceof Ostatus_profile) {
             common_log(LOG_INFO, sprintf('Canceling subscription from remote %s to local %s', $oprofile->getUri(), $this->user->getNickname()));
-            Subscription::cancel($oprofile->localProfile(), $this->user->getProfile());
+            try {
+                Subscription::cancel($oprofile->localProfile(), $this->user->getProfile());
+            } catch (AlreadyFulfilledException $e) {
+                common_debug('Subscription did not exist, so there was nothing to cancel');
+            }
         } else {
             common_log(LOG_ERR, "Can't cancel subscription from remote, didn't find the profile");
         }
diff --git a/plugins/OStatus/lib/salmonaction.php b/plugins/OStatus/lib/salmonaction.php
new file mode 100644 (file)
index 0000000..af6aaaa
--- /dev/null
@@ -0,0 +1,227 @@
+<?php
+/*
+ * StatusNet - the distributed open-source microblogging tool
+ * Copyright (C) 2010, StatusNet, 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/>.
+ */
+
+/**
+ * @package OStatusPlugin
+ * @author James Walker <james@status.net>
+ */
+
+if (!defined('GNUSOCIAL')) { exit(1); }
+
+class SalmonAction extends Action
+{
+    var $xml      = null;
+    var $activity = null;
+    var $target   = null;
+
+    protected function prepare(array $args=array())
+    {
+        StatusNet::setApi(true); // Send smaller error pages
+
+        parent::prepare($args);
+
+        if ($_SERVER['REQUEST_METHOD'] != 'POST') {
+            // TRANS: Client error. POST is a HTTP command. It should not be translated.
+            $this->clientError(_m('This method requires a POST.'));
+        }
+
+        if (empty($_SERVER['CONTENT_TYPE']) || $_SERVER['CONTENT_TYPE'] != 'application/magic-envelope+xml') {
+            // TRANS: Client error. Do not translate "application/magic-envelope+xml".
+            $this->clientError(_m('Salmon requires "application/magic-envelope+xml".'));
+        }
+
+        $xml = file_get_contents('php://input');
+
+        // Check the signature
+        $salmon = new Salmon;
+        if (!$salmon->verifyMagicEnv($xml)) {
+            common_log(LOG_DEBUG, "Salmon signature verification failed.");
+            // TRANS: Client error.
+            $this->clientError(_m('Salmon signature verification failed.'));
+        } else {
+            $magic_env = new MagicEnvelope();
+            $env = $magic_env->parse($xml);
+            $xml = $magic_env->unfold($env);
+        }
+
+        $dom = DOMDocument::loadXML($xml);
+        if ($dom->documentElement->namespaceURI != Activity::ATOM ||
+            $dom->documentElement->localName != 'entry') {
+            common_log(LOG_DEBUG, "Got invalid Salmon post: $xml");
+            // TRANS: Client error.
+            $this->clientError(_m('Salmon post must be an Atom entry.'));
+        }
+
+        $this->activity = new Activity($dom->documentElement);
+        return true;
+    }
+
+    /**
+     * Check the posted activity type and break out to appropriate processing.
+     */
+
+    protected function handle()
+    {
+        parent::handle();
+
+        common_log(LOG_DEBUG, "Got a " . $this->activity->verb);
+        if (Event::handle('StartHandleSalmonTarget', array($this->activity, $this->target)) &&
+            Event::handle('StartHandleSalmon', array($this->activity))) {
+            switch ($this->activity->verb)
+            {
+            case ActivityVerb::POST:
+                $this->handlePost();
+                break;
+            case ActivityVerb::SHARE:
+                $this->handleShare();
+                break;
+            case ActivityVerb::FAVORITE:
+                $this->handleFavorite();
+                break;
+            case ActivityVerb::UNFAVORITE:
+                $this->handleUnfavorite();
+                break;
+            case ActivityVerb::FOLLOW:
+            case ActivityVerb::FRIEND:
+                $this->handleFollow();
+                break;
+            case ActivityVerb::UNFOLLOW:
+                $this->handleUnfollow();
+                break;
+            case ActivityVerb::JOIN:
+                $this->handleJoin();
+                break;
+            case ActivityVerb::LEAVE:
+                $this->handleLeave();
+                break;
+            case ActivityVerb::TAG:
+                $this->handleTag();
+                break;
+            case ActivityVerb::UNTAG:
+                $this->handleUntag();
+                break;
+            case ActivityVerb::UPDATE_PROFILE:
+                $this->handleUpdateProfile();
+                break;
+            default:
+                // TRANS: Client exception.
+                throw new ClientException(_m('Unrecognized activity type.'));
+            }
+            Event::handle('EndHandleSalmon', array($this->activity));
+            Event::handle('EndHandleSalmonTarget', array($this->activity, $this->target));
+        }
+    }
+
+    function handlePost()
+    {
+        // TRANS: Client exception.
+        throw new ClientException(_m('This target does not understand posts.'));
+    }
+
+    function handleFollow()
+    {
+        // TRANS: Client exception.
+        throw new ClientException(_m('This target does not understand follows.'));
+    }
+
+    function handleUnfollow()
+    {
+        // TRANS: Client exception.
+        throw new ClientException(_m('This target does not understand unfollows.'));
+    }
+
+    function handleFavorite()
+    {
+        // TRANS: Client exception.
+        throw new ClientException(_m('This target does not understand favorites.'));
+    }
+
+    function handleUnfavorite()
+    {
+        // TRANS: Client exception.
+        throw new ClientException(_m('This target does not understand unfavorites.'));
+    }
+
+    function handleShare()
+    {
+        // TRANS: Client exception.
+        throw new ClientException(_m('This target does not understand share events.'));
+    }
+
+    function handleJoin()
+    {
+        // TRANS: Client exception.
+        throw new ClientException(_m('This target does not understand joins.'));
+    }
+
+    function handleLeave()
+    {
+        // TRANS: Client exception.
+        throw new ClientException(_m('This target does not understand leave events.'));
+    }
+
+    function handleTag()
+    {
+        // TRANS: Client exception.
+        throw new ClientException(_m('This target does not understand list events.'));
+    }
+
+    function handleUntag()
+    {
+        // TRANS: Client exception.
+        throw new ClientException(_m('This target does not understand unlist events.'));
+    }
+
+    /**
+     * Remote user sent us an update to their profile.
+     * If we already know them, accept the updates.
+     */
+    function handleUpdateProfile()
+    {
+        $oprofile = Ostatus_profile::getActorProfile($this->activity);
+        if ($oprofile instanceof Ostatus_profile) {
+            common_log(LOG_INFO, "Got a profile-update ping from $oprofile->uri");
+            $oprofile->updateFromActivityObject($this->activity->actor);
+        } else {
+            common_log(LOG_INFO, "Ignoring profile-update ping from unknown " . $this->activity->actor->id);
+        }
+    }
+
+    /**
+     * @return Ostatus_profile
+     */
+    function ensureProfile()
+    {
+        $actor = $this->activity->actor;
+        if (empty($actor->id)) {
+            common_log(LOG_ERR, "broken actor: " . var_export($actor, true));
+            common_log(LOG_ERR, "activity with no actor: " . var_export($this->activity, true));
+            // TRANS: Exception.
+            throw new Exception(_m('Received a salmon slap from unidentified actor.'));
+        }
+
+        return Ostatus_profile::ensureActivityObjectProfile($actor);
+    }
+
+    function saveNotice()
+    {
+        $oprofile = $this->ensureProfile();
+        return $oprofile->processPost($this->activity, 'salmon');
+    }
+}