WebSub/PubSubHubbub - Version 1.6.3

Version Description

  • Update hub URL for SuperFeedr (now pubsubhubbub.superfeedr.com)
  • Update credits and documentation
Download this release

Release Info

Developer joshfraz
Plugin Icon 128x128 WebSub/PubSubHubbub
Version 1.6.3
Comparing to
See all releases

Code changes from version 1.0 to 1.6.3

publisher.php DELETED
@@ -1,86 +0,0 @@
1
- <?php
2
-
3
- // a PHP client library for pubsubhubbub
4
- // as defined at http://code.google.com/p/pubsubhubbub/
5
- // written by Josh Fraser | joshfraser.com | joshfraz@gmail.com
6
- // Released under Apache License 2.0
7
-
8
- class Publisher {
9
-
10
- protected $hub_url;
11
- protected $last_response;
12
-
13
- // create a new Publisher
14
- public function __construct($hub_url) {
15
-
16
- if (!isset($hub_url))
17
- throw new Exception('Please specify a hub url');
18
-
19
- if (!preg_match("|^https?://|i",$hub_url))
20
- throw new Exception('The specified hub url does not appear to be valid: '.$hub_url);
21
-
22
- $this->hub_url = $hub_url;
23
- }
24
-
25
- // accepts either a single url or an array of urls
26
- public function publish_update($topic_urls, $http_function = false) {
27
- if (!isset($topic_urls))
28
- throw new Exception('Please specify a topic url');
29
-
30
- // check that we're working with an array
31
- if (!is_array($topic_urls)) {
32
- $topic_urls = array($topic_urls);
33
- }
34
-
35
- // set the mode to publish
36
- $post_string = "hub.mode=publish";
37
- // loop through each topic url
38
- foreach ($topic_urls as $topic_url) {
39
-
40
- // lightweight check that we're actually working w/ a valid url
41
- if (!preg_match("|^https?://|i",$topic_url))
42
- throw new Exception('The specified topic url does not appear to be valid: '.$topic_url);
43
-
44
- // append the topic url parameters
45
- $post_string .= "&hub.url=".urlencode($topic_url);
46
- }
47
-
48
- // make the http post request and return true/false
49
- // easy to over-write to use your own http function
50
- if ($http_function)
51
- return $http_function($this->hub_url,$post_string);
52
- else
53
- return $this->http_post($this->hub_url,$post_string);
54
- }
55
-
56
- // returns any error message from the latest request
57
- public function last_response() {
58
- return $this->last_response;
59
- }
60
-
61
- // default http function that uses curl to post to the hub endpoint
62
- private function http_post($url, $post_string) {
63
-
64
- // add any additional curl options here
65
- $options = array(CURLOPT_URL => $url,
66
- CURLOPT_POST => true,
67
- CURLOPT_POSTFIELDS => $post_string,
68
- CURLOPT_USERAGENT => "PubSubHubbub-Publisher-PHP/1.0");
69
-
70
- $ch = curl_init();
71
- curl_setopt_array($ch, $options);
72
-
73
- $response = curl_exec($ch);
74
- $this->last_response = $response;
75
- $info = curl_getinfo($ch);
76
-
77
- curl_close($ch);
78
-
79
- // all good
80
- if ($info['http_code'] == 204)
81
- return true;
82
- return false;
83
- }
84
- }
85
-
86
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pubsubhubbub-php/publisher.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // a PHP client library for pubsubhubbub
3
+ // as defined at http://code.google.com/p/pubsubhubbub/
4
+ // written by Josh Fraser | joshfraser.com | joshfraz@gmail.com
5
+ // modified by Matthias Pfefferle | notizblog.org | matthias@pfefferle.org
6
+ // Released under Apache License 2.0
7
+
8
+ /**
9
+ * a pubsubhubbub publisher
10
+ *
11
+ * @author Josh Fraser
12
+ * @author Matthias Pfefferle
13
+ */
14
+ class PshbPublisher {
15
+ protected $hub_url;
16
+ protected $last_response;
17
+
18
+ // create a new Publisher
19
+ public function __construct($hub_url) {
20
+
21
+ if (!isset($hub_url))
22
+ throw new Exception('Please specify a hub url');
23
+
24
+ if (!preg_match("|^https?://|i",$hub_url))
25
+ throw new Exception('The specified hub url does not appear to be valid: '.$hub_url);
26
+
27
+ $this->hub_url = $hub_url;
28
+ }
29
+
30
+ // accepts either a single url or an array of urls
31
+ public function publish_update($topic_urls, $http_function = false) {
32
+ if (!isset($topic_urls))
33
+ throw new Exception('Please specify a topic url');
34
+
35
+ // check that we're working with an array
36
+ if (!is_array($topic_urls)) {
37
+ $topic_urls = array($topic_urls);
38
+ }
39
+
40
+ // set the mode to publish
41
+ $post_string = "hub.mode=publish";
42
+ // loop through each topic url
43
+ foreach ($topic_urls as $topic_url) {
44
+ // lightweight check that we're actually working w/ a valid url
45
+ if (!preg_match("|^https?://|i",$topic_url))
46
+ throw new Exception('The specified topic url does not appear to be valid: '.$topic_url);
47
+
48
+ // append the topic url parameters
49
+ $post_string .= "&hub.url=".urlencode($topic_url);
50
+ }
51
+
52
+ // make the http post request and return true/false
53
+ // easy to over-write to use your own http function
54
+ if ($http_function)
55
+ return $http_function($this->hub_url,$post_string);
56
+ else
57
+ return $this->http_post($this->hub_url,$post_string);
58
+ }
59
+
60
+ // returns any error message from the latest request
61
+ public function last_response() {
62
+ return $this->last_response;
63
+ }
64
+
65
+ // default http function that uses curl to post to the hub endpoint
66
+ private function http_post($url, $post_string) {
67
+ // add any additional curl options here
68
+ $options = array(CURLOPT_URL => $url,
69
+ CURLOPT_POST => true,
70
+ CURLOPT_POSTFIELDS => $post_string,
71
+ CURLOPT_RETURNTRANSFER => true,
72
+ CURLOPT_USERAGENT => "PubSubHubbub-Publisher-PHP/1.0");
73
+
74
+ $ch = curl_init();
75
+ curl_setopt_array($ch, $options);
76
+
77
+ $response = curl_exec($ch);
78
+ $this->last_response = $response;
79
+ $info = curl_getinfo($ch);
80
+
81
+ curl_close($ch);
82
+
83
+ // all good
84
+ if ($info['http_code'] == 204)
85
+ return true;
86
+
87
+ return false;
88
+ }
89
+ }
90
+ ?>
pubsubhubbub-php/subscriber.php ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // a PHP client library for pubsubhubbub
3
+ // as defined at http://code.google.com/p/pubsubhubbub/
4
+ // written by Josh Fraser | joshfraser.com | joshfraz@gmail.com
5
+ // modified by Matthias Pfefferle | notizblog.org | matthias@pfefferle.org
6
+ // Released under Apache License 2.0
7
+
8
+ /**
9
+ * a pubsubhubbub subscriber
10
+ *
11
+ * @author Josh Fraser
12
+ * @author Matthias Pfefferle
13
+ */
14
+ class PshbSubscriber {
15
+ protected $hub_url;
16
+ protected $topic_url;
17
+ protected $callback_url;
18
+ protected $credentials;
19
+ // accepted values are "async" and "sync"
20
+ protected $verify = "async";
21
+ protected $verify_token;
22
+ protected $lease_seconds;
23
+
24
+ // create a new Subscriber (credentials added for SuperFeedr support)
25
+ public function __construct($callback_url, $hub_url = null, $credentials = false) {
26
+ if ($hub_url && !preg_match("|^https?://|i",$hub_url))
27
+ throw new Exception('The specified hub url does not appear to be valid: '.$hub_url);
28
+
29
+ if (!isset($callback_url))
30
+ throw new Exception('Please specify a callback');
31
+
32
+ $this->hub_url = $hub_url;
33
+ $this->callback_url = $callback_url;
34
+ $this->credentials = $credentials;
35
+ }
36
+
37
+ public function subscribe($topic_url, $http_function = false) {
38
+ if (!$this->hub_url) {
39
+ $this->find_hub($topic_url);
40
+ }
41
+
42
+ return $this->change_subscription("subscribe", $topic_url, $http_function = false);
43
+ }
44
+
45
+ public function unsubscribe($topic_url, $http_function = false) {
46
+ return $this->change_subscription("unsubscribe", $topic_url, $http_function = false);
47
+ }
48
+
49
+ // helper function since sub/unsub are handled the same way
50
+ private function change_subscription($mode, $topic_url, $http_function = false) {
51
+ if (!isset($topic_url))
52
+ throw new Exception('Please specify a topic url');
53
+
54
+ // lightweight check that we're actually working w/ a valid url
55
+ if (!preg_match("|^https?://|i",$topic_url))
56
+ throw new Exception('The specified topic url does not appear to be valid: '.$topic_url);
57
+
58
+ // set the mode subscribe/unsubscribe
59
+ $post_string = "hub.mode=".$mode;
60
+ $post_string .= "&hub.callback=".urlencode($this->callback_url);
61
+ $post_string .= "&hub.verify=".$this->verify;
62
+ $post_string .= "&hub.verify_token=".$this->verify_token;
63
+ $post_string .= "&hub.lease_seconds=".$this->lease_seconds;
64
+
65
+ // append the topic url parameters
66
+ $post_string .= "&hub.topic=".urlencode($topic_url);
67
+
68
+ // make the http post request and return true/false
69
+ // easy to over-write to use your own http function
70
+ if ($http_function)
71
+ return $http_function($this->hub_url,$post_string);
72
+ else
73
+ return $this->http($this->hub_url,$post_string);
74
+ }
75
+
76
+ // default http function that uses curl to post to the hub endpoint
77
+ private function http($url, $post_string = null) {
78
+
79
+ // add any additional curl options here
80
+ $options = array(CURLOPT_URL => $url,
81
+ CURLOPT_USERAGENT => "PubSubHubbub-Subscriber-PHP/1.0",
82
+ CURLOPT_RETURNTRANSFER => true,
83
+ CURLOPT_FOLLOWLOCATION => true);
84
+
85
+ if ($post_string) {
86
+ $options[CURLOPT_POST] = true;
87
+ $options[CURLOPT_POSTFIELDS] = $post_string;
88
+ }
89
+
90
+ if ($this->credentials)
91
+ $options[CURLOPT_USERPWD] = $this->credentials;
92
+
93
+ $ch = curl_init();
94
+ curl_setopt_array($ch, $options);
95
+
96
+ $response = curl_exec($ch);
97
+ $info = curl_getinfo($ch);
98
+
99
+ // all good -- anything in the 200 range
100
+ if (substr($info['http_code'],0,1) == "2") {
101
+ return $response;
102
+ }
103
+
104
+ return false;
105
+ }
106
+
107
+ // discover the hub url
108
+ public function find_hub($topic_url) {
109
+ $self = $topic_url;
110
+ $xml = $this->http($topic_url);
111
+ if (!$xml)
112
+ throw new Exception('Please enter a valid URL');
113
+
114
+ $xml_parser = xml_parser_create('');
115
+ $xml_values = array();
116
+ $xml_tags = array();
117
+
118
+ if(!$xml_parser)
119
+ throw new Exception('Your webserver doesn\'t support xml-parsing');
120
+
121
+ xml_parser_set_option($xml_parser, XML_OPTION_TARGET_ENCODING, 'UTF-8');
122
+ xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0);
123
+ xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 1);
124
+ xml_parse_into_struct($xml_parser, trim($xml), $xml_values);
125
+ xml_parser_free($xml_parser);
126
+
127
+ $hubs = array();
128
+
129
+ foreach ($xml_values as $value) {
130
+ // get hubs
131
+ if ($value['attributes']['rel'] == 'hub') {
132
+ $hubs[] = $value['attributes']['href'];
133
+ }
134
+ // get self url
135
+ if ($value['attributes']['rel'] == 'self') {
136
+ $self = $value['attributes']['href'];
137
+ }
138
+ }
139
+
140
+ if (count($hubs) >= 1)
141
+ $this->hub_url = $hubs[0];
142
+ else
143
+ throw new Exception('This feed doesn\'t reference a hub url');
144
+
145
+ $this->topic_url = $self;
146
+ }
147
+
148
+ // getter
149
+ public function get_topic_url() {
150
+ return $this->topic_url;
151
+ }
152
+ }
153
+ ?>
pubsubhubbub.php CHANGED
@@ -2,178 +2,318 @@
2
  /*
3
  Plugin Name: PubSubHubbub
4
  Plugin URI: http://code.google.com/p/pubsubhubbub/
5
- Description: A better way to tell the world when your blog is updated. Set a custom hub on the <a href="./options-general.php?page=pubsubhubbub/pubsubhubbub">PubSubHubbub settings page</a>
6
- Version: 1.1
7
- Author: Josh Fraser
8
  Author Email: joshfraz@gmail.com
9
- Author URI: http://www.joshfraser.com
10
  */
