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

ReportController::initXYData()   D

Complexity

Conditions 22
Paths 15

Size

Total Lines 96

Duplication

Lines 28
Ratio 29.17 %

Importance

Changes 0
Metric Value
dl 28
loc 96
rs 4.1666
c 0
b 0
f 0
cc 22
nc 15
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
            {
78
                $filters[$v['mode']] = $v['filters'];
79
            }
80
        }
81
82
        foreach($filters as $mode => $some_filters)
83
        {
84
            $filters[$mode] = $this->convFilters($project_key, $some_filters);
85
        }
86
87
        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...
88
    }
89
90
    /**
91
     * convert the filters.
92
     *
93
     * @param  array $filters
94
     * @return \Illuminate\Http\Response
95
     */
96
    public function convFilters($project_key, $filters)
97
    {
98
        foreach($filters as $key => $filter)
99
        {
100
            if ($filter['id'] === 'active_sprint')
101
            {
102
                $sprint = Sprint::where('project_key', $project_key)
103
                    ->where('status', 'active')
104
                    ->first();
105 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...
106
                {
107
                    $filters[$key]['query'] = [ 'sprints' => $sprint->no ];
108
                }
109
                else
110
                {
111
                    unset($filters[$key]);
112
                }
113
            }
114
            else if ($filter['id'] === 'latest_completed_sprint')
115
            {
116
                $sprint = Sprint::where('project_key', $project_key)
117
                    ->where('status', 'completed')
118
                    ->orderBy('no', 'desc')
119
                    ->first();
120 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...
121
                {
122
                    $filters[$key]['query'] = [ 'sprints' => $sprint->no ];
123
                }
124
                else
125
                {
126
                    unset($filters[$key]);
127
                }
128
            }
129
            else if ($filter['id'] === 'will_release_version')
130
            {
131
                $version = Version::where('project_key', $project_key)
132
                    ->where('status', 'unreleased')
133
                    ->orderBy('name', 'asc')
134
                    ->first();
135 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...
136
                {
137
                    $filters[$key]['query'] = [ 'resolve_version' => $version->id ];
138
                }
139
                else
140
                {
141
                    unset($filters[$key]);
142
                }
143
            }
144
            else if ($filter['id'] === 'latest_released_version')
145
            {
146
                $version = Version::where('project_key', $project_key)
147
                    ->where('status', 'released')
148
                    ->orderBy('name', 'desc')
149
                    ->first();
150 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...
151
                {
152
                    $filters[$key]['query'] = [ 'resolve_version' => $version->id ];
153
                }
154
                else
155
                {
156
                    unset($filters[$key]);
157
                }
158
            }
159
        }
160
        return array_values($filters);
161
    }
162
163
    /**
164
     * get the mode filter.
165
     *
166
     * @param  string $project_key
167
     * @param  string $mode
168
     * @return \Illuminate\Http\Response
169
     */
170
    public function getSomeFilters($project_key, $mode)
171
    {
172
        if (!in_array($mode, $this->mode_enum))
173
        {
174
            throw new \UnexpectedValueException('the mode value is error.', -11851);
175
        }
176
177
        $filters = isset($this->default_filters[$mode]) ? $this->default_filters[$mode] : []; 
178
179
        $res = ReportFilters::where('project_key', $project_key)
180
            ->where('mode', $mode)
181
            ->where('user', $this->user->id)
182
            ->first(); 
183
        if ($res)
184
        {
185
            $filters = isset($res->filters) ? $res->filters : [];
186
        }
187
188
        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...
189
    }
190
191
    /**
192
     * save the custimized filter.
193
     *
194
     * @param  string $project_key
195
     * @param  string $mode
196
     * @return \Illuminate\Http\Response
197
     */
198
    public function saveFilter(Request $request, $project_key, $mode)
199
    {
200
        if (!in_array($mode, $this->mode_enum))
201
        {
202
            throw new \UnexpectedValueException('the mode value is error.', -11851);
203
        }
204
205
        $name = $request->input('name');
206
        if (!$name)
207
        {
208
            throw new \UnexpectedValueException('the name can not be empty.', -11852);
209
        }
210
211
        $query = $request->input('query');
212
        if (!isset($query))
213
        {
214
            throw new \UnexpectedValueException('the query can not be empty.', -11853);
215
        }
216
        
217
        $res = ReportFilters::where('project_key', $project_key)
218
            ->where('mode', $mode)
219
            ->where('user', $this->user->id)
220
            ->first();
221
        if ($res)
222
        {
223
            $filters = isset($res['filters']) ? $res['filters'] : [];
224
            array_push($filters, [ 'id' => md5(microtime()), 'name' => $name, 'query' => $query ]);
225
            $res->filters = $filters;
226
            $res->save();
227
        }
228
        else
229
        {
230
            $filters = $this->default_filters[$mode];
231
            array_push($filters, [ 'id' => md5(microtime()), 'name' => $name, 'query' => $query ]);
232
            ReportFilters::create([ 'project_key' => $project_key, 'mode' => $mode, 'user' => $this->user->id, 'filters' => $filters ]); 
233
        }
234
235
        return $this->getSomeFilters($project_key, $mode);
236
    }
237
238
    /**
239
     * reset the mode filters.
240
     *
241
     * @param  string $project_key
242
     * @param  string $mode
243
     * @return \Illuminate\Http\Response
244
     */
245
    public function resetSomeFilters(Request $request, $project_key, $mode)
246
    {
247
        if (!in_array($mode, $this->mode_enum))
248
        {
249
            throw new \UnexpectedValueException('the mode value is error.', -11851);
250
        }
251
252
        ReportFilters::where('project_key', $project_key)
253
            ->where('mode', $mode)
254
            ->where('user', $this->user->id)
255
            ->delete();
256
        return $this->getSomeFilters($project_key, $mode);
257
    }
258
259
    /**
260
     * edit the mode filters.
261
     *
262
     * @param  string $project_key
263
     * @param  string $mode
264
     * @return \Illuminate\Http\Response
265
     */
