"Fossies" - the Fresh Open Source Software Archive 
Member "drupal-9.4.5/vendor/laminas/laminas-feed/src/PubSubHubbub/AbstractCallback.php" (24 Mar 2022, 10793 Bytes) of package /linux/www/drupal-9.4.5.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 <?php
2
3 namespace Laminas\Feed\PubSubHubbub;
4
5 use Laminas\Http\PhpEnvironment\Response as PhpResponse;
6 use Laminas\Stdlib\ArrayUtils;
7 use Traversable;
8
9 use function array_key_exists;
10 use function file_get_contents;
11 use function function_exists;
12 use function gettype;
13 use function intval;
14 use function is_array;
15 use function is_resource;
16 use function sprintf;
17 use function str_replace;
18 use function stream_get_contents;
19 use function strlen;
20 use function strpos;
21 use function strtoupper;
22 use function substr;
23 use function trim;
24
25 abstract class AbstractCallback implements CallbackInterface
26 {
27 /**
28 * An instance of Laminas\Feed\Pubsubhubbub\Model\SubscriptionPersistenceInterface
29 * used to background save any verification tokens associated with a subscription
30 * or other.
31 *
32 * @var Model\SubscriptionPersistenceInterface
33 */
34 protected $storage;
35
36 /**
37 * An instance of a class handling Http Responses. This is implemented in
38 * Laminas\Feed\Pubsubhubbub\HttpResponse which shares an unenforced interface with
39 * (i.e. not inherited from) Laminas\Controller\Response\Http.
40 *
41 * @var HttpResponse|PhpResponse
42 */
43 protected $httpResponse;
44
45 /**
46 * The input stream to use when retrieving the request body. Defaults to
47 * php://input, but can be set to another value in order to force usage
48 * of another input method. This should primarily be used for testing
49 * purposes.
50 *
51 * @var resource|string String indicates a filename or stream to open;
52 * resource indicates an already created stream to use.
53 */
54 protected $inputStream = 'php://input';
55
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 /**
64 * Constructor; accepts an array or Traversable object to preset
65 * options for the Subscriber without calling all supported setter
66 * methods in turn.
67 *
68 * @param null|array|Traversable $options Options array or Traversable object
69 */
70 public function __construct($options = null)
71 {
72 if ($options !== null) {
73 $this->setOptions($options);
74 }
75 }
76
77 /**
78 * Process any injected configuration options
79 *
80 * @param array|Traversable $options Options array or Traversable object
81 * @return $this
82 * @throws Exception\InvalidArgumentException
83 */
84 public function setOptions($options)
85 {
86 if ($options instanceof Traversable) {
87 $options = ArrayUtils::iteratorToArray($options);
88 }
89
90 if (! is_array($options)) {
91 throw new Exception\InvalidArgumentException(
92 'Array or Traversable object expected, got ' . gettype($options)
93 );
94 }
95
96 if (is_array($options)) {
97 $this->setOptions($options);
98 }
99
100 if (array_key_exists('storage', $options)) {
101 $this->setStorage($options['storage']);
102 }
103 return $this;
104 }
105
106 /**
107 * Send the response, including all headers.
108 * If you wish to handle this via Laminas\Http, use the getter methods
109 * to retrieve any data needed to be set on your HTTP Response object, or
110 * simply give this object the HTTP Response instance to work with for you!
111 *
112 * @return void
113 */
114 public function sendResponse()
115 {
116 $this->getHttpResponse()->send();
117 }
118
119 /**
120 * Sets an instance of Laminas\Feed\Pubsubhubbub\Model\SubscriptionPersistence used
121 * to background save any verification tokens associated with a subscription
122 * or other.
123 *
124 * @return $this
125 */
126 public function setStorage(Model\SubscriptionPersistenceInterface $storage)
127 {
128 $this->storage = $storage;
129 return $this;
130 }
131
132 /**
133 * Gets an instance of Laminas\Feed\Pubsubhubbub\Model\SubscriptionPersistence used
134 * to background save any verification tokens associated with a subscription
135 * or other.
136 *
137 * @return Model\SubscriptionPersistenceInterface
138 * @throws Exception\RuntimeException
139 */
140 public function getStorage()
141 {
142 if ($this->storage === null) {
143 throw new Exception\RuntimeException(
144 'No storage object has been set that subclasses'
145 . ' Laminas\Feed\Pubsubhubbub\Model\SubscriptionPersistence'
146 );
147 }
148 return $this->storage;
149 }
150
151 /**
152 * An instance of a class handling Http Responses. This is implemented in
153 * Laminas\Feed\Pubsubhubbub\HttpResponse which shares an unenforced interface with
154 * (i.e. not inherited from) Laminas\Controller\Response\Http.
155 *
156 * @param HttpResponse|PhpResponse $httpResponse
157 * @return $this
158 * @throws Exception\InvalidArgumentException
159 */
160 public function setHttpResponse($httpResponse)
161 {
162 if (! $httpResponse instanceof HttpResponse && ! $httpResponse instanceof PhpResponse) {
163 throw new Exception\InvalidArgumentException(
164 'HTTP Response object must'
165 . ' implement one of Laminas\Feed\Pubsubhubbub\HttpResponse or'
166 . ' Laminas\Http\PhpEnvironment\Response'
167 );
168 }
169 $this->httpResponse = $httpResponse;
170 return $this;
171 }
172
173 /**
174 * An instance of a class handling Http Responses. This is implemented in
175 * Laminas\Feed\Pubsubhubbub\HttpResponse which shares an unenforced interface with
176 * (i.e. not inherited from) Laminas\Controller\Response\Http.
177 *
178 * @return HttpResponse|PhpResponse
179 */
180 public function getHttpResponse()
181 {
182 if ($this->httpResponse === null) {
183 $this->httpResponse = new HttpResponse();
184 }
185 return $this->httpResponse;
186 }
187
188 /**
189 * Sets the number of Subscribers for which any updates are on behalf of.
190 * In other words, is this class serving one or more subscribers? How many?
191 * Defaults to 1 if left unchanged.
192 *
193 * @param int|string $count
194 * @return $this
195 * @throws Exception\InvalidArgumentException
196 */
197 public function setSubscriberCount($count)
198 {
199 $count = intval($count);
200 if ($count <= 0) {
201 throw new Exception\InvalidArgumentException(
202 'Subscriber count must be'
203 . ' greater than zero'
204 );
205 }
206 $this->subscriberCount = $count;
207 return $this;
208 }
209
210 /**
211 * Gets the number of Subscribers for which any updates are on behalf of.
212 * In other words, is this class serving one or more subscribers? How many?
213 *
214 * @return int
215 */
216 public function getSubscriberCount()
217 {
218 return $this->subscriberCount;
219 }
220
221 // phpcs:disable PSR2.Methods.MethodDeclaration.Underscore
222
223 /**
224 * Attempt to detect the callback URL (specifically the path forward)
225 *
226 * @return string
227 */
228 protected function _detectCallbackUrl()
229 {
230 $callbackUrl = null;
231
232 // IIS7 with URL Rewrite: make sure we get the unencoded url
233 // (double slash problem).
234 $iisUrlRewritten = $_SERVER['IIS_WasUrlRewritten'] ?? null;
235 $unencodedUrl = $_SERVER['UNENCODED_URL'] ?? null;
236 if ('1' === $iisUrlRewritten && ! empty($unencodedUrl)) {
237 return $unencodedUrl;
238 }
239
240 // HTTP proxy requests setup request URI with scheme and host [and port]
241 // + the URL path, only use URL path.
242 if (isset($_SERVER['REQUEST_URI'])) {
243 $callbackUrl = $this->buildCallbackUrlFromRequestUri();
244 }
245
246 if (null !== $callbackUrl) {
247 return $callbackUrl;
248 }
249
250 if (isset($_SERVER['ORIG_PATH_INFO'])) {
251 return $this->buildCallbackUrlFromOrigPathInfo();
252 }
253
254 return '';
255 }
256
257 /**
258 * Get the HTTP host
259 *
260 * @return string
261 */
262 protected function _getHttpHost()
263 {
264 if (! empty($_SERVER['HTTP_HOST'])) {
265 return $_SERVER['HTTP_HOST'];
266 }
267
268 $https = $_SERVER['HTTPS'] ?? null;
269 $scheme = $https === 'on' ? 'https' : 'http';
270 $name = $_SERVER['SERVER_NAME'] ?? '';
271 $port = isset($_SERVER['SERVER_PORT']) ? (int) $_SERVER['SERVER_PORT'] : 80;
272
273 if (
274 ($scheme === 'http' && $port === 80)
275 || ($scheme === 'https' && $port === 443)
276 ) {
277 return $name;
278 }
279
280 return sprintf('%s:%d', $name, $port);
281 }
282
283 /**
284 * Retrieve a Header value from either $_SERVER or Apache
285 *
286 * @param string $header
287 * @return bool|string
288 */
289 protected function _getHeader($header)
290 {
291 $temp = strtoupper(str_replace('-', '_', $header));
292 if (! empty($_SERVER[$temp])) {
293 return $_SERVER[$temp];
294 }
295 $temp = 'HTTP_' . strtoupper(str_replace('-', '_', $header));
296 if (! empty($_SERVER[$temp])) {
297 return $_SERVER[$temp];
298 }
299 if (function_exists('apache_request_headers')) {
300 $headers = apache_request_headers();
301 if (! empty($headers[$header])) {
302 return $headers[$header];
303 }
304 }
305 return false;
306 }
307
308 /**
309 * Return the raw body of the request
310 *
311 * @return false|string Raw body, or false if not present
312 */
313 protected function _getRawBody()
314 {
315 $body = is_resource($this->inputStream)
316 ? stream_get_contents($this->inputStream)
317 : file_get_contents($this->inputStream);
318
319 return strlen(trim($body)) > 0 ? $body : false;
320 }
321
322 // phpcs:enable PSR2.Methods.MethodDeclaration.Underscore
323
324 /**
325 * Build the callback URL from the REQUEST_URI server parameter.
326 *
327 * @return string
328 */
329 private function buildCallbackUrlFromRequestUri()
330 {
331 $callbackUrl = $_SERVER['REQUEST_URI'];
332 $https = $_SERVER['HTTPS'] ?? null;
333 $scheme = $https === 'on' ? 'https' : 'http';
334 if ($https === 'on') {
335 $scheme = 'https';
336 }
337 $schemeAndHttpHost = $scheme . '://' . $this->_getHttpHost();
338 if (strpos($callbackUrl, $schemeAndHttpHost) === 0) {
339 $callbackUrl = substr($callbackUrl, strlen($schemeAndHttpHost));
340 }
341 return $callbackUrl;
342 }
343
344 /**
345 * Build the callback URL from the ORIG_PATH_INFO server parameter.
346 *
347 * @return string
348 */
349 private function buildCallbackUrlFromOrigPathInfo()
350 {
351 $callbackUrl = $_SERVER['ORIG_PATH_INFO'];
352 if (! empty($_SERVER['QUERY_STRING'])) {
353 $callbackUrl .= '?' . $_SERVER['QUERY_STRING'];
354 }
355 return $callbackUrl;
356 }
357 }