Passed
Pull Request — master (#108)
by Dmitriy
11:25
created

Controller::getName()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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