ReportController::getRegressions()   F
last analyzed

Complexity

Conditions 43
Paths > 20000

Size

Total Lines 162

Duplication

Lines 43
Ratio 26.54 %

Importance

Changes 0
Metric Value
dl 43
loc 162
rs 0
c 0
b 0
f 0
cc 43
nc 23616
nop 2

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
use Fabrica\Project\Eloquent\Project;
8
use Fabrica\Project\Eloquent\Worklog;
9
use Fabrica\Project\Eloquent\ReportFilters;
10
use Fabrica\System\Eloquent\CalendarSingular;
11
12
use Fabrica\Http\Requests;
13
use Fabrica\Http\Api\Controller;
14
15
use Sentinel;
16
use DB;
17
use Fabrica\Project\Provider;
18
use Fabrica\Project\Eloquent\Sprint;
19
use Fabrica\Project\Eloquent\Version;
20
21
class ReportController extends Controller
22
{
23
    use TimeTrackTrait;
24
25
    private $default_filters = [
26
        'issues' => [
27
            [ 'id' => 'all_by_type', 'name' => '全部问题/按类型', 'query' => [ 'stat_x' => 'type', 'stat_y' => 'type' ] ], 
28
            [ 'id' => 'unresolved_by_assignee', 'name' => '未解决的/按经办人', 'query' => [ 'stat_x' => 'assignee', 'stat_y' => 'assignee', 'resolution' => 'Unresolved' ] ], 
29
            [ 'id' => 'unresolved_by_priority', 'name' => '未解决的/按优先级', 'query' => [ 'stat_x' => 'priority', 'stat_y' => 'priority', 'resolution' => 'Unresolved' ] ], 
30
            [ 'id' => 'unresolved_by_module', 'name' => '未解决的/按模块', 'query' => [ 'stat_x' => 'module', 'stat_y' => 'module', 'resolution' => 'Unresolved' ] ] 
31
        ], 
32
        'worklog' => [
33
            [ 'id' => 'all', 'name' => '全部填报', 'query' => [] ], 
34
            [ 'id' => 'in_one_month', 'name' => '过去一个月的', 'query' => [ 'recorded_at' => '1m' ] ], 
35
            [ 'id' => 'active_sprint', 'name' => '当前活动Sprint', 'query' => [] ], 
36
            [ 'id' => 'latest_completed_sprint', 'name' => '最近已完成Sprint', 'query' => [] ], 
37
            //[ 'id' => 'will_release_version', 'name' => '最近要发布版本', 'query' => [] ], 
38
            //[ 'id' => 'latest_released_version', 'name' => '最近已发布版本', 'query' => [] ], 
39
        ], 
40
        'timetracks' => [
41
            [ 'id' => 'all', 'name' => '全部问题', 'query' => [] ], 
42
            [ 'id' => 'unresolved', 'name' => '未解决的', 'query' => [ 'resolution' => 'Unresolved' ] ], 
43
            [ 'id' => 'active_sprint', 'name' => '当前活动Sprint', 'query' => [] ], 
44
            [ 'id' => 'latest_completed_sprint', 'name' => '最近已完成Sprint', 'query' => [] ], 
45
            //[ 'id' => 'will_release_version', 'name' => '最近要发布版本', 'query' => [] ], 
46
            //[ 'id' => 'latest_released_version', 'name' => '最近已发布版本', 'query' => [] ], 
47
        ], 
48
        'regressions' => [
49
            [ 'id' => 'all', 'name' => '已解决问题', 'query' => [] ], 
50
            [ 'id' => 'active_sprint', 'name' => '当前活动Sprint', 'query' => [] ], 
51
            [ 'id' => 'latest_completed_sprint', 'name' => '最近已完成Sprint', 'query' => [] ], 
52
        ],
53
        'trend' => [
54
            [ 'id' => 'day_in_one_month', 'name' => '问题每日变化趋势', 'query' => [ 'stat_time' => '1m' ] ], 
55
            [ 'id' => 'week_in_two_months', 'name' => '问题每周变化趋势', 'query' => [ 'stat_time' => '2m', 'interval' => 'week' ] ], 
56
        ]
57
    ];
58
59
    private $mode_enum = [ 'issues', 'trend', 'worklog', 'timetracks', 'regressions', 'others' ];
60
61
    /**
62
     * Display a listing of the resource.
63
     *
64
     * @param  string $project_key
65
     * @return \Illuminate\Http\Response
66
     */
67
    public function index($project_key)
68
    {
69
        $filters = $this->default_filters;
70
71
        $res = ReportFilters::where('project_key', $project_key)
72
            ->where('user', $this->user->id)
73
            ->get();
74
        foreach($res as $v)
75
        {
76
            if (isset($v['filters'])) {
77
                $filters[$v['mode']] = $v['filters'];
78
            }
79
        }
80
81
        foreach($filters as $mode => $some_filters)
82
        {
83
            $filters[$mode] = $this->convFilters($project_key, $some_filters);
84
        }
85
86
        return response()->json([ 'ecode' => 0, 'data' => $filters ]);
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...
87
    }
88
89
    /**
90
     * convert the filters.
91
     *
92
     * @param  array $filters
93
     * @return \Illuminate\Http\Response
94
     */
95
    public function convFilters($project_key, $filters)
96
    {
97
        foreach($filters as $key => $filter)
98
        {
99
            if ($filter['id'] === 'active_sprint') {
100
                $sprint = Sprint::where('project_key', $project_key)
101
                    ->where('status', 'active')
102
                    ->first();
103 View Code Duplication
                if ($sprint) {
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...
104
                    $filters[$key]['query'] = [ 'sprints' => $sprint->no ];
105
                }
106
                else
107
                {
108
                    unset($filters[$key]);
109
                }
110
            }
111
            else if ($filter['id'] === 'latest_completed_sprint') {
112
                $sprint = Sprint::where('project_key', $project_key)
113
                    ->where('status', 'completed')
114
                    ->orderBy('no', 'desc')
115
                    ->first();
116 View Code Duplication
                if ($sprint) {
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...
117
                    $filters[$key]['query'] = [ 'sprints' => $sprint->no ];
118
                }
119
                else
120
                {
121
                    unset($filters[$key]);
122
                }
123
            }
124
            else if ($filter['id'] === 'will_release_version') {
125
                $version = Version::where('project_key', $project_key)
126
                    ->where('status', 'unreleased')
127
                    ->orderBy('name', 'asc')
128
                    ->first();
129 View Code Duplication
                if ($version) {
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...
130
                    $filters[$key]['query'] = [ 'resolve_version' => $version->id ];
131
                }
132
                else
133
                {
134
                    unset($filters[$key]);
135
                }
136
            }
137
            else if ($filter['id'] === 'latest_released_version') {
138
                $version = Version::where('project_key', $project_key)
139
                    ->where('status', 'released')
140
                    ->orderBy('name', 'desc')
141
                    ->first();
142 View Code Duplication
                if ($version) {
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...
143
                    $filters[$key]['query'] = [ 'resolve_version' => $version->id ];
144
                }
145
                else
146
                {
147
                    unset($filters[$key]);
148
                }
149
            }
150
        }
151
        return array_values($filters);
152
    }
153
154
    /**
155
     * get the mode filter.
156
     *
157
     * @param  string $project_key
158
     * @param  string $mode
159
     * @return \Illuminate\Http\Response
160
     */
161
    public function getSomeFilters($project_key, $mode)
162
    {
163
        if (!in_array($mode, $this->mode_enum)) {
164
            throw new \UnexpectedValueException('the mode value is error.', -11851);
165
        }
166
167
        $filters = isset($this->default_filters[$mode]) ? $this->default_filters[$mode] : []; 
168
169
        $res = ReportFilters::where('project_key', $project_key)
170
            ->where('mode', $mode)
171
            ->where('user', $this->user->id)
172
            ->first(); 
173
        if ($res) {
174
            $filters = isset($res->filters) ? $res->filters : [];
175
        }
176
177
        return response()->json([ 'ecode' => 0, 'data' => $filters ]);
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...
178
    }
179
180
    /**
181
     * save the custimized filter.
182
     *
183
     * @param  string $project_key
184
     * @param  string $mode
185
     * @return \Illuminate\Http\Response
186
     */
187
    public function saveFilter(Request $request, $project_key, $mode)
188
    {
189
        if (!in_array($mode, $this->mode_enum)) {
190
            throw new \UnexpectedValueException('the mode value is error.', -11851);
191
        }
192
193
        $name = $request->input('name');
194
        if (!$name) {
195
            throw new \UnexpectedValueException('the name can not be empty.', -11852);
196
        }
197
198
        $query = $request->input('query');
199
        if (!isset($query)) {
200
            throw new \UnexpectedValueException('the query can not be empty.', -11853);
201
        }
202
        
203
        $res = ReportFilters::where('project_key', $project_key)
204
            ->where('mode', $mode)
205
            ->where('user', $this->user->id)
206
            ->first();
207
        if ($res) {
208
            $filters = isset($res['filters']) ? $res['filters'] : [];
209
            array_push($filters, [ 'id' => md5(microtime()), 'name' => $name, 'query' => $query ]);
210
            $res->filters = $filters;
211
            $res->save();
212
        }
213
        else
214
        {
215
            $filters = $this->default_filters[$mode];
216
            array_push($filters, [ 'id' => md5(microtime()), 'name' => $name, 'query' => $query ]);
217
            ReportFilters::create([ 'project_key' => $project_key, 'mode' => $mode, 'user' => $this->user->id, 'filters' => $filters ]); 
218
        }
219
220
        return $this->getSomeFilters($project_key, $mode);
221
    }
222
223
    /**
224
     * reset the mode filters.
225
     *
226
     * @param  string $project_key
227
     * @param  string $mode
228
     * @return \Illuminate\Http\Response
229
     */
230
    public function resetSomeFilters(Request $request, $project_key, $mode)
231
    {
232
        if (!in_array($mode, $this->mode_enum)) {
233
            throw new \UnexpectedValueException('the mode value is error.', -11851);
234
        }
235
236
        ReportFilters::where('project_key', $project_key)
237
            ->where('mode', $mode)
238
            ->where('user', $this->user->id)
239
            ->delete();
240
        return $this->getSomeFilters($project_key, $mode);
241
    }
242
243
    /**
244
     * edit the mode filters.
245
     *
246
     * @param  string $project_key
247
     * @param  string $mode
248
     * @return \Illuminate\Http\Response
249
     */
250
    public function editSomeFilters(Request $request, $project_key, $mode)
251
    {
252
        if (!in_array($mode, $this->mode_enum)) {
253
            throw new \UnexpectedValueException('the mode value is error.', -11851);
254
        }
255
256
        $sequence = $request->input('sequence');
257
        if (isset($sequence)) {
258
            $old_filters = $this->default_filters[$mode]; 
259
260
            $res = ReportFilters::where('project_key', $project_key)
261
                ->where('mode', $mode)
262
                ->where('user', $this->user->id)
263
                ->first();
264
            if ($res) {
265
                $old_filters = isset($res->filters) ? $res->filters : [];
266
            }
267
            
268
            $new_filters = [];
269 View Code Duplication
            foreach ($sequence as $id)
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...
270
            {
271
                foreach ($old_filters as $filter)
272
                {
273
                    if ($filter['id'] === $id) {
274
                        $new_filters[] = $filter;
275
                        break;
276
                    }
277
                }
278
            }
279
280 View Code Duplication
            if ($res) {
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...
281
                $res->filters = $new_filters;
282
                $res->save();
283
            }
284
            else
285
            {
286
                ReportFilters::create([ 'project_key' => $project_key, 'mode' => $mode, 'user' => $this->user->id, 'filters' => $new_filters ]); 
287
            }
288
        }
289
290
        return $this->getSomeFilters($project_key, $mode);
291
    }
292
293
    /**
294
     * get worklog report pipeline.
295
     *
296
     * @param  string $project_key
297
     * @return \Illuminate\Http\Response
298
     */
299
    public function getWorklogWhere($project_key, $options)
300
    {
301
        $where = [];
302
303
        $issue_id = isset($options['issue_id']) ? $options['issue_id'] : '';
304
        if ($issue_id) {
305
            $where['issue_id'] = $issue_id;
306
        }
307
        else
308
        {
309
            $issue_ids = [];
310
311
            $query = DB::collection('issue_' . $project_key)->whereRaw($this->getIssueQueryWhere($project_key, $options));
312
            $issues = $query->get([ '_id' ]);
313
            foreach ($issues as $issue)
314
            {
315
                $issue_ids[] = $issue['_id']->__toString();
316
            }
317
            $where['issue_id'] = [ '$in' => $issue_ids ];
318
        }
319
320
        $cond = [];
321
        $recorded_at = isset($options['recorded_at']) ? $options['recorded_at'] : '';
322
        if ($recorded_at) {
323
            if (strpos($recorded_at, '~') !== false) {
324
                $sections = explode('~', $recorded_at);
325
                if ($sections[0]) {
326
                    $cond['$gte'] = strtotime($sections[0]);
327
                }
328
                if ($sections[1]) {
329
                    $cond['$lte'] = strtotime($sections[1] . ' 23:59:59');
330
                }
331
                if ($cond) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $cond of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
332
                    $where['recorded_at'] = $cond;
333
                }
334
            }
335
            else
336
            {
337
                $unitMap = [ 'w' => 'week', 'm' => 'month', 'y' => 'year' ];
338
                $unit = substr($recorded_at, -1);
339
                if (in_array($unit, [ 'w', 'm', 'y' ])) {
340
                    $direct = substr($recorded_at, 0, 1);
341
                    $val = abs(substr($recorded_at, 0, -1));
342
                    $time_val = strtotime(date('Ymd', strtotime('-' . $val . ' ' . $unitMap[$unit])));
343
344
                    if ($direct === '-') {
345
                        $cond['$lt'] = $time_val;
346
                    }
347
                    else
348
                    {
349
                        $cond['$gte'] = $time_val;
350
                    }
351
                    if ($cond) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $cond of type array<string,integer> is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
352
                        $where['recorded_at'] = $cond;
353
                    }
354
                }
355
            }
356
        }
