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

SprintController::t2m()   B

Complexity

Conditions 10
Paths 20

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 31
rs 7.6666
c 0
b 0
f 0
cc 10
nc 20
nop 2

How to fix   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
namespace Fabrica\Http\Api;
3
4
use Illuminate\Http\Request;
5
use Illuminate\Support\Facades\Event;
6
7
use Fabrica\Http\Requests;
8
use Fabrica\Http\Api\Controller;
9
use Fabrica\Project\Eloquent\Sprint;
10
use Fabrica\Project\Eloquent\SprintDayLog;
11
use Fabrica\Project\Eloquent\Board;
12
use Fabrica\Project\Provider;
13
use Fabrica\Events\SprintEvent;
14
use Fabrica\System\Eloquent\CalendarSingular;
15
use DB;
16
17
class SprintController extends Controller
18
{
19
    public function __construct()
20
    {
21
        $this->middleware('privilege:manage_project', [ 'except' => [ 'show', 'getLog' ] ]);
22
        parent::__construct();
23
    }
24
25
    /**
26
     * Display a listing of the resource.
27
     *
28
     * @return \Illuminate\Http\Response
29
     */
30
    public function index($project_key)
31
    {
32
    }
33
34
    /**
35
     * Store a newly created resource in storage.
36
     *
37
     * @param  \Illuminate\Http\Request  $request
38
     * @return \Illuminate\Http\Response
39
     */
40
    public function store(Request $request, $project_key)
41
    {
42
        $sprint_count = Sprint::where('project_key', $project_key)->count();
43
        $sprint = Sprint::create([ 
0 ignored issues
show
Unused Code introduced by
$sprint 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...
44
            'project_key' => $project_key, 
45
            'no' => $sprint_count + 1, 
46
            'name' => 'Sprint ' . ($sprint_count + 1),
47
            'status' => 'waiting', 
48
            'issues' => [] 
49
        ]);
50
        return Response()->json(['ecode' => 0, 'data' => $this->getValidSprintList($project_key)]);
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...
51
    }
52
53
    /**
54
     * Display a listing of the resource.
55
     *
56
     * @return \Illuminate\Http\Response
57
     */
58
    public function moveIssue(Request $request, $project_key)
59
    {
60
        $issue_no = $request->input('issue_no');
61
        if (!$issue_no)
62
        {
63
            throw new \UnexpectedValueException('the moved issue cannot be empty', -11700);
64
        }
65
66
        $src_sprint_no = $request->input('src_sprint_no');
67
        if (!isset($src_sprint_no))
68
        {
69
            throw new \UnexpectedValueException('the src sprint of moved issue cannot be empty', -11701);
70
        }
71
        $src_sprint_no = intval($src_sprint_no);
72
73
        $dest_sprint_no = $request->input('dest_sprint_no');
74
        if (!isset($dest_sprint_no))
75
        {
76
            throw new \UnexpectedValueException('the dest sprint of moved issue cannot be empty', -11702);
77
        }
78
        $dest_sprint_no = intval($dest_sprint_no);
79
80 View Code Duplication
        if ($src_sprint_no > 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...
81
        {
82
            $src_sprint = Sprint::where('project_key', $project_key)->where('no', $src_sprint_no)->first(); 
83
            if (!in_array($issue_no, $src_sprint->issues ?: []))
84
            {
85
                throw new \UnexpectedValueException('the moved issue cannot be found in the src sprint', -11703);
86
            }
87
            if ($src_sprint->status == 'completed')
88
            {
89
                throw new \UnexpectedValueException('the moved issue cannot be moved into or moved out of the completed sprint', -11706);
90
            }
91
            $src_sprint->fill([ 'issues' => array_values(array_diff($src_sprint->issues, [ $issue_no ]) ?: []) ])->save();
92
93
            if ($src_sprint->status == 'active')
94
            {
95
                $this->popSprint($project_key, $issue_no, $src_sprint_no);
96
            }
97
        }
98
99 View Code Duplication
        if ($dest_sprint_no > 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...
100
        {
101
            $dest_sprint = Sprint::where('project_key', $project_key)->where('no', $dest_sprint_no)->first();
102
            if (in_array($issue_no, $dest_sprint->issues ?: []))
103
            {
104
                throw new \UnexpectedValueException('the moved issue has been in the dest sprint', -11704);
105
            }
106
            if ($dest_sprint->status == 'completed')
107
            {
108
                throw new \UnexpectedValueException('the moved issue cannot be moved into or moved out of the completed sprint', -11706);
109
            }
110
            $dest_sprint->fill([ 'issues' => array_values(array_merge($dest_sprint->issues ?: [], [ $issue_no ])) ])->save();
111
112
            if ($dest_sprint->status == 'active')
113
            {
114
                $this->pushSprint($project_key, $issue_no, $dest_sprint_no);
115
            }
116
        }
117
118
        return Response()->json([ 'ecode' => 0, 'data' => $this->getValidSprintList($project_key) ]);
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...
119
    }
120
121
    /**
122
     * Display the specified resource.
123
     *
124
     * @param  int  $id
0 ignored issues
show
Bug introduced by
There is no parameter named $id. 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...
125
     * @return \Illuminate\Http\Response
126
     */
127
    public function show($project_key, $no)
128
    {
129
        $sprint = Sprint::where('project_key', $project_key)->where('no', intval($no))->first();
130
        if (!$sprint->name)
131
        {
132
            $sprint->name = 'Sprint ' . $sprint->no;
133
        }
134
135
        return Response()->json(['ecode' => 0, 'data' => $sprint]);
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...
136
    }
137
138
    /**
139
     * publish the sprint.
140
     *
141
     * @param  \Illuminate\Http\Request  $request
142
     * @param  int  $id
0 ignored issues
show
Bug introduced by
There is no parameter named $id. 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...
143
     * @return \Illuminate\Http\Response
144
     */
145
    public function publish(Request $request, $project_key, $no)
146
    {
147
        if (!$no)
148
        {
149
            throw new \UnexpectedValueException('the published sprint cannot be empty', -11705);
150
        }
151
        $no = intval($no);
152
153
        $active_sprint_exists = Sprint::where('project_key', $project_key)
154
            ->where('status', 'active')
155
            ->exists();
156
        if ($active_sprint_exists)
157
        {
158
            throw new \UnexpectedValueException('the active sprint has been exists.', -11706);
159
        }
160
161
        $before_waiting_sprint_exists = Sprint::where('project_key', $project_key)
162
            ->where('status', 'waiting')
163
            ->where('no', '<', $no)
164
            ->exists();
165
        if ($before_waiting_sprint_exists)
166
        {
167
            throw new \UnexpectedValueException('the more first sprint has been exists.', -11707);
168
        }
169
170
        $sprint = Sprint::where('project_key', $project_key)
171
            ->where('no', $no)
172
            ->first();
173
        if (!$sprint || $project_key != $sprint->project_key)
174
        {
175
            throw new \UnexpectedValueException('the sprint does not exist or is not in the project.', -11708);
176
        }
177
178
        $updValues = [ 'status' => 'active' ];
179
180
        $start_time = $request->input('start_time');
181 View Code Duplication
        if (isset($start_time) && $start_time)
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...
182
        {
183
            $updValues['start_time'] = $start_time;
184
        }
185
        else
186
        {
187
            throw new \UnexpectedValueException('the sprint start time cannot be empty.', -11709);
188
        }
189
190
        $complete_time = $request->input('complete_time');
191 View Code Duplication
        if (isset($complete_time) && $complete_time)
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...
192
        {
193
            $updValues['complete_time'] = $complete_time;
194
        }
195
        else
196
        {
197
            throw new \UnexpectedValueException('the sprint complete time cannot be empty.', -11710);
198
        }
199
200
        $name = $request->input('name');
201
        if (isset($name) && $name)
202
        {
203
            $updValues['name'] = $name;
204
        }
205
206
        $description = $request->input('description');
207
        if (isset($description) && $description)
208
        {
209
            $updValues['description'] = $description;
210
        }
211
212
        $kanban_id = $request->input('kanban_id');
213
        if (!isset($kanban_id) || !$kanban_id)
214
        {
215
            throw new \UnexpectedValueException('the kanban id cannot be empty', -11717);
216
        }
217
218
        $new_issues = $this->filterIssues($project_key, isset($sprint->issues) ? $sprint->issues : [], $kanban_id);
219
220
        $updValues['issues'] = $new_issues['issues'];
221
        $updValues['origin_issues'] = $new_issues['origin_issues'];
222
223
        $sprint->fill($updValues)->save();
224
225
        foreach ($new_issues['issues'] as $issue_no)
226
        {
227
            $this->pushSprint($project_key, $issue_no, $no);
228
        }
229
230
        $isSendMsg = $request->input('isSendMsg') && true;
231
        $user = [ 'id' => $this->user->id, 'name' => $this->user->first_name, 'email' => $this->user->email ];
232
        Event::fire(new SprintEvent($project_key, $user, [ 'event_key' => 'start_sprint', 'isSendMsg' => $isSendMsg, 'data' => [ 'sprint_no' => $no ] ]));
233
234
        return Response()->json([ 'ecode' => 0, 'data' => $this->getValidSprintList($project_key) ]);
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...
235
    }
236
237
    /**
238
     * edit the sprint.
239
     *
240
     * @param  \Illuminate\Http\Request  $request
241
     * @param  int  $id
0 ignored issues
show
Bug introduced by
There is no parameter named $id. 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...
242
     * @return \Illuminate\Http\Response
243
     */
244
    public function update(Request $request, $project_key, $no)
245
    {
246
        if (!$no)
247
        {
248
            throw new \UnexpectedValueException('the updated sprint cannot be empty', -11718);
249
        }
250
        $no = intval($no);
251
252
        $sprint = Sprint::where('project_key', $project_key)->where('no', $no)->first();
253
        if (!$sprint || $project_key != $sprint->project_key)
254
        {
255
            throw new \UnexpectedValueException('the sprint does not exist or is not in the project.', -11708);
256
        }
257
258
        $updValues = [];
259
260
        $name = $request->input('name');
261
        if (isset($name) && $name)
262
        {
263
            $updValues['name'] = $name;
264
        }
265
266
        $description = $request->input('description');
267
        if (isset($description) && $description)
268
        {
269
            $updValues['description'] = $description;
270
        }
271
272
        $sprint->fill($updValues)->save();
273
274
        return Response()->json([ 'ecode' => 0, 'data' => $this->getValidSprintList($project_key) ]);
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...
275
    }
276
277
    /**
278
     * publish the sprint.
279
     *
280
     * @param  \Illuminate\Http\Request  $request
281
     * @param  int  $id
0 ignored issues
show
Bug introduced by
There is no parameter named $id. 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...
282
     * @return \Illuminate\Http\Response
283
     */
284
    public function complete(Request $request, $project_key, $no)
285
    {
286
        if (!$no)
287
        {
288
            throw new \UnexpectedValueException('the completed sprint cannot be empty', -11711);
289
        }
290
        $no = intval($no);
291
292
        $sprint = Sprint::where('project_key', $project_key)->where('no', $no)->first();
293
        if (!$sprint || $project_key != $sprint->project_key)
294
        {
295
            throw new \UnexpectedValueException('the sprint does not exist or is not in the project.', -11708);
296
        }
297
298 View Code Duplication
        if (!isset($sprint->status) || $sprint->status != 'active')
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...
299
        {
300
            throw new \UnexpectedValueException('the completed sprint must be active.', -11712);
301
        }
302
303
        $completed_issues = $request->input('completed_issues') ?: [];
304
        if (array_diff($completed_issues, $sprint->issues))
305
        {
306
            throw new \UnexpectedValueException('the completed sprint issues have errors.', -11713);
307
        }
308
309
        $incompleted_issues = array_values(array_diff($sprint->issues, $completed_issues));
310
311
        $valid_incompleted_issues = DB::collection('issue_' . $project_key)->whereIn('no', $incompleted_issues)->where('del_flg', '<>', 1)->get([ 'no' ]);
312
        if ($valid_incompleted_issues)
313
        {
314
    	    $valid_incompleted_issues = array_column($valid_incompleted_issues, 'no');
315
    	    $incompleted_issues = array_values(array_intersect($incompleted_issues, $valid_incompleted_issues));
316
        }
317
318
        $updValues = [ 
319
            'status' => 'completed', 
320
            'real_complete_time' => time(), 
321
            'completed_issues' => $completed_issues,
322
            'incompleted_issues' => $incompleted_issues 
323
        ];
324
325
        $sprint->fill($updValues)->save();
326
327
        if ($incompleted_issues)
0 ignored issues
show
Bug Best Practice introduced by
The expression $incompleted_issues 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...
328
        {
329
            $next_sprint = Sprint::where('project_key', $project_key)->where('status', 'waiting')->orderBy('no', 'asc')->first();
330 View Code Duplication
            if ($next_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...
331
            {
332
                $issues = !isset($next_sprint->issues) || !$next_sprint->issues ? [] : $next_sprint->issues;
333
                $issues = array_merge($incompleted_issues, $issues);
334
                $next_sprint->fill([ 'issues' => $issues ])->save();
335
            }
336
        }
337
338
        $isSendMsg = $request->input('isSendMsg') && true;
339
        $user = [ 'id' => $this->user->id, 'name' => $this->user->first_name, 'email' => $this->user->email ];
340
        Event::fire(new SprintEvent($project_key, $user, [ 'event_key' => 'complete_sprint', 'isSendMsg' => $isSendMsg, 'data' => [ 'sprint_no' => $no ] ]));
341
342
        return Response()->json([ 'ecode' => 0, 'data' => $this->getValidSprintList($project_key) ]);
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...
343
    }
344
345
    /**
346
     * Remove the specified resource from storage.
347
     *
348
     * @param  int  $id
0 ignored issues
show
Bug introduced by
There is no parameter named $id. 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...
349
     * @return \Illuminate\Http\Response
350
     */
351
    public function destroy($project_key, $no)
352
    {
353
        if (!$no)
354
        {
355
            throw new \UnexpectedValueException('the deleted sprint cannot be empty', -11714);
356
        }
357
        $no = intval($no);
358
359
        $sprint = Sprint::where('project_key', $project_key)->where('no', $no)->first();
360
        if (!$sprint || $project_key != $sprint->project_key)
361
        {
362
            throw new \UnexpectedValueException('the sprint does not exist or is not in the project.', -11708);
363
        }
364
365 View Code Duplication
        if ($sprint->status == 'completed' || $sprint->status == 'active')
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...
366
	{
367
            throw new \UnexpectedValueException('the active or completed sprint cannot be removed.', -11715);
368
        }
369
370
        if (isset($sprint->issues) && $sprint->issues)
371
        {
372
            $next_sprint = Sprint::where('project_key', $project_key)->where('no', '>', $no)->first();
373 View Code Duplication
            if ($next_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...
374
            {
375
                $issues = !isset($next_sprint->issues) || !$next_sprint->issues ? [] : $next_sprint->issues;
376
                $issues = array_merge($sprint->issues, $issues);
377
                $next_sprint->fill([ 'issues' => $issues ])->save();
378
            }
379
        }
380
381
        $sprint->delete();
382
383
        Sprint::where('project_key', $project_key)->where('no', '>', $no)->decrement('no');
384
385
        return Response()->json([ 'ecode' => 0, 'data' => $this->getValidSprintList($project_key) ]);
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...
386
    }
387
388
    /**
389
     * get waiting or active sprint list.
390
     *
391
     * @param  string  $project_key
392
     * @return array 
393
     */
394
    public function getValidSprintList($project_key)
395
    {
396
        $sprints = Sprint::where('project_key', $project_key)
397
            ->whereIn('status', [ 'active', 'waiting' ])
398
            ->orderBy('no', 'asc')
399
            ->get();
400
401
        foreach ($sprints as $sprint)
402
        {
403
            if (!$sprint->name)
404
            {
405
                $sprint->name = 'Sprint ' . $sprint->no;
406
            }
407
        }
408
409
        return $sprints;
410
    }
411
412
    /**
413
     * push sprint to issue detail.
414
     *
415
     * @param  string  $project_key
416
     * @param  string  $issue_no
417
     * @param  string  $sprint_no
418
     * @return void 
419
     */
420 View Code Duplication
    public function pushSprint($project_key, $issue_no, $sprint_no)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
421
    {
422
        $issue = DB::collection('issue_' . $project_key)->where('no', $issue_no)->first();
423
        if (!$issue)
424
        {
425
            return;
426
        }
427
428
        $sprints = [];
429
        if (isset($issue['sprints']) && $issue['sprints'])
430
        {
431
            $sprints = $issue['sprints'];
432
        }
433
        array_push($sprints, $sprint_no);
434
435
        DB::collection('issue_' . $project_key)->where('no', $issue_no)->update(['sprints' => $sprints]);
436
    }
437
438
    /**
439
     * pop sprint from issue detail.
440
     *
441
     * @param  string  $project_key
442
     * @param  string  $issue_no
443
     * @param  string  $sprint_no
444
     * @return void 
445
     */
446 View Code Duplication
    public function popSprint($project_key, $issue_no, $sprint_no)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
447
    {
448
        $issue = DB::collection('issue_' . $project_key)->where('no', $issue_no)->first();
449
        if (!$issue)
450
        {
451
            return;
452
        }
453
454
        $sprints = [];
455
        if (isset($issue['sprints']) && $issue['sprints'])
456
        {
457
            $sprints = $issue['sprints'];
458
        }
459
        $new_sprints = array_diff($sprints, [ $sprint_no ]);
460
461
        DB::collection('issue_' . $project_key)->where('no', $issue_no)->update(['sprints' => $new_sprints]);
462
    }
463
464
   /**
465
     * get the last column state of the kanban.
466
     *
467
     * @param  string $kanban_id
468
     * @return array 
469
     */
470
    public function getLastColumnStates($kanban_id)
471
    {
472
        // remaining start
473
        $last_column_states = [];
474
        $board = Board::find($kanban_id);
475 View Code Duplication
        if ($board && isset($board->columns))
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...
476
        {
477
            $board_columns = $board->columns;
478
            $last_column = array_pop($board_columns) ?: [];
479
            if ($last_column && isset($last_column['states']) && $last_column['states'])
480
            {
481
                $last_column_states = $last_column['states'];
482
            }
483
        }
484
        return $last_column_states; 
485
    }
486
487
   /**
488
     * get sprint original state.
489
     *
490
     * @param  string $project_key
491
     * @param  array  $issue_nos
492
     * @param  string $kanban_id
493
     * @return array
494
     */
495
    public function filterIssues($project_key, $issue_nos, $kanban_id)
496
    {
497
        // get the kanban last column states
498
        $last_column_states = $this->getLastColumnStates($kanban_id);
499
500
        $new_issue_nos = [];
501
        $origin_issues = [];
502
503
        $issues = DB::collection('issue_' . $project_key)
504
            ->where([ 'no' => [ '$in' => $issue_nos ] ])
505
            ->where([ 'state' => [ '$nin' => $last_column_states ] ])
506
            ->get();
507
        foreach ($issues as $issue)
508
        {
509
            $new_issue_nos[] = $issue['no'];
510
511
            $origin_issues[] = [
512
                'no' => $issue['no'],
513
                'state' => isset($issue['state']) ? $issue['state'] : '',
514
                'story_points' => isset($issue['story_points']) ? $issue['story_points'] : 0 ];
515
        }
516
517
        return [ 'issues' => $new_issue_nos, 'origin_issues' => $origin_issues ];
518
    }
519
520
   /**
521
     * get sprint original state.
522
     *
523
     * @param  string $project_key 
524
     * @param  array  $issue_nos
525
     * @return array 
526
     */
527
    public function getOriginIssues($project_key, $issue_nos)
528
    {
529
        $origin_issues = [];
530
        $issues = DB::collection('issue_' . $project_key)->where([ 'no' => [ '$in' => $issue_nos ] ])->get();
531
        foreach ($issues as $issue)
532
        {
533
            $origin_issues[] = [ 
534
                'no' => $issue['no'], 
535
                'state' => isset($issue['state']) ? $issue['state'] : '', 
536
                'story_points' => isset($issue['story_points']) ? $issue['story_points'] : 0 ];
537
        }
538
        return $origin_issues;
539
    }
540
541
    /**
542
     * get sprint log.
543
     *
544
     * @param  string  $project_key
545
     * @param  string  $sprint_no
546
     * @return \Illuminate\Http\Response
547
     */
548
    public function getLog(Request $request, $project_key, $sprint_no)
549
    {
550
        $sprint_no = intval($sprint_no);
551
552
        $kanban_id = $request->input('kanban_id');
553
        if (!$kanban_id)
554
        {
555
            throw new \UnexpectedValueException('the kanban id cannot be empty', -11717);
556
        }
557
558
        $sprint = Sprint::where('project_key', $project_key)
559
            ->where('no', $sprint_no)
560
            ->first();
561
        if (!$sprint)
562
        {
563
            throw new \UnexpectedValueException('the sprint does not exist or is not in the project.', -11708);
564
        }
565
566
        $origin_issue_count = 0;
567
        if (isset($sprint->origin_issues))
568
        {
569
            $origin_issue_count = count($sprint->origin_issues); 
570
        }
571
        $origin_story_points = 0;
572
        if (isset($sprint->origin_issues))
573
        {
574
            foreach ($sprint->origin_issues as $val)
575
            {
576
                $origin_story_points += $val['story_points']; 
577
            }
578
        }
579
580
        $workingDays = $this->getWorkingDay($sprint->start_time, $sprint->complete_time); 
581
        $workingDayNum = 0;
582
        foreach ($workingDays as $val)
583
        {
584
            $workingDayNum += $val;
585
        }
586
587
        // guideline start
588
        $issue_count_guideline = [];
589
        $story_points_guideline = [];
590
        $issue_count_guideline[] = [ 'day' => '', 'value' => $origin_issue_count ];
591
        $story_points_guideline[] = [ 'day' => '', 'value' => $origin_story_points ];
592
        $tmp_issue_count = $origin_issue_count;
593
        $tmp_story_points = $origin_story_points;
594
        foreach ($workingDays as $day => $flag)
595
        {
596
            if ($flag === 1)
597
            {
598
                $tmp_issue_count = max([ round($tmp_issue_count - $origin_issue_count / $workingDayNum, 2), 0 ]);
599
                $tmp_story_points = max([ round($tmp_story_points - $origin_story_points / $workingDayNum, 2), 0 ]);
600
            }
601
            $issue_count_guideline[] = [ 'day' => substr($day, 5), 'value' => $tmp_issue_count, 'notWorking' => ($flag + 1) % 2 ];
602
            $story_points_guideline[] = [ 'day' => substr($day, 5), 'value' => $tmp_story_points, 'notWorking' => ($flag + 1) % 2 ];
603
        }
604
        // guideline end 
605
606
        // remaining start
607
        $last_column_states = $this->getLastColumnStates($kanban_id);
608
609
        $sprint_day_log = SprintDayLog::where('project_key', $project_key)
610
            ->where('no', $sprint_no)
611
            ->orderBy('day', 'asc')
612
            ->get();
613
614
        $issue_count_remaining = [];
615
        $story_points_remaining = [];
616
	$issue_count_remaining[] = [ 'day' => '', 'value' => $origin_issue_count ];
617
	$story_points_remaining[] = [ 'day' => '', 'value' => $origin_story_points ];
618
        foreach($sprint_day_log as $daylog)
619
        {
620
            $incompleted_issue_num = 0;
621
            $incompleted_story_points = 0;
622
            $issues = isset($daylog->issues) ? $daylog->issues : []; 
623
            foreach ($issues as $issue)
624
            {
625
                if (!in_array($issue['state'], $last_column_states))
626
                {
627
                    $incompleted_issue_num++;
628
                    $incompleted_story_points += isset($issue['story_points']) ? $issue['story_points'] : 0;
629
                } 
630
            }
631
            $issue_count_remaining[] = [ 'day' => substr($daylog->day, 5), 'value' => $incompleted_issue_num, 'notWorking' => isset($workingDays[$daylog->day]) ? ($workingDays[$daylog->day] + 1) % 2 : 0 ]; 
632
            $story_points_remaining[] = [ 'day' => substr($daylog->day, 5), 'value' => $incompleted_story_points, 'notWorking' => isset($workingDays[$daylog->day]) ? ($workingDays[$daylog->day] + 1) % 2 : 0 ]; 
633
        }
634
        // remaining start
635
636
        return Response()->json([ 'ecode' => 0, 'data' => [ 'issue_count' => [ 'guideline' => $issue_count_guideline, 'remaining' => $issue_count_remaining ], 'story_points' => [ 'guideline' => $story_points_guideline, 'remaining' => $story_points_remaining ] ] ]);
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...
637
    }
638
639
    /**
640
     * get working day flag.
641
     *
642
     * @param  int  $start_time
643
     * @param  int  $complete_time
0 ignored issues
show
Bug introduced by
There is no parameter named $complete_time. 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...
644
     * @return \Illuminate\Http\Response
645
     */
646
    public function getWorkingDay($start_time, $end_time)
647
    {
648
        $days = [];
649
        $tmp_time = $start_time;
650
        while ($tmp_time < $end_time)
651
        {
652
            $day = date('Y/m/d', $tmp_time);
653
            $days[] = $day;
654
655
            $week_flg = intval(date('w', $tmp_time));
656
            $workingDays[$day] = ($week_flg === 0 || $week_flg === 6) ? 0 : 1;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$workingDays was never initialized. Although not strictly required by PHP, it is generally a good practice to add $workingDays = 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...
657
658
            $tmp_time += 24 * 60 * 60;
659
        }
660
661
        $singulars = CalendarSingular::where([ 'date' => [ '$in' => $days ] ])->get();
662
        foreach ($singulars as $singular)
663
        {
664
            $tmp = $singular->date;
665
            $workingDays[$tmp] = $singular->type == 'holiday' ? 0 : 1;
0 ignored issues
show
Bug introduced by
The variable $workingDays 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...
666
        }
667
        return $workingDays;
668
    }
669
670
    public function t2m($val, $options) 
671
    {
672
        $w2d = isset($options['w2d']) ? $options['w2d'] : 5;
673
        $d2h = isset($options['d2h']) ? $options['d2h'] : 8;
674
675
        $total = 0;
676
        $tmp = explode(' ', $val);
677
        foreach ($tmp as $v)
678
        {
679
            $t = substr($v, 0, strlen($v) - 1);
680
            $u = substr($v, -1);
681
682
            if ($u == 'w' || $u == 'W')
683
            {
684
                $total += $total + $t * $w2d * $d2h;
685
            }
686
            else if ($u == 'd' || $u == 'D')
687
            {
688
                $total += $t * $d2h * 60;
689
            }
690
            else if ($u == 'h' || $u == 'H')
691
            {
692
                $total += $t * 60;
693
            }
694
            else 
695
            {
696
                $total += $t;
697
            }
698
        }
699
        return $total;
700
    }
701
702
    public function getRemainingTime($issue_no)
703
    {
704
        $origin_estimate_time = 0;
705
        $issue = DB::where('no', $issue_no)->first();
706
        if (isset($issue['original_estimate']))
707
        {
708
            $origin_estimate_time = $issue['original_estimate'];
709
        }
710
711
        $leave_estimate_m = $this->t2m($origin_estimate_time);
712
        if ($leave_estimate_m <= 0)
713
        {
714
            return 0;
715
        }
716
717
        $worklogs = Worklog::Where('project_key', $project_key)
0 ignored issues
show
Bug introduced by
The variable $project_key does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
718
            ->where('issue_id', $issue_id)
0 ignored issues
show
Bug introduced by
The variable $issue_id does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
719
            ->orderBy('recorded_at', 'asc')
720
            ->get();
721
722
        foreach ($worklogs as $worklog)
723
        {
724
            if (!isset($worklog['spend']))
725
            {
726
                continue;
727
            }
728
            if (isset($worklog['adjust_type']))
729
            {
730
                if ($worklog['adjust_type'] == 1)
731
                {
732
                    $spend_m = $this->t2m($worklog['spend']);
733
                    $leave_estimate_m = $leave_estimate_m - $spend_m;
734
                }
735
                else if ($worklog['adjust_type'] == 3)
736
                {
737
                    $leave_estimate_m = $this->t2m(isset($worklog['cut']) ? $worklog['cut'] : 0);
738
                }
739
            }
740
        }
741
    }
742
}
743