SprintController::update()   B
last analyzed

Complexity

Conditions 8
Paths 6

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 28
rs 8.4444
c 0
b 0
f 0
cc 8
nc 6
nop 3
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
            [ 
45
            'project_key' => $project_key, 
46
            'no' => $sprint_count + 1, 
47
            'name' => 'Sprint ' . ($sprint_count + 1),
48
            'status' => 'waiting', 
49
            'issues' => [] 
50
            ]
51
        );
52
        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...
53
    }
54
55
    /**
56
     * Display a listing of the resource.
57
     *
58
     * @return \Illuminate\Http\Response
59
     */
60
    public function moveIssue(Request $request, $project_key)
61
    {
62
        $issue_no = $request->input('issue_no');
63
        if (!$issue_no) {
64
            throw new \UnexpectedValueException('the moved issue cannot be empty', -11700);
65
        }
66
67
        $src_sprint_no = $request->input('src_sprint_no');
68
        if (!isset($src_sprint_no)) {
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
            throw new \UnexpectedValueException('the dest sprint of moved issue cannot be empty', -11702);
76
        }
77
        $dest_sprint_no = intval($dest_sprint_no);
78
79 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...
80
            $src_sprint = Sprint::where('project_key', $project_key)->where('no', $src_sprint_no)->first(); 
81
            if (!in_array($issue_no, $src_sprint->issues ?: [])) {
82
                throw new \UnexpectedValueException('the moved issue cannot be found in the src sprint', -11703);
83
            }
84
            if ($src_sprint->status == 'completed') {
85
                throw new \UnexpectedValueException('the moved issue cannot be moved into or moved out of the completed sprint', -11706);
86
            }
87
            $src_sprint->fill([ 'issues' => array_values(array_diff($src_sprint->issues, [ $issue_no ]) ?: []) ])->save();
88
89
            if ($src_sprint->status == 'active') {
90
                $this->popSprint($project_key, $issue_no, $src_sprint_no);
91
            }
92
        }
93
94 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...
95
            $dest_sprint = Sprint::where('project_key', $project_key)->where('no', $dest_sprint_no)->first();
96
            if (in_array($issue_no, $dest_sprint->issues ?: [])) {
97
                throw new \UnexpectedValueException('the moved issue has been in the dest sprint', -11704);
98
            }
99
            if ($dest_sprint->status == 'completed') {
100
                throw new \UnexpectedValueException('the moved issue cannot be moved into or moved out of the completed sprint', -11706);
101
            }
102
            $dest_sprint->fill([ 'issues' => array_values(array_merge($dest_sprint->issues ?: [], [ $issue_no ])) ])->save();
103
104
            if ($dest_sprint->status == 'active') {
105
                $this->pushSprint($project_key, $issue_no, $dest_sprint_no);
106
            }
107
        }
108
109
        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...
110
    }
111
112
    /**
113
     * Display the specified resource.
114
     *
115
     * @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...
116
     * @return \Illuminate\Http\Response
117
     */
118
    public function show($project_key, $no)
119
    {
120
        $sprint = Sprint::where('project_key', $project_key)->where('no', intval($no))->first();
121
        if (!$sprint->name) {
122
            $sprint->name = 'Sprint ' . $sprint->no;
123
        }
124
125
        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...
126
    }
127
128
    /**
129
     * publish the sprint.
130
     *
131
     * @param  \Illuminate\Http\Request $request
132
     * @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...
133
     * @return \Illuminate\Http\Response
134
     */
135
    public function publish(Request $request, $project_key, $no)
