Completed
Push — fetcher_factories ( 10a56f...fd93ea )
by David
13:44
created

SplashUtils::getResponseHeaders()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 13
rs 9.4285
cc 2
eloc 7
nc 2
nop 0
1
<?php
2
3
namespace Mouf\Mvc\Splash\Services;
4
5
use Mouf\Mvc\Splash\Utils\SplashException;
6
use Psr\Http\Message\ResponseInterface;
7
use Zend\Diactoros\Response\HtmlResponse;
8
9
class SplashUtils
10
{
11
    const MODE_WEAK = 'weak';
12
    const MODE_STRICT = 'strict';
13
14
    public static function buildControllerResponse($callback, $mode = self::MODE_STRICT, $debug = false)
15
    {
16
        ob_start();
17
        try {
18
            $result = $callback();
19
        } catch (\Exception $e) {
20
            ob_end_clean();
21
            // Rethrow and keep stack trace.
22
            throw $e;
23
        }
24
        $html = ob_get_clean();
25
26
        if (!empty($html) || $mode === self::MODE_WEAK) {
27
            if ($mode === self::MODE_WEAK) {
28
                $code = http_response_code();
29
                $headers = self::getResponseHeaders();
30
31
                // Suppress actual headers (re-add by PSR-7 Response)
32
                // If you don't remove old headers, it's duplicated in HTTP Headers
33
                foreach ($headers as $key => $head) {
34
                    header_remove($key);
35
                }
36
37
                if ($result !== null) {
38
                    // We might be in weak mode, it is not normal to have both an output and a response!
39
                    $html = '<h1>Output started in controller. It is not normal to have an output in the controller, and a response returned by the controller. Output detected:</h1>'.$html;
40
                    $code = 500;
41
                }
42
43
                return new HtmlResponse($html, $code, $headers);
44
            } else {
45
                if ($debug) {
46
                    $html = '<h1>Output started in controller. A controller should return an object implementing the ResponseInterface rather than outputting directly content. Output detected:</h1>'.$html;
47
48
                    return new HtmlResponse($html, 500);
49
                } else {
50
                    throw new SplashException('Output started in Controller : '.$html);
51
                }
52
            }
53
        }
54
55
        if (!$result instanceof ResponseInterface) {
56
            if ($result === null) {
57
                throw new SplashException('Your controller should return an instance of Psr\\Http\\Message\\ResponseInterface. Your controller did not return any value.');
58
            } else {
59
                $class = (gettype($result) == 'object') ? get_class($result) : gettype($result);
60
                throw new SplashException('Your controller should return an instance of Psr\\Http\\Message\\ResponseInterface. Type of value returned: '.$class);
61
            }
62
        }
63
64
        return $result;
65
66
        // TODO: If Symfony Response convert to psr-7
67
//        if ($result instanceof Response) {
68
//            if ($html !== "") {
69
//                throw new SplashException("You cannot output text AND return Response object in the same action. Output already started :'$html");
70
//            }
71
//
72
//            if (headers_sent()) {
73
//                $headers = headers_list();
74
//                throw new SplashException("Headers already sent. Detected headers are : ".var_export($headers, true));
75
//            }
76
//
77
//            return $result;
78
//        }
79
//
80
//        $code = http_response_code();
81
//        $headers = SplashUtils::greatResponseHeaders();
82
//
83
//        // Suppress actual headers (re-add by Symfony Response)
84
//        // If you don't remove old headers, it's duplicated in HTTP Headers
85
//        foreach ($headers as $key => $head) {
86
//            header_remove($key);
87
//        }
88
//
89
//        return new Response($html, $code, $headers);
90
    }
91
92
    /**
93
     * Same as apache_response_headers (for any server).
94
     *
95
     * @return array
96
     */
97
    private static function getResponseHeaders()
98
    {
99
        $arh = array();
100
101
        // headers_list don't return associative array
102
        $headers = headers_list();
103
        foreach ($headers as $header) {
104
            $header = explode(':', $header);
105
            $arh[array_shift($header)] = trim(implode(':', $header));
106
        }
107
108
        return $arh;
109
    }
110
}
111