357
358
        $recorder = isset($options['recorder']) ? $options['recorder'] : '';
359
        if ($recorder) {
360
            $where['recorder.id'] = $recorder;
361
        }
362
363
        $sprint_no = isset($options['sprints']) ? $options['sprints'] : '';
364
        if ($sprint_no) {
365
            $sprint = Sprint::where('project_key', $project_key)->where('no', intval($sprint_no))->first();
366
367
            $sprint_start_time = strtotime(date('Ymd', $sprint->start_time));
368
            if (!isset($cond['$gte']) || $cond['$gte'] < $sprint_start_time) {
369
                $cond['$gte'] = $sprint_start_time;
370
            }
371
372
            if (isset($sprint->real_complete_time) && $sprint->real_complete_time > 0) {
373
                $sprint_complet_time = strtotime(date('Ymd', $sprint->real_complete_time) . ' 23:59:59');
374
                if (!isset($cond['$lte']) || $cond['$lte'] > $sprint_complet_time) {
375
                    $cond['$lte'] = $sprint_complet_time; 
376
                }
377
            }
378
379
            $where['recorded_at'] = $cond;
380
        }
381
382
        $where['project_key'] = $project_key;
383
384
        return $where;
385
    }
386
387
    /**
388
     * get worklog detail report by issue.
389
     *
390
     * @param  string $project_key
391
     * @param  string $issue_id
392
     * @return \Illuminate\Http\Response
393
     */