11
 
12
- include("publisher.php");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  // function that is called whenever a new post is published
15
- function publish_to_hub($post_id) {
16
-
17
- // we want to notify the hub for every feed
18
- $feed_urls = array();
19
- $feed_urls[] = get_bloginfo('atom_url');
20
- $feed_urls[] = get_bloginfo('rss_url');
21
- $feed_urls[] = get_bloginfo('rdf_url');
22
- $feed_urls[] = get_bloginfo('rss2_url');
23
- // remove dups (ie. they all point to feedburner)
24
- $feed_urls = array_unique($feed_urls);
25
- // get the address of the publish endpoint on the hub
26
- $hub_url = get_pubsub_endpoint();
27
- $p = new Publisher($hub_url);
28
- // need better error handling
29
- if (!$p->publish_update($feed_urls, "http_post_wp")) {
30
- print_r($p->last_response());
31
- }
32
- return $post_id;
 
 
 
 
 
 
 
 
 
 
33
  }
 
34
 
35
- function add_atom_link_tag() {
36
- $sub_url = get_pubsub_endpoint();
37
- echo '<link rel="hub" href="'.$sub_url.'" />';
 
 
 
38
  }
 
 
 
39
 
40
- function add_rss_link_tag() {
41
- $sub_url = get_pubsub_endpoint();
42
- echo '<atom:link rel="hub" href="'.$sub_url.'"/>';
 
 
43
  }
 
 
 
 
