Test Failed
Push — master ( 00affb...1204ff )
by Divine Niiquaye
02:07
created

Publisher::publish()   B

Complexity

Conditions 7
Paths 21

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 13
c 0
b 0
f 0
nc 21
nop 2
dl 0
loc 24
rs 8.8333
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Flight Routing.
7
 *
8
 * PHP version 7.1 and above required
9
 *
10
 * @author    Divine Niiquaye Ibok <[email protected]>
11
 * @copyright 2019 Biurad Group (https://biurad.com/)
12
 * @license   https://opensource.org/licenses/BSD-3-Clause License
13
 *
14
 * For the full copyright and license information, please view the LICENSE
15
 * file that was distributed with this source code.
16
 */
17
18
namespace Flight\Routing;
19
20
use Flight\Routing\Interfaces\PublisherInterface;
21
use Laminas\HttpHandlerRunner\Emitter\EmitterInterface;
22
use LogicException;
23
use Psr\Http\Message\ResponseInterface as PsrResponseInterface;
24
use Psr\Http\Message\StreamInterface;
25
26
/**
27
 * Class StreamPublisher.
28
 * StreamPublisher publishes the given response.
29
 *
30
 * @author Divine Niiquaye Ibok <[email protected]>
31
 */
32
class Publisher implements PublisherInterface
33
{
34
    /**
35
     * {@inheritdoc}
36
     *
37
     * @throws LogicException
38
     */
39
    public function publish($content, ?EmitterInterface $emitter): bool
40
    {
41
        try {
42
            if (null !== $emitter && $content instanceof PsrResponseInterface) {
43
                return $emitter->emit($content);
44
            }
45
46
            if (null === $emitter && $content instanceof PsrResponseInterface) {
47
                $this->emitResponseHeaders($content);
48
                $content = $content->getBody();
49
            }
50
51
            \flush();
52
53
            if ($content instanceof StreamInterface) {
54
                return $this->emitStreamBody($content);
55
            }
56
        } finally {
57
            if (\function_exists('fastcgi_finish_request')) {
58
                fastcgi_finish_request();
59
            }
60
        }
61
62
        throw new LogicException('The response body must be instance of PsrResponseInterface or StreamInterface');
63
    }
64
65
    /**
66
     * Emit the message body.
67
     *
68
     * @param StreamInterface $body
69
     *
70
     * @return bool
71
     */
72
    private function emitStreamBody(StreamInterface $body): bool
73
    {
74
        if ($body->isSeekable()) {
75
            $body->rewind();
76
        }
77
78
        if (!$body->isReadable()) {
79
            echo $body;
80
81
            return true;
82
        }
83
84
        while (!$body->eof()) {
85
            echo $body->read(8192);
86
        }
87
88
        return true;
89
    }
90
91
    /**
92
     * Emit the response header.
93
     *
94
     * @param PsrResponseInterface $response
95
     */
96
    private function emitResponseHeaders(PsrResponseInterface $response): void
97
    {
98
        $statusCode = $response->getStatusCode();
99
100
        foreach ($response->getHeaders() as $name => $values) {
101
            $name  = \ucwords($name, '-'); // Filter a header name to wordcase
102
            $first = $name !== 'Set-Cookie';
103
104
            foreach ($values as $value) {
105
                \header(\sprintf('%s: %s', $name, $value), $first, $statusCode);
106
                $first = false;
107
            }
108
        }
109
    }
110
}
111