394
    public function getWorklogDetail(Request $request, $project_key, $issue_id)
395
    {
396
        $total = Worklog::Where('project_key', $project_key)
397
            ->where('issue_id', $issue_id)
398
            ->orderBy('recorded_at', 'desc')
399
            ->get();
400
401
        $where = $this->getWorklogWhere($project_key, [ 'issue_id' => $issue_id ] + $request->all());
402
        $parts = Worklog::WhereRaw($where)
403
            ->orderBy('recorded_at', 'desc')
404
            ->get();
405
406
        return response()->json(['ecode' => 0, 'data' => [ 'total' => $total, 'parts' => $parts ] ]);
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...
407
    }
408
409
    /**
410
     * get worklog detail report by memeber.
411
     *
412
     * @param  string $project_key
413
     * @return \Illuminate\Http\Response
414
     */
415
    public function getWorklogList(Request $request, $project_key)
416
    {
417
        $pipeline = [];
418
419
        $where = $this->getWorklogWhere($project_key, $request->all());
420
        $pipeline[] = [ '$match' => $where ];
421
422
        $pipeline[] = [ '$group' => [ '_id' => '$issue_id', 'value' => [ '$sum' => '$spend_m' ] ] ];
423
424
        $ret = DB::collection('worklog')->raw(
425
            function ($col) use ($pipeline) {
426
                return $col->aggregate($pipeline);
427
            }
428
        );
429
430
        $new_results = [];
431
        $results = iterator_to_array($ret);
432
        foreach ($results as $k => $r)
433
        {
434
            $tmp = [];
435
            $tmp['total_value'] = $r['value'];
436
            $issue = DB::collection('issue_' . $project_key)
437
                ->where('_id', $r['_id'])
438
                ->first();
439
            $tmp['id']      = $issue['_id']->__toString();
440
            $tmp['no']      = $issue['no'];
441
            $tmp['title']   = $issue['title'];
442
            $tmp['state']   = $issue['state'];
443
            $tmp['type']    = $issue['type'];
444
            $new_results[]  = $tmp;
445
 
446
        }
447
448
        usort(
449
            $new_results, function ($a, $b) {
450
                return $a['no'] <= $b['no']; 
451
            }
452
        );
453
454
        return response()->json([ 'ecode' => 0, 'data' => $new_results ]);
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...
455
    }
456
457
    /**
458
     * get worklog report by project_key.
459
     *
460
     * @param  string $project_key
461
     * @return \Illuminate\Http\Response
462
     */
463
    public function getWorklogs(Request $request, $project_key)
464
    {
465
        $pipeline = [];
466
467
        $where = $this->getWorklogWhere($project_key, $request->all());
468
        $pipeline[] = [ '$match' => $where ];
469
470
        $pipeline[] = [ '$group' => [ '_id' => '$recorder.id', 'value' => [ '$sum' => '$spend_m' ] ] ]; 
471
472
        $ret = DB::collection('worklog')->raw(
473
            function ($col) use ($pipeline) {
474
                return $col->aggregate($pipeline);
475
            }
476
        );
477
478
        $others_val = 0;
479
        $results = iterator_to_array($ret);
480
        $new_results = [];
481
        foreach ($results as $r) 
482
        {
483
            $user = Sentinel::findById($r['_id']);
484
            if ($user) {
485
                $new_results[] = [ 'user' => [ 'id' => $user->id, 'name' => $user->first_name ], 'value' => $r['value'] ];
486
            }
487
            else
488
            {
489
                $others_val += $r['value'];
490
            }
491
        }
492
        if ($others_val > 0) {
493
            $new_results[] = [ 'user' => [ 'id' => 'other', 'name' => '' ], 'value' => $other_val ];
0 ignored issues
show
Bug introduced by
The variable $other_val does not exist. Did you mean $others_val?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
494
        }
495
496
        return response()->json([ 'ecode' => 0, 'data' => $new_results ]);
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...
497
    }
498
499
    /**
500
     * get worklog detail report by issue.
501
     *
502
     * @param  string $project_key
503
     * @param  string $issue_id
504
     * @return \Illuminate\Http\Response
505
     */
506
    public function getTimetracksDetail(Request $request, $project_key, $issue_id)
507
    {
508
        $worklogs = Worklog::Where('project_key', $project_key)
509
            ->where('issue_id', $issue_id)
510
            ->orderBy('recorded_at', 'desc')
511
            ->get();
512
513
        foreach($worklogs as $worklog)
514
        {
515
            if (!isset($worklog->spend_m) || !$worklog->spend_m) {
516
                $worklog->spend_m = $this->ttHandleInM($worklog->spend ?: '');
517
            }
518
        }
519
520
        return response()->json(['ecode' => 0, 'data' => $worklogs ]);
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...
521
    }