136
    {
137
        if (!$no) {
138
            throw new \UnexpectedValueException('the published sprint cannot be empty', -11705);
139
        }
140
        $no = intval($no);
141
142
        $active_sprint_exists = Sprint::where('project_key', $project_key)
143
            ->where('status', 'active')
144
            ->exists();
145
        if ($active_sprint_exists) {
146
            throw new \UnexpectedValueException('the active sprint has been exists.', -11706);
147
        }
148
149
        $before_waiting_sprint_exists = Sprint::where('project_key', $project_key)
150
            ->where('status', 'waiting')
151
            ->where('no', '<', $no)
152
            ->exists();
153
        if ($before_waiting_sprint_exists) {
154
            throw new \UnexpectedValueException('the more first sprint has been exists.', -11707);
155
        }
156
157
        $sprint = Sprint::where('project_key', $project_key)
158
            ->where('no', $no)
159
            ->first();
160
        if (!$sprint || $project_key != $sprint->project_key) {
161
            throw new \UnexpectedValueException('the sprint does not exist or is not in the project.', -11708);
162
        }
163
164
        $updValues = [ 'status' => 'active' ];
165
166
        $start_time = $request->input('start_time');
167 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...
168
            $updValues['start_time'] = $start_time;
169
        }
170
        else
171
        {
172
            throw new \UnexpectedValueException('the sprint start time cannot be empty.', -11709);
173
        }
174
175
        $complete_time = $request->input('complete_time');
176 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...
177
            $updValues['complete_time'] = $complete_time;
178
        }
179
        else
180
        {
181
            throw new \UnexpectedValueException('the sprint complete time cannot be empty.', -11710);
182
        }
183
184
        $name = $request->input('name');
185
        if (isset($name) && $name) {
186
            $updValues['name'] = $name;
187
        }
188
189
        $description = $request->input('description');
190
        if (isset($description) && $description) {
191
            $updValues['description'] = $description;
192
        }
193
194
        $kanban_id = $request->input('kanban_id');
195
        if (!isset($kanban_id) || !$kanban_id) {
196
            throw new \UnexpectedValueException('the kanban id cannot be empty', -11717);
197
        }
198
199
        $new_issues = $this->filterIssues($project_key, isset($sprint->issues) ? $sprint->issues : [], $kanban_id);
200
201
        $updValues['issues'] = $new_issues['issues'];
202
        $updValues['origin_issues'] = $new_issues['origin_issues'];
203
204
        $sprint->fill($updValues)->save();
205
206
        foreach ($new_issues['issues'] as $issue_no)
207
        {
208
            $this->pushSprint($project_key, $issue_no, $no);
209
        }
210
211
        $isSendMsg = $request->input('isSendMsg') && true;
212
        $user = [ 'id' => $this->user->id, 'name' => $this->user->first_name, 'email' => $this->user->email ];
213
        Event::fire(new SprintEvent($project_key, $user, [ 'event_key' => 'start_sprint', 'isSendMsg' => $isSendMsg, 'data' => [ 'sprint_no' => $no ] ]));
214
215
        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...
216
    }
217
218
    /**
219
     * edit the sprint.
220
     *
221
     * @param  \Illuminate\Http\Request $request
222
     * @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...
223
     * @return \Illuminate\Http\Response
224
     */
225
    public function update(Request $request, $project_key, $no)
226
    {
227
        if (!$no) {
228
            throw new \UnexpectedValueException('the updated sprint cannot be empty', -11718);
229
        }
230
        $no = intval($no);
231
232
        $sprint = Sprint::where('project_key', $project_key)->where('no', $no)->first();
233
        if (!$sprint || $project_key != $sprint->project_key) {
234
            throw new \UnexpectedValueException('the sprint does not exist or is not in the project.', -11708);
235
        }
236
237
        $updValues = [];
238
239
        $name = $request->input('name');
240
        if (isset($name) && $name) {
241
            $updValues['name'] = $name;
242
        }
243
244
        $description = $request->input('description');
245
        if (isset($description) && $description) {
246
            $updValues['description'] = $description;
247
        }
248
249
        $sprint->fill($updValues)->save();
250
251
        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...
252
    }
253
254
    /**
255
     * publish the sprint.
256
     *
257
     * @param  \Illuminate\Http\Request $request
258
     * @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...
259
     * @return \Illuminate\Http\Response
260
     */
261
    public function complete(Request $request, $project_key, $no)
