WebSub/PubSubHubbub - Version 1.0

Version Description

Download this release

Release Info

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

Version 1.0

Files changed (4) hide show
  1. publisher.php +86 -0
  2. pubsubhubbub.php +179 -0
  3. readme.txt +43 -0
  4. screenshot-1.png +0 -0
publisher.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
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
+ ?>
readme.txt ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+
33
+ = Where can I learn more about the PubSubHubbub protocol? =
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
screenshot-1.png ADDED
Binary file