522
523
     /* get timetracks report by project_key.
524
     *
525
     * @param  string $project_key
526
     * @return \Illuminate\Http\Response
527
     */
528
    public function getTimetracks(Request $request, $project_key)
529
    {
530
        $where = $this->getIssueQueryWhere($project_key, $request->all());
531
532
        $scale = $request->input('scale');
533
        if ($scale === 'only') {
534
            $where['$and'][] = [ 'original_estimate' => [ '$exists' => 1, '$ne' => '' ] ];
535
        }
536
537
        $query = DB::collection('issue_' . $project_key)->whereRaw($where);
538
        $issues = $query->orderBy('no', 'desc')->take(10000)->get();
539
540
        $new_issues = [];
541
        foreach($issues as $issue)
542
        {
543
            $issue_id = $issue['_id']->__toString();
544
545
            $tmp['id']        = $issue_id;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$tmp was never initialized. Although not strictly required by PHP, it is generally a good practice to add $tmp = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
546
            $tmp['no']        = $issue['no'];
0 ignored issues
show
Bug introduced by
The variable $tmp does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
547
            $tmp['title']     = $issue['title'];
548
            $tmp['state']     = $issue['state'];
549
            $tmp['type']      = $issue['type'];
550
            $tmp['origin']    = isset($issue['original_estimate']) ? $issue['original_estimate'] : '';
551
            $tmp['origin_m']  = isset($issue['original_estimatei_m']) ? $issue['original_estimatei_m'] : $this->ttHandleInM($tmp['origin']);
552
553
            $spend_m = 0;
554
            $left_m = $tmp['origin_m'];
555
            $worklogs = Worklog::Where('project_key', $project_key)
556
                ->where('issue_id', $issue_id)
557
                ->orderBy('recorded_at', 'asc')
558
                ->get();
559
            foreach($worklogs as $log)
560
            {
561
                $this_spend_m = isset($log['spend_m']) ? $log['spend_m'] : $this->ttHandleInM(isset($log['spend']) ? $log['spend'] : ''); 
562
                $spend_m += $this_spend_m; 
563
                if ($log['adjust_type'] == '1') {
564
                    $left_m = $left_m === '' ? '' : $left_m - $this_spend_m;
565
                }
566
                else if ($log['adjust_type'] == '3') {
567
                    $leave_estimate = isset($log['leave_estimate']) ? $log['leave_estimate'] : '';
568
                    $leave_estimate_m = isset($log['leave_estimate_m']) ? $log['leave_estimate_m'] : $this->ttHandleInM($leave_estimate);
569
                    $left_m = $leave_estimate_m;
570
                }
571
                else if ($log['adjust_type'] == '4') {
572
                    $cut = isset($log['cut']) ? $log['cut'] : '';
573
                    $cut_m = isset($log['cut_m']) ? $log['cut_m'] : $this->ttHandleInM($cut);
574
                    $left_m = $left_m === '' ? '' : $left_m - $cut_m;
575
                }
576
            }
577
            $tmp['spend_m'] = $spend_m;
578
            $tmp['spend'] = $this->ttHandle($spend_m . 'm');
579
580
            $tmp['left_m'] = $left_m === '' ? '' : max([ $left_m, 0 ]);
581
            $tmp['left'] = $left_m === '' ? '' : $this->ttHandle(max([ $left_m, 0]) . 'm');
582
583
            $new_issues[] = $tmp;
584
        }
585
586
        return response()->json([ 'ecode' => 0, 'data' => $new_issues ]);
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...
587
    }
588
589
    /**
590
     * get initialized trend data.
591
     *
592
     * @param  string $interval
593
     * @param  number $star_stat_time
0 ignored issues
show
Documentation introduced by
There is no parameter named $star_stat_time. Did you maybe mean $start_stat_time?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
594
     * @param  number $end_stat_time 
595
     * @return \Illuminate\Http\Response
596
     */
597
    public function getInitializedTrendData($interval, $start_stat_time, $end_stat_time)
598
    {
599
        // initialize the results
600
        $results = [];
601
        $t = $end_stat_time;
0 ignored issues
show
Unused Code introduced by
$t is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
602
        if ($interval == 'month') {
603
               $t = strtotime(date('Y/m/t', $end_stat_time));
604
        }
605
        else if ($interval == 'week') {
606
            $n = date('N', $end_stat_time);
607
            $t = strtotime(date('Y/m/d', $end_stat_time) . ' +' . (7 - $n) . ' day');
608
        }
609
        else
610
        {
611
            $t = strtotime(date('Y/m/d', $end_stat_time));
612
        }
613
614
        $i = 0;
615
        $days = [];
616
        while($t >= $start_stat_time && $i < 100)
617
        {
618
            $tmp = [ 'new' => 0, 'resolved' => 0, 'closed' => 0 ];
619
            $y = date('Y', $t);
620
            $m = date('m', $t);
621
            $d = date('d', $t);
622
            if ($interval == 'month') {
623
                $tmp['category'] = date('Y/m', $t);
624
                $t = mktime(0, 0, 0, $m - 1, $d, $y);
625
            }
626
            else if ($interval == 'week') {
627
                $tmp['category'] = date('Y/m/d', $t - 6 * 24 * 3600);
628
                $t = mktime(0, 0, 0, $m, $d - 7, $y);
629
            }
630
            else
631
            {
632
                $tmp['category'] = date('Y/m/d', $t);
633
634
                $days[] = $tmp['category'];
635
                $week_flg = intval(date('w', $t));
636
                $tmp['notWorking'] = ($week_flg === 0 || $week_flg === 6) ? 1 : 0;
637
638
                $t = mktime(0, 0, 0, $m, $d - 1, $y);
639
            }
640
            $results[$tmp['category']] = $tmp;
641
            $i++;
642
        }
643
644
        if ($days) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $days of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
645
            $singulars = CalendarSingular::where([ 'date' => [ '$in' => $days ] ])->get();
646
            foreach ($singulars as $singular)
647
            {
648
                if (isset($results[$singular->day])) {
649
                    $results[$singular->day]['notWorking'] = $singular->type == 'holiday' ? 1 : 0;
650
                }
651
            }
652
        }
653
654
        return array_reverse($results);
655
    }
656
657
658
    /**
659
     * get trend report by project_key.
660
     *
661
     * @param  string $project_key
662
     * @return \Illuminate\Http\Response
663
     */
664
    public function getTrends(Request $request, $project_key)