44
 
45
- function add_rdf_ns_link() {
46
- echo 'xmlns:atom="http://www.w3.org/2005/Atom"';
47
  }
 
 
48
 
49
  // hack to add the atom definition to the RSS feed
50
  // start capturing the feed output. this is run at priority 9 (before output)
51
- function start_rss_link_tag() {
52
- ob_start();
53
  }
 
54
 
55
  // this is run at priority 11 (after output)
56
  // add in the xmlns atom definition link
57
- function end_rss_link_tag() {
58
- $feed = ob_get_clean();
59
- $pattern = '/<rss version="(.+)">/i';
60
- $replacement = '<rss version="$1" xmlns:atom="http://www.w3.org/2005/Atom">';
61
- // change <rss version="X.XX"> to <rss version="X.XX" xmlns:atom="http://www.w3.org/2005/Atom">
62
- echo preg_replace($pattern, $replacement, $feed);
63
  }
 
64
 
65
  // add a link to our settings page in the WP menu
66
- function add_plugin_menu() {
67
- add_options_page('PubSubHubbub Settings', 'PubSubHubbub', 8, __FILE__, 'add_settings_page');
68
  }
 
69
 
70
  // get the endpoints from the wordpress options table
71
  // valid parameters are "publish" or "subscribe"
72
- function get_pubsub_endpoint() {
73
- $endpoint = get_option('pubsub_endpoint');
 
 
 
 
 
 
 
74
 
75
- // if no values have been set, revert to the defaults (pubsubhubbub on app engine)
76
- if (!$endpoint) {
77
- $endpoint = "http://pubsubhubbub.appspot.com";
 
 
 
78
  }
79
- return $endpoint;
 
 
80
  }
