Passed
Push — master ( 33118b...5ca5e8 )
by Mehmet
06:00
created

Response::returnHtml()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 20

Duplication

Lines 24
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 24
loc 24
ccs 0
cts 23
cp 0
rs 8.9713
c 0
b 0
f 0
cc 2
eloc 20
nc 2
nop 2
crap 6
1
<?php
2
declare(strict_types=1);
3
4
namespace Selami\Foundation;
5
6
use Selami as s;
7
use Zend\Config\Config as ZendConfig;
8
use Psr\Container\ContainerInterface;
9
use Selami\View\ViewInterface;
10
use Symfony\Component\HttpFoundation\Session\Session;
11
12
class Response
13
{
14
    private $config;
15
    private $container;
16
    private $view;
17
    private $session;
18
    /**
19
     * @var int
20
     */
21
    private $statusCode = 200;
22
    /**
23
     * @var array
24
     */
25
    private $headers = [];
26
    /**
27
     * @var array
28
     */
29
    private $cookies = [];
30
    /**
31
     * @var string
32
     */
33
    private $body = '';
34
35
    /**
36
     * @var array
37
     */
38
    private $data = [];
39
    /**
40
     * @var string
41
     */
42
    private $contentType = 'html';
43
44
    /**
45
     * @var string
46
     */
47
    private $redirect;
48
49
    public function __construct(ContainerInterface $container)
50
    {
51
        $this->container = $container;
52
        $this->config = $container->get(ZendConfig::class);
53
    }
54
55
    private function checkTemplateFile($template, $type, $controller) : void
56
    {
57
        if (!file_exists($this->config->app->get('templates_dir', './templates') .'/'. $template)) {
58
            $message  = sprintf(
59
                '%s  template file not found! %s  needs a main template file at: %s',
60
                $type,
61
                $controller,
62
                $this->config['app_dir'] .'/'. $template
63
            );
64
            throw new \DomainException($message);
65
        }
66
    }
67
68
    public function returnRedirect(array $functionOutput, string $controller) : void
0 ignored issues
show
Unused Code introduced by
The parameter $controller is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
69
    {
70
        $this->contentType = 'redirect';
71
        if (isset($functionOutput['redirect'])) {
72
            $this->contentType = 'redirect';
73
            $this->statusCode = 301;
74
            $this->redirect = $functionOutput['redirect'];
75
        }
76
    }
77
78
    public function returnJson(array $functionOutput, string $controllerClass) : void
0 ignored issues
show
Unused Code introduced by
The parameter $controllerClass is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
79
    {
80
        $this->contentType = 'json';
81
        if (isset($functionOutput['redirect'])) {
82
            $this->contentType = 'redirect';
83
            $this->statusCode = 301;
84
            $this->redirect = $functionOutput['redirect'];
85
        }
86
        if (!is_array($functionOutput)) {
87
            $functionOutput = ['status' => 500, 'error' => 'Internal Server Error'];
88
        } elseif (!isset($functionOutput['status'])) {
89
            $functionOutput['status'] = 200;
90
        }
91
        $status = (int) $functionOutput['status'];
92
        $this->statusCode = $status;
93
        $this->data = $functionOutput;
94
    }
95
96 View Code Duplication
    public function returnHtml(array $functionOutput, string $controllerClass) : void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
97
    {
98
        $this->useSession();
99
        $this->useView($this->container->get(ViewInterface::class));
100
        $paths = explode("\\", $controllerClass);
101
        $templateFile = array_pop($paths);
102
        $templateFolder = array_pop($paths);
103
        $template = strtolower($templateFolder) . '/' . strtolower($templateFile) . '.twig';
104
105
        if (isset($functionOutput['redirect'])) {
106
            $this->contentType   = 'redirect';
107
            $this->statusCode       = 301;
108
            $this->redirect     = $functionOutput['redirect'];
109
        }
110
        $this->view->addGlobal('defined', get_defined_constants(true)['user'] ?? []);
111
        $this->view->addGlobal('session', $this->session->all());
112
        $this->checkTemplateFile($template, 'Method\'s', $controllerClass);
113
        $functionOutput['data'] = $functionOutput['data'] ?? [];
114
        $functionOutput['app_content'] = $this->view->render($template, $functionOutput['data']);
115
        $mainTemplateName = $functionOutput['app_main_template'] ?? 'default';
116
        $mainTemplate = '_' . strtolower($mainTemplateName) . '.twig';
117
        $this->checkTemplateFile($mainTemplate, 'Main', $controllerClass);
118
        $this->body = $this->view->render($mainTemplate, $functionOutput);
119
    }
120
121
122 View Code Duplication
    public function returnText(array $functionOutput, string $controllerClass) : void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
123
    {
124
        $this->useSession();
125
        $this->useView($this->container->get(ViewInterface::class));
126
        $paths = explode("\\", $controllerClass);
127
        $templateFile = array_pop($paths);
128
        $templateFolder = array_pop($paths);
129
        $template = strtolower($templateFolder) . '/' . strtolower($templateFile) . '.twig';
130
        if (isset($functionOutput['redirect'])) {
131
            $this->contentType   = 'redirect';
132
            $this->statusCode       = 301;
133
            $this->redirect     = $functionOutput['redirect'];
134
        }
135
        $this->view->addGlobal('defined', get_defined_constants(true)['user'] ?? []);
136
        $this->view->addGlobal('session', $this->session->all());
137
        $this->checkTemplateFile($template, 'Method\'s', $controllerClass);
138
        $functionOutput['data'] = $functionOutput['data'] ?? [];
139
        $functionOutput['app_content'] = $this->view->render($template, $functionOutput['data']);
140
        $mainTemplateName = $functionOutput['layout'] ?? 'default';
141
        $mainTemplate = '_' . strtolower($mainTemplateName) . '.twig';
142
        $this->checkTemplateFile($mainTemplate, 'Main', $controllerClass);
143
        $this->contentType = 'text';
144
        $this->body = $this->view->render($mainTemplate, $functionOutput);
145
    }
146
147
    public function notFound($status = 404, $returnType = 'html', $message = 'Not Found') : void
148
    {
149
        if ($returnType == 'json') {
150
            $this->body = ['status' => $status, 'message' => $message];
0 ignored issues
show
Documentation Bug introduced by
It seems like array('status' => $status, 'message' => $message) of type array<string,integer|str...r","message":"string"}> is incompatible with the declared type string of property $body.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
151
        } else {
152
            $this->useView($this->container->get('view'));
153
            $notFoundTemplate = '_404.twig';
154
            $this->contentType = $returnType;
155
            $this->body = $this->view->render(
156
                $notFoundTemplate,
157
                ['message' => $message, 'status' => $status]
158
            );
159
        }
160
        $this->statusCode = $status;
161
    }
162
163
    private function useView(ViewInterface $view) : void
164
    {
165
        $this->view = $view;
166
    }
167
168
    private function useSession() : void
169
    {
170
        $this->session = $this->container->get(Session::class);
171
    }
172
173
    private function setHeaders() : void
174
    {
175
        $this->headers['X-Powered-By']      = 'r/selami';
176
        $this->headers['X-Frame-Options']   = 'SAMEORIGIN';
177
        $this->headers['X-XSS-Protection']  = '1; mode=block';
178
        $this->headers['Strict-Transport-Security'] = 'max-age=31536000';
179
        if (array_key_exists('headers', $this->config) && is_array($this->config['headers'])) {
180
            foreach ($this->config['headers'] as $header => $value) {
181
                $this->headers[$header] = $value;
182
            }
183
        }
184
    }
185
186
    public function getResponse() : array
187
    {
188
        $headers = $this->config['headers'] ?? null;
189
        $this->setHeaders($headers);
0 ignored issues
show
Unused Code introduced by
The call to Response::setHeaders() has too many arguments starting with $headers.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
190
        return [
191
            'statusCode'    => $this->statusCode,
192
            'headers'       => $this->headers,
193
            'cookies'       => $this->cookies,
194
            'body'          => (string) $this->body,
195
            'data'          => $this->data,
196
            'contentType'   => $this->contentType,
197
            'redirect'      => $this->redirect
198
        ];
199
    }
200
201
    public function sendResponse() : void
202
    {
203
        $response = new s\Http\Response();
204
        $response->setHeaders($this->headers);
205
        $response->setStatusCode($this->statusCode);
206
        switch ($this->contentType) {
207
        case 'redirect':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
208
            $response->setOutputType('redirect');
209
            $response->setRedirect($this->redirect);
210
            break;
211
        case 'json':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
212
            $response->setOutputType('json');
213
            $response->setData($this->data);
214
            break;
215
        case 'text':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
216
            $response->setOutputType('text');
217
            $response->setBody($this->body);
218
            break;
219
        case 'html':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
220
        default:
0 ignored issues
show
Coding Style introduced by
DEFAULT statements must be defined using a colon

As per the PSR-2 coding standard, default statements should not be wrapped in curly braces.

switch ($expr) {
    default: { //wrong
        doSomething();
        break;
    }
}

switch ($expr) {
    default: //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
221
            $response->setOutputType('html');
222
            $response->setBody($this->body);
223
            break;
224
        }
225
        $response->send();
226
    }
227
}
228