File indexing completed on 2025-01-19 05:21:05

0001 <?php
0002 /**
0003  * Zend Framework
0004  *
0005  * LICENSE
0006  *
0007  * This source file is subject to the new BSD license that is bundled
0008  * with this package in the file LICENSE.txt.
0009  * It is also available through the world-wide-web at this URL:
0010  * http://framework.zend.com/license/new-bsd
0011  * If you did not receive a copy of the license and are unable to
0012  * obtain it through the world-wide-web, please send an email
0013  * to license@zend.com so we can send you a copy immediately.
0014  *
0015  * @category   Zend
0016  * @package    Zend_Feed_Pubsubhubbub
0017  * @subpackage Callback
0018  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0019  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0020  * @version    $Id$
0021  */
0022 
0023 /**
0024  * @see Zend_Feed_Pubsubhubbub_CallbackInterface
0025  */
0026 // require_once 'Zend/Feed/Pubsubhubbub/CallbackInterface.php';
0027 
0028 /**
0029  * @see Zend_Feed_Pubsubhubbub_HttpResponse
0030  */
0031 // require_once 'Zend/Feed/Pubsubhubbub/HttpResponse.php';
0032 
0033 /**
0034  * @category   Zend
0035  * @package    Zend_Feed_Pubsubhubbub
0036  * @subpackage Callback
0037  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0038  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0039  */
0040 abstract class Zend_Feed_Pubsubhubbub_CallbackAbstract
0041     implements Zend_Feed_Pubsubhubbub_CallbackInterface
0042 {
0043     /**
0044      * An instance of Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface used
0045      * to background save any verification tokens associated with a subscription
0046      * or other.
0047      *
0048      * @var Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface
0049      */
0050     protected $_storage = null;
0051 
0052     /**
0053      * An instance of a class handling Http Responses. This is implemented in
0054      * Zend_Feed_Pubsubhubbub_HttpResponse which shares an unenforced interface with
0055      * (i.e. not inherited from) Zend_Controller_Response_Http.
0056      *
0057      * @var Zend_Feed_Pubsubhubbub_HttpResponse|Zend_Controller_Response_Http
0058      */
0059     protected $_httpResponse = null;
0060 
0061     /**
0062      * The number of Subscribers for which any updates are on behalf of.
0063      *
0064      * @var int
0065      */
0066     protected $_subscriberCount = 1;
0067 
0068     /**
0069      * Constructor; accepts an array or Zend_Config instance to preset
0070      * options for the Subscriber without calling all supported setter
0071      * methods in turn.
0072      *
0073      * @param array|Zend_Config|null $config Options array or Zend_Config instance
0074      */
0075     public function __construct($config = null)
0076     {
0077         if ($config !== null) {
0078             $this->setConfig($config);
0079         }
0080     }
0081 
0082     /**
0083      * Process any injected configuration options
0084      *
0085      * @param  array|Zend_Config $config Options array or Zend_Config instance
0086      * @throws Zend_Feed_Pubsubhubbub_Exception
0087      * @return Zend_Feed_Pubsubhubbub_CallbackAbstract
0088      */
0089     public function setConfig($config)
0090     {
0091         if ($config instanceof Zend_Config) {
0092             $config = $config->toArray();
0093         } elseif (!is_array($config)) {
0094             // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
0095             throw new Zend_Feed_Pubsubhubbub_Exception('Array or Zend_Config object'
0096             . 'expected, got ' . gettype($config));
0097         }
0098         if (array_key_exists('storage', $config)) {
0099             $this->setStorage($config['storage']);
0100         }
0101         return $this;
0102     }
0103 
0104     /**
0105      * Send the response, including all headers.
0106      * If you wish to handle this via Zend_Controller, use the getter methods
0107      * to retrieve any data needed to be set on your HTTP Response object, or
0108      * simply give this object the HTTP Response instance to work with for you!
0109      *
0110      * @return void
0111      */
0112     public function sendResponse()
0113     {
0114         $this->getHttpResponse()->sendResponse();
0115     }
0116 
0117     /**
0118      * Sets an instance of Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface used
0119      * to background save any verification tokens associated with a subscription
0120      * or other.
0121      *
0122      * @param  Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface $storage
0123      * @return Zend_Feed_Pubsubhubbub_CallbackAbstract
0124      */
0125     public function setStorage(Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface $storage)
0126     {
0127         $this->_storage = $storage;
0128         return $this;
0129     }
0130 
0131     /**
0132      * Gets an instance of Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface used
0133      * to background save any verification tokens associated with a subscription
0134      * or other.
0135      *
0136      * @throws Zend_Feed_Pubsubhubbub_Exception
0137      * @return Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface
0138      */
0139     public function getStorage()
0140     {
0141         if ($this->_storage === null) {
0142             // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
0143             throw new Zend_Feed_Pubsubhubbub_Exception('No storage object has been'
0144                 . ' set that subclasses Zend_Feed_Pubsubhubbub_Model_SubscriptionInterface');
0145         }
0146         return $this->_storage;
0147     }
0148 
0149     /**
0150      * An instance of a class handling Http Responses. This is implemented in
0151      * Zend_Feed_Pubsubhubbub_HttpResponse which shares an unenforced interface with
0152      * (i.e. not inherited from) Zend_Controller_Response_Http.
0153      *
0154      * @param  Zend_Feed_Pubsubhubbub_HttpResponse|Zend_Controller_Response_Http $httpResponse
0155      * @throws Zend_Feed_Pubsubhubbub_Exception
0156      * @return Zend_Feed_Pubsubhubbub_CallbackAbstract
0157      */
0158     public function setHttpResponse($httpResponse)
0159     {
0160         if (!is_object($httpResponse)
0161             || (!$httpResponse instanceof Zend_Feed_Pubsubhubbub_HttpResponse
0162                 && !$httpResponse instanceof Zend_Controller_Response_Http)
0163         ) {
0164             // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
0165             throw new Zend_Feed_Pubsubhubbub_Exception('HTTP Response object must'
0166                 . ' implement one of Zend_Feed_Pubsubhubbub_HttpResponse or'
0167                 . ' Zend_Controller_Response_Http');
0168         }
0169         $this->_httpResponse = $httpResponse;
0170         return $this;
0171     }
0172 
0173     /**
0174      * An instance of a class handling Http Responses. This is implemented in
0175      * Zend_Feed_Pubsubhubbub_HttpResponse which shares an unenforced interface with
0176      * (i.e. not inherited from) Zend_Controller_Response_Http.
0177      *
0178      * @return Zend_Feed_Pubsubhubbub_HttpResponse|Zend_Controller_Response_Http
0179      */
0180     public function getHttpResponse()
0181     {
0182         if ($this->_httpResponse === null) {
0183             $this->_httpResponse = new Zend_Feed_Pubsubhubbub_HttpResponse;
0184         }
0185         return $this->_httpResponse;
0186     }
0187 
0188     /**
0189      * Sets the number of Subscribers for which any updates are on behalf of.
0190      * In other words, is this class serving one or more subscribers? How many?
0191      * Defaults to 1 if left unchanged.
0192      *
0193      * @param  string|int $count
0194      * @throws Zend_Feed_Pubsubhubbub_Exception
0195      * @return Zend_Feed_Pubsubhubbub_CallbackAbstract
0196      */
0197     public function setSubscriberCount($count)
0198     {
0199         $count = intval($count);
0200         if ($count <= 0) {
0201             // require_once 'Zend/Feed/Pubsubhubbub/Exception.php';
0202             throw new Zend_Feed_Pubsubhubbub_Exception('Subscriber count must be'
0203                 . ' greater than zero');
0204         }
0205         $this->_subscriberCount = $count;
0206         return $this;
0207     }
0208 
0209     /**
0210      * Gets the number of Subscribers for which any updates are on behalf of.
0211      * In other words, is this class serving one or more subscribers? How many?
0212      *
0213      * @return int
0214      */
0215     public function getSubscriberCount()
0216     {
0217         return $this->_subscriberCount;
0218     }
0219 
0220     /**
0221      * Attempt to detect the callback URL (specifically the path forward)
0222      */
0223     protected function _detectCallbackUrl()
0224     {
0225         $callbackUrl = '';
0226         if (isset($_SERVER['HTTP_X_ORIGINAL_URL'])) {
0227             $callbackUrl = $_SERVER['HTTP_X_ORIGINAL_URL'];
0228         } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
0229             $callbackUrl = $_SERVER['HTTP_X_REWRITE_URL'];
0230         } elseif (isset($_SERVER['REQUEST_URI'])) {
0231             $callbackUrl = $_SERVER['REQUEST_URI'];
0232             $scheme = 'http';
0233             if ($_SERVER['HTTPS'] == 'on') {
0234                 $scheme = 'https';
0235             }
0236             $schemeAndHttpHost = $scheme . '://' . $this->_getHttpHost();
0237             if (strpos($callbackUrl, $schemeAndHttpHost) === 0) {
0238                 $callbackUrl = substr($callbackUrl, strlen($schemeAndHttpHost));
0239             }
0240         } elseif (isset($_SERVER['ORIG_PATH_INFO'])) {
0241             $callbackUrl= $_SERVER['ORIG_PATH_INFO'];
0242             if (!empty($_SERVER['QUERY_STRING'])) {
0243                 $callbackUrl .= '?' . $_SERVER['QUERY_STRING'];
0244             }
0245         }
0246         return $callbackUrl;
0247     }
0248 
0249     /**
0250      * Get the HTTP host
0251      *
0252      * @return string
0253      */
0254     protected function _getHttpHost()
0255     {
0256         if (!empty($_SERVER['HTTP_HOST'])) {
0257             return $_SERVER['HTTP_HOST'];
0258         }
0259         $scheme = 'http';
0260         if ($_SERVER['HTTPS'] == 'on') {
0261             $scheme = 'https';
0262         }
0263         $name = $_SERVER['SERVER_NAME'];
0264         $port = $_SERVER['SERVER_PORT'];
0265         if (($scheme == 'http' && $port == 80)
0266             || ($scheme == 'https' && $port == 443)
0267         ) {
0268             return $name;
0269         } else {
0270             return $name . ':' . $port;
0271         }
0272     }
0273 
0274     /**
0275      * Retrieve a Header value from either $_SERVER or Apache
0276      *
0277      * @param  string $header
0278      * @return bool
0279      */
0280     protected function _getHeader($header)
0281     {
0282         $temp = strtoupper(str_replace('-', '_', $header));
0283         if (!empty($_SERVER[$temp])) {
0284             return $_SERVER[$temp];
0285         }
0286         $temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header));
0287         if (!empty($_SERVER[$temp])) {
0288             return $_SERVER[$temp];
0289         }
0290         if (function_exists('apache_request_headers')) {
0291             $headers = apache_request_headers();
0292             if (!empty($headers[$header])) {
0293                 return $headers[$header];
0294             }
0295         }
0296         return false;
0297     }
0298 
0299     /**
0300      * Return the raw body of the request
0301      *
0302      * @return string|false Raw body, or false if not present
0303      */
0304     protected function _getRawBody()
0305     {
0306         $body = file_get_contents('php://input');
0307         if (strlen(trim($body)) == 0 && isset($GLOBALS['HTTP_RAW_POST_DATA'])) {
0308             $body = $GLOBALS['HTTP_RAW_POST_DATA'];
0309         }
0310         if (strlen(trim($body)) > 0) {
0311             return $body;
0312         }
0313         return false;
0314     }
0315 }