266
    public function editSomeFilters(Request $request, $project_key, $mode)
267
    {
268
        if (!in_array($mode, $this->mode_enum))
269
        {
270
            throw new \UnexpectedValueException('the mode value is error.', -11851);
271
        }
272
273
        $sequence = $request->input('sequence');
274
        if (isset($sequence))
275
        {
276
            $old_filters = $this->default_filters[$mode]; 
277
278
            $res = ReportFilters::where('project_key', $project_key)
279
                ->where('mode', $mode)
280
                ->where('user', $this->user->id)
281
                ->first();
282
            if ($res)
283
            {
284
                $old_filters = isset($res->filters) ? $res->filters : [];
285
            }
286
            
287
            $new_filters = [];
288 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...
289
            {
290
                foreach ($old_filters as $filter)
291
                {
292
                    if ($filter['id'] === $id)
293
                    {
294
                        $new_filters[] = $filter;
295
                        break;
296
                    }
297
                }
298
            }
299
300 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...
301
            {
302
                $res->filters = $new_filters;
303
                $res->save();
304
            }
305
            else
306
            {
307
                ReportFilters::create([ 'project_key' => $project_key, 'mode' => $mode, 'user' => $this->user->id, 'filters' => $new_filters ]); 
308
            }
309
        }
310
311
        return $this->getSomeFilters($project_key, $mode);
312
    }
313
314
    /**
315
     * get worklog report pipeline.
316
     *
317
     * @param  string $project_key
318
     * @return \Illuminate\Http\Response
319
     */
320
    public function getWorklogWhere($project_key, $options)
321
    {
322
        $where = [];
323
324
        $issue_id = isset($options['issue_id']) ? $options['issue_id'] : '';
325
        if ($issue_id)
326
        {
327
            $where['issue_id'] = $issue_id;
328
        }
329
        else
330
        {
331
            $issue_ids = [];
332
333
            $query = DB::collection('issue_' . $project_key)->whereRaw($this->getIssueQueryWhere($project_key, $options));
334
            $issues = $query->get([ '_id' ]);
335
            foreach ($issues as $issue)
336
            {
337
                $issue_ids[] = $issue['_id']->__toString();
338
            }
339
            $where['issue_id'] = [ '$in' => $issue_ids ];
340
        }
341
342
        $cond = [];
343
        $recorded_at = isset($options['recorded_at']) ? $options['recorded_at'] : '';
344
        if ($recorded_at)
345
        {
346
            if (strpos($recorded_at, '~') !== false)
347
            {
348
                $sections = explode('~', $recorded_at);
349
                if ($sections[0])
350
                {
351
                    $cond['$gte'] = strtotime($sections[0]);
352
                }
353
                if ($sections[1])
354
                {
355
                    $cond['$lte'] = strtotime($sections[1] . ' 23:59:59');
356
                }
357
                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...
358
                {
359
                    $where['recorded_at'] = $cond;
360
                }
361
            }
362
            else
363
            {
364
                $unitMap = [ 'w' => 'week', 'm' => 'month', 'y' => 'year' ];
365
                $unit = substr($recorded_at, -1);
366
                if (in_array($unit, [ 'w', 'm', 'y' ]))
367
                {
368
                    $direct = substr($recorded_at, 0, 1);
369
                    $val = abs(substr($recorded_at, 0, -1));
370
                    $time_val = strtotime(date('Ymd', strtotime('-' . $val . ' ' . $unitMap[$unit])));
371
372
                    if ($direct === '-')
373
                    {
374
                        $cond['$lt'] = $time_val;
375
                    }
376
                    else
377
                    {
378
                        $cond['$gte'] = $time_val;
379
                    }
380
                    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...
381
                    {
382
                        $where['recorded_at'] = $cond;
383
                    }
384
                }
385
            }
386
        }
387
388
        $recorder = isset($options['recorder']) ? $options['recorder'] : '';
389
        if ($recorder)
390
        {
391
            $where['recorder.id'] = $recorder;
392
        }
393
394
        $sprint_no = isset($options['sprints']) ? $options['sprints'] : '';
395
        if ($sprint_no)
396
        {
397
            $sprint = Sprint::where('project_key', $project_key)->where('no', intval($sprint_no))->first();
398
399
            $sprint_start_time = strtotime(date('Ymd', $sprint->start_time));
400
            if (!isset($cond['$gte']) || $cond['$gte'] < $sprint_start_time)
401
            {
402
                $cond['$gte'] = $sprint_start_time;
403
            }
404
405
            if (isset($sprint->real_complete_time) && $sprint->real_complete_time > 0)
406
            {
407
                $sprint_complet_time = strtotime(date('Ymd', $sprint->real_complete_time) . ' 23:59:59');
408
                if (!isset($cond['$lte']) || $cond['$lte'] > $sprint_complet_time)
409
                {
410
                    $cond['$lte'] = $sprint_complet_time; 
411
                }
412
            }
413
414
            $where['recorded_at'] = $cond;
415
        }
416
417
        $where['project_key'] = $project_key;
418
419
        return $where;
420
    }
421
422
    /**
423
     * get worklog detail report by issue.
424
     *
425
     * @param  string $project_key
426
     * @param  string $issue_id
427
     * @return \Illuminate\Http\Response
428
     */
429
    public function getWorklogDetail(Request $request, $project_key, $issue_id)
430
    {
431
        $total = Worklog::Where('project_key', $project_key)
432
            ->where('issue_id', $issue_id)
433
            ->orderBy('recorded_at', 'desc')
434
            ->get();
435
436
        $where = $this->getWorklogWhere($project_key, [ 'issue_id' => $issue_id ] + $request->all());
437
        $parts = Worklog::WhereRaw($where)
438
           ->orderBy('recorded_at', 'desc')
439
           ->get();
440
441
        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...
442
    }
