├── readme.md ├── publisher.php └── subscriber.php /readme.md: -------------------------------------------------------------------------------- 1 | ## Publisher 2 | 3 | A simple "publisher" demo: 4 | 5 | ```php 6 | include("publisher.php"); 7 | 8 | $hub_url = "http://pubsubhubbub.appspot.com"; 9 | $topic_url = "http://notizblog.org/feed/"; 10 | 11 | $p = new PshbPublisher($hub_url); 12 | if ($p->publish_update($topic_url)) { 13 | echo "$topic_url was successfully published to $hub_url"; 14 | } else { 15 | echo "ooops..."; 16 | print_r($p->last_response()); 17 | } 18 | ``` 19 | 20 | ## Subscriber 21 | 22 | A simple "subscriber" demo: 23 | 24 | ```php 25 | include("subscriber.php"); 26 | 27 | $hub_url = "http://pubsubhubbub.appspot.com"; 28 | $callback_url = "put your own endpoint here"; 29 | 30 | $feed = "http://notizblog.org/feed/"; 31 | 32 | // create a new subscriber 33 | $s = new PshbSubscriber($hub_url, $callback_url); 34 | 35 | // subscribe to a feed 36 | $s->subscribe($feed); 37 | 38 | // unsubscribe from a feed 39 | $s->unsubscribe($feed); 40 | ``` 41 | -------------------------------------------------------------------------------- /publisher.php: -------------------------------------------------------------------------------- 1 | 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 | ?> 91 | -------------------------------------------------------------------------------- /subscriber.php: -------------------------------------------------------------------------------- 1 | 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 | ?> --------------------------------------------------------------------------------