Completed
Pull Request — master (#56)
by
unknown
02:01
created

Widget::render()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
ccs 0
cts 2
cp 0
cc 1
nc 1
nop 2
crap 2
1
<?php
2
declare(strict_types = 1);
3
4
namespace Yiisoft\Widget;
5
6
use Psr\EventDispatcher\EventDispatcherInterface;
7
use ReflectionClass;
8
use Yiisoft\View\ViewContextInterface;
9
use Yiisoft\View\WebView;
10
use Yiisoft\Widget\Event\AfterRun;
11
use Yiisoft\Widget\Event\BeforeRun;
12
13
/**
14
 * Widget is the base class for widgets.
15
 *
16
 * For more details and usage information on Widget, see the [guide article on widgets](guide:structure-widgets).
17
 */
18
class Widget implements ViewContextInterface
19
{
20
    /**
21
     * @var EventDispatcherInterface event handler.
22
     */
23
    protected $eventDispatcher;
24
25
    /**
26
     * @var WebView $view
27
     */
28
    protected $webView;
29
30 25
    public function __construct(EventDispatcherInterface $eventDispatcher, WebView $webView)
31
    {
32 25
        $this->eventDispatcher = $eventDispatcher;
33 25
        $this->webView = $webView;
34
    }
35
36 8
    public static function begin(WebView $view): self
37
    {
38 8
        return $view->beginWidget(static::class);
39
    }
40
41 8
    public static function end(WebView $view): self
42
    {
43 8
        return $view->endWidget(static::class);
44
    }
45
46 17
    public static function widget(WebView $view): self
47
    {
48 17
        return $view->widget(static::class);
49
    }
50
51
    /**
52
     * Returns the view object that can be used to render views or view files.
53
     *
54
     * The {@see render()} and {@see renderFile()} methods will use this view object to implement the actual view
55
     * rendering. If not set, it will default to the "view" application component.
56
     */
57 2
    public function getView(): WebView
58
    {
59 2
        return $this->webView;
60
    }
61
62
    public function init(): void
63
    {
64
    }
65
66
    public function getContent(): string
67
    {
68
    }
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return string. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
69
70
    /**
71
     * Executes the widget.
72
     *
73
     * @return string the result of widget execution to be outputted.
74
     */
75 16
    public function run(): string
76
    {
77 16
        $out = '';
78
79 16
        if ($this->beforeRun()) {
80 16
            $result = $this->getContent();
81 16
            $out = $this->afterRun($result);
82
        }
83
84 16
        return $out;
85
    }
86
87
    /**
88
     * Renders a view.
89
     *
90
     * The view to be rendered can be specified in one of the following formats:
91
     *
92
     * - [path alias](guide:concept-aliases) (e.g. "@app/views/site/index");
93
     * - absolute path within application (e.g. "//site/index"): the view name starts with double slashes.
94
     * - absolute path within module (e.g. "/site/index"): the view name starts with a single slash.
95
     * - relative path (e.g. "index"): the actual view file will be looked for under {@see viewPath}.
96
     *
97
     * If the view name does not contain a file extension, it will use the default one `.php`.
98
     *
99
     * @param string $view the view name.
100
     * @param array $params the parameters (name-value pairs) that should be made available in the view.
101
     *
102
     * @return string the rendering result.
103
     */
104
    public function render(string $view, array $params = []): string
105
    {
106
        return $this->getView()->render($view, $params, $this);
107
    }
108
109
    /**
110
     * Renders a view file.
111
     *
112
     * @param string $file the view file to be rendered. This can be either a file path or a [path alias](guide:concept-aliases).
113
     * @param array $params the parameters (name-value pairs) that should be made available in the view.
114
     *
115
     * @return string the rendering result.
116
     * @throws \Throwable
117
     */
118
    public function renderFile(string $file, array $params = []): string
119
    {
120
        return $this->getView()->renderFile($file, $params, $this);
121
    }
122
123
    /**
124
     * Returns the directory containing the view files for this widget.
125
     * The default implementation returns the 'views' subdirectory under the directory containing the widget class file.
126
     *
127
     * @return string the directory containing the view files for this widget.
128
     *
129
     * @throws \InvalidArgumentException
130
     * @throws \ReflectionException
131
     */
132
    public function getViewPath(): string
133
    {
134
        $class = new ReflectionClass($this);
135
136
        return dirname($class->getFileName()) . DIRECTORY_SEPARATOR . 'views';
137
    }
138
139
    /**
140
     * This method is invoked right before the widget is executed.
141
     *
142
     * The method will trigger the {@see BeforeRun()} event. The return value of the method will determine whether the
143
     * widget should continue to run.
144
     *
145
     * When overriding this method, make sure you call the parent implementation like the following:
146
     *
147
     * ```php
148
     * public function beforeRun()
149
     * {
150
     *     if (!parent::beforeRun()) {
151
     *         return false;
152
     *     }
153
     *
154
     *     // your custom code here
155
     *
156
     *     return true; // or false to not run the widget
157
     * }
158
     * ```
159
     *
160
     * @return bool whether the widget should continue to be executed.
161
     */
162 23
    public function beforeRun(): bool
163
    {
164 23
        $event = new BeforeRun();
165 23
        $event = $this->eventDispatcher->dispatch($event);
166
167 23
        return !$event->isPropagationStopped();
168
    }
169
170
    /**
171
     * This method is invoked right after a widget is executed.
172
     *
173
     * The method will trigger the {@see {AfterRun()} event. The return value of the method will be used as the widget
174
     * return value.
175
     *
176
     * If you override this method, your code should look like the following:
177
     *
178
     * ```php
179
     * public function afterRun($result)
180
     * {
181
     *     $result = parent::afterRun($result);
182
     *     // your custom code here
183
     *     return $result;
184
     * }
185
     * ```
186
     *
187
     * @param mixed $result the widget return result.
188
     *
189
     * @return mixed the processed widget result.
190
     */
191 23
    public function afterRun($result)
192
    {
193 23
        $event = new AfterRun($result);
194 23
        $event = $this->eventDispatcher->dispatch($event);
195
196 23
        return $event->getResult();
197
    }
198
199
    public function __toString()
200
    {
201
        return $this->run();
202
    }
203
}
204