Passed
Push — master ( 4f4caa...6a3ad3 )
by Iman
02:28
created

WidgetRenderer::renderWidget()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4.5923

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 4
eloc 12
c 3
b 0
f 0
nc 8
nop 2
dl 0
loc 21
ccs 8
cts 12
cp 0.6667
crap 4.5923
rs 9.8666
1
<?php
2
3
namespace Imanghafoori\Widgets\Utils;
4
5
use Illuminate\Contracts\Debug\ExceptionHandler;
6
7
class WidgetRenderer
8
{
9
    public $html;
10
11
    private $_viewData;
12
13
    private $_policies;
14
15
    /**
16
     * BaseWidget constructor.
17
     */
18 20
    public function __construct()
19
    {
20 20
        $this->_policies = app(Policies::class);
21 20
    }
22
23
    /**
24
     * @param $widget object|string
25
     * @param array $args
26
     * @return string
27
     */
28 20
    public function renderWidget($widget, ...$args)
29
    {
30 20
        if (is_string($widget)) {
31 1
            $widget = $this->makeWidgetObj($widget);
32
        }
33 20
        event('widgetize.rendering_widget', [$widget]);
34
35 20
        app(Normalizer::class)->normalizeWidgetConfig($widget);
36
37 20
        if (app()->offsetExists('debugbar')) {
38
            app('widgetize.debugger')->addMessage(['widget class:' => $widget, 'args:' => $args]);
39
        }
40
41
        try {
42 20
            $html = $this->generateHtml($widget, ...$args);
43
        } catch (\Exception $e) {
44
            dd($e);
45
            return app()->make(ExceptionHandler::class)->render(app('request'), $e)->send();
46
        }
47
48 20
        return $html;
49
    }
50
51
    /**
52
     * @param $widget object
53
     * @return \Illuminate\Foundation\Application|mixed
54
     */
55 1
    private function makeWidgetObj($widget)
56
    {
57 1
        if (starts_with($widget, ['\\'])) {
58
            return app($widget);
59
        }
60
61 1
        $widget = app()->getNamespace().'Widgets\\'.$widget;
0 ignored issues
show
introduced by
The method getNamespace() does not exist on Illuminate\Container\Container. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

61
        $widget = app()->/** @scrutinizer ignore-call */ getNamespace().'Widgets\\'.$widget;
Loading history...
62
63 1
        return app($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
     *
72
     * @return string
73
     */
74
    private function generateHtml($widget, ...$args)
75
    {
76
        // Everything inside this function is executed only when the cache is not available.
77 20
        $expensivePhpCode = function () use ($widget, $args) {
78 18
            $this->makeDataForView($widget, $args);
79
80 18
            return $this->renderTemplate($widget);
81 20
        };
82
83 20
        if (! $widget->cacheView) {
84 2
            return $expensivePhpCode();
85
        }
86
87
        // We first try to get the output from the cache before trying to run the expensive $expensivePhpCode...
88 19
        return app(Cache::class)->cacheResult($args, $expensivePhpCode, $widget);
0 ignored issues
show
Bug introduced by
Are you sure the usage of app(Imanghafoori\Widgets...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 getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
89
    }
90
91
    /**
92
     * @param $widget object
93
     * @param $args array
94
     *
95
     * @return null
96
     */
97
    private function makeDataForView($widget, array $args)
98
    {
99 18
        $expensiveCode = function () use ($widget, $args) {
100
101
            // Here we call the data method on the widget class.
102 18
            $viewData = \App::call($widget->controller, ...$args);
0 ignored issues
show
Bug introduced by
$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 ignore-type  annotation

102
            $viewData = \App::call($widget->controller, /** @scrutinizer ignore-type */ ...$args);
Loading history...
103
104 18
            if (($widget->presenter)) {
105
                // We make an object and call the `present` method on it.
106
                // Piping the data through the presenter before sending it to view.
107 1
                $viewData = \App::call($widget->presenter, [$viewData]);
108
            }
109
110 18
            return $viewData;
111 18
        };
112
113 18
        if ($widget->cacheView) {
114 17
            $this->_viewData = $expensiveCode();
115
        } else {
116 2
            $this->_viewData = app(Cache::class)->cacheResult($args, $expensiveCode, $widget, 'dataProvider');
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $this->_viewData is correct as app(Imanghafoori\Widgets...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 getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
117
        }
118 18
    }
119
120
    /**
121
     * @param $widget object
122
     * @return string HTML output
123
     * @throws \Throwable
124
     */
125 18
    private function renderTemplate($widget)
126
    {
127
        // Here we render the view file to raw html.
128
        try {
129 18
            $this->html = view($widget->template, [$widget->contextAs => $this->_viewData])->render();
130
        } catch (\Exception $e) {
131
            dd($e);
132
        }
133
134
        // We try to minify the html before storing it in cache to save space.
135 18
        if ($this->_policies->widgetShouldBeMinified($widget)) {
136 9
            $this->html = app(HtmlMinifier::class)->minify($this->html);
137
        }
138
139
        // We add some HTML comments before and after the widget output
140
        // So then, we will be able to easily identify the widget in browser's developer tool.
141 18
        if ($this->_policies->widgetShouldHaveDebugInfo()) {
142 8
            $this->html = app(DebugInfo::class)->addIdentifierToHtml($widget, $this->html);
143
        }
144
145 18
        return $this->html;
146
    }
147
}
148