Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
View
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
4 / 4
5
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 render
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 output
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 templateContext
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray\Node;
6
7use Celema\Core\Response;
8use Cosray\Cms;
9use Cosray\Context;
10use Cosray\Contract\ViewContext;
11use Cosray\Renderer;
12
13/**
14 * A node's own view, bound to the node it renders.
15 *
16 * Nodes inject it to render themselves — typically from an `Http*` handler
17 * that answers with the node plus a message or the submitted values:
18 *
19 * ```php
20 * public function httpPost(): Response
21 * {
22 *     return $this->view->render(['error' => __('Please confirm.')]);
23 * }
24 * ```
25 *
26 * The passed context wins over `ViewContext::viewContext()`, so a node can
27 * declare defaults there and override them per request here.
28 */
29final class View
30{
31    public function __construct(
32        private readonly object $node,
33        private readonly Cms $cms,
34        private readonly Context $context,
35        private readonly Types $types,
36    ) {}
37
38    /** @param array<string, mixed> $context */
39    public function render(array $context = []): Response
40    {
41        return new Response(
42            $this->context
43                ->factory
44                ->response()
45                ->withHeader('Content-Type', 'text/html; charset=utf-8'),
46        )->body($this->output($context));
47    }
48
49    /**
50     * The rendered template as a string, for nodes that build their own
51     * response and for nodes rendered into another node's template.
52     *
53     * @param array<string, mixed> $context
54     */
55    public function output(array $context = []): string
56    {
57        return $this->context
58            ->container
59            ->tag(Renderer::class)
60            ->get('view')
61            ->render(
62                $this->types->schemaOf($this->node::class)->renderer,
63                $this->templateContext($context),
64            );
65    }
66
67    /**
68     * @param  array<string, mixed> $extra
69     * @return array<string, mixed>
70     */
71    private function templateContext(array $extra): array
72    {
73        $request = $this->context->httpRequest();
74        $proxy = new Wrapper(
75            $this->node,
76            Factory::fieldNamesFor($this->node),
77            $this->types,
78            $this->context,
79            $this->cms,
80            $this->cms->nodeFactory(),
81        );
82
83        return array_merge(
84            [
85                'node' => $proxy,
86                'cms' => $this->cms,
87                'locale' => $this->context->locale(),
88                'locales' => $this->context->locales(),
89                'request' => $request,
90                'container' => $this->context->container,
91                'debug' => $this->context->config->debug(),
92                'env' => $this->context->config->env(),
93            ],
94            $this->node instanceof ViewContext ? $this->node->viewContext($proxy) : [],
95            $extra,
96        );
97    }
98}