665
    {
666
        $interval = $request->input('interval') ?: 'day';
667
        if (!in_array($interval, [ 'day', 'week', 'month' ])) {
668
            throw new \UnexpectedValueException('the name can not be empty.', -11852);
669
        }
670
671
        $is_accu = $request->input('is_accu') === '1' ? true : false;
672
673
        $project = Project::where('key', $project_key)->first();
674
        if (!$project) {
675
            throw new \UnexpectedValueException('the project is not exists.', -11850);
676
        }
677
678
        $start_stat_time = strtotime($project->created_at);
679
        $end_stat_time = time();
680
681
        $where = $this->getIssueQueryWhere($project_key, $request->all());
682
683
        $stat_time = $request->input('stat_time');
684
        if (isset($stat_time) && $stat_time) {
685
            $or = [];
686
            if (strpos($stat_time, '~') !== false) {
687
                $cond = [];
688
                $sections = explode('~', $stat_time);
689 View Code Duplication
                if ($sections[0]) {
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...
690
                    $cond['$gte'] = strtotime($sections[0]);
691
                    $start_stat_time = max([ $start_stat_time, $cond['$gte'] ]);
692
                }
693 View Code Duplication
                if ($sections[1]) {
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...
694
                    $cond['$lte'] = strtotime($sections[1] . ' 23:59:59');
695
                    $end_stat_time = min([ $end_stat_time, $cond['$lte'] ]);
696
                }
697 View Code Duplication
                if ($cond) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $cond of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
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...
698
                    $or[] = [ 'created_at' =>  $cond ];
699
                    $or[] = [ 'resolved_at' =>  $cond ];
700
                    $or[] = [ 'closed_at' => $cond ];
701
                }
702
            }
703
            else
704
            {
705
                $unitMap = [ 'w' => 'week', 'm' => 'month', 'y' => 'year' ];
706
                $unit = substr($stat_time, -1);
707
                if (in_array($unit, [ 'w', 'm', 'y' ])) {
708
                    $direct = substr($stat_time, 0, 1);
709
                    $val = abs(substr($stat_time, 0, -1));
710
                    $time_val = strtotime(date('Ymd', strtotime('-' . $val . ' ' . $unitMap[$unit])));
711
                    $cond = [];
712
                    if ($direct === '-') {
713
                        $cond['$lt'] = $time_val;
714
                        $end_stat_time = min([ $end_stat_time, $cond['$lt'] ]);
715
                    }
716
                    else
717
                    {
718
                        $cond['$gte'] = $time_val;
719
                        $start_stat_time = max([ $start_stat_time, $cond['$gte'] ]);
720
                    }
721 View Code Duplication
                    if ($cond) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $cond of type array<string,integer> is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
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...
722
                        $or[] = [ 'created_at' =>  $cond ];
723
                        $or[] = [ 'resolved_at' =>  $cond ];
724
                        $or[] = [ 'closed_at' => $cond ];
725
                    }
726
                }
727
            }
728
729
            if (!$is_accu && $or) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $or of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
730
                $where['$and'][] = [ '$or' => $or ];
731
            }
732
            else
733
            {
734
                $where['$and'][] = [ 'created_at' => [ '$lte' => $end_stat_time ] ];
735
            }
736
        }
737
738
        $results = $this->getInitializedTrendData($interval, $start_stat_time, $end_stat_time);
739
740
        $query = DB::collection('issue_' . $project_key)->whereRaw($where);
741
        $issues = $query->get([ 'created_at', 'resolved_at', 'closed_at' ]);
742
743
        foreach ($issues as $issue)
744
        {
745 View Code Duplication
            if (isset($issue['created_at']) && $issue['created_at']) {
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...
746
                $created_date = $this->convDate($interval, $issue['created_at']);; 
747
                if ($is_accu) {
748
                    foreach($results as $key => $val)
749
                    {
750
                        if ($key >= $created_date) {
751
                            $results[$key]['new'] += 1;
752
                        }
753
                    }
754
                }
755
                else if (isset($results[$created_date]) && $issue['created_at'] >= $start_stat_time) {
756
                    $results[$created_date]['new'] += 1;
757
                }
758
            }
759 View Code Duplication
            if (isset($issue['resolved_at']) && $issue['resolved_at']) {
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...
760
                $resolved_date = $this->convDate($interval, $issue['resolved_at']);
761
                if ($is_accu) {
762
                    foreach($results as $key => $val)
763
                    {
764
                        if ($key >= $resolved_date) {
765
                            $results[$key]['resolved'] += 1;
766
                        }
767
                    }
768
                }
769
                else if (isset($results[$resolved_date]) && $issue['resolved_at'] >= $start_stat_time) {
770
                    $results[$resolved_date]['resolved'] += 1;
771
                }
772
            }
773 View Code Duplication
            if (isset($issue['closed_at']) && $issue['closed_at']) {
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...
774
                $closed_date = $this->convDate($interval, $issue['closed_at']);
775
                if ($is_accu) {
776
                    foreach($results as $key => $val)
777
                    {
778
                        if ($key >= $closed_date) {
779
                            $results[$key]['closed'] += 1;
780
                        }
781
                    }
782
                }
783
                else if (isset($results[$closed_date]) && $issue['closed_at'] >= $start_stat_time) {
784
                    $results[$closed_date]['closed'] += 1;
785
                }
786
            }
787
        }
788
789
        return response()->json(
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...
790
            [ 
791
            'ecode' => 0, 
792
            'data' => array_values($results), 
793
            'options' => [ 'trend_start_stat_date' => date('Y/m/d', $start_stat_time), 'trend_end_stat_date' => date('Y/m/d', $end_stat_time) ] 
794
            ]
795
        );
796
    }
797
798
    /**
799
     * get converted date.
800
     *
801
     * @param  string $interval
802
     * @param  number $at
803
     * @return string 
804
     */
805
    public function convDate($interval, $at)
806
    {
807
        if ($interval === 'week') {
808
            $n = date('N', $at);
809
            return date('Y/m/d', $at - ($n - 1) * 24 * 3600); 
810
        }
811
        else if ($interval === 'month') {
812
            return date('Y/m', $at); 
813
        }
814
        else
815
        {
816
            return date('Y/m/d', $at); 
817
        }
818
    }
819
820
    public function arrangeRegressionData($data, $project_key, $dimension)