81
 
82
  // write the content for our settings page that allows you to define your endpoints
83
- function add_settings_page() { ?>
84
- <div class="wrap">
85
- <h2>Define a custom endpoint</h2>
86
-
87
- <form method="post" action="options.php">
88
- <?php wp_nonce_field('update-options'); ?>
89
-
90
- <?php
91
-
92
- // load the existing pubsub endpoint value from the wordpress options table
93
- $pubsub_endpoint = get_pubsub_endpoint();
94
-
95
- ?>
96
-
97
- <table class="form-table">
98
-
99
- <tr valign="top">
100
- <th scope="row">Endpoint URL:</th>
101
- <td><input type="text" name="pubsub_endpoint" value="<?php echo $pubsub_endpoint; ?>" size="50" /></td>
102
- </tr>
103
-
104
- </table>
105
-
106
- <input type="hidden" name="action" value="update" />
107
- <input type="hidden" name="page_options" value="pubsub_endpoint" />
108
-
109
- <p class="submit">
110
- <input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
111
- </p>
112
-
113
- </form>
114
-
115
- <br /><br />
116
- Thanks for using PubSubHubbub. Learn more about PubSubHubbub and author of this plugin:
 
 
 
 
117
  <ul>
118
- <li><a href='http://www.onlineaspect.com'>Subscribe to Online Aspect</a></li>
119
- <li><a href='http://www.twitter.com/joshfraser'>Follow Josh Fraser on twitter</a></li>
120
- <li><a href='http://code.google.com/p/pubsubhubbub/'>Learn more about the PubSubHubbub protocol</a></li>
121
  </ul>
122
-
123
- </div>
124
 
125
  <?php }
126
 
 
 
 
 
 
 
 
 
 
127
 
128
- // helper function to use the WP-friendly snoopy library
129
- if (!function_exists('get_snoopy')) {
130
- function get_snoopy() {
131
- include_once(ABSPATH.'/wp-includes/class-snoopy.php');
132
- return new Snoopy;
133
- }
134
- }
135
-
136
- // over-ride the default curl http function to post to the hub endpoint
137
- function http_post_wp($url, $post_vars) {
138
-
139
- // turn the query string into an array for snoopy
140
- parse_str($post_vars);
141
- $post_vars = array();
142
- $post_vars['hub.mode'] = $hub_mode; // PHP converts the periods to underscores
143
- $post_vars['hub.url'] = $hub_url;
144
-
145
- // more universal than curl
146
- $snoopy = get_snoopy();
147
- $snoopy->agent = "(PubSubHubbub-Publisher-WP/1.0)";
148
- $snoopy->submit($url,$post_vars);
149
- $response = $snoopy->results;
150
- // TODO: store the last_response. requires a litle refactoring work.
151
- $response_code = $snoopy->response_code;
152
- if ($response_code == 204)
153
- return true;
154
- return false;
155
  }
 
156
 
 
 
 
 
157
 
158
- // attach the handler that gets called every time you publish a post
159
- add_action('publish_post', 'publish_to_hub');
160
- // add the link to our settings page in the WP menu structure
161
- add_action('admin_menu', 'add_plugin_menu');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
- // add the link tag that points to the hub in the header of our template...
 
 
 
 
164
 
165
- // to our atom feed
166
- add_action('atom_head', 'add_atom_link_tag');
167
- // to our RSS 0.92 feed (requires a bit of a hack to include the ATOM namespace definition)
168
- add_action('do_feed_rss', 'start_rss_link_tag', 9); // run before output
169
- add_action('do_feed_rss', 'end_rss_link_tag', 11); // run after output
170
- add_action('rss_head', 'add_rss_link_tag');
171
- // to our RDF / RSS 1 feed
172
- add_action('rdf_ns', 'add_rdf_ns_link');
173
- add_action('rdf_header', 'add_rss_link_tag');
174
- // to our RSS 2 feed
175
- add_action('rss2_head', 'add_rss_link_tag');
176
- // to our main HTML header -- not sure if we want to include this long-term or not.
177
- add_action('wp_head', 'add_atom_link_tag');
178
-
179
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
2
  /*
3
  Plugin Name: PubSubHubbub
4
  Plugin URI: http://code.google.com/p/pubsubhubbub/
5
+ Description: A better way to tell the world when your blog is updated.
6
+ Version: 1.6.3
7
+ Author: Josh Fraser, Matthias Pfefferle
8
  Author Email: joshfraz@gmail.com
9
+ Author URI: http://wordpress.org/extend/plugins/pubsubhubbub/
10
  */
