WidgetFactory::prepareAsyncContent()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Rinvex\Widgets\Factories;
6
7
use Illuminate\Support\HtmlString;
8
use Rinvex\Widgets\Models\AbstractWidget;
9
use Rinvex\Widgets\Exceptions\WidgetException;
10
11
class WidgetFactory
12
{
13
    /**
14
     * Widget object to work with.
15
     *
16
     * @var \Rinvex\Widgets\Models\AbstractWidget
17
     */
18
    protected $widget;
19
20
    /**
21
     * Instantiate a widget instance.
22
     *
23
     * @param string $widget
24
     * @param array  $params
25
     * @param bool   $async
26
     *
27
     * @throws \Rinvex\Widgets\Exceptions\WidgetException
28
     *
29
     * @return \Illuminate\Support\HtmlString
30
     */
31
    public function make(string $widget, array $params = [], bool $async = false)
32
    {
33
        $widget = trim($widget, " \t\n\r\0\x0B\"'");
34
35
        if (! is_callable([$widget, 'make'])) {
36
            throw WidgetException::invalidMethod($widget);
37
        }
38
39
        if (! is_subclass_of($widget, AbstractWidget::class)) {
40
            throw WidgetException::invalidClass($widget);
41
        }
42
43
        $this->widget = new $widget($params);
44
        $content = $async ? $this->prepareAsyncContent() : $this->prepareContent();
45
46
        return new HtmlString($this->wrapContentInContainer($content));
47
    }
48
49
    /**
50
     * Wrap the given content in a container if it's not an async call.
51
     *
52
     * @param string $content
53
     *
54
     * @return string
55
     */
56
    protected function wrapContentInContainer(string $content): string
57
    {
58
        $widget = $this->widget;
59
60
        return empty($widget->getParam('async')) ? view($widget->getContainer(), compact('content', 'widget'))->render() : $content;
61
    }
62
63
    /**
64
     * Encrypt widget params to be transported via HTTP.
65
     *
66
     * @param array $params
67
     *
68
     * @return string
69
     */
70
    public function encryptWidgetParams(array $params = []): string
71
    {
72
        return app('encrypter')->encrypt(json_encode($params));
73
    }
74
75
    /**
76
     * Decrypt widget params that were transported via HTTP.
77
     *
78
     * @param string $params
79
     *
80
     * @return array
81
     */
82
    public function decryptWidgetParams(string $params = ''): array
83
    {
84
        return json_decode(app('encrypter')->decrypt($params), true) ?? [];
85
    }
86
87
    /**
88
     * Construct javascript code to load the widget.
89
     *
90
     * @param float $timeout
0 ignored issues
show
Documentation introduced by
Should the type for parameter $timeout not be integer|double?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
91
     *
92
     * @return string
93
     */
94
    protected function getLoader(float $timeout = 0): string
95
    {
96
        $timeout = $timeout * 1000;
97
        $asyncCall = $this->constructAsyncCall();
98
        $template = $timeout ? 'reloader' : 'loader';
99
100
        return view("rinvex/widgets::{$template}", compact('timeout', 'asyncCall'))->render();
101
    }
102
103
    /**
104
     * Construct async call for loaders.
105
     *
106
     * @throws \Throwable
107
     *
108
     * @return string
109
     */
110
    protected function constructAsyncCall(): string
111
    {
112
        $params = [
113
            'id' => $this->widget->getId(),
114
            'params' => $this->encryptWidgetParams($this->widget->getParams() + ['async' => true]),
115
        ];
116
117
        return view('rinvex/widgets::async', compact('params'))->render();
118
    }
119
120
    /**
121
     * Prepare widget content.
122
     *
123
     * @return string
124
     */
125
    protected function prepareContent(): string
126
    {
127
        $content = app()->call([$this->widget, 'make'], $this->widget->getParams());
128
        $content = is_object($content) ? $content->__toString() : $content;
129
130
        if ($timeout = $this->widget->getReloadTimeout()) {
131
            $content .= $this->getLoader($timeout);
132
        }
133
134
        return $content;
135
    }
136
137
    /**
138
     * Prepare async widget content.
139
     *
140
     * @return string
141
     */
142
    protected function prepareAsyncContent(): string
143
    {
144
        return is_callable([$this->widget, 'placeholder'])
145
            ? call_user_func([$this->widget, 'placeholder']).$this->getLoader() : $this->getLoader();
146
    }
147
}
148