CallbackAbstract.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Feed_Pubsubhubbub
  17. * @subpackage Callback
  18. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id$
  21. */
  22. /**
  23. * @see Zend_Feed_Pubsubhubbub_CallbackInterface
  24. */
  25. require_once 'Zend/Feed/Pubsubhubbub/CallbackInterface.php';
  26. /**
  27. * @see Zend_Feed_Pubsubhubbub_HttpResponse
  28. */
  29. require_once 'Zend/Feed/Pubsubhubbub/HttpResponse.php';
  30. /**
  31. * @category Zend
  32. * @package Zend_Feed_Pubsubhubbub
  33. * @subpackage Callback
  34. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  35. * @license http://framework.zend.com/license/new-bsd New BSD License
  36. */
  37. abstract class Zend_Feed_Pubsubhubbub_CallbackAbstract
  38. implements Zend_Feed_Pubsubhubbub_CallbackInterface
  39. {
  40. /**
  41. * An instance of Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface used
  42. * to background save any verification tokens associated with a subscription
  43. * or other.
  44. *
  45. * @var Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface
  46. */
  47. protected $_storage = null;
  48. /**
  49. * An instance of a class handling Http Responses. This is implemented in
  50. * Zend_Feed_Pubsubhubbub_HttpResponse which shares an unenforced interface with
  51. * (i.e. not inherited from) Zend_Controller_Response_Http.
  52. *
  53. * @var Zend_Feed_Pubsubhubbub_HttpResponse|Zend_Controller_Response_Http
  54. */
  55. protected $_httpResponse = null;
  56. /**
  57. * The number of Subscribers for which any updates are on behalf of.
  58. *
  59. * @var int
  60. */
  61. protected $_subscriberCount = 1;
  62. /**
  63. * Constructor; accepts an array or Zend_Config instance to preset
  64. * options for the Subscriber without calling all supported setter
  65. * methods in turn.
  66. *
  67. * @param array|Zend_Config|null $config Options array or Zend_Config instance
  68. */
  69. public function __construct($config = null)
  70. {
  71. if ($config !== null) {
  72. $this->setConfig($config);
  73. }
  74. }
  75. /**
  76. * Process any injected configuration options
  77. *
  78. * @param array|Zend_Config $config Options array or Zend_Config instance
  79. * @throws Zend_Feed_Pubsubhubbub_Exception
  80. * @return Zend_Feed_Pubsubhubbub_CallbackAbstract
  81. */
  82. public function setConfig($config)
  83. {
  84. if ($config instanceof Zend_Config) {
  85. $config = $config->toArray();
  86. } elseif (!is_array($config)) {
  87. require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
  88. throw new Zend_Feed_Pubsubhubbub_Exception('Array or Zend_Config object'
  89. . 'expected, got ' . gettype($config));
  90. }
  91. if (array_key_exists('storage', $config)) {
  92. $this->setStorage($config['storage']);
  93. }
  94. return $this;
  95. }
  96. /**
  97. * Send the response, including all headers.
  98. * If you wish to handle this via Zend_Controller, use the getter methods
  99. * to retrieve any data needed to be set on your HTTP Response object, or
  100. * simply give this object the HTTP Response instance to work with for you!
  101. *
  102. * @return void
  103. */
  104. public function sendResponse()
  105. {
  106. $this->getHttpResponse()->sendResponse();
  107. }
  108. /**
  109. * Sets an instance of Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface used
  110. * to background save any verification tokens associated with a subscription
  111. * or other.
  112. *
  113. * @param Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface $storage
  114. * @return Zend_Feed_Pubsubhubbub_CallbackAbstract
  115. */
  116. public function setStorage(Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface $storage)
  117. {
  118. $this->_storage = $storage;
  119. return $this;
  120. }
  121. /**
  122. * Gets an instance of Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface used
  123. * to background save any verification tokens associated with a subscription
  124. * or other.
  125. *
  126. * @throws Zend_Feed_Pubsubhubbub_Exception
  127. * @return Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface
  128. */
  129. public function getStorage()
  130. {
  131. if ($this->_storage === null) {
  132. require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
  133. throw new Zend_Feed_Pubsubhubbub_Exception('No storage object has been'
  134. . ' set that subclasses Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface');
  135. }
  136. return $this->_storage;
  137. }
  138. /**
  139. * An instance of a class handling Http Responses. This is implemented in
  140. * Zend_Feed_Pubsubhubbub_HttpResponse which shares an unenforced interface with
  141. * (i.e. not inherited from) Zend_Controller_Response_Http.
  142. *
  143. * @param Zend_Feed_Pubsubhubbub_HttpResponse|Zend_Controller_Response_Http $httpResponse
  144. * @throws Zend_Feed_Pubsubhubbub_Exception
  145. * @return Zend_Feed_Pubsubhubbub_CallbackAbstract
  146. */
  147. public function setHttpResponse($httpResponse)
  148. {
  149. if (!is_object($httpResponse)
  150. || (!$httpResponse instanceof Zend_Feed_Pubsubhubbub_HttpResponse
  151. && !$httpResponse instanceof Zend_Controller_Response_Http)
  152. ) {
  153. require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
  154. throw new Zend_Feed_Pubsubhubbub_Exception('HTTP Response object must'
  155. . ' implement one of Zend_Feed_Pubsubhubbub_HttpResponse or'
  156. . ' Zend_Controller_Response_Http');
  157. }
  158. $this->_httpResponse = $httpResponse;
  159. return $this;
  160. }
  161. /**
  162. * An instance of a class handling Http Responses. This is implemented in
  163. * Zend_Feed_Pubsubhubbub_HttpResponse which shares an unenforced interface with
  164. * (i.e. not inherited from) Zend_Controller_Response_Http.
  165. *
  166. * @return Zend_Feed_Pubsubhubbub_HttpResponse|Zend_Controller_Response_Http
  167. */
  168. public function getHttpResponse()
  169. {
  170. if ($this->_httpResponse === null) {
  171. $this->_httpResponse = new Zend_Feed_Pubsubhubbub_HttpResponse;
  172. }
  173. return $this->_httpResponse;
  174. }
  175. /**
  176. * Sets the number of Subscribers for which any updates are on behalf of.
  177. * In other words, is this class serving one or more subscribers? How many?
  178. * Defaults to 1 if left unchanged.
  179. *
  180. * @param string|int $count
  181. * @throws Zend_Feed_Pubsubhubbub_Exception
  182. * @return Zend_Feed_Pubsubhubbub_CallbackAbstract
  183. */
  184. public function setSubscriberCount($count)
  185. {
  186. $count = intval($count);
  187. if ($count <= 0) {
  188. require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
  189. throw new Zend_Feed_Pubsubhubbub_Exception('Subscriber count must be'
  190. . ' greater than zero');
  191. }
  192. $this->_subscriberCount = $count;
  193. return $this;
  194. }
  195. /**
  196. * Gets the number of Subscribers for which any updates are on behalf of.
  197. * In other words, is this class serving one or more subscribers? How many?
  198. *
  199. * @return int
  200. */
  201. public function getSubscriberCount()
  202. {
  203. return $this->_subscriberCount;
  204. }
  205. /**
  206. * Attempt to detect the callback URL (specifically the path forward)
  207. */
  208. protected function _detectCallbackUrl()
  209. {
  210. $callbackUrl = '';
  211. if (isset($_SERVER['HTTP_X_ORIGINAL_URL'])) {
  212. $callbackUrl = $_SERVER['HTTP_X_ORIGINAL_URL'];
  213. } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
  214. $callbackUrl = $_SERVER['HTTP_X_REWRITE_URL'];
  215. } elseif (isset($_SERVER['REQUEST_URI'])) {
  216. $callbackUrl = $_SERVER['REQUEST_URI'];
  217. $scheme = 'http';
  218. if ($_SERVER['HTTPS'] == 'on') {
  219. $scheme = 'https';
  220. }
  221. $schemeAndHttpHost = $scheme . '://' . $this->_getHttpHost();
  222. if (strpos($callbackUrl, $schemeAndHttpHost) === 0) {
  223. $callbackUrl = substr($callbackUrl, strlen($schemeAndHttpHost));
  224. }
  225. } elseif (isset($_SERVER['ORIG_PATH_INFO'])) {
  226. $callbackUrl= $_SERVER['ORIG_PATH_INFO'];
  227. if (!empty($_SERVER['QUERY_STRING'])) {
  228. $callbackUrl .= '?' . $_SERVER['QUERY_STRING'];
  229. }
  230. }
  231. return $callbackUrl;
  232. }
  233. /**
  234. * Get the HTTP host
  235. *
  236. * @return string
  237. */
  238. protected function _getHttpHost()
  239. {
  240. if (!empty($_SERVER['HTTP_HOST'])) {
  241. return $_SERVER['HTTP_HOST'];
  242. }
  243. $scheme = 'http';
  244. if ($_SERVER['HTTPS'] == 'on') {
  245. $scheme = 'https';
  246. }
  247. $name = $_SERVER['SERVER_NAME'];
  248. $port = $_SERVER['SERVER_PORT'];
  249. if (($scheme == 'http' && $port == 80)
  250. || ($scheme == 'https' && $port == 443)
  251. ) {
  252. return $name;
  253. } else {
  254. return $name . ':' . $port;
  255. }
  256. }
  257. /**
  258. * Retrieve a Header value from either $_SERVER or Apache
  259. *
  260. * @param string $header
  261. * @return bool
  262. */
  263. protected function _getHeader($header)
  264. {
  265. $temp = strtoupper(str_replace('-', '_', $header));
  266. if (!empty($_SERVER[$temp])) {
  267. return $_SERVER[$temp];
  268. }
  269. $temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header));
  270. if (!empty($_SERVER[$temp])) {
  271. return $_SERVER[$temp];
  272. }
  273. if (function_exists('apache_request_headers')) {
  274. $headers = apache_request_headers();
  275. if (!empty($headers[$header])) {
  276. return $headers[$header];
  277. }
  278. }
  279. return false;
  280. }
  281. /**
  282. * Return the raw body of the request
  283. *
  284. * @return string|false Raw body, or false if not present
  285. */
  286. protected function _getRawBody()
  287. {
  288. $body = file_get_contents('php://input');
  289. if (strlen(trim($body)) == 0 && isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
  290. $body = $GLOBALS['HTTP_RAW_POST_DATA'];
  291. }
  292. if (strlen(trim($body)) > 0) {
  293. return $body;
  294. }
  295. return false;
  296. }
  297. }