11
 
12
+ include("pubsubhubbub-php/publisher.php");
13
+ include("pubsubhubbub-php/subscriber.php");
14
+
15
+ // the ability for other plugins to hook into the PuSH code based on a
16
+ // fix by Stephen Paul Weber (http://singpolyma.net)
17
+ function pshb_publish_to_hub($feed_urls) {
18
+ // remove dups (ie. they all point to feedburner)
19
+ $feed_urls = array_unique($feed_urls);
20
+ // get the list of hubs
21
+ $hub_urls = pshb_get_pubsub_endpoints();
22
+ // loop through each hub
23
+ foreach ($hub_urls as $hub_url) {
24
+ $p = new PshbPublisher($hub_url);
25
+ // publish the update to each hub
26
+ if (!$p->publish_update($feed_urls)) {
27
+ // TODO: add better error handling here
28
+ }
29
+ }
30
+ }
31
+
32
+ // subscribe to a feed
33
+ // NOTE! THIS IS BETA STATE
34
+ function pshb_subscribe($url) {
35
+ try {
36
+ $s = new PshbSubscriber(site_url("/?pubsubhubbub=endpoint"));
37
+ $s->find_hub($url);
38
+
39
+ $subscriptions = get_option('pubsub_subscribe');
40
+ $subscriptions[] = $s->get_topic_url();
41
+ update_option('pubsub_subscribe', array_unique($subscriptions));
42
+
43
+ if ($s->subscribe($s->get_topic_url()) !== false) {
44
+ return true;
45
+ }
46
+ } catch (Exception $e) {
47
+ return $e->getMessage();
48
+ }
49
+
50
+ return false;
51
+ }
52
+
53
+ // unsubscribe from a feed
54
+ // NOTE! THIS IS BETA STATE
55
+ function pshb_unsubscribe($url) {
56
+ try {
57
+ $s = new PshbSubscriber(site_url("/?pubsubhubbub=endpoint"));
58
+ $s->find_hub($url);
59
+
60
+ $to_unsubscribe = get_option('pubsub_unsubscribe');
61
+ $to_unsubscribe[] = $s->get_topic_url();
62
+ update_option('pubsub_unsubscribe', array_unique($to_unsubscribe));
63
+
64
+ if ($s->unsubscribe($s->get_topic_url()) !== false) {
65
+ return true;
66
+ }
67
+ } catch (Exception $e) {
68
+ return $e->getMessage();
69
+ }
70
+
71
+ return false;
72
+ }
73
 
74
  // function that is called whenever a new post is published
75
+ function pshb_publish_post($post_id) {
76
+ // we want to notify the hub for every feed
77
+ $feed_urls = array();
78
+ $feed_urls[] = get_bloginfo('atom_url');
79
+ $feed_urls[] = get_bloginfo('rss_url');
80
+ $feed_urls[] = get_bloginfo('rdf_url');
81
+ $feed_urls[] = get_bloginfo('rss2_url');
82
+ // customize default feeds
83
+ $feed_urls = apply_filters('pshb_feed_urls', $feed_urls);
84
+
85
+ pshb_publish_to_hub($feed_urls);
86
+
87
+ return $post_id;
88
+ }
89
+ add_action('publish_post', 'pshb_publish_post');
90
+
91
+ // function that is called whenever a new comment is published
92
+ function pshb_publish_comment($comment_id) {
93
+ // we want to notify the hub for every feed
94
+ $feed_urls = array();
95
+ $feed_urls[] = get_bloginfo('comments_atom_url');
96
+ $feed_urls[] = get_bloginfo('comments_rss2_url');
97
+ // customize default feeds
98
+ $feed_urls = apply_filters('pshb_comment_feed_urls', $feed_urls);
99
+
100
+ pshb_publish_to_hub($feed_urls);
101
+
102
+ return $comment_id;
103
  }
104
+ add_action('comment_post', 'pshb_publish_comment');
105
 
106
+ // to our atom feed
107
+ function pshb_add_atom_link_tag() {
108
+ $hub_urls = pshb_get_pubsub_endpoints();
109
+ foreach ($hub_urls as $hub_url) {
110
+ echo '<link rel="hub" href="'.$hub_url.'" />';
111
+ }
112
  }
113
+ add_action('atom_head', 'pshb_add_atom_link_tag');
114
+ add_action('comments_atom_head', 'pshb_add_atom_link_tag');
115
+ //add_action('wp_head', 'pshb_add_atom_link_tag');
116
 
117
+ function pshb_add_rss_link_tag() {
118
+ $hub_urls = pshb_get_pubsub_endpoints();
119
+ foreach ($hub_urls as $hub_url) {
120
+ echo '<atom:link rel="hub" href="'.$hub_url.'"/>';
121
+ }
122
  }
