1 | <?php |
||||
2 | |||||
3 | namespace Imanghafoori\Widgets\Utils; |
||||
4 | |||||
5 | use Illuminate\Support\Str; |
||||
6 | |||||
7 | class WidgetRenderer |
||||
8 | { |
||||
9 | use SlotRenderer; |
||||
10 | |||||
11 | public $html; |
||||
12 | |||||
13 | private $_viewData; |
||||
14 | |||||
15 | private $_policies; |
||||
16 | |||||
17 | /** |
||||
18 | * BaseWidget constructor. |
||||
19 | */ |
||||
20 | 25 | public function __construct() |
|||
21 | { |
||||
22 | 25 | $this->_policies = resolve(Policies::class); |
|||
23 | 25 | } |
|||
24 | |||||
25 | /** |
||||
26 | * @param $widget object|string |
||||
27 | * @param array $args |
||||
28 | * @return string |
||||
29 | */ |
||||
30 | 22 | public function renderWidget($widget, ...$args) |
|||
31 | { |
||||
32 | 22 | if (is_string($widget)) { |
|||
33 | 1 | $widget = $this->makeWidgetObj($widget); |
|||
34 | } |
||||
35 | |||||
36 | 22 | if (is_array($widget)) { |
|||
37 | $widget = (object) $widget; |
||||
38 | } |
||||
39 | |||||
40 | 22 | event('widgetize.rendering_widget', [$widget]); |
|||
41 | |||||
42 | 22 | resolve(Normalizer::class)->normalizeWidgetConfig($widget); |
|||
43 | |||||
44 | 22 | if (app()->offsetExists('debugbar')) { |
|||
45 | app('widgetize.debugger')->addMessage(['widget class:' => $widget, 'args:' => $args]); |
||||
46 | } |
||||
47 | |||||
48 | 22 | return $this->generateHtml($widget, ...$args); |
|||
49 | } |
||||
50 | |||||
51 | /** |
||||
52 | * @param $widget object |
||||
53 | * @return \Illuminate\Foundation\Application|mixed |
||||
54 | */ |
||||
55 | 1 | private function makeWidgetObj($widget) |
|||
56 | { |
||||
57 | 1 | if (Str::startsWith($widget, ['\\'])) { |
|||
58 | return resolve($widget); |
||||
59 | } |
||||
60 | |||||
61 | 1 | $widget = app()->getNamespace().'Widgets\\'.$widget; |
|||
0 ignored issues
–
show
introduced
by
![]() |
|||||
62 | |||||
63 | 1 | return resolve($widget); |
|||
64 | } |
||||
65 | |||||
66 | /** |
||||
67 | * It tries to get the html from cache if possible, otherwise generates it. |
||||
68 | * |
||||
69 | * @param $widget object |
||||
70 | * @param array ...$args |
||||
71 | * @return string |
||||
72 | */ |
||||
73 | private function generateHtml($widget, ...$args) |
||||
74 | { |
||||
75 | // Everything inside this function is executed only when the cache is not available. |
||||
76 | 22 | $expensivePhpCode = function () use ($widget, $args) { |
|||
77 | 20 | $this->makeDataForView($widget, $args); |
|||
78 | |||||
79 | 20 | return $this->renderTemplate($widget, ...$args); |
|||
0 ignored issues
–
show
$args is expanded, but the parameter $args of Imanghafoori\Widgets\Uti...derer::renderTemplate() does not expect variable arguments.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
80 | 22 | }; |
|||
81 | |||||
82 | 22 | if (! $widget->cacheView) { |
|||
83 | 2 | return $expensivePhpCode(); |
|||
84 | } |
||||
85 | |||||
86 | // We first try to get the output from the cache before trying to run the expensive $expensivePhpCode... |
||||
87 | 21 | return resolve(Cache::class)->cacheResult($args, $expensivePhpCode, $widget); |
|||
0 ignored issues
–
show
Are you sure the usage of
resolve(Imanghafoori\Wid...ensivePhpCode, $widget) targeting Imanghafoori\Widgets\Utils\Cache::cacheResult() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||
88 | } |
||||
89 | |||||
90 | /** |
||||
91 | * @param $widget object |
||||
92 | * @param $args array |
||||
93 | * @return null |
||||
94 | */ |
||||
95 | private function makeDataForView($widget, array $args) |
||||
96 | { |
||||
97 | 20 | $expensiveCode = function () use ($widget, $args) { |
|||
98 | 20 | $viewData = $this->callController($widget, $args); |
|||
99 | |||||
100 | 20 | if ($widget->presenter) { |
|||
101 | // Pipe the data through the presenter before sending it to view. |
||||
102 | 1 | $viewData = \App::call($widget->presenter, [$viewData]); |
|||
103 | } |
||||
104 | |||||
105 | 20 | return $viewData; |
|||
106 | 20 | }; |
|||
107 | |||||
108 | 20 | if ($widget->cacheView) { |
|||
109 | 19 | $this->_viewData = $expensiveCode(); |
|||
110 | } else { |
||||
111 | 2 | $this->_viewData = resolve(Cache::class)->cacheResult($args, $expensiveCode, $widget, 'dataProvider'); |
|||
0 ignored issues
–
show
Are you sure the assignment to
$this->_viewData is correct as resolve(Imanghafoori\Wid...widget, 'dataProvider') targeting Imanghafoori\Widgets\Utils\Cache::cacheResult() seems to always return null.
This check looks for function or method calls that always return null and whose return value is assigned to a variable. class A
{
function getObject()
{
return null;
}
}
$a = new A();
$object = $a->getObject();
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||
112 | } |
||||
113 | 20 | } |
|||
114 | |||||
115 | /** |
||||
116 | * @param $widget object |
||||
117 | * @param null $args |
||||
0 ignored issues
–
show
|
|||||
118 | * @return string HTML output |
||||
119 | * |
||||
120 | * @throws \Throwable |
||||
121 | */ |
||||
122 | 20 | private function renderTemplate($widget, $args = null) |
|||
123 | { |
||||
124 | // Here we render the view file to raw html. |
||||
125 | 20 | $data = [$widget->contextAs => $this->_viewData, 'params' => $args]; |
|||
126 | |||||
127 | // add slots if exists |
||||
128 | 20 | $this->hasSlots() && $data['slots'] = $this->getSlots(); |
|||
129 | |||||
130 | try { |
||||
131 | 20 | $this->html = view($widget->template, $data)->render(); |
|||
132 | } catch (\Throwable $t) { |
||||
133 | throw new \ErrorException('There was some error rendering '.get_class($widget).', template file: \''.$widget->template.'\' Error: '.$t->getMessage()); |
||||
134 | } |
||||
135 | |||||
136 | // We try to minify the html before storing it in cache to save space. |
||||
137 | 20 | if ($this->_policies->widgetShouldBeMinified($widget)) { |
|||
138 | 9 | $this->html = resolve(HtmlMinifier::class)->minify($this->html); |
|||
139 | } |
||||
140 | |||||
141 | // We add some HTML comments before and after the widget output |
||||
142 | // So then, we will be able to easily identify the widget in browser's developer tool. |
||||
143 | 20 | if ($this->_policies->widgetShouldHaveDebugInfo()) { |
|||
144 | 10 | $this->html = resolve(DebugInfo::class)->addIdentifierToHtml($widget, $this->html); |
|||
145 | } |
||||
146 | |||||
147 | 20 | return $this->html; |
|||
148 | } |
||||
149 | |||||
150 | 20 | private function callController($widget, array $args) |
|||
151 | { |
||||
152 | 20 | if (! isset($widget->controller)) { |
|||
153 | $viewData = []; |
||||
154 | 20 | } elseif (is_array($widget->controller) && is_string($widget->controller[0])) { |
|||
155 | $viewData = call_user_func_array($widget->controller, $args); |
||||
156 | } else { |
||||
157 | // Here we call the data method on the widget class. |
||||
158 | 20 | $viewData = \App::call($widget->controller, ...$args); |
|||
0 ignored issues
–
show
$args is expanded, but the parameter $parameters of Illuminate\Foundation\Application::call() does not expect variable arguments.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
159 | } |
||||
160 | |||||
161 | 20 | return $viewData; |
|||
162 | } |
||||
163 | } |
||||
164 |