443
444
    /**
445
     * get worklog detail report by memeber.
446
     *
447
     * @param  string $project_key
448
     * @return \Illuminate\Http\Response
449
     */
450
    public function getWorklogList(Request $request, $project_key)
451
    {
452
        $pipeline = [];
453
454
        $where = $this->getWorklogWhere($project_key, $request->all());
455
        $pipeline[] = [ '$match' => $where ];
456
457
        $pipeline[] = [ '$group' => [ '_id' => '$issue_id', 'value' => [ '$sum' => '$spend_m' ] ] ];
458
459
        $ret = DB::collection('worklog')->raw(function($col) use($pipeline) {
460
            return $col->aggregate($pipeline);
461
        });
462
463
        $new_results = [];
464
        $results = iterator_to_array($ret);
465
        foreach ($results as $k => $r)
466
        {
467
            $tmp = [];
468
            $tmp['total_value'] = $r['value'];
469
            $issue = DB::collection('issue_' . $project_key)
470
                ->where('_id', $r['_id'])
471
                ->first();
472
            $tmp['id']      = $issue['_id']->__toString();
473
            $tmp['no']      = $issue['no'];
474
            $tmp['title']   = $issue['title'];
475
            $tmp['state']   = $issue['state'];
476
            $tmp['type']    = $issue['type'];
477
            $new_results[]  = $tmp;
478
 
479
        }
480
481
        usort($new_results, function ($a, $b) { return $a['no'] <= $b['no']; });
482
483
        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...
484
    }
485
486
    /**
487
     * get worklog report by project_key.
488
     *
489
     * @param  string $project_key
490
     * @return \Illuminate\Http\Response
491
     */
492
    public function getWorklogs(Request $request, $project_key)
493
    {
494
        $pipeline = [];
495
496
        $where = $this->getWorklogWhere($project_key, $request->all());
497
        $pipeline[] = [ '$match' => $where ];
498
499
        $pipeline[] = [ '$group' => [ '_id' => '$recorder.id', 'value' => [ '$sum' => '$spend_m' ] ] ]; 
500
501
        $ret = DB::collection('worklog')->raw(function($col) use($pipeline) {
502
            return $col->aggregate($pipeline);
503
        });
504
505
        $others_val = 0;
506
        $results = iterator_to_array($ret);
507
        $new_results = [];
508
        foreach ($results as $r) 
509
        {
510
            $user = Sentinel::findById($r['_id']);
511
            if ($user)
512
            {
513
                $new_results[] = [ 'user' => [ 'id' => $user->id, 'name' => $user->first_name ], 'value' => $r['value'] ];
514
            }
515
            else
516
            {
517
                $others_val += $r['value'];
518
            }
519
        }
520
        if ($others_val > 0)
521
        {
522
            $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...
523
        }
524
525
        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...
526
    }
527
528
    /**
529
     * get worklog detail report by issue.
530
     *
531
     * @param  string $project_key
532
     * @param  string $issue_id
533
     * @return \Illuminate\Http\Response
534
     */
535
    public function getTimetracksDetail(Request $request, $project_key, $issue_id)
536
    {
537
        $worklogs = Worklog::Where('project_key', $project_key)
538
            ->where('issue_id', $issue_id)
539
            ->orderBy('recorded_at', 'desc')
540
            ->get();
541
542
        foreach($worklogs as $worklog)
543
        {
544
            if (!isset($worklog->spend_m) || !$worklog->spend_m)
545
            {
546
                $worklog->spend_m = $this->ttHandleInM($worklog->spend ?: '');
547
            }
548
        }
549
550
        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...
551
    }
552
553
     /* get timetracks report by project_key.
554
     *
555
     * @param  string $project_key
556
     * @return \Illuminate\Http\Response
557
     */
558
    public function getTimetracks(Request $request, $project_key)
559
    {
560
        $where = $this->getIssueQueryWhere($project_key, $request->all());
561
562
        $scale = $request->input('scale');
563
        if ($scale === 'only')
564
        {
565
            $where['$and'][] = [ 'original_estimate' => [ '$exists' => 1, '$ne' => '' ] ];
566
        }
567
568
        $query = DB::collection('issue_' . $project_key)->whereRaw($where);
569
        $issues = $query->orderBy('no', 'desc')->take(10000)->get();
570
571
        $new_issues = [];
572
        foreach($issues as $issue)
573
        {
574
            $issue_id = $issue['_id']->__toString();
575
576
            $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...
577
            $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...
578
            $tmp['title']     = $issue['title'];
579
            $tmp['state']     = $issue['state'];
580
            $tmp['type']      = $issue['type'];
581
            $tmp['origin']    = isset($issue['original_estimate']) ? $issue['original_estimate'] : '';
582
            $tmp['origin_m']  = isset($issue['original_estimatei_m']) ? $issue['original_estimatei_m'] : $this->ttHandleInM($tmp['origin']);
583
584
            $spend_m = 0;
585
            $left_m = $tmp['origin_m'];
586
            $worklogs = Worklog::Where('project_key', $project_key)
587
                ->where('issue_id', $issue_id)
588
                ->orderBy('recorded_at', 'asc')
589
                ->get();
590
            foreach($worklogs as $log)
591
            {
592
                $this_spend_m = isset($log['spend_m']) ? $log['spend_m'] : $this->ttHandleInM(isset($log['spend']) ? $log['spend'] : ''); 
593
                $spend_m += $this_spend_m; 
594
                if ($log['adjust_type'] == '1')
595
                {
596
                    $left_m = $left_m === '' ? '' : $left_m - $this_spend_m;
597
                }
598
                else if ($log['adjust_type'] == '3')
599
                {
600
                    $leave_estimate = isset($log['leave_estimate']) ? $log['leave_estimate'] : '';
601
                    $leave_estimate_m = isset($log['leave_estimate_m']) ? $log['leave_estimate_m'] : $this->ttHandleInM($leave_estimate);
602
                    $left_m = $leave_estimate_m;
603
                }
604
                else if ($log['adjust_type'] == '4')
605
                {
606
                    $cut = isset($log['cut']) ? $log['cut'] : '';
607
                    $cut_m = isset($log['cut_m']) ? $log['cut_m'] : $this->ttHandleInM($cut);
608
                    $left_m = $left_m === '' ? '' : $left_m - $cut_m;
609
                }
610
            }
611
            $tmp['spend_m'] = $spend_m;
612
            $tmp['spend'] = $this->ttHandle($spend_m . 'm');
613
614
            $tmp['left_m'] = $left_m === '' ? '' : max([ $left_m, 0 ]);
615
            $tmp['left'] = $left_m === '' ? '' : $this->ttHandle(max([ $left_m, 0]) . 'm');
616
617
            $new_issues[] = $tmp;
618
        }
619
620
        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...
621
    }