123
+ add_action('rss_head', 'pshb_add_rss_link_tag');
124
+ add_action('rdf_header', 'pshb_add_rss_link_tag');
125
+ add_action('rss2_head', 'pshb_add_rss_link_tag');
126
+ add_action('commentsrss2_head', 'pshb_add_rss_link_tag');
127
 
128
+ function pshb_add_rdf_ns_link() {
129
+ echo 'xmlns:atom="http://www.w3.org/2005/Atom"';
130
  }
131
+ add_action('rdf_ns', 'pshb_add_rdf_ns_link');
132
+
133
 
134
  // hack to add the atom definition to the RSS feed
135
  // start capturing the feed output. this is run at priority 9 (before output)
136
+ function pshb_start_rss_link_tag() {
137
+ ob_start();
138
  }
139
+ add_action('do_feed_rss', 'pshb_start_rss_link_tag', 9); // run before output
140
 
141
  // this is run at priority 11 (after output)
142
  // add in the xmlns atom definition link
143
+ function pshb_end_rss_link_tag() {
144
+ $feed = ob_get_clean();
145
+ $pattern = '/<rss version="(.+)">/i';
146
+ $replacement = '<rss version="$1" xmlns:atom="http://www.w3.org/2005/Atom">';
147
+ // change <rss version="X.XX"> to <rss version="X.XX" xmlns:atom="http://www.w3.org/2005/Atom">
148
+ echo preg_replace($pattern, $replacement, $feed);
149
  }
150
+ add_action('do_feed_rss', 'pshb_end_rss_link_tag', 11); // run after output
151
 
152
  // add a link to our settings page in the WP menu
153
+ function pshb_add_plugin_menu() {
154
+ add_options_page('PubSubHubbub Settings', 'PubSubHubbub', 'administrator', __FILE__, 'pshb_add_settings_page');
155
  }
156
+ add_action('admin_menu', 'pshb_add_plugin_menu');
157
 
158
  // get the endpoints from the wordpress options table
159
  // valid parameters are "publish" or "subscribe"
160
+ function pshb_get_pubsub_endpoints() {
161
+ $endpoints = get_option('pubsub_endpoints');
162
+ $hub_urls = explode("\n",$endpoints);
163
+
164
+ // if no values have been set, revert to the defaults (pubsubhubbub on app engine & superfeedr)
165
+ if (!$endpoints) {
166
+ $hub_urls[] = "http://pubsubhubbub.appspot.com";
167
+ $hub_urls[] = "http://pubsubhubbub.superfeedr.com";
168
+ }
169
 
170
+ // clean out any blank values
171
+ foreach ($hub_urls as $key => $value) {
172
+ if (is_null($value) || $value=="") {
173
+ unset($hub_urls[$key]);
174
+ } else {
175
+ $hub_urls[$key] = trim($hub_urls[$key]);
176
  }
177
+ }
178
+
179
+ return $hub_urls;
180
  }
181
 
182
  // write the content for our settings page that allows you to define your endpoints
183
+ function pshb_add_settings_page() { ?>
184
+ <div class="wrap">
185
+ <h2>Define custom hubs</h2>
186
+
187
+ <form method="post" action="options.php">
188
+ <?php //wp_nonce_field('update-options'); ?>
189
+ <!-- starting -->
190
+ <?php settings_fields('my_settings_group'); ?>
191
+ <?php do_settings_sections('my_settings_section'); ?>
192
+ <!-- ending -->
193
+
194
+ <?php
195
+ // load the existing pubsub endpoint list from the wordpress options table
196
+ $pubsub_endpoints = trim(implode("\n",pshb_get_pubsub_endpoints()),"\n");
197
+ ?>
198
+
199
+ <table class="form-table">
200
+
201
+ <tr valign="top">
202
+ <th scope="row">Hubs (one per line)</th>
203
+ <td><textarea name="pubsub_endpoints" style='width:600px;height:100px'><?php echo $pubsub_endpoints; ?></textarea></td>
204
+ </tr>
205
+
206
+ </table>
207
+
208
+ <input type="hidden" name="action" value="update" />
209
+ <input type="hidden" name="page_options" value="pubsub_endpoints" />
210
+
211
+ <p class="submit">
212
+ <input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
213
+ </p>
214
+
215
+ </form>
216
+
217
+ <br /><br />
218
+ <div style='background-color:#FFFEEB;border:1px solid #CCCCCC;padding:12px'>
219
+ <strong>Thanks for using PubSubHubbub!</strong><br />
220
+ Visit these links to learn more about PubSubHubbub and the author of this plugin:<br />
221
  <ul>
222
+ <li><a href='http://www.onlineaspect.com'>Subscribe to Online Aspect</a></li>
223
+ <li><a href='http://www.twitter.com/joshfraser'>Follow Josh Fraser on twitter</a></li>
224
+ <li><a href='http://code.google.com/p/pubsubhubbub/'>Learn more about the PubSubHubbub protocol</a></li>
225
  </ul>
226
+ </div>
227
+ </div>
228
 
229
  <?php }
230
 
