Added the Search API Synonym module to deal specifically with licence and license...
[yaffs-website] / vendor / zendframework / zend-feed / src / PubSubHubbub / AbstractCallback.php
1 <?php
2 /**
3  * Zend Framework (http://framework.zend.com/)
4  *
5  * @link      http://github.com/zendframework/zf2 for the canonical source repository
6  * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7  * @license   http://framework.zend.com/license/new-bsd New BSD License
8  */
9
10 namespace Zend\Feed\PubSubHubbub;
11
12 use Traversable;
13 use Zend\Http\PhpEnvironment\Response as PhpResponse;
14 use Zend\Stdlib\ArrayUtils;
15
16 abstract class AbstractCallback implements CallbackInterface
17 {
18     /**
19      * An instance of Zend\Feed\Pubsubhubbub\Model\SubscriptionPersistenceInterface
20      * used to background save any verification tokens associated with a subscription
21      * or other.
22      *
23      * @var Model\SubscriptionPersistenceInterface
24      */
25     protected $storage = null;
26
27     /**
28      * An instance of a class handling Http Responses. This is implemented in
29      * Zend\Feed\Pubsubhubbub\HttpResponse which shares an unenforced interface with
30      * (i.e. not inherited from) Zend\Controller\Response\Http.
31      *
32      * @var HttpResponse|PhpResponse
33      */
34     protected $httpResponse = null;
35
36     /**
37      * The input stream to use when retrieving the request body. Defaults to
38      * php://input, but can be set to another value in order to force usage
39      * of another input method. This should primarily be used for testing
40      * purposes.
41      *
42      * @var string|resource String indicates a filename or stream to open;
43      *     resource indicates an already created stream to use.
44      */
45     protected $inputStream = 'php://input';
46
47     /**
48      * The number of Subscribers for which any updates are on behalf of.
49      *
50      * @var int
51      */
52     protected $subscriberCount = 1;
53
54     /**
55      * Constructor; accepts an array or Traversable object to preset
56      * options for the Subscriber without calling all supported setter
57      * methods in turn.
58      *
59      * @param  array|Traversable $options Options array or Traversable object
60      */
61     public function __construct($options = null)
62     {
63         if ($options !== null) {
64             $this->setOptions($options);
65         }
66     }
67
68     /**
69      * Process any injected configuration options
70      *
71      * @param  array|Traversable $options Options array or Traversable object
72      * @return AbstractCallback
73      * @throws Exception\InvalidArgumentException
74      */
75     public function setOptions($options)
76     {
77         if ($options instanceof Traversable) {
78             $options = ArrayUtils::iteratorToArray($options);
79         }
80
81         if (! is_array($options)) {
82             throw new Exception\InvalidArgumentException('Array or Traversable object'
83             . 'expected, got ' . gettype($options));
84         }
85
86         if (is_array($options)) {
87             $this->setOptions($options);
88         }
89
90         if (array_key_exists('storage', $options)) {
91             $this->setStorage($options['storage']);
92         }
93         return $this;
94     }
95
96     /**
97      * Send the response, including all headers.
98      * If you wish to handle this via Zend\Http, 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()->send();
107     }
108
109     /**
110      * Sets an instance of Zend\Feed\Pubsubhubbub\Model\SubscriptionPersistence used
111      * to background save any verification tokens associated with a subscription
112      * or other.
113      *
114      * @param  Model\SubscriptionPersistenceInterface $storage
115      * @return AbstractCallback
116      */
117     public function setStorage(Model\SubscriptionPersistenceInterface $storage)
118     {
119         $this->storage = $storage;
120         return $this;
121     }
122
123     /**
124      * Gets an instance of Zend\Feed\Pubsubhubbub\Model\SubscriptionPersistence used
125      * to background save any verification tokens associated with a subscription
126      * or other.
127      *
128      * @return Model\SubscriptionPersistenceInterface
129      * @throws Exception\RuntimeException
130      */
131     public function getStorage()
132     {
133         if ($this->storage === null) {
134             throw new Exception\RuntimeException('No storage object has been'
135                 . ' set that subclasses Zend\Feed\Pubsubhubbub\Model\SubscriptionPersistence');
136         }
137         return $this->storage;
138     }
139
140     /**
141      * An instance of a class handling Http Responses. This is implemented in
142      * Zend\Feed\Pubsubhubbub\HttpResponse which shares an unenforced interface with
143      * (i.e. not inherited from) Zend\Controller\Response\Http.
144      *
145      * @param  HttpResponse|PhpResponse $httpResponse
146      * @return AbstractCallback
147      * @throws Exception\InvalidArgumentException
148      */
149     public function setHttpResponse($httpResponse)
150     {
151         if (! $httpResponse instanceof HttpResponse && ! $httpResponse instanceof PhpResponse) {
152             throw new Exception\InvalidArgumentException('HTTP Response object must'
153                 . ' implement one of Zend\Feed\Pubsubhubbub\HttpResponse or'
154                 . ' Zend\Http\PhpEnvironment\Response');
155         }
156         $this->httpResponse = $httpResponse;
157         return $this;
158     }
159
160     /**
161      * An instance of a class handling Http Responses. This is implemented in
162      * Zend\Feed\Pubsubhubbub\HttpResponse which shares an unenforced interface with
163      * (i.e. not inherited from) Zend\Controller\Response\Http.
164      *
165      * @return HttpResponse|PhpResponse
166      */
167     public function getHttpResponse()
168     {
169         if ($this->httpResponse === null) {
170             $this->httpResponse = new HttpResponse;
171         }
172         return $this->httpResponse;
173     }
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      * @return AbstractCallback
182      * @throws Exception\InvalidArgumentException
183      */
184     public function setSubscriberCount($count)
185     {
186         $count = intval($count);
187         if ($count <= 0) {
188             throw new Exception\InvalidArgumentException('Subscriber count must be'
189                 . ' greater than zero');
190         }
191         $this->subscriberCount = $count;
192         return $this;
193     }
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     /**
207      * Attempt to detect the callback URL (specifically the path forward)
208      * @return string
209      */
210     // @codingStandardsIgnoreStart
211     protected function _detectCallbackUrl()
212     {
213         // @codingStandardsIgnoreEnd
214         $callbackUrl = null;
215
216         // IIS7 with URL Rewrite: make sure we get the unencoded url
217         // (double slash problem).
218         $iisUrlRewritten = isset($_SERVER['IIS_WasUrlRewritten']) ? $_SERVER['IIS_WasUrlRewritten'] : null;
219         $unencodedUrl    = isset($_SERVER['UNENCODED_URL']) ? $_SERVER['UNENCODED_URL'] : null;
220         if ('1' == $iisUrlRewritten && ! empty($unencodedUrl)) {
221             return $unencodedUrl;
222         }
223
224         // HTTP proxy requests setup request URI with scheme and host [and port]
225         // + the URL path, only use URL path.
226         if (isset($_SERVER['REQUEST_URI'])) {
227             $callbackUrl = $this->buildCallbackUrlFromRequestUri();
228         }
229
230         if (null !== $callbackUrl) {
231             return $callbackUrl;
232         }
233
234         if (isset($_SERVER['ORIG_PATH_INFO'])) {
235             return $this->buildCallbackUrlFromOrigPathInfo();
236         }
237
238         return '';
239     }
240
241     /**
242      * Get the HTTP host
243      *
244      * @return string
245      */
246     // @codingStandardsIgnoreStart
247     protected function _getHttpHost()
248     {
249         // @codingStandardsIgnoreEnd
250         if (! empty($_SERVER['HTTP_HOST'])) {
251             return $_SERVER['HTTP_HOST'];
252         }
253
254         $https  = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : null;
255         $scheme = $https === 'on' ? 'https' : 'http';
256         $name   = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '';
257         $port   = isset($_SERVER['SERVER_PORT']) ? (int) $_SERVER['SERVER_PORT'] : 80;
258
259         if (($scheme === 'http' && $port === 80)
260             || ($scheme === 'https' && $port === 443)
261         ) {
262             return $name;
263         }
264
265         return sprintf('%s:%d', $name, $port);
266     }
267
268     /**
269      * Retrieve a Header value from either $_SERVER or Apache
270      *
271      * @param string $header
272      * @return bool|string
273      */
274     // @codingStandardsIgnoreStart
275     protected function _getHeader($header)
276     {
277         // @codingStandardsIgnoreEnd
278         $temp = strtoupper(str_replace('-', '_', $header));
279         if (! empty($_SERVER[$temp])) {
280             return $_SERVER[$temp];
281         }
282         $temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header));
283         if (! empty($_SERVER[$temp])) {
284             return $_SERVER[$temp];
285         }
286         if (function_exists('apache_request_headers')) {
287             $headers = apache_request_headers();
288             if (! empty($headers[$header])) {
289                 return $headers[$header];
290             }
291         }
292         return false;
293     }
294
295     /**
296      * Return the raw body of the request
297      *
298      * @return string|false Raw body, or false if not present
299      */
300     // @codingStandardsIgnoreStart
301     protected function _getRawBody()
302     {
303         // @codingStandardsIgnoreEnd
304         $body = is_resource($this->inputStream)
305             ? stream_get_contents($this->inputStream)
306             : file_get_contents($this->inputStream);
307
308         return strlen(trim($body)) > 0 ? $body : false;
309     }
310
311     /**
312      * Build the callback URL from the REQUEST_URI server parameter.
313      *
314      * @return string
315      */
316     private function buildCallbackUrlFromRequestUri()
317     {
318         $callbackUrl = $_SERVER['REQUEST_URI'];
319         $https = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : null;
320         $scheme = $https === 'on' ? 'https' : 'http';
321         if ($https === 'on') {
322             $scheme = 'https';
323         }
324         $schemeAndHttpHost = $scheme . '://' . $this->_getHttpHost();
325         if (strpos($callbackUrl, $schemeAndHttpHost) === 0) {
326             $callbackUrl = substr($callbackUrl, strlen($schemeAndHttpHost));
327         }
328         return $callbackUrl;
329     }
330
331     /**
332      * Build the callback URL from the ORIG_PATH_INFO server parameter.
333      *
334      * @return string
335      */
336     private function buildCallbackUrlFromOrigPathInfo()
337     {
338         $callbackUrl = $_SERVER['ORIG_PATH_INFO'];
339         if (! empty($_SERVER['QUERY_STRING'])) {
340             $callbackUrl .= '?' . $_SERVER['QUERY_STRING'];
341         }
342         return $callbackUrl;
343     }
344 }