Completed
Pull Request — master (#4321)
by xiaohui
02:28
created

Dialog::buildActionPromise()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 60

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 5
nop 0
dl 0
loc 60
rs 8.8727
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Encore\Admin\Actions\Interactor;
4
5
use Encore\Admin\Admin;
6
7
class Dialog extends Interactor
8
{
9
    /**
10
     * @var bool
11
     */
12
    protected $uploadFile = false;
13
14
    /**
15
     * @var array
16
     */
17
    protected $settings;
18
19
    /**
20
     * @param string $title
21
     * @param string $text
22
     * @param array  $options
23
     *
24
     * @return Dialog
25
     */
26
    public function success($title, $text = '', $options = [])
27
    {
28
        return $this->addSettings($title, __FUNCTION__, $text, $options);
29
    }
30
31
    /**
32
     * @param string $title
33
     * @param string $text
34
     * @param array  $options
35
     *
36
     * @return Dialog
37
     */
38
    public function error($title, $text = '', $options = [])
39
    {
40
        return $this->addSettings($title, __FUNCTION__, $text, $options);
41
    }
42
43
    /**
44
     * @param string $title
45
     * @param string $text
46
     * @param array  $options
47
     *
48
     * @return $this
49
     */
50
    public function warning($title, $text = '', $options = [])
51
    {
52
        return $this->addSettings($title, __FUNCTION__, $text, $options);
53
    }
54
55
    /**
56
     * @param string $title
57
     * @param string $text
58
     * @param array  $options
59
     *
60
     * @return Dialog
61
     */
62
    public function info($title, $text = '', $options = [])
63
    {
64
        return $this->addSettings($title, __FUNCTION__, $text, $options);
65
    }
66
67
    /**
68
     * @param string $title
69
     * @param string $text
70
     * @param array  $options
71
     *
72
     * @return Dialog
73
     */
74
    public function question($title, $text = '', $options = [])
75
    {
76
        return $this->addSettings($title, __FUNCTION__, $text, $options);
77
    }
78
79
    /**
80
     * @param string $title
81
     * @param string $text
82
     * @param array  $options
83
     *
84
     * @return Dialog
85
     */
86
    public function confirm($title, $text = '', $options = [])
87
    {
88
        return $this->addSettings($title, 'question', $text, $options);
89
    }
90
91
    /**
92
     * @param string $title
93
     * @param string $type
94
     * @param string $text
95
     * @param array  $options
96
     *
97
     * @return $this
98
     */
99
    protected function addSettings($title, $type, $text = '', $options = [])
100
    {
101
        $this->settings = array_merge(
102
            compact('title', 'text', 'type'),
103
            $options
104
        );
105
106
        return $this;
107
    }
108
109
    /**
110
     * @return array
111
     */
112
    protected function defaultSettings()
113
    {
114
        $trans = [
115
            'cancel' => trans('admin.cancel'),
116
            'submit' => trans('admin.submit'),
117
        ];
118
119
        return [
120
            'type'                => 'question',
121
            'showCancelButton'    => true,
122
            'showLoaderOnConfirm' => true,
123
            'confirmButtonText'   => $trans['submit'],
124
            'cancelButtonText'    => $trans['cancel'],
125
        ];
126
    }
127
128
    /**
129
     * @return string
130
     */
131
    protected function formatSettings()
132
    {
133
        if (empty($this->settings)) {
134
            return '';
135
        }
136
137
        $settings = array_merge($this->defaultSettings(), $this->settings);
138
139
        return trim(substr(json_encode($settings, JSON_PRETTY_PRINT), 1, -1));
140
    }
141
142
    /**
143
     * @return void
144
     */
145
    public function addScript()
146
    {
147
        $parameters = json_encode($this->action->parameters());
148
149
        $script = <<<SCRIPT
150
151
(function ($) {
152
    $('{$this->action->selector($this->action->selectorPrefix)}').off('{$this->action->event}').on('{$this->action->event}', function() {
153
        var data = $(this).data();
154
        var target = $(this);
155
        Object.assign(data, {$parameters});
156
        {$this->action->actionScript()}
157
        {$this->buildActionPromise()}
158
        {$this->action->handleActionPromise()}
159
    });
160
})(jQuery);
161
162
SCRIPT;
163
164
        Admin::script($script);
165
    }
166
167
    /**
168
     * @return string
169
     */
170
    protected function buildActionPromise()
171
    {
172
        call_user_func([$this->action, 'dialog']);
173
174
        $route = $this->action->getHandleRoute();
175
        $settings = $this->formatSettings();
176
        $calledClass = $this->action->getCalledClass();
177
178
        if ($this->uploadFile) {
179
            return $this->buildUploadFileActionPromise($settings, $calledClass, $route);
0 ignored issues
show
Bug introduced by
It seems like $route defined by $this->action->getHandleRoute() on line 174 can also be of type object<Illuminate\Contracts\Routing\UrlGenerator>; however, Encore\Admin\Actions\Int...loadFileActionPromise() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
180
        }
181
182
        $controller = '';
183
        if (request()->route()) {
184
            $controller = request()->route()->getController();
185
        }
186
        if ($controller) {
187
            $controller = str_replace('\\', '_', get_class($controller));
188
        }
189
190
        return <<<PROMISE
191
        var process = $.admin.swal({
192
            {$settings},
193
            preConfirm: function(input) {
194
                return new Promise(function(resolve, reject) {
195
                    Object.assign(data, {
196
                        _token: $.admin.token,
197
                        _action: '$calledClass',
198
                        _controller: '$controller',
199
                        _input: input,
200
                    });
201
202
                    $.ajax({
203
                        method: '{$this->action->getMethod()}',
204
                        url: '$route',
205
                        data: data,
206
                        success: function (data) {
207
                            resolve(data);
208
                        },
209
                        error:function(request){
210
                            reject(request);
211
                        }
212
                    });
213
                });
214
            }
215
        }).then(function(result) {
216
            if (typeof result.dismiss !== 'undefined') {
217
                return Promise.reject();
218
            }
219
220
            if (typeof result.status === "boolean") {
221
                var response = result;
222
            } else {
223
                var response = result.value;
224
            }
225
226
            return [response, target];
227
        });
228
PROMISE;
229
    }
230
231
    /**
232
     * @param string $settings
233
     * @param string $calledClass
234
     * @param string $route
235
     *
236
     * @return string
237
     */
238
    protected function buildUploadFileActionPromise($settings, $calledClass, $route)
239
    {
240
        return <<<PROMISE
241
var process = $.admin.swal({
242
    {$settings}
243
}).then(function (file) {
244
    return new Promise(function (resolve) {
245
        var data = {
246
            _token: $.admin.token,
247
            _action: '$calledClass',
248
        };
249
250
        var formData = new FormData();
251
        for ( var key in data ) {
252
            formData.append(key, data[key]);
253
        }
254
255
        formData.append('_input', file.value, file.value.name);
256
257
        $.ajax({
258
            url: '{$route}',
259
            type: 'POST',
260
            data: formData,
261
            processData: false,
262
            contentType: false,
263
            enctype: 'multipart/form-data',
264
            success: function (data) {
265
                resolve([response, target]);
266
            },
267
            error:function(request){
268
                reject(request);
269
            }
270
        });
271
    });
272
})
273
PROMISE;
274
    }
275
}
276