821
    {
822
        if (!$dimension) {
823
            return $data;
824
        }
825
826
        $results = [];
827
        if (in_array($dimension, ['reporter', 'assignee', 'resolver', 'closer'])) {
828 View Code Duplication
            foreach ($data as $value)
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...
829
            {
830
                $tmp = [];
831
                $tmp['ones'] = $value['ones'];
832
                $tmp['gt_ones'] = $value['gt_ones'];
833
                $tmp['category'] = $value['name'];
834
                $results[] = $tmp;
835
            }
836
        }
837
        else if (in_array($dimension, ['type', 'priority', 'module', 'resolve_version', 'epic'])) {
838
            if ($dimension === 'module') {
839
                $modules = Provider::getModuleList($project_key, ['name']);
840
                foreach ($modules as $m)
841
                {
842
                    foreach ($data as $key => $val)
843
                    {
844
                        if ($key === $m->id) {
845
                            $val['category'] = $m->name;
846
                            $results[$m->id] = $val;
847
                            break;
848
                        }
849
                    }
850
                }
851
            }
852
            else if ($dimension === 'resolve_version') {
853
                $versions = Provider::getVersionList($project_key, ['name']);
854
                foreach ($versions as $v)
855
                {
856
                    foreach ($data as $key => $val)
857
                    {
858
                        if ($key === $v->id) {
859
                            $val['category'] = $v->name;
860
                            $results[$key] = $val;
861
                            break;
862
                        }
863
                    }
864
                }
865
            }
866
            else if ($dimension === 'type') {
867
                $types = Provider::getTypeList($project_key, ['name']);
868
                foreach ($types as $v)
869
                {
870
                    foreach ($data as $key => $val)
871
                    {
872
                        if ($key === $v->id) {
873
                            $val['category'] = $v->name;
874
                            $results[$key] = $val;
875
                            break;
876
                        }
877
                    }
878
                }                
879
            }
880
            else if ($dimension === 'priority') {
881
                $priorities = Provider::getPriorityOptions($project_key, ['name']);
0 ignored issues
show
Unused Code introduced by
The call to Provider::getPriorityOptions() has too many arguments starting with array('name').

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
882 View Code Duplication
                foreach ($priorities as $v)
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...
883
                {
884
                    foreach ($data as $key => $val)
885
                    {
886
                        if ($key === $v['_id']) {
887
                            $val['category'] = $v['name'];
888
                            $results[$key] = $val;
889
                            break;
890
                        }
891
                    }
892
                }
893
            }
894
            else if ($dimension === 'epic') {
895
                $epics = Provider::getEpicList($project_key, ['name']);
896 View Code Duplication
                foreach ($epics as $v)
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...
897
                {
898
                    foreach ($data as $key => $val)
899
                    {
900
                        if ($key === $v['_id']) {
901
                            $val['category'] = $v['name'];
902
                            $results[$key] = $val;
903
                            break;
904
                        }
905
                    }
906
                }
907
            }
908
909
            //$others = [ 'ones' => [], 'gt_ones' => [], 'category' => 'others' ];
910
            //foreach ($data as $key => $val) 
911
            //{
912
            //    if (!isset($results[$key]))
913
            //    {
914
            //        $others['ones'] = array_unique(array_merge($others['ones'], $val['ones']));
915
            //        $others['gt_ones'] = array_unique(array_merge($others['gt_ones'], $val['gt_ones']));
916
            //    }
917
            //}
918
919
            //if ($others['ones'] && $others['gt_ones'])
920
            //{
921
            //    $results['others'] = $others;
922
            //}
923
        }
924
        else if ($dimension === 'sprints') {
925 View Code Duplication
            foreach ($data as $key => $val) 
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...
926
            {
927
                $tmp = [];
928
                $tmp['ones'] = $val['ones'];
929
                $tmp['gt_ones'] = $val['gt_ones'];
930
                $tmp['category'] = 'Sprint ' . $key;
931
                $results[] = $tmp;
932
            }           
933
        }
934
        else if ($dimension === 'labels') {
935
            foreach ($data as $key => $val) 
936
            {
937
                $tmp = [];
938
                $tmp['ones'] = $val['ones'];
939
                $tmp['gt_ones'] = $val['gt_ones'];
940
                $tmp['category'] = $key;
941
                $results[] = $tmp;
942
            }             
943
        }
944
        else
945
        {
946
            $fields = Provider::getFieldList($project_key);
947
            foreach ($fields as $field)
948
            {
949
                if ($field->key === $dimension) {
950
                    if (isset($field->optionValues) && $field->optionValues) {
951 View Code Duplication
                        foreach($field->optionValues as $v)
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...
952
                        {
953
                            foreach ($data as $key => $val)
954
                            {
955
                                if ($key === $v['id']) {
956
                                    $val['category'] = $v['name'];
957
                                    $results[$key] = $val;
958
                                    break;
959
                                }
960
                            }
961
                        }
962
                    }
963
                    break;
964
                }
965
            }
966
        }
967
968
        return array_values($results);
969
    }
970
971
    /* get resolution regression report by project_key.
972
     *
973
     * @param  string $project_key
974
     * @return \Illuminate\Http\Response
975
     */
976
    public function getRegressions(Request $request, $project_key)
977
    {
978
        $where = $this->getIssueQueryWhere($project_key, $request->all());
979
980
        $his_resolvers = $request->input('his_resolvers') ? explode(',', $request->input('his_resolvers')) : [];
981
        $or = [];
982
        foreach ($his_resolvers as $resolver)
983
        {
984
            $or[] = [ 'his_resolvers' => $resolver ];
985
        }
986
        if ($or) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $or of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
987
            $where['$and'][] = [ '$or' => $or ];
988
        }
989
990
        $where['$and'][] = [ 'regression_times' => [ '$exists' => 1 ] ];
991
992
        $sprint_start_time = $sprint_complete_time = 0;
993
        $sprint_no = $request->input('sprint') ?: '';
994
        if ($sprint_no) {
995
            $sprint = Sprint::where('project_key', $project_key)->where('no', intval($sprint_no))->first();
996
997
            $sprint_start_time = strtotime(date('Ymd', $sprint->start_time));
998
            if (isset($sprint->real_complete_time) && $sprint->real_complete_time > 0) {
999
                $sprint_complete_time = $sprint->real_complete_time;
1000
            }
1001
        }
1002
1003
        $dimension = $request->input('stat_dimension') ?: '';
1004
        if ($dimension) {
1005
            $results = [];
0 ignored issues
show
Unused Code introduced by
$results is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1006
        }
1007
        else
1008
        {
1009
            $results = [ 'ones' => [], 'gt_ones' => [] ];
0 ignored issues
show
Unused Code introduced by
$results is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1010
        }
1011
1012
        $results = [];
1013
        $query = DB::collection('issue_' . $project_key)->whereRaw($where);
1014
        $issues = $query->orderBy('no', 'desc')->take(1000)->get();
1015
        foreach($issues as $issue)