262
    {
263
        if (!$no) {
264
            throw new \UnexpectedValueException('the completed sprint cannot be empty', -11711);
265
        }
266
        $no = intval($no);
267
268
        $sprint = Sprint::where('project_key', $project_key)->where('no', $no)->first();
269
        if (!$sprint || $project_key != $sprint->project_key) {
270
            throw new \UnexpectedValueException('the sprint does not exist or is not in the project.', -11708);
271
        }
272
273 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...
274
            throw new \UnexpectedValueException('the completed sprint must be active.', -11712);
275
        }
276
277
        $completed_issues = $request->input('completed_issues') ?: [];
278
        if (array_diff($completed_issues, $sprint->issues)) {
279
            throw new \UnexpectedValueException('the completed sprint issues have errors.', -11713);
280
        }
281
282
        $incompleted_issues = array_values(array_diff($sprint->issues, $completed_issues));
283
284
        $valid_incompleted_issues = DB::collection('issue_' . $project_key)->whereIn('no', $incompleted_issues)->where('del_flg', '<>', 1)->get([ 'no' ]);
285
        if ($valid_incompleted_issues) {
286
            $valid_incompleted_issues = array_column($valid_incompleted_issues, 'no');
287
            $incompleted_issues = array_values(array_intersect($incompleted_issues, $valid_incompleted_issues));
288
        }
289
290
        $updValues = [ 
291
            'status' => 'completed', 
292
            'real_complete_time' => time(), 
293
            'completed_issues' => $completed_issues,
294
            'incompleted_issues' => $incompleted_issues 
295
        ];
296
297
        $sprint->fill($updValues)->save();
298
299
        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...
300
            $next_sprint = Sprint::where('project_key', $project_key)->where('status', 'waiting')->orderBy('no', 'asc')->first();
301 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...
302
                $issues = !isset($next_sprint->issues) || !$next_sprint->issues ? [] : $next_sprint->issues;
303
                $issues = array_merge($incompleted_issues, $issues);
304
                $next_sprint->fill([ 'issues' => $issues ])->save();
305
            }
306
        }
307
308
        $isSendMsg = $request->input('isSendMsg') && true;
309
        $user = [ 'id' => $this->user->id, 'name' => $this->user->first_name, 'email' => $this->user->email ];
310
        Event::fire(new SprintEvent($project_key, $user, [ 'event_key' => 'complete_sprint', 'isSendMsg' => $isSendMsg, 'data' => [ 'sprint_no' => $no ] ]));
311
312
        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...
313
    }
314
315
    /**
316
     * Remove the specified resource from storage.
317
     *
318
     * @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...
319
     * @return \Illuminate\Http\Response
320
     */
321
    public function destroy($project_key, $no)
322
    {
323
        if (!$no) {
324
            throw new \UnexpectedValueException('the deleted sprint cannot be empty', -11714);
325
        }
326
        $no = intval($no);
327
328
        $sprint = Sprint::where('project_key', $project_key)->where('no', $no)->first();
329
        if (!$sprint || $project_key != $sprint->project_key) {
330
            throw new \UnexpectedValueException('the sprint does not exist or is not in the project.', -11708);
331
        }
332
333 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...
334
            throw new \UnexpectedValueException('the active or completed sprint cannot be removed.', -11715);
335
        }
336
337
        if (isset($sprint->issues) && $sprint->issues) {
338
            $next_sprint = Sprint::where('project_key', $project_key)->where('no', '>', $no)->first();
339 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...
340
                $issues = !isset($next_sprint->issues) || !$next_sprint->issues ? [] : $next_sprint->issues;
341
                $issues = array_merge($sprint->issues, $issues);
342
                $next_sprint->fill([ 'issues' => $issues ])->save();
343
            }
344
        }
345
346
        $sprint->delete();
347
348
        Sprint::where('project_key', $project_key)->where('no', '>', $no)->decrement('no');
349
350
        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...
351
    }
352
353
    /**
354
     * get waiting or active sprint list.
355
     *
356
     * @param  string $project_key
357
     * @return array 
358
     */
