X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=plugins%2FRSSCloud%2FRSSCloudNotifier.php;h=d454691c80ec5ee028d814505b212aebe776d1b7;hb=57ac912519d861c7764af4eabbc8e07b10e0b6e7;hp=eb3198b5a43e489ae2a2f538a4afe33c68f740e7;hpb=61804bb7bbd0cea92ba2bbcce15e37a35195341a;p=quix0rs-gnu-social.git diff --git a/plugins/RSSCloud/RSSCloudNotifier.php b/plugins/RSSCloud/RSSCloudNotifier.php index eb3198b5a4..d454691c80 100644 --- a/plugins/RSSCloud/RSSCloudNotifier.php +++ b/plugins/RSSCloud/RSSCloudNotifier.php @@ -31,8 +31,29 @@ if (!defined('STATUSNET')) { exit(1); } -class RSSCloudNotifier { +/** + * Class for notifying cloud-enabled RSS aggregators that StatusNet + * feeds have been updated. + * + * @category Plugin + * @package StatusNet + * @author Zach Copley + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + **/ +class RSSCloudNotifier +{ + const MAX_FAILURES = 3; + /** + * Send an HTTP GET to the notification handler with a + * challenge string to see if it repsonds correctly. + * + * @param string $endpoint URL of the notification handler + * @param string $feed the feed being subscribed to + * + * @return boolean success + */ function challenge($endpoint, $feed) { $code = common_confirmation_code(128); @@ -40,10 +61,11 @@ class RSSCloudNotifier { $url = $endpoint . '?' . http_build_query($params); try { - $client = new HTTPClient(); + $client = new HTTPClient(); $response = $client->get($url); } catch (HTTP_Request2_Exception $e) { - common_log(LOG_INFO, 'RSSCloud plugin - failure testing notify handler ' . + common_log(LOG_INFO, + 'RSSCloud plugin - failure testing notify handler ' . $endpoint . ' - ' . $e->getMessage()); return false; } @@ -55,6 +77,11 @@ class RSSCloudNotifier { if ($status >= 200 && $status < 300) { + // NOTE: the spec says that the body must contain the string + // challenge. It doesn't say that the body must contain the + // challenge string ONLY, although that seems to be the way + // the other implementors have interpreted it. + if (strpos($body, $code) !== false) { common_log(LOG_INFO, 'RSSCloud plugin - ' . "success testing notify handler: $endpoint"); @@ -75,13 +102,23 @@ class RSSCloudNotifier { } } - function postUpdate($endpoint, $feed) { + /** + * HTTP POST a notification that a feed has been updated + * ('ping the cloud'). + * + * @param String $endpoint URL of the notification handler + * @param String $feed the feed being subscribed to + * + * @return boolean success + */ + function postUpdate($endpoint, $feed) + { $headers = array(); $postdata = array('url' => $feed); try { - $client = new HTTPClient(); + $client = new HTTPClient(); $response = $client->post($endpoint, $headers, $postdata); } catch (HTTP_Request2_Exception $e) { common_log(LOG_INFO, 'RSSCloud plugin - failure notifying ' . @@ -100,10 +137,104 @@ class RSSCloudNotifier { common_log(LOG_INFO, 'RSSCloud plugin - failure notifying ' . $endpoint . ' that feed ' . $feed . ' has changed: got HTTP ' . $status); - common_debug('body = ' . var_export($response->getBody(), true)); return false; } } + /** + * Notify all subscribers to a profile feed that it has changed. + * + * @param Profile $profile the profile whose feed has been + * updated + * + * @return boolean success + */ + function notify($profile) + { + $feed = common_path('api/statuses/user_timeline/') . + $profile->nickname . '.rss'; + + $cloudSub = new RSSCloudSubscription(); + + $cloudSub->subscribed = $profile->id; + + if ($cloudSub->find()) { + while ($cloudSub->fetch()) { + $result = $this->postUpdate($cloudSub->url, $feed); + if ($result == false) { + $this->handleFailure($cloudSub); + } + } + } + + return true; + } + + /** + * Handle problems posting cloud notifications. Increment the failure + * count, or delete the subscription if the maximum number of failures + * is exceeded. + * + * XXX: Redo with proper DB_DataObject methods once I figure out what + * what the problem is with pluginized DB_DataObjects. -Z + * + * @param RSSCloudSubscription $cloudSub the subscription in question + * + * @return boolean success + */ + function handleFailure($cloudSub) + { + $failCnt = $cloudSub->failures + 1; + + if ($failCnt == self::MAX_FAILURES) { + + common_log(LOG_INFO, + 'Deleting RSSCloud subcription ' . + '(max failure count reached), profile: ' . + $cloudSub->subscribed . + ' handler: ' . + $cloudSub->url); + + // XXX: WTF! ->delete() doesn't work. Clearly, there are some issues with + // the DB_DataObject, or my understanding of it. Have to drop into SQL. + + // $result = $cloudSub->delete(); + + $qry = 'DELETE from rsscloud_subscription' . + ' WHERE subscribed = ' . $cloudSub->subscribed . + ' AND url = \'' . $cloudSub->url . '\''; + + $result = $cloudSub->query($qry); + + if (!$result) { + common_log_db_error($cloudSub, 'DELETE', __FILE__); + common_log(LOG_ERR, 'Could not delete RSSCloud subscription.'); + } + + } else { + + common_debug('Updating failure count on RSSCloud subscription. ' . + $failCnt); + + $failCnt = $cloudSub->failures + 1; + + // XXX: ->update() not working either, gar! + + $qry = 'UPDATE rsscloud_subscription' . + ' SET failures = ' . $failCnt . + ' WHERE subscribed = ' . $cloudSub->subscribed . + ' AND url = \'' . $cloudSub->url . '\''; + + $result = $cloudSub->query($qry); + + if (!$result) { + common_log_db_error($cloudsub, 'UPDATE', __FILE__); + common_log(LOG_ERR, + 'Could not update failure ' . + 'count on RSSCloud subscription'); + } + } + } + }