1016
        {
1017
            $no = $issue['no'];
1018
            $regression_times = $issue['regression_times'];
1019
            $resolved_logs = isset($issue['resolved_logs']) ? $issue['resolved_logs'] : [];
1020
1021
            if ($sprint_start_time > 0) {
1022
                $tmp_log = [];
1023
                foreach($resolved_logs as $rl)
1024
                {
1025
                    if ($rl['at'] > $sprint_start_time && ($sprint_complete_time <= 0 || $rl['at'] < $sprint_complete_time)) {
1026
                        if ($his_resolvers && !in_array($rl['user']['id'], $his_resolvers)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $his_resolvers of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1027
                            continue;
1028
                        }
1029
                        else
1030
                        {
1031
                            $tmp_log[] = $rl;
1032
                        }
1033
                    }
1034
                }
1035
                if (!$tmp_log) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $tmp_log of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1036
                    continue;
1037
                }
1038
1039
                $resolved_logs = $tmp_log;
1040
                $regression_times = count($tmp_log);
1041
            }
1042
1043
            if ($dimension == 'resolver') {
1044
                $log_cnt = count($resolved_logs);
1045
                $tmp_uids = [];
1046
                foreach ($resolved_logs as $key => $log) 
1047
                {
1048
                    $uid = $log['user']['id'];
1049
                    if (in_array($uid, $tmp_uids)) {
1050
                        continue;
1051
                    }
1052
                    else
1053
                    {
1054
                        $tmp_uids[] = $uid;
1055
                    }
1056
                    
1057 View Code Duplication
                    if (!isset($results[$uid])) {
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...
1058
                        $results[$uid] = [ 'ones' => [], 'gt_ones' => [], 'name' => isset($log['user']['name']) ? $log['user']['name'] : '' ];
1059
                    }
1060
                    if ($regression_times > 1) {
1061
                        if ($key == $log_cnt - 1) {
1062
                            $results[$uid]['ones'][] = $no;
1063
                        }
1064
                        else
1065
                        {
1066
                            $results[$uid]['gt_ones'][] = $no;
1067
                        }
1068
                    }
1069
                    else
1070
                    {
1071
                        $results[$uid]['ones'][] = $no;
1072
                    }
1073
                }
1074
            }
1075
            else if ($dimension) {
1076
                $dimension_values = isset($issue[$dimension]) ? $issue[$dimension] : '';
1077
                if ($dimension_values && is_array($dimension_values)) {
1078
                    if (isset($dimension_values['id'])) {
1079 View Code Duplication
                        if (!isset($results[$dimension_values['id']])) {
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...
1080
                            $results[$dimension_values['id']] = [ 'ones' => [], 'gt_ones' => [], 'name' => isset($dimension_values['name']) ? $dimension_values['name'] : '' ];
1081
                        }
1082
                        if ($regression_times > 1) {
1083
                            $results[$dimension_values['id']]['gt_ones'][] = $no;
1084
                        }
1085
                        else
1086
                        {
1087
                            $results[$dimension_values['id']]['ones'][] = $no;
1088
                        }
1089
                    }
1090 View Code Duplication
                    else
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...
1091
                    {
1092
                        foreach($dimension_values as $val)
1093
                        {
1094
                            if (!isset($results[$val])) {
1095
                                $results[$val] = [ 'ones' => [], 'gt_ones' => [] ];
1096
                            }
1097
1098
                            if ($regression_times > 1) {
1099
                                $results[$val]['gt_ones'][] = $no;
1100
                            }
1101
                            else
1102
                            {
1103
                                $results[$val]['ones'][] = $no;
1104
                            }
1105
                        }                        
1106
                    }
1107
                }
1108 View Code Duplication
                else if ($dimension_values) {
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...
1109
                    if (!isset($results[$dimension_values])) {
1110
                        $results[$dimension_values] = [ 'ones' => [], 'gt_ones' => [] ];
1111
                    }
1112
1113
                    if ($regression_times > 1) {
1114
                        $results[$dimension_values]['gt_ones'][] = $no;
1115
                    }
1116
                    else
1117
                    {
1118
                        $results[$dimension_values]['ones'][] = $no;
1119
                    }
1120
                }
1121
            }
1122
            else
1123
            {
1124
                if (!isset($results[0])) {
1125
                    $results[0] = [ 'ones' => [], 'gt_ones' => [] ];
1126
                }
1127
                if ($regression_times > 1) {
1128
                    $results[0]['gt_ones'][] = $no;
1129
                }
1130
                else
1131
                {
1132
                    $results[0]['ones'][] = $no;
1133
                }
1134
            }
1135
        }
1136
        return response()->json([ 'ecode' => 0, 'data' => $this->arrangeRegressionData($results, $project_key, $dimension) ]);
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...
1137
    }
1138
1139
    /* init the X,Y data by dimension.
1140
     *
1141
     * @param  string $project_key
1142
     * @param  string $dimension
1143
     * @return array 
1144
     */
1145
    public function initXYData($project_key, $dimension)
1146
    {
1147
        $results = [];
1148
1149
        switch ($dimension) {
1150
1151 View Code Duplication
        case '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...
1152
            $types = Provider::getTypeList($project_key, ['name']);
1153
            foreach ($types as $key => $value) 
1154
            {
1155
                $results[$value->id] = [ 'name' => $value->name, 'nos' => [] ];
1156
            }
1157
            break;
1158
1159
        case 'priority':
1160
            $priorities = Provider::getPriorityOptions($project_key, ['name']);
0 ignored issues
show
Unused Code introduced by
The call to Provider::getPriorityOptions() has too many arguments starting with array('name').

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
1161
            foreach ($priorities as $key => $value) 
1162
            {
1163
                $results[$value['_id']] = [ 'name' => $value['name'], 'nos' => [] ];
1164
            }
1165
            break;
1166
1167
        case 'state':
1168
            $states = Provider::getStateOptions($project_key, ['name']);
0 ignored issues
show
Unused Code introduced by
The call to Provider::getStateOptions() has too many arguments starting with array('name').

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
1169
            foreach ($states as $key => $value)
1170
            {
1171
                $results[$value['_id']] = [ 'name' => $value['name'], 'nos' => [] ];
1172
            }
1173
            break;
1174
1175 View Code Duplication
        case 'resolution':
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...
1176
            $resolutions = Provider::getResolutionOptions($project_key, ['name']);
0 ignored issues
show
Unused Code introduced by
The call to Provider::getResolutionOptions() has too many arguments starting with array('name').

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
1177
            foreach ($resolutions as $key => $value)
1178
            {
1179
                $results[$value['_id']] = [ 'name' => $value['name'], 'nos' => [] ];
1180
            }
1181
            break;
1182
1183 View Code Duplication
        case 'module':
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...
1184
            $modules = Provider::getModuleList($project_key, ['name']);
1185
            foreach ($modules as $key => $value) 
1186
            {
1187
                $results[$value->id] = [ 'name' => $value->name, 'nos' => [] ];
1188
            }
1189
            break;
1190
1191
        case 'resolve_version':
1192
            $versions = Provider::getVersionList($project_key, ['name']);
1193
            foreach ($versions as $key => $value) 
1194
            {
1195
                $results[$value->id] = [ 'name' => $value->name, 'nos' => [] ];
1196
            }
1197
            $results = array_reverse($results);
1198
            break;
1199
1200 View Code Duplication
        case 'epic':
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...
1201
            $epics = Provider::getEpicList($project_key, ['name']);
1202
            foreach ($epics as $key => $value) 
1203
            {
1204
                $results[$value['_id']] = [ 'name' => $value['name'], 'nos' => [] ];
1205
            }
1206
            break; 
1207
1208
        case 'sprints':
1209
            $sprints = Sprint::where('project_key', $project_key)
1210
                ->whereIn('status', [ 'active', 'completed' ])
1211
                ->orderBy('no', 'asc')
1212
                ->get();
1213
            foreach($sprints as $s)
1214
            {
1215
                $results[$s->no] = [ 'name' => 'Sprint' . $s->no, 'nos' => [] ];
1216
            }
1217
            break;
1218
1219
        default:
1220
            $fields = Provider::getFieldList($project_key);
1221
            foreach ($fields as $field) 
1222
            {
1223
                if ($field->key === $dimension) {
1224
                    if (isset($field->optionValues) && $field->optionValues) {
1225
                        foreach($field->optionValues as $val)
1226
                        {
1227
                            $results[$val['id']] = [ 'name' => $val['name'], 'nos' => [] ];
1228
                        }
1229
                    }
1230
                    break;
1231
                }
1232
            }
1233
            // code...
1234
            break;
1235
        }
1236
1237
        return $results;
1238
    }