359
    public function getValidSprintList($project_key)
360
    {
361
        $sprints = Sprint::where('project_key', $project_key)
362
            ->whereIn('status', [ 'active', 'waiting' ])
363
            ->orderBy('no', 'asc')
364
            ->get();
365
366
        foreach ($sprints as $sprint)
367
        {
368
            if (!$sprint->name) {
369
                $sprint->name = 'Sprint ' . $sprint->no;
370
            }
371
        }
372
373
        return $sprints;
374
    }
375
376
    /**
377
     * push sprint to issue detail.
378
     *
379
     * @param  string $project_key
380
     * @param  string $issue_no
381
     * @param  string $sprint_no
382
     * @return void 
383
     */
384 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...
385
    {
386
        $issue = DB::collection('issue_' . $project_key)->where('no', $issue_no)->first();
387
        if (!$issue) {
388
            return;
389
        }
390
391
        $sprints = [];
392
        if (isset($issue['sprints']) && $issue['sprints']) {
393
            $sprints = $issue['sprints'];
394
        }
395
        array_push($sprints, $sprint_no);
396
397
        DB::collection('issue_' . $project_key)->where('no', $issue_no)->update(['sprints' => $sprints]);
398
    }
399
400
    /**
401
     * pop sprint from issue detail.
402
     *
403
     * @param  string $project_key
404
     * @param  string $issue_no
405
     * @param  string $sprint_no
406
     * @return void 
407
     */
408 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...
409
    {
410
        $issue = DB::collection('issue_' . $project_key)->where('no', $issue_no)->first();
411
        if (!$issue) {
412
            return;
413
        }
414
415
        $sprints = [];
416
        if (isset($issue['sprints']) && $issue['sprints']) {
417
            $sprints = $issue['sprints'];
418
        }
419
        $new_sprints = array_diff($sprints, [ $sprint_no ]);
420
421
        DB::collection('issue_' . $project_key)->where('no', $issue_no)->update(['sprints' => $new_sprints]);
422
    }
423
424
    /**
425
     * get the last column state of the kanban.
426
     *
427
     * @param  string $kanban_id
428
     * @return array 
429
     */
430
    public function getLastColumnStates($kanban_id)
431
    {
432
        // remaining start
433
        $last_column_states = [];
434
        $board = Board::find($kanban_id);
435 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...
436
            $board_columns = $board->columns;
437
            $last_column = array_pop($board_columns) ?: [];
438
            if ($last_column && isset($last_column['states']) && $last_column['states']) {
439
                $last_column_states = $last_column['states'];
440
            }
441
        }
442
        return $last_column_states; 
443
    }
444
445
    /**
446
     * get sprint original state.
447
     *
448
     * @param  string $project_key
449
     * @param  array  $issue_nos
450
     * @param  string $kanban_id
451
     * @return array
452
     */
453
    public function filterIssues($project_key, $issue_nos, $kanban_id)
454
    {
455
        // get the kanban last column states
456
        $last_column_states = $this->getLastColumnStates($kanban_id);
457
458
        $new_issue_nos = [];
459
        $origin_issues = [];
460
461
        $issues = DB::collection('issue_' . $project_key)
462
            ->where([ 'no' => [ '$in' => $issue_nos ] ])
463
            ->where([ 'state' => [ '$nin' => $last_column_states ] ])
464
            ->get();
465
        foreach ($issues as $issue)
466
        {
467
            $new_issue_nos[] = $issue['no'];
468
469
            $origin_issues[] = [
470
                'no' => $issue['no'],
471
                'state' => isset($issue['state']) ? $issue['state'] : '',
472
                'story_points' => isset($issue['story_points']) ? $issue['story_points'] : 0 ];
473
        }
474
475
        return [ 'issues' => $new_issue_nos, 'origin_issues' => $origin_issues ];
476
    }
477
478
    /**
479
     * get sprint original state.
480
     *
481
     * @param  string $project_key 
482
     * @param  array  $issue_nos
483
     * @return array 
484
     */