231
+ // add a settings link next to deactive / edit
232
+ function pshb_add_settings_link( $links, $file ) {
233
+ if( $file == 'pubsubhubbub/pubsubhubbub.php' && function_exists( "admin_url" ) ) {
234
+ $settings_link = '<a href="' . admin_url( 'options-general.php?page=pubsubhubbub/pubsubhubbub' ) . '">' . __('Settings') . '</a>';
235
+ array_unshift( $links, $settings_link ); // before other links
236
+ }
237
+ return $links;
238
+ }
239
+ add_filter('plugin_action_links', 'pshb_add_settings_link', 10, 2);
240
 
241
+ // adds some query vars
242
+ function pshb_query_var($vars) {
243
+ $vars[] = 'hub_mode';
244
+ $vars[] = 'hub_challenge';
245
+ $vars[] = 'hub_topic';
246
+ $vars[] = 'hub_url';
247
+ $vars[] = 'pubsubhubbub';
248
+ return $vars;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  }
250
+ add_filter('query_vars', 'pshb_query_var');
251
 
252
+ // parses the request
253
+ function pshb_parse_request() {
254
+ global $wp_query, $wp;
255
+ $query_vars = $wp->query_vars;
256
 
257
+ // handle (un)subscribe requests
258
+ if (array_key_exists('hub_mode', $query_vars)
259
+ && in_array($query_vars['hub_mode'], array("subscribe", "unsubscribe"))
260
+ && isset($query_vars['hub_challenge'])) {
261
+ $list = get_option('pubsub_'.$query_vars['hub_mode']);
262
+ if (is_array($list) && in_array($query_vars['hub_topic'], $list)) {
263
+ // remove urls from option lists when unsubscribing
264
+ if ($query_vars['hub_mode'] == "unsubscribe") {
265
+ pshb_remove_from_option($query_vars['hub_topic'], "unsubscribe");
266
+ pshb_remove_from_option($query_vars['hub_topic'], "subscribe");
267
+ }
268
+ echo $query_vars['hub_challenge'];
269
+ exit;
270
+ }
271
+ // handle pushes
272
+ } elseif (array_key_exists('pubsubhubbub', $query_vars)
273
+ && $query_vars['pubsubhubbub'] == "endpoint"
274
+ && $request_body = @file_get_contents('php://input')) {
275
+ do_action('pshb_push', $request_body);
276
+ exit;
277
+ }
278
+ }
279
+ add_action('parse_request', 'pshb_parse_request');
280
+
281
+ // remove something from the option list
282
+ function pshb_remove_from_option($url, $option) {
283
+ if (!in_array($option, array("subscribe", "unsubscribe"))) {
284
+ return false;
285
+ }
286
 
287
+ $list = get_option('pubsub_'.$option);
288
+ $key = array_search($url, $list);
289
+ unset($list[$key]);
290
+ update_option('pubsub_'.$option, $list);
291
+ }
292
 
