imanghafoori1 /
laravel-widgetize
| 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
Loading history...
|
|||||
| 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
Loading history...
|
|||||
| 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. Loading history...
|
|||||
| 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. Loading history...
|
|||||
| 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
Loading history...
|
|||||
| 159 | } |
||||
| 160 | |||||
| 161 | 20 | return $viewData; |
|||
| 162 | } |
||||
| 163 | } |
||||
| 164 |