622
623
    /**
624
     * get initialized trend data.
625
     *
626
     * @param  string $interval
627
     * @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...
628
     * @param  number $end_stat_time 
629
     * @return \Illuminate\Http\Response
630
     */
631
    public function getInitializedTrendData($interval, $start_stat_time, $end_stat_time)
632
    {
633
        // initialize the results
634
        $results = [];
635
        $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...
636
        if ($interval == 'month')
637
        {
638
       	    $t = strtotime(date('Y/m/t', $end_stat_time));
639
        }
640
        else if ($interval == 'week')
641
        {
642
            $n = date('N', $end_stat_time);
643
            $t = strtotime(date('Y/m/d', $end_stat_time) . ' +' . (7 - $n) . ' day');
644
        }
645
        else
646
        {
647
            $t = strtotime(date('Y/m/d', $end_stat_time));
648
        }
649
650
        $i = 0;
651
        $days = [];
652
        while($t >= $start_stat_time && $i < 100)
653
        {
654
            $tmp = [ 'new' => 0, 'resolved' => 0, 'closed' => 0 ];
655
            $y = date('Y', $t);
656
            $m = date('m', $t);
657
            $d = date('d', $t);
658
            if ($interval == 'month')
659
            {
660
                $tmp['category'] = date('Y/m', $t);
661
                $t = mktime(0, 0, 0, $m - 1, $d, $y);
662
            }
663
            else if ($interval == 'week')
664
            {
665
                $tmp['category'] = date('Y/m/d', $t - 6 * 24 * 3600);
666
                $t = mktime(0, 0, 0, $m, $d - 7, $y);
667
            }
668
            else
669
            {
670
                $tmp['category'] = date('Y/m/d', $t);
671
672
                $days[] = $tmp['category'];
673
                $week_flg = intval(date('w', $t));
674
                $tmp['notWorking'] = ($week_flg === 0 || $week_flg === 6) ? 1 : 0;
675
676
                $t = mktime(0, 0, 0, $m, $d - 1, $y);
677
            }
678
            $results[$tmp['category']] = $tmp;
679
            $i++;
680
        }
681
682
        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...
683
        {
684
            $singulars = CalendarSingular::where([ 'date' => [ '$in' => $days ] ])->get();
685
            foreach ($singulars as $singular)
686
            {
687
                if (isset($results[$singular->day]))
688
                {
689
                    $results[$singular->day]['notWorking'] = $singular->type == 'holiday' ? 1 : 0;
690
                }
691
            }
692
        }
693
694
        return array_reverse($results);
695
    }
696
697
698
    /**
699
     * get trend report by project_key.
700
     *
701
     * @param  string $project_key
702
     * @return \Illuminate\Http\Response
703
     */
704
    public function getTrends(Request $request, $project_key)
