Passed
Push — master ( 82f522...91162e )
by Iman
03:01
created

WidgetRenderer   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Test Coverage

Coverage 90.7%

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 41
c 5
b 0
f 0
dl 0
loc 137
ccs 39
cts 43
cp 0.907
rs 10
wmc 16

6 Methods

Rating   Name   Duplication   Size   Complexity  
A makeWidgetObj() 0 9 2
A renderWidget() 0 19 4
A __construct() 0 3 1
A renderTemplate() 0 17 3
A makeDataForView() 0 24 3
A generateHtml() 0 16 3
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 15
    public function __construct()
19
    {
20 15
        $this->_policies = app(Policies::class);
21 15
    }
22
23
    /**
24
     * @param $widget object|string
25
     * @param array $args
26
     * @return string
27
     */
28 15
    public function renderWidget($widget, ...$args)
29
    {
30 15
        if (is_string($widget)) {
31 1
            $widget = $this->makeWidgetObj($widget);
32
        }
33
34 15
        app(Normalizer::class)->normalizeWidgetConfig($widget);
35
36 15
        if (app()->offsetExists('debugbar')) {
37
            app('widgetize.debugger')->addMessage(['widget class:' => $widget, 'args:' => $args]);
38
        }
39
40
        try {
41 15
            $html = $this->generateHtml($widget, ...$args);
42
        } catch (\Exception $e) {
43
            return app()->make(ExceptionHandler::class)->render(app('request'), $e)->send();
44
        }
45
46 15
        return $html;
47
    }
48
49
    /**
50
     * @param $widget object
51
     * @return \Illuminate\Foundation\Application|mixed
52
     */
53 1
    private function makeWidgetObj($widget)
54
    {
55 1
        if (starts_with($widget, ['\\'])) {
56
            return app($widget);
57
        }
58
59 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

59
        $widget = app()->/** @scrutinizer ignore-call */ getNamespace().'Widgets\\'.$widget;
Loading history...
60
61 1
        return app($widget);
62
    }
63
64
    /**
65
     * It tries to get the html from cache if possible, otherwise generates it.
66
     *
67
     * @param $widget object
68
     * @param array ...$args
69
     *
70
     * @return string
71
     */
72
    private function generateHtml($widget, ...$args)
73
    {
74
        // Everything inside this function is executed only when the cache is not available.
75 15
        $expensivePhpCode = function () use ($widget, $args) {
76 13
            $this->makeDataForView($widget, $args);
77
78
            // render the template with the resulting data.
79 13
            return $this->renderTemplate($widget);
80 15
        };
81
82
        // We first try to get the output from the cache before trying to run the expensive $expensivePhpCode...
83 15
        if ($this->_policies->widgetShouldUseCache() && $widget->cacheView) {
84 6
            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...
85
        }
86
87 9
        return $expensivePhpCode();
88
    }
89
90
    /**
91
     * @param $widget object
92
     * @param $args array
93
     *
94
     * @return null
95
     */
96
    private function makeDataForView($widget, array $args)
97
    {
98 13
        $expensiveCode = function () use ($widget, $args) {
99
100
            // Here we call the data method on the widget class.
101 13
            $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

101
            $viewData = \App::call($widget->controller, /** @scrutinizer ignore-type */ ...$args);
Loading history...
102
103 13
            if (($widget->presenter)) {
104
                // We make an object and call the `present` method on it.
105
                // Piping the data through the presenter before sending it to view.
106 1
                $viewData = \App::call($widget->presenter, [$viewData]);
107
                
108
            }
109
            
110 13
            return $viewData;
111 13
        };
112
113 13
        if (! $widget->cacheView) {
114 1
            $viewData = app(Cache::class)->cacheResult($args, $expensiveCode, $widget, 'dataProvider');
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $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...
115
        } else {
116 12
            $viewData = $expensiveCode();
117
        }
118
119 13
        $this->_viewData = $viewData;
120 13
    }
121
122
    /**
123
     * @param $widget object
124
     * @return string HTML output
125
     * @throws \Throwable
126
     */
127 13
    private function renderTemplate($widget)
128
    {
129
        // Here we render the view file to raw html.
130 13
        $this->html = view($widget->template, [$widget->contextAs => $this->_viewData])->render();
131
132
        // We try to minify the html before storing it in cache to save space.
133 13
        if ($this->_policies->widgetShouldBeMinified()) {
134 7
            $this->html = app(HtmlMinifier::class)->minify($this->html);
135
        }
136
137
        // We add some HTML comments before and after the widget output
138
        // So then, we will be able to easily identify the widget in browser's developer tool.
139 13
        if ($this->_policies->widgetShouldHaveDebugInfo()) {
140 6
            $this->html = app(DebugInfo::class)->addIdentifierToHtml($widget, $this->html);
141
        }
142
143 13
        return $this->html;
144
    }
145
}
146