293
+ // adds link headers as defined in the curren v0.4 draft
294
+ // https://github.com/pubsubhubbub/PubSubHubbub/issues/2
295
+ function pshb_template_redirect() {
296
+ if ((is_comment_feed() && !is_singular())
297
+ || (is_feed() && !is_comment_feed() && !is_archive())) {
298
+ $hub_urls = pshb_get_pubsub_endpoints();
299
+ foreach ($hub_urls as $hub_url) {
300
+ header('Link: <'.$hub_url.'>; rel=hub', false);
301
+ }
302
+ header('Link: <'.( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'].'>; rel=self', false);
303
+ }
304
+ }
305
+ add_action('template_redirect', 'pshb_template_redirect');
306
+
307
+ // keep WPMU happy
308
+ function pshb_register_my_settings() {
309
+ register_setting('my_settings_group','pubsub_endpoints');
310
+ }
311
+ add_action('admin_init', 'pshb_register_my_settings');
312
+
313
+ /**
314
+ * beeing backwards compatible
315
+ * @deprecated
316
+ */
317
+ function publish_to_hub($deprecated = null, $feed_urls) {
318
+ pshb_publish_to_hub($feed_urls);
319
+ }
readme.txt CHANGED
@@ -1,32 +1,37 @@
1
  === Plugin Name ===
2
- Contributors: joshfraz
3
- Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5426516
4
  Tags: pubsubhubbub
5
  Requires at least: 2.5
6
- Tested up to: 2.7
7
- Stable tag: /trunk/
8
 
9
  A better way to tell the world when your blog is updated.
10
 
11
  == Description ==
12
 
13
- This plugin that implements [the PubSubHubbub protocol](http://pubsubhubbub.googlecode.com/svn/trunk/pubsubhubbub-core-0.1.html "the PubSubHubbub protocol"). [PubSubHubbub](http://code.google.com/p/pubsubhubbub/ "PubSubHubbub") is a simple, open, server-to-server web-hook-based pubsub (publish/subscribe) protocol as a simple extension to Atom and RSS.
14
-
15
- Parties (servers) speaking the PubSubHubbub protocol can get near-instant notifications (via webhook callbacks) when a topic (feed URL) they're interested in is updated.
16
 
17
  This plugin:
18
-
19
- * Notifies your specified hub each time you publish a new post
20
- * Announces your specified hub by adding `<link rel="hub" ...>` to your template header and ATOM feed
 
 
 
21
  * Adds `<atom:link rel="hub" ...>` to your RSS feeds along with the necessary XMLNS declaration for RSS 0.92/1.0
22
 
23
- The PubSubHubbub protocol is decentralized and free. No company is at the center of this controlling it. Anybody can run a hub, or anybody can ping (publish) or subscribe using open hubs. If no custom hub is specified, this plugin will use the demonstration hub that is running on Google App Engine.
 
 
 
 
 
24
 
25
  == Installation ==
26
 
27
  1. Upload the `pubsubhubbub` directory to your `/wp-content/plugins/` directory
28
  2. Activate the plugin through the 'Plugins' menu in WordPress
29
- 3. Select a custom hub under your PubSubHubbub Settings (optional)
30
 
31
  == Frequently Asked Questions ==
32
 
@@ -34,10 +39,49 @@ The PubSubHubbub protocol is decentralized and free. No company is at the center
34
 
35
  You can visit [PubSubHubbb on Google Code](http://code.google.com/p/pubsubhubbub/ "PubSubHubbb on Google Code")
36
 
37
- = Where can I learn more about the author of this plugin? =
38
 
39
  You can learn more about [Josh Fraser](http://www.joshfraser.com "Josh Fraser") at [Online Aspect](http://www.onlineaspect.com "Online Aspect")
 
40
 
41
  == Screenshots ==
42
 
43
- 1. The PubSubHubbub Settings page allows you to define custom endpoints for your chosen hub
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  === Plugin Name ===
2
+ Contributors: joshfraz, pfefferle
 
3
  Tags: pubsubhubbub
4
  Requires at least: 2.5
5
+ Tested up to: 3.5.1
6
+ Stable tag: 1.6.3
7
 
8
  A better way to tell the world when your blog is updated.
9
 
10
  == Description ==
11
 
12
+ This [PubSubHubbub](http://code.google.com/p/pubsubhubbub/ "PubSubHubbub") plugin is a simple way to let people know in real-time when your blog is updated. PubSubHubbub is widely adopted and is used by Google Reader, Google Alerts and many other services.
 
 
13
 
14
  This plugin:
15
+
16
+ * Sends realtime notifications when you update your blog
17
+ * Supports multi-user installations (Wordpress MU)
18
+ * Supports multiple hubs
19
+ * Supports all of the feed formats used by WordPress, not just ATOM and RSS2
20
+ * Announces which hubs you are using by adding `<link rel="hub" ...>` declarations to your template header and ATOM feed
21
  * Adds `<atom:link rel="hub" ...>` to your RSS feeds along with the necessary XMLNS declaration for RSS 0.92/1.0
22
 
23
+ By default this plugin will ping the following hubs:
24
+
25
+ * [Demo hub on Google App Engine](http://pubsubhubbub.appspot.com "Demo hub on Google App Engine")
26
+ * [SuperFeedr](http://pubsubhubbub.superfeedr.com "SuperFeedr")
27
+
28
+ Please contact me if you operate a hub that you would like to be included as a default option.
29
 
30
  == Installation ==
31
 
32
  1. Upload the `pubsubhubbub` directory to your `/wp-content/plugins/` directory
33
  2. Activate the plugin through the 'Plugins' menu in WordPress
34
+ 3. Select custom hubs under your PubSubHubbub Settings (optional)
35
 
36
  == Frequently Asked Questions ==
37
 
39
 
40
  You can visit [PubSubHubbb on Google Code](http://code.google.com/p/pubsubhubbub/ "PubSubHubbb on Google Code")
41
 
42
+ = Where can I learn more about the authors of this plugin? =
43
 
44
  You can learn more about [Josh Fraser](http://www.joshfraser.com "Josh Fraser") at [Online Aspect](http://www.onlineaspect.com "Online Aspect")
45
+ and [Matthias Pfefferle](http://pfefferle.org "Matthias Pfefferle") at [Notizblog](http://notizblog.org/ "Notizblog")
46
 
47
  == Screenshots ==
48
 
49
+ 1. The PubSubHubbub Settings page allows you to define which hubs you want to use
50
+
51
+ == Changelog ==
52
+
53
+ = 1.6.3 =
54
+ * Update hub URL for SuperFeedr (now pubsubhubbub.superfeedr.com)
55
+ * Update credits and documentation
56
+
57
+ = 1.6.1 =
58
+ * Bug fixes
59
+
60
+ = 1.6 =
61
+ * Added comment-feed support
62
+ * Added simple subscriber functions
63
+ * Added link header
64
+
65
+ = 1.5 =
66
+ * Added filter to modify $feed_urls
67
+ * Re-Added Stephen Paul Webers changes
68
+
69
+ = 1.4 =
70
+ * Added name spacing to avoid conflicts with other plugins & added patch from pfefferle
71
+
72
+ = 1.3 =
73
+ * Added multi-user support and now tested up to 2.9.1
74
+
75
+ = 1.2 =
76
+ * Added support for multiple hubs
77
+
78
+ = 1.1 =
79
+ * Added RSS support
80
+
81
+ = 1.0 =
82
+ * First attempt
83
+
84
+ == Upgrade Notice ==
85
+
86
+ = 1.4 =
87
+ Upgrade eliminates conflicts with other Wordpress plugins
screenshot-1.png CHANGED
Binary file