Completed
Push — master ( ab60f2...c901a1 )
by Ricardo
07:00
created

FieldController::update()   F

Complexity

Conditions 30
Paths 5283

Size

Total Lines 103

Duplication

Lines 8
Ratio 7.77 %

Importance

Changes 0
Metric Value
dl 8
loc 103
rs 0
c 0
b 0
f 0
cc 30
nc 5283
nop 3

How to fix   Long Method    Complexity   

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 Fabrica\Http\Api;
4
5
use Illuminate\Http\Request;
6
use Illuminate\Support\Facades\Event;
7
8
use Fabrica\Events\FieldChangeEvent;
9
use Fabrica\Events\FieldDeleteEvent;
10
use Fabrica\Http\Requests;
11
use Fabrica\Http\Api\Controller;
12
use Fabrica\Customization\Eloquent\Field;
13
use Fabrica\Customization\Eloquent\Screen;
14
use Fabrica\Project\Eloquent\Project;
15
use Fabrica\Project\Provider;
16
17
use DB;
18
19
class FieldController extends Controller
20
{
21
    private $special_fields = [
22
        'id', 
23
        'type', 
24
        'state', 
25
        'reporter', 
26
        'modifier', 
27
        'created_at', 
28
        'updated_at', 
29
        'resolved_at', 
30
        'closed_at', 
31
        'regression_times', 
32
        'his_resolvers',
33
        'resolved_logs',
34
        'no', 
35
        'schema', 
36
        'parent_id', 
37
        'parent', 
38
        'links', 
39
        'subtasks', 
40
        'entry_id', 
41
        'definition_id', 
42
        'comments_num', 
43
        'worklogs_num', 
44
        'gitcommits_num', 
45
        'sprint', 
46
        'sprints', 
47
        'filter', 
48
        'from',
49
        'from_kanban_id',
50
        'limit',
51
        'page',
52
        'orderBy',
53
        'stat_x',
54
        'stat_y',
55
    ];
56
57
    private $sys_fields = [
58
        'title',
59
        'priority',
60
        'resolution',
61
        'assignee',
62
        'module',
63
        'comments',
64
        'resolve_version',
65
        'effect_versions',
66
        'expect_complete_time',
67
        'expect_start_time',
68
        'progress',
69
        'related_users',
70
        'descriptions',
71
        'epic',
72
        'labels',
73
        'original_estimate',
74
        'story_points',
75
        'attachments'
76
    ];
77
78
    private $all_types = [
79
        'Tags', 
80
        'Integer', 
81
        'Number', 
82
        'Text', 
83
        'TextArea', 
84
        'Select', 
85
        'MultiSelect', 
86
        'RadioGroup', 
87
        'CheckboxGroup', 
88
        'DatePicker', 
89
        'DateTimePicker', 
90
        'TimeTracking', 
91
        'File', 
92
        'SingleVersion', 
93
        'MultiVersion', 
94
        'SingleUser', 
95
        'MultiUser', 
96
        'Url'
97
    ];
98
    /**
99
     * Display a listing of the resource.
100
     *
101
     * @return \Illuminate\Http\Response
102
     */
103
    public function index($project_key)
104
    {
105
        $fields = Provider::getFieldList($project_key);
106
        foreach ($fields as $field)
107
        {
108
            $field->screens = Screen::whereRaw([ 'field_ids' => $field->id ])
109
                ->orderBy('project_key', 'asc')
110
                ->get(['project_key', 'name'])
111
                ->toArray();
112
113
            $field->is_used = !!($field->screens);
114
115
            $field->screens = array_filter($field->screens, function($item) use($project_key) { 
116
                return $item['project_key'] === $project_key || $item['project_key'] === '$_sys_$';
117
            });
118
        }
119
        $types = Provider::getTypeList($project_key, ['name']);
120
        return Response()->json(['ecode' => 0, 'data' => $fields, 'options' => [ 'types' => $types ]]);
0 ignored issues
show
Bug introduced by
The method json does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
121
    }
122
123
    /**
124
     * Store a newly created resource in storage.
125
     *
126
     * @param  \Illuminate\Http\Request  $request
127
     * @return \Illuminate\Http\Response
128
     */
129
    public function store(Request $request, $project_key)
130
    {
131
        $name = $request->input('name');
132
        if (!$name)
133
        {
134
            throw new \UnexpectedValueException('the name cannot be empty.', -12200);
135
        }
136
137
        $key = $request->input('key');
138
        if (!$key)
139
        {
140
            throw new \InvalidArgumentException('field key cannot be empty.', -12201);
141
        }
142
143
        if (in_array($key, $this->special_fields))
144
        {
145
            throw new \InvalidArgumentException('field key has been used by system.', -12202);
146
        }
147
148
        if (Provider::isFieldKeyExisted($project_key, $key))
149
        {
150
            throw new \InvalidArgumentException('field key cannot be repeated.', -12203);
151
        }
152
153
        $type = $request->input('type');
154
        if (!$type)
155
        {
156
            throw new \UnexpectedValueException('the type cannot be empty.', -12204);
157
        }
158
159
        if ($type === 'TimeTracking' && Provider::isFieldKeyExisted($project_key, $key . '_m'))
160
        {
161
            throw new \InvalidArgumentException('field key cannot be repeated.', -12203);
162
        }
163
164
        if ($type === 'MultiUser' && Provider::isFieldKeyExisted($project_key, $key . '_ids'))
165
        {
166
            throw new \UnexpectedValueException('the type cannot be empty.', -12204);
167
        }
168
169
        if (!in_array($type, $this->all_types))
170
        {
171
            throw new \UnexpectedValueException('the type is incorrect type.', -12205);
172
        }
173
174
        $optionTypes = [ 'Select', 'MultiSelect', 'RadioGroup', 'CheckboxGroup' ];
175
        if (in_array($type, $optionTypes))
176
        {
177
            $optionValues = $request->input('optionValues') ?: [];
178
            foreach ($optionValues as $key => $val)
179
            {
180
                if (!isset($val['name']) || !$val['name'])
181
                {
182
                    continue;
183
                }
184
                $optionValues[$key]['id'] = md5(microtime() . $val['name']);
185
            }
186
187
            $defaultValue = $request->input('defaultValue') ?: '';
188
            if ($defaultValue)
189
            {
190
                $defaults = is_array($defaultValue) ? $defaultValue : explode(',', $defaultValue);
191
                $options = array_column($optionValues, 'id');
192 View Code Duplication
                if ('MultiSelect' === $type || 'CheckboxGroup' === $type)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
193
                {
194
                    $defaultValue = array_values(array_intersect($defaults, $options));
195
                }
196
                else
197
                {
198
                    $defaultValue = implode(',', array_intersect($defaults, $options));
199
                }
200
            }
201
            $field = Field::create([ 'project_key' => $project_key, 'optionValues' => $optionValues, 'defaultValue' => $defaultValue ] + $request->all());
202
        }
203
        else
204
        {
205
            $field = Field::create([ 'project_key' => $project_key ] + $request->all());
206
        }
207
        return Response()->json(['ecode' => 0, 'data' => $field]);
0 ignored issues
show
Bug introduced by
The method json does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
208
    }
209
210
    /**
211
     * Display the specified resource.
212
     *
213
     * @param  int  $id
214
     * @return \Illuminate\Http\Response
215
     */
216
    public function show($project_key, $id)
217
    {
218
        $field = Field::find($id);
219
        //if (!$field || $project_key != $field->project_key)
220
        //{
221
        //    throw new \UnexpectedValueException('the field does not exist or is not in the project.', -10002);
222
        //}
223
        // get related screen
224
        $field->screens = Screen::whereRaw([ 'field_ids' => $id ])->get(['name']);
225
226
        return Response()->json(['ecode' => 0, 'data' => $field]);
0 ignored issues
show
Bug introduced by
The method json does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
227
    }
228
229
    /**
230
     * Update the specified resource in storage.
231
     *
232
     * @param  \Illuminate\Http\Request  $request
233
     * @param  int  $id
234
     * @return \Illuminate\Http\Response
235
     */
236
    public function update(Request $request, $project_key, $id)
237
    {
238
        $name = $request->input('name');
239
        if (isset($name))
240
        {
241
            if (!$name)
242
            {
243
                throw new \UnexpectedValueException('the name can not be empty.', -12200);
244
            }
245
        }
246
247
        $field = Field::find($id);
248
        if (!$field || $project_key != $field->project_key)
249
        {
250
            throw new \UnexpectedValueException('the field does not exist or is not in the project.', -12206);
251
        }
252
253
        $updValues = [];
254
255
        $optionTypes = [ 'Select', 'MultiSelect', 'RadioGroup', 'CheckboxGroup' ];
256
        if (in_array($field->type, $optionTypes))
257
        {
258
            $optionValues = $request->input('optionValues');
259
            $defaultValue = $request->input('defaultValue');
260
            if (isset($optionValues) || isset($defaultValue))
261
            {
262
                if (isset($optionValues))
263
                {
264
                    if (isset($field->optionValues) && $field->optionValues)
265
                    {
266
                        $old_option_ids = array_column($field->optionValues, 'id');
267
                    }
268
                    else
269
                    {
270
                        $old_option_ids = [];
271
                    }
272
273
                    foreach ($optionValues as $key => $val)
274
                    {
275
                        if (!isset($val['name']) || !$val['name'])
276
                        {
277
                            continue;
278
                        }
279
280
                        if (!isset($val['id']) || !in_array($val['id'], $old_option_ids))
281
                        {
282
                            $optionValues[$key]['id'] = md5(microtime() . $val['name']);
283
                        }
284
                    }
285
                }
286
                else
287
                {
288
                    $optionValues = $field->optionValues ?: [];
289
                }
290
                $updValues['optionValues'] = $optionValues;
291
292
                $options = array_column($optionValues, 'id');
293
                $defaultValue = isset($defaultValue) ? $defaultValue : ($field->defaultValue ?: '');
294
                $defaults = is_array($defaultValue) ? $defaultValue : explode(',', $defaultValue);
295 View Code Duplication
                if ('MultiSelect' === $field->type || 'CheckboxGroup' === $field->type)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
296
                {
297
                    $defaultValue = array_values(array_intersect($defaults, $options));
298
                }
299
                else
300
                {
301
                    $defaultValue = implode(',', array_intersect($defaults, $options));
302
                }
303
                $updValues['defaultValue'] = $defaultValue;
304
            }
305
        }
306
307
        $mmTypes = [ 'Number', 'Integer' ];
308
        if (in_array($field->type, $mmTypes))
309
        {
310
            $maxValue = $request->input('maxValue');
311
            if (isset($maxValue))
312
            {
313
                $updValues['maxValue'] = ($maxValue === '' ? '' : ($maxValue + 0));
314
            }
315
316
            $minValue = $request->input('minValue');
317
            if (isset($minValue))
318
            {
319
                $updValues['minValue'] = ($minValue === '' ? '' : ($minValue + 0));
320
            }
321
        }
322
323
        $mlTypes = [ 'Text', 'TextArea' ];
324
        if (in_array($field->type, $mlTypes))
325
        {
326
            $maxLength = $request->input('maxLength');
327
            if (isset($maxLength))
328
            {
329
                $updValues['maxLength'] = ($maxLength === '' ? '' : intval($maxLength));
330
            }
331
        }
332
333
        $field->fill($updValues + $request->except(['project_key', 'key', 'type']))->save();
334
335
        Event::fire(new FieldChangeEvent($id));
336
337
        return Response()->json(['ecode' => 0, 'data' => Field::find($id)]);
0 ignored issues
show
Bug introduced by
The method json does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
338
    }
339
340
    /**
341
     * Remove the specified resource from storage.
342
     *
343
     * @param  int  $id
344
     * @return \Illuminate\Http\Response
345
     */
346
    public function destroy($project_key, $id)
347
    {
348
        $field = Field::find($id);
349
        if (!$field || $project_key != $field->project_key)
350
        {
351
            throw new \UnexpectedValueException('the field does not exist or is not in the project.', -12206);
352
        }
353
354
        if (in_array($field->key, $this->sys_fields))
355
        {
356
            throw new \UnexpectedValueException('the field is built in the system.', -12208);
357
        }
358
359
        $isUsed = Screen::whereRaw([ 'field_ids' => $id ])->exists();
360
        if ($isUsed)
361
        {
362
            throw new \UnexpectedValueException('the field has been used in screen.', -12207);
363
        }
364
365
        Field::destroy($id);
366
367
        Event::fire(new FieldDeleteEvent($project_key, $id, $field->key, $field->type));
368
        return Response()->json(['ecode' => 0, 'data' => ['id' => $id]]);
0 ignored issues
show
Bug introduced by
The method json does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
369
    }
370
371
    /**
372
     * view the application in the all projects.
373
     *
374
     * @return \Illuminate\Http\Response
375
     */
376 View Code Duplication
    public function viewUsedInProject($project_key, $id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
377
    {
378
        if ($project_key !== '$_sys_$')
379
        {
380
            return Response()->json(['ecode' => 0, 'data' => [] ]);
0 ignored issues
show
Bug introduced by
The method json does only exist in Illuminate\Contracts\Routing\ResponseFactory, but not in Illuminate\Http\Response.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
381
        }
382
383
        $res = [];
384
        $projects = Project::all();
385
        foreach($projects as $project)
386
        {
387
            $screens = Screen::where('field_ids', $id)
388
                ->where('project_key', '<>', '$_sys_$')
389
                ->where('project_key', $project->key)
390
                ->get([ 'id', 'name' ])
391
                ->toArray();
392
393
            if ($screens)
394
            {
395
                $res[] = [ 'key' => $project->key, 'name' => $project->name, 'status' => $project->status, 'screens' => $screens ];
396
            }
397
        }
398
399
        return Response()->json(['ecode' => 0, 'data' => $res ]);
400
    }
401
}
402