705
    {
706
    	$interval = $request->input('interval') ?: 'day';
707
    	if (!in_array($interval, [ 'day', 'week', 'month' ]))
708
    	{
709
    	    throw new \UnexpectedValueException('the name can not be empty.', -11852);
710
    	}
711
712
    	$is_accu = $request->input('is_accu') === '1' ? true : false;
713
714
    	$project = Project::where('key', $project_key)->first();
715
    	if (!$project)
716
    	{
717
    	    throw new \UnexpectedValueException('the project is not exists.', -11850);
718
    	}
719
720
    	$start_stat_time = strtotime($project->created_at);
721
    	$end_stat_time = time();
722
723
    	$where = $this->getIssueQueryWhere($project_key, $request->all());
724
725
        $stat_time = $request->input('stat_time');
726
        if (isset($stat_time) && $stat_time)
727
        {
728
            $or = [];
729
            if (strpos($stat_time, '~') !== false)
730
            {
731
                $cond = [];
732
                $sections = explode('~', $stat_time);
733 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...
734
                {
735
                    $cond['$gte'] = strtotime($sections[0]);
736
                    $start_stat_time = max([ $start_stat_time, $cond['$gte'] ]);
737
                }
738 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...
739
                {
740
                    $cond['$lte'] = strtotime($sections[1] . ' 23:59:59');
741
                    $end_stat_time = min([ $end_stat_time, $cond['$lte'] ]);
742
                }
743 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...
744
                {
745
                    $or[] = [ 'created_at' =>  $cond ];
746
                    $or[] = [ 'resolved_at' =>  $cond ];
747
                    $or[] = [ 'closed_at' => $cond ];
748
                }
749
            }
750
            else
751
            {
752
                $unitMap = [ 'w' => 'week', 'm' => 'month', 'y' => 'year' ];
753
                $unit = substr($stat_time, -1);
754
                if (in_array($unit, [ 'w', 'm', 'y' ]))
755
                {
756
                    $direct = substr($stat_time, 0, 1);
757
                    $val = abs(substr($stat_time, 0, -1));
758
                    $time_val = strtotime(date('Ymd', strtotime('-' . $val . ' ' . $unitMap[$unit])));
759
                    $cond = [];
760
                    if ($direct === '-')
761
                    {
762
                        $cond['$lt'] = $time_val;
763
                        $end_stat_time = min([ $end_stat_time, $cond['$lt'] ]);
764
                    }
765
                    else
766
                    {
767
                        $cond['$gte'] = $time_val;
768
                        $start_stat_time = max([ $start_stat_time, $cond['$gte'] ]);
769
                    }
770 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...
771
                    {
772
                        $or[] = [ 'created_at' =>  $cond ];
773
                        $or[] = [ 'resolved_at' =>  $cond ];
774
                        $or[] = [ 'closed_at' => $cond ];
775
                    }
776
                }
777
            }
778
779
            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...
780
            {
781
            	$where['$and'][] = [ '$or' => $or ];
782
            }
783
            else
784
            {
785
            	$where['$and'][] = [ 'created_at' => [ '$lte' => $end_stat_time ] ];
786
            }
787
        }
788
789
        $results = $this->getInitializedTrendData($interval, $start_stat_time, $end_stat_time);
790
791
        $query = DB::collection('issue_' . $project_key)->whereRaw($where);
792
        $issues = $query->get([ 'created_at', 'resolved_at', 'closed_at' ]);
793
794
        foreach ($issues as $issue)
795
        {
796 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...
797
            {
798
                $created_date = $this->convDate($interval, $issue['created_at']);; 
799
                if ($is_accu)
800
                {
801
                    foreach($results as $key => $val)
802
                    {
803
                        if ($key >= $created_date)
804
                        {
805
                            $results[$key]['new'] += 1;
806
                        }
807
                    }
808
                }
809
                else if (isset($results[$created_date]) && $issue['created_at'] >= $start_stat_time)
810
                {
811
                    $results[$created_date]['new'] += 1;
812
                }
813
            }
814 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...
815
            {
816
                $resolved_date = $this->convDate($interval, $issue['resolved_at']);
817
                if ($is_accu)
818
                {
819
                    foreach($results as $key => $val)
820
                    {
821
                        if ($key >= $resolved_date)
822
                        {
823
                            $results[$key]['resolved'] += 1;
824
                        }
825
                    }
826
                }
827
                else if (isset($results[$resolved_date]) && $issue['resolved_at'] >= $start_stat_time)
828
                {
829
                    $results[$resolved_date]['resolved'] += 1;
830
                }
831
            }
832 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...
833
            {
834
                $closed_date = $this->convDate($interval, $issue['closed_at']);
835
                if ($is_accu)
836
                {
837
                    foreach($results as $key => $val)
838
                    {
839
                        if ($key >= $closed_date)
840
                        {
841
                            $results[$key]['closed'] += 1;
842
                        }
843
                    }
844
                }
845
                else if (isset($results[$closed_date]) && $issue['closed_at'] >= $start_stat_time)
846
                {
847
                    $results[$closed_date]['closed'] += 1;
848
                }
849
            }
850
        }
851
852
        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...
853
            'ecode' => 0, 
854
            'data' => array_values($results), 
855
            'options' => [ 'trend_start_stat_date' => date('Y/m/d', $start_stat_time), 'trend_end_stat_date' => date('Y/m/d', $end_stat_time) ] 
856
        ]);
857
    }
858
859
    /**
860
     * get converted date.
861
     *
862
     * @param  string $interval
863
     * @param  number $at
864
     * @return string 
865
     */
866
    public function convDate($interval, $at)
867
    {
868
        if ($interval === 'week')
869
        {
870
            $n = date('N', $at);
871
            return date('Y/m/d', $at - ($n - 1) * 24 * 3600); 
872
        }
873
        else if ($interval === 'month')
874
        {
875
            return date('Y/m', $at); 
876
        }
877
        else
878
        {
879
            return date('Y/m/d', $at); 
880
        }
881
    }
882
883
    public function arrangeRegressionData($data, $project_key, $dimension)