1239
1240
    /* get the issues by X,Y dimensions.
1241
     *
1242
     * @param  string $project_key
1243
     * @param  string $dimension
0 ignored issues
show
Bug introduced by
There is no parameter named $dimension. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1244
     * @return \Illuminate\Http\Response
1245
     */
1246
    public function getIssues(Request $request, $project_key)
1247
    {
1248
        $X = $request->input('stat_x') ?: '';
1249
        if (!$X) {
1250
            throw new \UnexpectedValueException('the currentX can not be empty.', -11855);
1251
        }
1252
        //$X = $X === 'sprint' ? 'sprints' : $X;
1253
1254
        $Y = $request->input('stat_y') ?: '';
1255
        //$Y = $Y === 'sprint' ? 'sprints' : $Y;
1256
     
1257
1258
        $XYData = [];
1259
        $YAxis = [];
1260
        if ($X === $Y || !$Y) {
1261
            $XYData[$X] = $this->initXYData($project_key, $X);
1262
        }
1263
        else
1264
        {
1265
            $XYData[$X] = $this->initXYData($project_key, $X);
1266
            $XYData[$Y] = $this->initXYData($project_key, $Y);
1267
        }
1268
1269
        $where = $this->getIssueQueryWhere($project_key, $request->all());
1270
        $query = DB::collection('issue_' . $project_key)->whereRaw($where);
1271
        $issues = $query->orderBy('no', 'desc')->take(10000)->get();
1272
1273
        foreach($issues as $issue)
1274
        {
1275
            foreach ($XYData as $dimension => $z)
1276
            {
1277
                if (!isset($issue[$dimension]) || !$issue[$dimension]) {
1278
                    continue;
1279
                }
1280
1281
                $issue_vals = [];
1282
                if (is_string($issue[$dimension])) {
1283
                    if (strpos($issue[$dimension], ',') !== false) {
1284
                        $issue_vals = explode(',', $issue[$dimension]);
1285
                    }
1286
                    else
1287
                    {
1288
                        $issue_vals = [ $issue[$dimension] ];
1289
                    }
1290
                }
1291
                else if (is_array($issue[$dimension])) {
1292
                    $issue_vals = $issue[$dimension];
1293
                    if (isset($issue[$dimension]['id'])) {
1294
                        $issue_vals = [ $issue[$dimension] ];
1295
                    }
1296
                }
1297
1298
                foreach ($issue_vals as $issue_val)
1299
                {
1300
                    $tmpv = $issue_val;
1301
                    if (is_array($issue_val) && isset($issue_val['id'])) {
1302
                        $tmpv = $issue_val['id'];
1303
                    }
1304
1305
                    if (isset($z[$tmpv])) {
1306
                        $XYData[$dimension][$tmpv]['nos'][] = $issue['no'];
1307
                    }
1308
                    else if ((is_array($issue_val) && isset($issue_val['id'])) || $dimension === 'labels') {
1309
                        if ($dimension === $Y && $X !== $Y) {
1310
                            $YAxis[$tmpv] = isset($issue[$dimension]['name']) ? $issue[$dimension]['name'] : $tmpv;
1311
                        }
1312
1313
                        $XYData[$dimension][$tmpv] = [ 'name' => isset($issue[$dimension]['name']) ? $issue[$dimension]['name'] : $tmpv, 'nos' => [ $issue['no'] ] ];
1314
                    }
1315
                }
1316
            }
1317
        }
1318
1319
        $results = [];
1320
        if ($X === $Y || !$Y) {
1321
            foreach ($XYData[$X] as $key => $value)
1322
            {
1323
                $results[] = [ 'id' => $key, 'name' => $value['name'], 'cnt' => count($value['nos']) ];
1324
            }
1325
        }
1326
        else
1327
        {
1328
            foreach ($XYData[$X] as $key => $value)
1329
            {
1330
                $results[$key] = [ 'id' => $key, 'name' => $value['name'], 'y' => [] ];
1331
                $x_cnt = 0;
1332
1333
                if ($YAxis) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $YAxis of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1334
                    foreach ($YAxis as $yai => $yav) 
1335
                    {
1336
                        if (isset($XYData[$Y][$yai])) {
1337
                            $y_cnt = count(array_intersect($value['nos'], $XYData[$Y][$yai]['nos']));
1338
                            $results[$key]['y'][] = [ 'id' => $yai, 'name' => $yav, 'cnt' => $y_cnt ];
1339
                            $x_cnt += $y_cnt;
1340
                        }
1341
                        else
1342
                        {
1343
                            $results[$key]['y'][] = [ 'id' => $yai, 'name' => yav, 'cnt' => 0 ];
1344
                        }
1345
                    }
1346
                }
1347
                else
1348
                {
1349
                    foreach ($XYData[$Y] as $key2 => $value2)
1350
                    {
1351
                        $y_cnt = count(array_intersect($value['nos'], $value2['nos']));
1352
1353
                        $results[$key]['y'][] = [ 'id' => $key2, 'name' => $value2['name'], 'cnt' => $y_cnt ];
1354
                        $x_cnt += $y_cnt;
1355
                    }
1356
                }
1357
                 $results[$key]['cnt'] = $x_cnt;
1358
            }
1359
        }
1360
1361
        return response()->json([ 'ecode' => 0, 'data' =>  array_values($results) ]);
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...
1362
    }
1363
}
1364