485
    public function getOriginIssues($project_key, $issue_nos)
486
    {
487
        $origin_issues = [];
488
        $issues = DB::collection('issue_' . $project_key)->where([ 'no' => [ '$in' => $issue_nos ] ])->get();
489
        foreach ($issues as $issue)
490
        {
491
            $origin_issues[] = [ 
492
                'no' => $issue['no'], 
493
                'state' => isset($issue['state']) ? $issue['state'] : '', 
494
                'story_points' => isset($issue['story_points']) ? $issue['story_points'] : 0 ];
495
        }
496
        return $origin_issues;
497
    }
498
499
    /**
500
     * get sprint log.
501
     *
502
     * @param  string $project_key
503
     * @param  string $sprint_no
504
     * @return \Illuminate\Http\Response
505
     */
506
    public function getLog(Request $request, $project_key, $sprint_no)
507
    {
508
        $sprint_no = intval($sprint_no);
509
510
        $kanban_id = $request->input('kanban_id');
511
        if (!$kanban_id) {
512
            throw new \UnexpectedValueException('the kanban id cannot be empty', -11717);
513
        }
514
515
        $sprint = Sprint::where('project_key', $project_key)
516
            ->where('no', $sprint_no)
517
            ->first();
518
        if (!$sprint) {
519
            throw new \UnexpectedValueException('the sprint does not exist or is not in the project.', -11708);
520
        }
521
522
        $origin_issue_count = 0;
523
        if (isset($sprint->origin_issues)) {
524
            $origin_issue_count = count($sprint->origin_issues); 
525
        }
526
        $origin_story_points = 0;
527
        if (isset($sprint->origin_issues)) {
528
            foreach ($sprint->origin_issues as $val)
529
            {
530
                $origin_story_points += $val['story_points']; 
531
            }
532
        }
533
534
        $workingDays = $this->getWorkingDay($sprint->start_time, $sprint->complete_time); 
535
        $workingDayNum = 0;
536
        foreach ($workingDays as $val)
537
        {
538
            $workingDayNum += $val;
539
        }
540
541
        // guideline start
542
        $issue_count_guideline = [];
543
        $story_points_guideline = [];
544
        $issue_count_guideline[] = [ 'day' => '', 'value' => $origin_issue_count ];
545
        $story_points_guideline[] = [ 'day' => '', 'value' => $origin_story_points ];
546
        $tmp_issue_count = $origin_issue_count;
547
        $tmp_story_points = $origin_story_points;
548
        foreach ($workingDays as $day => $flag)
549
        {
550
            if ($flag === 1) {
551
                $tmp_issue_count = max([ round($tmp_issue_count - $origin_issue_count / $workingDayNum, 2), 0 ]);
552
                $tmp_story_points = max([ round($tmp_story_points - $origin_story_points / $workingDayNum, 2), 0 ]);
553
            }
554
            $issue_count_guideline[] = [ 'day' => substr($day, 5), 'value' => $tmp_issue_count, 'notWorking' => ($flag + 1) % 2 ];
555
            $story_points_guideline[] = [ 'day' => substr($day, 5), 'value' => $tmp_story_points, 'notWorking' => ($flag + 1) % 2 ];
556
        }
557
        // guideline end 
558
559
        // remaining start
560
        $last_column_states = $this->getLastColumnStates($kanban_id);
561
562
        $sprint_day_log = SprintDayLog::where('project_key', $project_key)
563
            ->where('no', $sprint_no)
564
            ->orderBy('day', 'asc')
565
            ->get();
566
567
        $issue_count_remaining = [];
568
        $story_points_remaining = [];
569
        $issue_count_remaining[] = [ 'day' => '', 'value' => $origin_issue_count ];
570
        $story_points_remaining[] = [ 'day' => '', 'value' => $origin_story_points ];
571
        foreach($sprint_day_log as $daylog)
572
        {
573
            $incompleted_issue_num = 0;
574
            $incompleted_story_points = 0;
575
            $issues = isset($daylog->issues) ? $daylog->issues : []; 
576
            foreach ($issues as $issue)
577
            {
578
                if (!in_array($issue['state'], $last_column_states)) {
579
                    $incompleted_issue_num++;
580
                    $incompleted_story_points += isset($issue['story_points']) ? $issue['story_points'] : 0;
581
                } 
582
            }
583
            $issue_count_remaining[] = [ 'day' => substr($daylog->day, 5), 'value' => $incompleted_issue_num, 'notWorking' => isset($workingDays[$daylog->day]) ? ($workingDays[$daylog->day] + 1) % 2 : 0 ]; 
584
            $story_points_remaining[] = [ 'day' => substr($daylog->day, 5), 'value' => $incompleted_story_points, 'notWorking' => isset($workingDays[$daylog->day]) ? ($workingDays[$daylog->day] + 1) % 2 : 0 ]; 
585
        }
586
        // remaining start
587
588
        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...
589
    }