884
    {
885
        if (!$dimension)
886
        {
887
            return $data;
888
        }
889
890
        $results = [];
891
        if (in_array($dimension, ['reporter', 'assignee', 'resolver', 'closer']))
892
        {
893 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...
894
            {
895
                $tmp = [];
896
                $tmp['ones'] = $value['ones'];
897
                $tmp['gt_ones'] = $value['gt_ones'];
898
                $tmp['category'] = $value['name'];
899
                $results[] = $tmp;
900
            }
901
        }
902
        else if (in_array($dimension, ['type', 'priority', 'module', 'resolve_version', 'epic']))
903
        {
904
            if ($dimension === 'module')
905
            {
906
                $modules = Provider::getModuleList($project_key, ['name']);
907
                foreach ($modules as $m)
908
                {
909
                    foreach ($data as $key => $val)
910
                    {
911
                        if ($key === $m->id)
912
                        {
913
                            $val['category'] = $m->name;
914
                            $results[$m->id] = $val;
915
                            break;
916
                        }
917
                    }
918
                }
919
            }
920
            else if ($dimension === 'resolve_version')
921
            {
922
                $versions = Provider::getVersionList($project_key, ['name']);
923
                foreach ($versions as $v)
924
                {
925
                    foreach ($data as $key => $val)
926
                    {
927
                        if ($key === $v->id)
928
                        {
929
                            $val['category'] = $v->name;
930
                            $results[$key] = $val;
931
                            break;
932
                        }
933
                    }
934
                }
935
            }
936
            else if ($dimension === 'type')
937
            {
938
                $types = Provider::getTypeList($project_key, ['name']);
939
                foreach ($types as $v)
940
                {
941
                    foreach ($data as $key => $val)
942
                    {
943
                        if ($key === $v->id)
944
                        {
945
                            $val['category'] = $v->name;
946
                            $results[$key] = $val;
947
                            break;
948
                        }
949
                    }
950
                }                
951
            }
952
            else if ($dimension === 'priority')
953
            {
954
                $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...
955 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...
956
                {
957
                    foreach ($data as $key => $val)
958
                    {
959
                        if ($key === $v['_id'])
960
                        {
961
                            $val['category'] = $v['name'];
962
                            $results[$key] = $val;
963
                            break;
964
                        }
965
                    }
966
                }
967
            }
968
            else if ($dimension === 'epic')
969
            {
970
                $epics = Provider::getEpicList($project_key, ['name']);
971 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...
972
                {
973
                    foreach ($data as $key => $val)
974
                    {
975
                        if ($key === $v['_id'])
976
                        {
977
                            $val['category'] = $v['name'];
978
                            $results[$key] = $val;
979
                            break;
980
                        }
981
                    }
982
                }
983
            }
984
985
            //$others = [ 'ones' => [], 'gt_ones' => [], 'category' => 'others' ];
986
            //foreach ($data as $key => $val) 
987
            //{
988
            //    if (!isset($results[$key]))
989
            //    {
990
            //        $others['ones'] = array_unique(array_merge($others['ones'], $val['ones']));
991
            //        $others['gt_ones'] = array_unique(array_merge($others['gt_ones'], $val['gt_ones']));
992
            //    }
993
            //}
994
995
            //if ($others['ones'] && $others['gt_ones'])
996
            //{
997
            //    $results['others'] = $others;
998
            //}
999
        }
1000
        else if ($dimension === 'sprints')
1001
        {
1002 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...
1003
            {
1004
                $tmp = [];
1005
                $tmp['ones'] = $val['ones'];
1006
                $tmp['gt_ones'] = $val['gt_ones'];
1007
                $tmp['category'] = 'Sprint ' . $key;
1008
                $results[] = $tmp;
1009
            }           
1010
        }
1011
        else if ($dimension === 'labels')
1012
        {
1013
            foreach ($data as $key => $val) 
1014
            {
1015
                $tmp = [];
1016
                $tmp['ones'] = $val['ones'];
1017
                $tmp['gt_ones'] = $val['gt_ones'];
1018
                $tmp['category'] = $key;
1019
                $results[] = $tmp;
1020
            }             
1021
        }
1022
        else
1023
        {
1024
            $fields = Provider::getFieldList($project_key);
1025
            foreach ($fields as $field)
1026
            {
1027
                if ($field->key === $dimension)
1028
                {
1029
                    if (isset($field->optionValues) && $field->optionValues)
1030
                    {
1031 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...
1032
                        {
1033
                            foreach ($data as $key => $val)
1034
                            {
1035
                                if ($key === $v['id'])
1036
                                {
1037
                                    $val['category'] = $v['name'];
1038
                                    $results[$key] = $val;
1039
                                    break;
1040
                                }
1041
                            }
1042
                        }
1043
                    }
1044
                    break;
1045
                }
1046
            }
1047
        }
1048
1049
        return array_values($results);
1050
    }
1051
1052
    /* get resolution regression report by project_key.
1053
     *
1054
     * @param  string $project_key
1055
     * @return \Illuminate\Http\Response
1056
     */
1057
    public function getRegressions(Request $request, $project_key)
