Passed
Push — master ( 9744dd...66fdc9 )
by Alexander
14:28
created

AbstractController::getName()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 8
c 0
b 0
f 0
nc 3
nop 0
dl 0
loc 15
ccs 0
cts 0
cp 0
crap 20
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Controller;
6
7
use Psr\Http\Message\ResponseInterface;
8
use Yiisoft\Aliases\Aliases;
9
use Yiisoft\Strings\Inflector;
10
use Yiisoft\View\ViewContextInterface;
11
use Yiisoft\View\WebView;
12
use Yiisoft\Yii\Web\Data\DataResponseFactoryInterface;
13
14
use function is_file;
15
use function pathinfo;
16
17
abstract class AbstractController implements ViewContextInterface
18
{
19
    protected static ?string $name = null;
20
    private string $layout;
21
    private WebView $view;
22
    protected Aliases $aliases;
23 1
    protected DataResponseFactoryInterface $responseFactory;
24
25
    public function __construct(
26
        DataResponseFactoryInterface $responseFactory,
27
        Aliases $aliases,
28 1
        WebView $view
29 1
    ) {
30 1
        $this->responseFactory = $responseFactory;
31 1
        $this->aliases = $aliases;
32 1
        $this->view = $view;
33
        $this->layout = $aliases->get('@resources/layout') . '/main';
34 1
    }
35
36 1
    protected function render(string $view, array $parameters = []): ResponseInterface
37
    {
38 1
        $contentRenderer = fn () => $this->renderContent($view, $parameters);
39
40
        return $this->responseFactory->createResponse($contentRenderer);
41 1
    }
42
43 1
    private function renderContent(string $view, array $parameters = []): string
44 1
    {
45
        $content = $this->view->render($view, $parameters, $this);
46 1
        $layout = $this->findLayoutFile($this->layout);
47 1
48 1
        if (is_file($layout)) {
49 1
            return $this->view->renderFile(
50
                $layout,
51 1
                array_merge(
52
                    [
53
                        'content' => $content
54
                    ],
55
                    $parameters
56
                ),
57
                $this
58
            );
59
        }
60
61
        return $content;
62 1
    }
63
64 1
    public function getViewPath(): string
65
    {
66
        return $this->aliases->get('@views') . '/' . static::getName();
67 1
    }
68
69 1
    private function findLayoutFile(string $file): string
70
    {
71
        if (pathinfo($file, PATHINFO_EXTENSION) !== '') {
72
            return $file;
73 1
        }
74
75
        return $file . '.' . $this->view->getDefaultExtension();
76
    }
77
78
    /**
79
     * Returns the controller name. Name should be converted to "id" case.
80
     * Method returns classname without `controller` on the ending.
81
     * If namespace is not contain `controller` or `controllers`
82
     * then returns only classname without `controller` on the ending
83
     * else returns all subnamespaces from `controller` (or `controllers`) to the end
84
     *
85
     * @return string
86
     * @example App\Controller\FooBar\BazController -> foo-bar/baz
87
     * @example App\Controllers\FooBar\BazController -> foo-bar/baz
88
     * @example Path\To\File\BlogController -> blog
89
     * @see Inflector::camel2id()
90
     */
91
    protected static function getName(): string
92
    {
93
        if (static::$name !== null) {
94
            return static::$name;
95
        }
96
97
        $regexp = '/((?<=controller\\\|s\\\)(?:[\w\\\]+)|(?:[a-z]+))controller/iuU';
98
        if (!preg_match($regexp, static::class, $m) || empty($m[1])) {
99
            throw new \RuntimeException('Cannot detect controller name');
100
        }
101
102
        $inflector = new Inflector();
103
        $name = str_replace('\\', '/', $m[1]);
104
105
        return static::$name = $inflector->camel2id($name);
106
    }
107
}
108