Passed
Pull Request — master (#56)
by
unknown
01:37
created

Widget::begin()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
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
    /**
37
     * @see WebView::beginWidget()
38
     * @param WebView $view
39
     * @return static
40
     */
41 8
    public static function begin(WebView $view): self
42
    {
43 8
        return $view->beginWidget(static::class);
44
    }
45
46
    /**
47
     * @see WebView::endWidget()
48
     * @param WebView $view
49
     * @return static
50
     */
51 8
    public static function end(WebView $view): self
52
    {
53 8
        return $view->endWidget(static::class);
54
    }
55
56
    /**
57
     * @see WebView::widget()
58
     * @param WebView $view
59
     * @return static
60
     */
61 17
    public static function widget(WebView $view): self
62
    {
63 17
        return $view->widget(static::class);
64
    }
65
66
    /**
67
     * Returns the view object that can be used to render views or view files.
68
     *
69
     * The {@see render()} and {@see renderFile()} methods will use this view object to implement the actual view
70
     * rendering. If not set, it will default to the "view" application component.
71
     */
72 2
    public function getView(): WebView
73
    {
74 2
        return $this->webView;
75
    }
76
77
    public function init(): void
78
    {
79
    }
80
81
    public function getContent(): string
82
    {
83
    }
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...
84
85
    /**
86
     * Executes the widget.
87
     *
88
     * @return string the result of widget execution to be outputted.
89
     */
90 16
    public function run(): string
91
    {
92 16
        $out = '';
93
94 16
        if ($this->beforeRun()) {
95 16
            $result = $this->getContent();
96 16
            $out = $this->afterRun($result);
97
        }
98
99 16
        return $out;
100
    }
101
102
    /**
103
     * Renders a view.
104
     *
105
     * The view to be rendered can be specified in one of the following formats:
106
     *
107
     * - [path alias](guide:concept-aliases) (e.g. "@app/views/site/index");
108
     * - absolute path within application (e.g. "//site/index"): the view name starts with double slashes.
109
     * - absolute path within module (e.g. "/site/index"): the view name starts with a single slash.
110
     * - relative path (e.g. "index"): the actual view file will be looked for under {@see viewPath}.
111
     *
112
     * If the view name does not contain a file extension, it will use the default one `.php`.
113
     *
114
     * @param string $view the view name.
115
     * @param array $params the parameters (name-value pairs) that should be made available in the view.
116
     *
117
     * @return string the rendering result.
118
     */
119
    public function render(string $view, array $params = []): string
120
    {
121
        return $this->getView()->render($view, $params, $this);
122
    }
123
124
    /**
125
     * Renders a view file.
126
     *
127
     * @param string $file the view file to be rendered. This can be either a file path or a [path alias](guide:concept-aliases).
128
     * @param array $params the parameters (name-value pairs) that should be made available in the view.
129
     *
130
     * @return string the rendering result.
131
     * @throws \Throwable
132
     */
133
    public function renderFile(string $file, array $params = []): string
134
    {
135
        return $this->getView()->renderFile($file, $params, $this);
136
    }
137
138
    /**
139
     * Returns the directory containing the view files for this widget.
140
     * The default implementation returns the 'views' subdirectory under the directory containing the widget class file.
141
     *
142
     * @return string the directory containing the view files for this widget.
143
     *
144
     * @throws \InvalidArgumentException
145
     * @throws \ReflectionException
146
     */
147
    public function getViewPath(): string
148
    {
149
        $class = new ReflectionClass($this);
150
151
        return dirname($class->getFileName()) . DIRECTORY_SEPARATOR . 'views';
152
    }
153
154
    /**
155
     * This method is invoked right before the widget is executed.
156
     *
157
     * The method will trigger the {@see BeforeRun()} event. The return value of the method will determine whether the
158
     * widget should continue to run.
159
     *
160
     * When overriding this method, make sure you call the parent implementation like the following:
161
     *
162
     * ```php
163
     * public function beforeRun()
164
     * {
165
     *     if (!parent::beforeRun()) {
166
     *         return false;
167
     *     }
168
     *
169
     *     // your custom code here
170
     *
171
     *     return true; // or false to not run the widget
172
     * }
173
     * ```
174
     *
175
     * @return bool whether the widget should continue to be executed.
176
     */
177 23
    public function beforeRun(): bool
178
    {
179 23
        $event = new BeforeRun();
180 23
        $event = $this->eventDispatcher->dispatch($event);
181
182 23
        return !$event->isPropagationStopped();
183
    }
184
185
    /**
186
     * This method is invoked right after a widget is executed.
187
     *
188
     * The method will trigger the {@see {AfterRun()} event. The return value of the method will be used as the widget
189
     * return value.
190
     *
191
     * If you override this method, your code should look like the following:
192
     *
193
     * ```php
194
     * public function afterRun($result)
195
     * {
196
     *     $result = parent::afterRun($result);
197
     *     // your custom code here
198
     *     return $result;
199
     * }
200
     * ```
201
     *
202
     * @param mixed $result the widget return result.
203
     *
204
     * @return mixed the processed widget result.
205
     */
206 23
    public function afterRun($result)
207
    {
208 23
        $event = new AfterRun($result);
209 23
        $event = $this->eventDispatcher->dispatch($event);
210
211 23
        return $event->getResult();
212
    }
213
214
    public function __toString()
215
    {
216
        return $this->run();
217
    }
218
}
219