1058
    {
1059
        $where = $this->getIssueQueryWhere($project_key, $request->all());
1060
1061
        $his_resolvers = $request->input('his_resolvers') ? explode(',', $request->input('his_resolvers')) : [];
1062
        $or = [];
1063
        foreach ($his_resolvers as $resolver)
1064
        {
1065
            $or[] = [ 'his_resolvers' => $resolver ];
1066
        }
1067
        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...
1068
        {
1069
            $where['$and'][] = [ '$or' => $or ];
1070
        }
1071
1072
        $where['$and'][] = [ 'regression_times' => [ '$exists' => 1 ] ];
1073
1074
        $sprint_start_time = $sprint_complete_time = 0;
1075
        $sprint_no = $request->input('sprint') ?: '';
1076
        if ($sprint_no)
1077
        {
1078
            $sprint = Sprint::where('project_key', $project_key)->where('no', intval($sprint_no))->first();
1079
1080
            $sprint_start_time = strtotime(date('Ymd', $sprint->start_time));
1081
            if (isset($sprint->real_complete_time) && $sprint->real_complete_time > 0)
1082
            {
1083
                $sprint_complete_time = $sprint->real_complete_time;
1084
            }
1085
        }
1086
1087
        $dimension = $request->input('stat_dimension') ?: '';
1088
        if ($dimension)
1089
        {
1090
            $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...
1091
        }
1092
        else
1093
        {
1094
            $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...
1095
        }
1096
1097
        $results = [];
1098
        $query = DB::collection('issue_' . $project_key)->whereRaw($where);
1099
        $issues = $query->orderBy('no', 'desc')->take(1000)->get();
1100
        foreach($issues as $issue)
1101
        {
1102
            $no = $issue['no'];
1103
            $regression_times = $issue['regression_times'];
1104
            $resolved_logs = isset($issue['resolved_logs']) ? $issue['resolved_logs'] : [];
1105
1106
            if ($sprint_start_time > 0)
1107
            {
1108
                $tmp_log = [];
1109
                foreach($resolved_logs as $rl)
1110
                {
1111
                    if ($rl['at'] > $sprint_start_time && ($sprint_complete_time <= 0 || $rl['at'] < $sprint_complete_time))
1112
                    {
1113
                        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...
1114
                        {
1115
                            continue;
1116
                        }
1117
                        else
1118
                        {
1119
                            $tmp_log[] = $rl;
1120
                        }
1121
                    }
1122
                }
1123
                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...
1124
                {
1125
                    continue;
1126
                }
1127
1128
                $resolved_logs = $tmp_log;
1129
                $regression_times = count($tmp_log);
1130
            }
1131
1132
            if ($dimension == 'resolver')
1133
            {
1134
                $log_cnt = count($resolved_logs);
1135
                $tmp_uids = [];
1136
                foreach ($resolved_logs as $key => $log) 
1137
                {
1138
                    $uid = $log['user']['id'];
1139
                    if (in_array($uid, $tmp_uids))
1140
                    {
1141
                        continue;
1142
                    }
1143
                    else
1144
                    {
1145
                        $tmp_uids[] = $uid;
1146
                    }
1147
                    
1148 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...
1149
                    {
1150
                        $results[$uid] = [ 'ones' => [], 'gt_ones' => [], 'name' => isset($log['user']['name']) ? $log['user']['name'] : '' ];
1151
                    }
1152
                    if ($regression_times > 1)
1153
                    {
1154
                        if ($key == $log_cnt - 1)
1155
                        {
1156
                            $results[$uid]['ones'][] = $no;
1157
                        }
1158
                        else
1159
                        {
1160
                            $results[$uid]['gt_ones'][] = $no;
1161
                        }
1162
                    }
1163
                    else
1164
                    {
1165
                        $results[$uid]['ones'][] = $no;
1166
                    }
1167
                }
1168
            }
1169
            else if ($dimension)
1170
            {
1171
                $dimension_values = isset($issue[$dimension]) ? $issue[$dimension] : '';
1172
                if ($dimension_values && is_array($dimension_values))
1173
                {
1174
                    if (isset($dimension_values['id']))
1175
                    {
1176 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...
1177
                        {
1178
                            $results[$dimension_values['id']] = [ 'ones' => [], 'gt_ones' => [], 'name' => isset($dimension_values['name']) ? $dimension_values['name'] : '' ];
1179
                        }
1180
                        if ($regression_times > 1)
1181
                        {
1182
                            $results[$dimension_values['id']]['gt_ones'][] = $no;
1183
                        }
1184
                        else
1185
                        {
1186
                            $results[$dimension_values['id']]['ones'][] = $no;
1187
                        }
1188
                    }
1189 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...
1190
                    {
1191
                        foreach($dimension_values as $val)
1192
                        {
1193
                            if (!isset($results[$val]))
1194
                            {
1195
                                $results[$val] = [ 'ones' => [], 'gt_ones' => [] ];
1196
                            }
1197
1198
                            if ($regression_times > 1)
1199
                            {
1200
                                $results[$val]['gt_ones'][] = $no;
1201
                            }
1202
                            else
1203
                            {
1204
                                $results[$val]['ones'][] = $no;
1205
                            }
1206
                        }                        
1207
                    }
1208
                }
1209 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...
1210
                {
1211
                    if (!isset($results[$dimension_values]))
1212
                    {
1213
                        $results[$dimension_values] = [ 'ones' => [], 'gt_ones' => [] ];
1214
                    }
1215
1216
                    if ($regression_times > 1)
1217
                    {
1218
                        $results[$dimension_values]['gt_ones'][] = $no;
1219
                    }
1220
                    else
1221
                    {
1222
                        $results[$dimension_values]['ones'][] = $no;
1223
                    }
1224
                }
1225
            }
1226
            else
1227
            {
1228
                if (!isset($results[0]))
1229
                {
1230
                    $results[0] = [ 'ones' => [], 'gt_ones' => [] ];
1231
                }
1232
                if ($regression_times > 1)
1233
                {
1234
                    $results[0]['gt_ones'][] = $no;
1235
                }
1236
                else
1237
                {
1238
                    $results[0]['ones'][] = $no;
1239
                }
1240
            }
1241
        }
1242
        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...
1243
    }
1244
1245
    /* init the X,Y data by dimension.
1246
     *
1247
     * @param  string $project_key
1248
     * @param  string $dimension
1249
     * @return array 
1250
     */
1251
    public function initXYData($project_key, $dimension)
1252
    {
1253
        $results = [];
1254
1255
        switch ($dimension) {
1256
1257 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...
1258
                $types = Provider::getTypeList($project_key, ['name']);
1259
                foreach ($types as $key => $value) 
1260
                {
1261
                    $results[$value->id] = [ 'name' => $value->name, 'nos' => [] ];
1262
                }
1263
                break;
1264
1265
            case 'priority':
1266
                $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...
1267
                foreach ($priorities as $key => $value) 
1268
                {
1269
                    $results[$value['_id']] = [ 'name' => $value['name'], 'nos' => [] ];
1270
                }
1271
                break;
1272
1273
            case 'state':
1274
                $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...
1275
                foreach ($states as $key => $value)
1276
                {
1277
                    $results[$value['_id']] = [ 'name' => $value['name'], 'nos' => [] ];
1278
                }
1279
                break;
1280
1281 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...
1282
                $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...
1283
                foreach ($resolutions as $key => $value)
1284
                {
1285
                    $results[$value['_id']] = [ 'name' => $value['name'], 'nos' => [] ];
1286
                }
1287
                break;
1288
1289 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...
1290
                $modules = Provider::getModuleList($project_key, ['name']);
1291
                foreach ($modules as $key => $value) 
1292
                {
1293
                    $results[$value->id] = [ 'name' => $value->name, 'nos' => [] ];
1294
                }
1295
                break;
1296
1297
            case 'resolve_version':
1298
                $versions = Provider::getVersionList($project_key, ['name']);
1299
                foreach ($versions as $key => $value) 
1300
                {
1301
                    $results[$value->id] = [ 'name' => $value->name, 'nos' => [] ];
1302
                }
1303
                $results = array_reverse($results);
1304
                break;
1305
1306 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...
1307
                $epics = Provider::getEpicList($project_key, ['name']);
1308
                foreach ($epics as $key => $value) 
1309
                {
1310
                    $results[$value['_id']] = [ 'name' => $value['name'], 'nos' => [] ];
1311
                }
1312
                break; 
1313
1314
            case 'sprints':
1315
                $sprints = Sprint::where('project_key', $project_key)
1316
                    ->whereIn('status', [ 'active', 'completed' ])
1317
                    ->orderBy('no', 'asc')
1318
                    ->get();
1319
                foreach($sprints as $s)
1320
                {
1321
                    $results[$s->no] = [ 'name' => 'Sprint' . $s->no, 'nos' => [] ];
1322
                }
1323
                break;
1324
1325
            default:
1326
                $fields = Provider::getFieldList($project_key);
1327
                foreach ($fields as $field) 
1328
                {
1329
                    if ($field->key === $dimension)
1330
                    {
1331
                        if (isset($field->optionValues) && $field->optionValues)
1332
                        {
1333
                            foreach($field->optionValues as $val)
1334
                            {
1335
                                $results[$val['id']] = [ 'name' => $val['name'], 'nos' => [] ];
1336
                            }
1337
                        }
1338
                        break;
1339
                    }
1340
                }
1341
                # code...
1342
                break;
1343
        }
1344
1345
        return $results;
1346
    }
