Added the zend framework 2 library, the path is specified in line no.26 in zend_modul...
[openemr.git] / interface / modules / zend_modules / library / Zend / Feed / PubSubHubbub / Subscriber / Callback.php
blob4e15e58dbaed66bceaa86a20964d65b2f4dcea50
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\Feed\PubSubHubbub\Subscriber;
12 use Zend\Feed\PubSubHubbub;
13 use Zend\Feed\PubSubHubbub\Exception;
14 use Zend\Feed\Uri;
16 class Callback extends PubSubHubbub\AbstractCallback
18 /**
19 * Contains the content of any feeds sent as updates to the Callback URL
21 * @var string
23 protected $feedUpdate = null;
25 /**
26 * Holds a manually set subscription key (i.e. identifies a unique
27 * subscription) which is typical when it is not passed in the query string
28 * but is part of the Callback URL path, requiring manual retrieval e.g.
29 * using a route and the \Zend\Mvc\Router\RouteMatch::getParam() method.
31 * @var string
33 protected $subscriptionKey = null;
35 /**
36 * After verification, this is set to the verified subscription's data.
38 * @var array
40 protected $currentSubscriptionData = null;
42 /**
43 * Set a subscription key to use for the current callback request manually.
44 * Required if usePathParameter is enabled for the Subscriber.
46 * @param string $key
47 * @return \Zend\Feed\PubSubHubbub\Subscriber\Callback
49 public function setSubscriptionKey($key)
51 $this->subscriptionKey = $key;
52 return $this;
55 /**
56 * Handle any callback from a Hub Server responding to a subscription or
57 * unsubscription request. This should be the Hub Server confirming the
58 * the request prior to taking action on it.
60 * @param array $httpGetData GET data if available and not in $_GET
61 * @param bool $sendResponseNow Whether to send response now or when asked
62 * @return void
64 public function handle(array $httpGetData = null, $sendResponseNow = false)
66 if ($httpGetData === null) {
67 $httpGetData = $_GET;
70 /**
71 * Handle any feed updates (sorry for the mess :P)
73 * This DOES NOT attempt to process a feed update. Feed updates
74 * SHOULD be validated/processed by an asynchronous process so as
75 * to avoid holding up responses to the Hub.
77 $contentType = $this->_getHeader('Content-Type');
78 if (strtolower($_SERVER['REQUEST_METHOD']) == 'post'
79 && $this->_hasValidVerifyToken(null, false)
80 && (stripos($contentType, 'application/atom+xml') === 0
81 || stripos($contentType, 'application/rss+xml') === 0
82 || stripos($contentType, 'application/xml') === 0
83 || stripos($contentType, 'text/xml') === 0
84 || stripos($contentType, 'application/rdf+xml') === 0)
85 ) {
86 $this->setFeedUpdate($this->_getRawBody());
87 $this->getHttpResponse()->setHeader('X-Hub-On-Behalf-Of', $this->getSubscriberCount());
88 /**
89 * Handle any (un)subscribe confirmation requests
91 } elseif ($this->isValidHubVerification($httpGetData)) {
92 $this->getHttpResponse()->setContent($httpGetData['hub_challenge']);
94 switch (strtolower($httpGetData['hub_mode'])) {
95 case 'subscribe':
96 $data = $this->currentSubscriptionData;
97 $data['subscription_state'] = PubSubHubbub\PubSubHubbub::SUBSCRIPTION_VERIFIED;
98 if (isset($httpGetData['hub_lease_seconds'])) {
99 $data['lease_seconds'] = $httpGetData['hub_lease_seconds'];
101 $this->getStorage()->setSubscription($data);
102 break;
103 case 'unsubscribe':
104 $verifyTokenKey = $this->_detectVerifyTokenKey($httpGetData);
105 $this->getStorage()->deleteSubscription($verifyTokenKey);
106 break;
107 default:
108 throw new Exception\RuntimeException(sprintf(
109 'Invalid hub_mode ("%s") provided',
110 $httpGetData['hub_mode']
114 * Hey, C'mon! We tried everything else!
116 } else {
117 $this->getHttpResponse()->setStatusCode(404);
120 if ($sendResponseNow) {
121 $this->sendResponse();
126 * Checks validity of the request simply by making a quick pass and
127 * confirming the presence of all REQUIRED parameters.
129 * @param array $httpGetData
130 * @return bool
132 public function isValidHubVerification(array $httpGetData)
135 * As per the specification, the hub.verify_token is OPTIONAL. This
136 * implementation of Pubsubhubbub considers it REQUIRED and will
137 * always send a hub.verify_token parameter to be echoed back
138 * by the Hub Server. Therefore, its absence is considered invalid.
140 if (strtolower($_SERVER['REQUEST_METHOD']) !== 'get') {
141 return false;
143 $required = array(
144 'hub_mode',
145 'hub_topic',
146 'hub_challenge',
147 'hub_verify_token',
149 foreach ($required as $key) {
150 if (!array_key_exists($key, $httpGetData)) {
151 return false;
154 if ($httpGetData['hub_mode'] !== 'subscribe'
155 && $httpGetData['hub_mode'] !== 'unsubscribe'
157 return false;
159 if ($httpGetData['hub_mode'] == 'subscribe'
160 && !array_key_exists('hub_lease_seconds', $httpGetData)
162 return false;
164 if (!Uri::factory($httpGetData['hub_topic'])->isValid()) {
165 return false;
169 * Attempt to retrieve any Verification Token Key attached to Callback
170 * URL's path by our Subscriber implementation
172 if (!$this->_hasValidVerifyToken($httpGetData)) {
173 return false;
175 return true;
179 * Sets a newly received feed (Atom/RSS) sent by a Hub as an update to a
180 * Topic we've subscribed to.
182 * @param string $feed
183 * @return \Zend\Feed\PubSubHubbub\Subscriber\Callback
185 public function setFeedUpdate($feed)
187 $this->feedUpdate = $feed;
188 return $this;
192 * Check if any newly received feed (Atom/RSS) update was received
194 * @return bool
196 public function hasFeedUpdate()
198 if ($this->feedUpdate === null) {
199 return false;
201 return true;
205 * Gets a newly received feed (Atom/RSS) sent by a Hub as an update to a
206 * Topic we've subscribed to.
208 * @return string
210 public function getFeedUpdate()
212 return $this->feedUpdate;
216 * Check for a valid verify_token. By default attempts to compare values
217 * with that sent from Hub, otherwise merely ascertains its existence.
219 * @param array $httpGetData
220 * @param bool $checkValue
221 * @return bool
223 protected function _hasValidVerifyToken(array $httpGetData = null, $checkValue = true)
225 $verifyTokenKey = $this->_detectVerifyTokenKey($httpGetData);
226 if (empty($verifyTokenKey)) {
227 return false;
229 $verifyTokenExists = $this->getStorage()->hasSubscription($verifyTokenKey);
230 if (!$verifyTokenExists) {
231 return false;
233 if ($checkValue) {
234 $data = $this->getStorage()->getSubscription($verifyTokenKey);
235 $verifyToken = $data['verify_token'];
236 if ($verifyToken !== hash('sha256', $httpGetData['hub_verify_token'])) {
237 return false;
239 $this->currentSubscriptionData = $data;
240 return true;
242 return true;
246 * Attempt to detect the verification token key. This would be passed in
247 * the Callback URL (which we are handling with this class!) as a URI
248 * path part (the last part by convention).
250 * @param null|array $httpGetData
251 * @return false|string
253 protected function _detectVerifyTokenKey(array $httpGetData = null)
256 * Available when sub keys encoding in Callback URL path
258 if (isset($this->subscriptionKey)) {
259 return $this->subscriptionKey;
263 * Available only if allowed by PuSH 0.2 Hubs
265 if (is_array($httpGetData)
266 && isset($httpGetData['xhub_subscription'])
268 return $httpGetData['xhub_subscription'];
272 * Available (possibly) if corrupted in transit and not part of $_GET
274 $params = $this->_parseQueryString();
275 if (isset($params['xhub.subscription'])) {
276 return rawurldecode($params['xhub.subscription']);
279 return false;
283 * Build an array of Query String parameters.
284 * This bypasses $_GET which munges parameter names and cannot accept
285 * multiple parameters with the same key.
287 * @return array|void
289 protected function _parseQueryString()
291 $params = array();
292 $queryString = '';
293 if (isset($_SERVER['QUERY_STRING'])) {
294 $queryString = $_SERVER['QUERY_STRING'];
296 if (empty($queryString)) {
297 return array();
299 $parts = explode('&', $queryString);
300 foreach ($parts as $kvpair) {
301 $pair = explode('=', $kvpair);
302 $key = rawurldecode($pair[0]);
303 $value = rawurldecode($pair[1]);
304 if (isset($params[$key])) {
305 if (is_array($params[$key])) {
306 $params[$key][] = $value;
307 } else {
308 $params[$key] = array($params[$key], $value);
310 } else {
311 $params[$key] = $value;
314 return $params;