Html::render()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace alkemann\h2l\response;
4
5
use alkemann\h2l\Message;
6
use alkemann\h2l\Response;
7
use alkemann\h2l\util\Http;
8
9
/**
10
 * Class Html
11
 *
12
 * Content should be either a rendered HTML string or an object that when cast to string renders the HTML.
13
 * Also a slim templateing system is provided. You can use this by sending an array as content, but the
14
 * array must follow some strict rules. The first value (no key), should be the template string. Any key/value
15
 * pair added to this array will be applied as replacements in the template in the following manner:
16
 *
17
 *  - The content key must be a unique string name, like `city`
18
 *  - The place in the template must be prefixed with `{:` and end with `}`, i.e. `{:city}
19
 *
20
 * Example:
21
 *
22
 * ```php
23
 *  Router::add('|city/(?<city>\w+)|', function(Request $request): Html {
24
 *      $template = <<<TEM
25
 *  <html>
26
 *      <head>
27
 *          <title>{:name}</title>
28
 *      </head>
29
 *      <body>
30
 *          <h1>City {:name}</h1>
31
 *          <p>On {:street}</p>
32
 *      </body>
33
 *  </html>
34
 *  TEM;
35
 *
36
 *  $data = [
37
 *      $template,
38
 *      'name' => $r->param('city'),
39
 *      'street' => 'Mainstreet',
40
 *  ];
41
 *  return new Html($data, 200);
42
 *
43
 *  }
44
 * ```
45
 *
46
 * Going to localhost/city/Oslo, will render as:
47
 *
48
 * ```
49
 *  <html>
50
 *      <head>
51
 *          <title>Oslo</title>
52
 *      </head>
53
 *      <body>
54
 *          <h1>City Oslo</h1>
55
 *          <p>On Mainstreet</p>
56
 *      </body>
57
 *  </html>
58
 * ```
59
 *
60
 * @package alkemann\h2l
61
 */
62
class Html extends Response
63
{
64
    /**
65
     * @param string|mixed $content HTML. Objects will be cast, arrays will render template
66
     * @param int $code HTTP code to respond with, defaults to `200`
67
     * @param array<string, mixed> $config inject config/overrides like `header_func`
68
     */
69
    public function __construct($content = null, int $code = Http::CODE_OK, array $config = [])
70
    {
71
        if (is_string($content) === false) {
72
            $content = $this->convertToString($content, $config);
73
        }
74
        $this->config = $config;
75
        $this->message = (new Message())
76
            ->withCode($code)
77
            ->withHeaders(['Content-Type' => Http::CONTENT_HTML])
78
            ->withBody($content ? "$content" : '')
79
        ;
80
    }
81
82
    /**
83
     * @param mixed $content
84
     * @param array<string, mixed> $config
85
     * @return string
86
     */
87
    private function convertToString($content, array $config = []): string
0 ignored issues
show
Unused Code introduced by
The parameter $config is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

87
    private function convertToString($content, /** @scrutinizer ignore-unused */ array $config = []): string

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

Loading history...
88
    {
89
        if (is_array($content) === false) {
90
            return (string) $content;
91
        }
92
        reset($content);
93
        $template = array_shift($content);
94
        $replace = [];
95
        foreach ($content as $name => $value) {
96
            $replace["{:$name}"] = $value;
97
        }
98
        return strtr($template, $replace);
99
    }
100
101
    /**
102
     * Set header and return a string rendered and ready to be echo'ed as response
103
     *
104
     * Header 'Content-type:' will be set using `header` or an injeced 'header_func' through constructor
105
     *
106
     * @return string
107
     */
108
    public function render(): string
109
    {
110
        $this->setHeaders();
111
        return $this->message->body();
112
    }
113
}
114