1347
1348
    /* get the issues by X,Y dimensions.
1349
     *
1350
     * @param  string $project_key
1351
     * @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...
1352
     * @return \Illuminate\Http\Response
1353
     */
1354
    public function getIssues(Request $request, $project_key)
1355
    {
1356
        $X = $request->input('stat_x') ?: '';
1357
        if (!$X)
1358
        {
1359
            throw new \UnexpectedValueException('the currentX can not be empty.', -11855);
1360
        }
1361
        //$X = $X === 'sprint' ? 'sprints' : $X;
1362
1363
        $Y = $request->input('stat_y') ?: '';
1364
        //$Y = $Y === 'sprint' ? 'sprints' : $Y;
1365
     
1366
1367
        $XYData = [];
1368
        $YAxis = [];
1369
        if ($X === $Y || !$Y)
1370
        {
1371
            $XYData[$X] = $this->initXYData($project_key, $X);
1372
        }
1373
        else
1374
        {
1375
            $XYData[$X] = $this->initXYData($project_key, $X);
1376
            $XYData[$Y] = $this->initXYData($project_key, $Y);
1377
        }
1378
1379
        $where = $this->getIssueQueryWhere($project_key, $request->all());
1380
        $query = DB::collection('issue_' . $project_key)->whereRaw($where);
1381
        $issues = $query->orderBy('no', 'desc')->take(10000)->get();
1382
1383
        foreach($issues as $issue)
1384
        {
1385
            foreach ($XYData as $dimension => $z)
1386
            {
1387
                if (!isset($issue[$dimension]) || !$issue[$dimension])
1388
                {
1389
                    continue;
1390
                }
1391
1392
                $issue_vals = [];
1393
                if (is_string($issue[$dimension]))
1394
                {
1395
                    if (strpos($issue[$dimension], ',') !== false)
1396
                    {
1397
                        $issue_vals = explode(',', $issue[$dimension]);
1398
                    }
1399
                    else
1400
                    {
1401
                        $issue_vals = [ $issue[$dimension] ];
1402
                    }
1403
                }
1404
                else if (is_array($issue[$dimension]))
1405
                {
1406
                    $issue_vals = $issue[$dimension];
1407
                    if (isset($issue[$dimension]['id']))
1408
                    {
1409
                        $issue_vals = [ $issue[$dimension] ];
1410
                    }
1411
                }
1412
1413
                foreach ($issue_vals as $issue_val)
1414
                {
1415
                    $tmpv = $issue_val;
1416
                    if (is_array($issue_val) && isset($issue_val['id']))
1417
                    {
1418
                        $tmpv = $issue_val['id'];
1419
                    }
1420
1421
                    if (isset($z[$tmpv]))
1422
                    {
1423
                        $XYData[$dimension][$tmpv]['nos'][] = $issue['no'];
1424
                    }
1425
                    else if ((is_array($issue_val) && isset($issue_val['id'])) || $dimension === 'labels')
1426
                    {
1427
                        if ($dimension === $Y && $X !== $Y)
1428
                        {
1429
                            $YAxis[$tmpv] = isset($issue[$dimension]['name']) ? $issue[$dimension]['name'] : $tmpv;
1430
                        }
1431
1432
                        $XYData[$dimension][$tmpv] = [ 'name' => isset($issue[$dimension]['name']) ? $issue[$dimension]['name'] : $tmpv, 'nos' => [ $issue['no'] ] ];
1433
                    }
1434
                }
1435
            }
1436
        }
1437
1438
        $results = [];
1439
        if ($X === $Y || !$Y)
1440
        {
1441
            foreach ($XYData[$X] as $key => $value)
1442
            {
1443
                $results[] = [ 'id' => $key, 'name' => $value['name'], 'cnt' => count($value['nos']) ];
1444
            }
1445
        }
1446
        else
1447
        {
1448
            foreach ($XYData[$X] as $key => $value)
1449
            {
1450
                $results[$key] = [ 'id' => $key, 'name' => $value['name'], 'y' => [] ];
1451
                $x_cnt = 0;
1452
1453
                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...
1454
                {
1455
                    foreach ($YAxis as $yai => $yav) 
1456
                    {
1457
                        if (isset($XYData[$Y][$yai]))
1458
                        {
1459
                            $y_cnt = count(array_intersect($value['nos'], $XYData[$Y][$yai]['nos']));
1460
                            $results[$key]['y'][] = [ 'id' => $yai, 'name' => $yav, 'cnt' => $y_cnt ];
1461
                            $x_cnt += $y_cnt;
1462
                        }
1463
                        else
1464
                        {
1465
                            $results[$key]['y'][] = [ 'id' => $yai, 'name' => yav, 'cnt' => 0 ];
1466
                        }
1467
                    }
1468
                }
1469
                else
1470
                {
1471
                    foreach ($XYData[$Y] as $key2 => $value2)
1472
                    {
1473
                        $y_cnt = count(array_intersect($value['nos'], $value2['nos']));
1474
1475
                        $results[$key]['y'][] = [ 'id' => $key2, 'name' => $value2['name'], 'cnt' => $y_cnt ];
1476
                        $x_cnt += $y_cnt;
1477
                    }
1478
                 }
1479
                 $results[$key]['cnt'] = $x_cnt;
1480
            }
1481
        }
1482
1483
        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...
1484
    }
1485
}
1486