TemplateEngine::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 3
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Explicit Architecture POC,
7
 * which is created on top of the Symfony Demo application.
8
 *
9
 * (c) Herberto Graça <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace Acme\App\Infrastructure\TemplateEngine\Twig;
16
17
use Acme\App\Core\Port\TemplateEngine\NullTemplateViewModel;
18
use Acme\App\Core\Port\TemplateEngine\TemplateEngineInterface;
19
use Acme\App\Core\Port\TemplateEngine\TemplateViewModelInterface;
20
use Psr\Http\Message\ResponseInterface;
21
use ReflectionClass;
22
use ReflectionMethod;
23
use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface;
24
use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
25
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
26
27
final class TemplateEngine implements TemplateEngineInterface
28
{
29
    /**
30
     * @var EngineInterface
31
     */
32
    private $templateEngine;
33
34
    /**
35
     * @var HttpFoundationFactoryInterface
36
     */
37
    private $symfonyResponseFactory;
38
39
    /**
40
     * @var HttpMessageFactoryInterface
41
     */
42
    private $psrResponseFactory;
43
44
    public function __construct(
45
        EngineInterface $templateEngine,
46
        HttpFoundationFactoryInterface $symfonyResponseFactory,
47
        HttpMessageFactoryInterface $psrResponseFactory
48
    ) {
49
        $this->templateEngine = $templateEngine;
50
        $this->symfonyResponseFactory = $symfonyResponseFactory;
51
        $this->psrResponseFactory = $psrResponseFactory;
52
    }
53
54
    /**
55
     * @throws \ReflectionException
56
     */
57
    public function render(string $template, TemplateViewModelInterface $viewModel = null): string
58
    {
59
        return $this->templateEngine->render(
60
            $template,
61
            $this->extractParametersFromViewModel($viewModel ?? new NullTemplateViewModel())
62
        );
63
    }
64
65
    /**
66
     * @throws \ReflectionException
67
     */
68
    public function renderResponse(
69
        string $template,
70
        TemplateViewModelInterface $viewModel = null,
71
        ResponseInterface $response = null
72
    ): ResponseInterface {
73
        if ($response) {
74
            $response = $this->symfonyResponseFactory->createResponse($response);
75
        }
76
77
        $parameters = $this->extractParametersFromViewModel($viewModel ?? new NullTemplateViewModel());
78
79
        $response = $this->psrResponseFactory->createResponse(
80
            $this->templateEngine->renderResponse($template, $parameters, $response)
81
        );
82
83
        $response->getBody()->rewind();
84
85
        return $response;
86
    }
87
88
    public function exists(string $template): bool
89
    {
90
        return $this->templateEngine->exists($template);
91
    }
92
93
    /**
94
     * @throws \ReflectionException
95
     */
96
    private function extractParametersFromViewModel(TemplateViewModelInterface $viewModel): array
97
    {
98
        $parameters = ['viewModel' => $viewModel];
99
        $viewModelReflection = new ReflectionClass($viewModel);
100
        $methods = $viewModelReflection->getMethods(ReflectionMethod::IS_PUBLIC);
101
        foreach ($methods as $method) {
102
            if ($this->methodNameHasTemplatePrefix($method)) {
103
                $parameters[$this->generateTemplateVariableName($method)] = $method->invoke($viewModel);
104
            }
105
        }
106
107
        return $parameters;
108
    }
109
110
    private function methodNameHasTemplatePrefix(ReflectionMethod $method): bool
111
    {
112
        return (bool) preg_match('/^(' . self::PARSED_METHOD_PREFIXES . ')/', $method->getName());
0 ignored issues
show
Bug introduced by
Consider using $method->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
113
    }
114
115
    private function generateTemplateVariableName(ReflectionMethod $method): string
116
    {
117
        return lcfirst(str_replace('get', '', $method->getName()));
0 ignored issues
show
Bug introduced by
Consider using $method->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
118
    }
119
}
120