590
591
    /**
592
     * get working day flag.
593
     *
594
     * @param  int $start_time
595
     * @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...
596
     * @return \Illuminate\Http\Response
597
     */
598
    public function getWorkingDay($start_time, $end_time)
599
    {
600
        $days = [];
601
        $tmp_time = $start_time;
602
        while ($tmp_time < $end_time)
603
        {
604
            $day = date('Y/m/d', $tmp_time);
605
            $days[] = $day;
606
607
            $week_flg = intval(date('w', $tmp_time));
608
            $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...
609
610
            $tmp_time += 24 * 60 * 60;
611
        }
612
613
        $singulars = CalendarSingular::where([ 'date' => [ '$in' => $days ] ])->get();
614
        foreach ($singulars as $singular)
615
        {
616
            $tmp = $singular->date;
617
            $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...
618
        }
619
        return $workingDays;
620
    }
621
622
    public function t2m($val, $options) 
623
    {
624
        $w2d = isset($options['w2d']) ? $options['w2d'] : 5;
625
        $d2h = isset($options['d2h']) ? $options['d2h'] : 8;
626
627
        $total = 0;
628
        $tmp = explode(' ', $val);
629
        foreach ($tmp as $v)
630
        {
631
            $t = substr($v, 0, strlen($v) - 1);
632
            $u = substr($v, -1);
633
634
            if ($u == 'w' || $u == 'W') {
635
                $total += $total + $t * $w2d * $d2h;
636
            }
637
            else if ($u == 'd' || $u == 'D') {
638
                $total += $t * $d2h * 60;
639
            }
640
            else if ($u == 'h' || $u == 'H') {
641
                $total += $t * 60;
642
            }
643
            else 
644
            {
645
                $total += $t;
646
            }
647
        }
648
        return $total;
649
    }
650
651
    public function getRemainingTime($issue_no)
652
    {
653
        $origin_estimate_time = 0;
654
        $issue = DB::where('no', $issue_no)->first();
655
        if (isset($issue['original_estimate'])) {
656
            $origin_estimate_time = $issue['original_estimate'];
657
        }
658
659
        $leave_estimate_m = $this->t2m($origin_estimate_time);
660
        if ($leave_estimate_m <= 0) {
661
            return 0;
662
        }
663
664
        $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...
665
            ->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...
666
            ->orderBy('recorded_at', 'asc')
667
            ->get();
668
669
        foreach ($worklogs as $worklog)
670
        {
671
            if (!isset($worklog['spend'])) {
672
                continue;
673
            }
674
            if (isset($worklog['adjust_type'])) {
675
                if ($worklog['adjust_type'] == 1) {
676
                    $spend_m = $this->t2m($worklog['spend']);
677
                    $leave_estimate_m = $leave_estimate_m - $spend_m;
678
                }
679
                else if ($worklog['adjust_type'] == 3) {
680
                    $leave_estimate_m = $this->t2m(isset($worklog['cut']) ? $worklog['cut'] : 0);
681
                }
682
            }
683
        }
684
    }
685
}
686