1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* GitScrum v0.1. |
4
|
|
|
* |
5
|
|
|
* @author Renato Marinho <[email protected]> |
6
|
|
|
* @license http://opensource.org/licenses/GPL-3.0 GPLv3 |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
namespace GitScrum\Http\Controllers; |
10
|
|
|
|
11
|
|
|
use Illuminate\Http\Request; |
12
|
|
|
use GitScrum\Http\Requests\IssueRequest; |
13
|
|
|
use GitScrum\Models\Sprint; |
14
|
|
|
use GitScrum\Models\UserStory; |
15
|
|
|
use GitScrum\Models\Issue; |
16
|
|
|
use GitScrum\Models\Organization; |
17
|
|
|
use GitScrum\Models\IssueType; |
18
|
|
|
use GitScrum\Models\ConfigStatus; |
19
|
|
|
use GitScrum\Models\ConfigIssueEffort; |
20
|
|
|
use Carbon\Carbon; |
21
|
|
|
use Auth; |
22
|
|
|
|
23
|
|
|
class IssueController extends Controller |
24
|
|
|
{ |
25
|
|
|
public function index($slug) |
|
|
|
|
26
|
|
|
{ |
27
|
|
|
if ($slug) { |
28
|
|
|
$sprint = Sprint::slug($slug) |
29
|
|
|
->with('issues.user') |
30
|
|
|
->with('issues.users') |
31
|
|
|
->with('issues.commits') |
32
|
|
|
->with('issues.statuses') |
33
|
|
|
->with('issues.status') |
34
|
|
|
->with('issues.comments') |
35
|
|
|
->with('issues.attachments') |
36
|
|
|
->with('issues.type') |
37
|
|
|
->with('issues.productBacklog') |
38
|
|
|
->with('issues.sprint') |
39
|
|
|
->with('issues.configEffort') |
40
|
|
|
->first(); |
41
|
|
|
|
42
|
|
|
$issues = $sprint->issues; |
43
|
|
|
} else { |
44
|
|
|
$sprint = null; |
45
|
|
|
$issues = Auth::user()->issues() |
46
|
|
|
->with('user') |
47
|
|
|
->with('users') |
48
|
|
|
->with('commits') |
49
|
|
|
->with('statuses') |
50
|
|
|
->with('status') |
51
|
|
|
->with('comments') |
52
|
|
|
->with('attachments') |
53
|
|
|
->with('type') |
54
|
|
|
->with('productBacklog') |
55
|
|
|
->with('sprint') |
56
|
|
|
->with('configEffort') |
57
|
|
|
->get(); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
$issues = $issues->sortBy('position')->groupBy('config_status_id'); |
61
|
|
|
|
62
|
|
|
$configStatus = ConfigStatus::type('issue')->get(); |
63
|
|
|
|
64
|
|
|
if (!is_null($sprint) && !count($sprint)) { |
65
|
|
|
return redirect()->route('sprints.index'); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
return view('issues.index') |
|
|
|
|
69
|
|
|
->with('sprint', $sprint) |
70
|
|
|
->with('issues', $issues) |
71
|
|
|
->with('configStatus', $configStatus); |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
public function create($slug_sprint = null, $slug_user_story = null, $parent_id = null) |
|
|
|
|
75
|
|
|
{ |
76
|
|
|
$issue_types = IssueType::where('enabled', 1) |
77
|
|
|
->orderby('position', 'ASC') |
78
|
|
|
->get(); |
79
|
|
|
|
80
|
|
|
$issue_efforts = ConfigIssueEffort::where('enabled', 1) |
81
|
|
|
->orderby('position', 'ASC') |
82
|
|
|
->get(); |
83
|
|
|
|
84
|
|
|
$userStory = $productBacklogs = null; |
85
|
|
|
|
86
|
|
|
if ((is_null($slug_sprint) || !$slug_sprint) && $slug_user_story) { |
87
|
|
|
$userStory = UserStory::slug($slug_user_story)->first(); |
88
|
|
|
$productBacklogs = Auth::user()->productBacklogs($userStory->product_backlog_id); |
89
|
|
|
$usersByOrganization = Organization::find($userStory->productBacklog->organization_id)->users; |
90
|
|
|
} elseif ($slug_sprint) { |
91
|
|
|
$usersByOrganization = Organization::find(Sprint::slug($slug_sprint)->first() |
92
|
|
|
->productBacklog->organization_id)->users; |
93
|
|
|
} else { |
94
|
|
|
$issue = Issue::find($parent_id); |
95
|
|
|
$productBacklogs = $issue->product_backlog_id; |
96
|
|
|
$usersByOrganization = Organization::find($issue->productBacklog->organization_id)->users; |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
return view('issues.create') |
|
|
|
|
100
|
|
|
->with('productBacklogs', $productBacklogs) |
101
|
|
|
->with('userStory', $userStory) |
102
|
|
|
->with('slug', $slug_sprint) |
103
|
|
|
->with('parent_id', $parent_id) |
104
|
|
|
->with('issue_types', $issue_types) |
105
|
|
|
->with('issue_efforts', $issue_efforts) |
106
|
|
|
->with('usersByOrganization', $usersByOrganization) |
107
|
|
|
->with('action', 'Create'); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
public function store(IssueRequest $request) |
111
|
|
|
{ |
112
|
|
|
$issue = Issue::create($request->all()); |
113
|
|
|
|
114
|
|
|
if (is_array($request->members)) { |
|
|
|
|
115
|
|
|
$issue->users()->sync($request->members); |
|
|
|
|
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
return redirect()->route('issues.show', ['slug' => $issue->slug]) |
|
|
|
|
119
|
|
|
->with('success', trans('Congratulations! The Issue has been created with successfully')); |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
public function show($slug) |
|
|
|
|
123
|
|
|
{ |
124
|
|
|
$issue = Issue::slug($slug) |
125
|
|
|
->with('sprint') |
126
|
|
|
->with('type') |
127
|
|
|
->with('configEffort') |
128
|
|
|
->with('labels') |
129
|
|
|
->first(); |
130
|
|
|
|
131
|
|
|
$usersByOrganization = Organization::find($issue->productBacklog->organization_id)->users; |
132
|
|
|
|
133
|
|
|
return view('issues.show') |
|
|
|
|
134
|
|
|
->with('issue', $issue) |
135
|
|
|
->with('usersByOrganization', $usersByOrganization); |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
public function edit($slug) |
|
|
|
|
139
|
|
|
{ |
140
|
|
|
$issue = Issue::slug($slug)->first(); |
141
|
|
|
|
142
|
|
|
$issue_types = IssueType::where('enabled', 1) |
143
|
|
|
->orderby('position', 'ASC') |
144
|
|
|
->get(); |
145
|
|
|
|
146
|
|
|
$issue_efforts = ConfigIssueEffort::where('enabled', 1) |
147
|
|
|
->orderby('position', 'ASC') |
148
|
|
|
->get(); |
149
|
|
|
|
150
|
|
|
$usersByOrganization = Organization::find($issue->productBacklog->organization_id)->users; |
151
|
|
|
|
152
|
|
|
return view('issues.edit') |
|
|
|
|
153
|
|
|
->with('productBacklogs', $issue->productBacklog->id) |
154
|
|
|
->with('userStory', $issue->userStory) |
155
|
|
|
->with('slug', isset($issue->sprint->slug) ? $issue->sprint->slug : null) |
156
|
|
|
->with('issue_types', $issue_types) |
157
|
|
|
->with('issue_efforts', $issue_efforts) |
158
|
|
|
->with('usersByOrganization', $usersByOrganization) |
159
|
|
|
->with('issue', $issue) |
160
|
|
|
->with('action', 'Edit'); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
public function update(IssueRequest $request, $slug) |
164
|
|
|
{ |
165
|
|
|
$issue = Issue::slug($slug)->first(); |
166
|
|
|
$issue->update($request->all()); |
167
|
|
|
|
168
|
|
|
if (is_array($request->members)) { |
|
|
|
|
169
|
|
|
$issue->users()->sync($request->members); |
|
|
|
|
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
return back() |
173
|
|
|
->with('success', trans('Congratulations! The Issue has been edited with successfully')); |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
public function statusUpdate(Request $request, $slug = null, int $status = 0) |
177
|
|
|
{ |
178
|
|
|
if (!isset($request->status_id)) { |
179
|
|
|
$request->status_id = $status; |
180
|
|
|
} |
181
|
|
|
$status = ConfigStatus::find($request->status_id); |
182
|
|
|
$save = function ($issue, $position = null) use ($request, $status) { |
183
|
|
|
$issue->config_status_id = $request->status_id; |
184
|
|
|
|
185
|
|
|
if (!is_null($status->is_closed) && is_null($issue->closed_at)) { |
186
|
|
|
$issue->closed_user_id = Auth::id(); |
187
|
|
|
$issue->closed_at = Carbon::now(); |
188
|
|
|
} elseif (is_null($status->is_closed)) { |
189
|
|
|
$issue->closed_user_id = null; |
190
|
|
|
$issue->closed_at = null; |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
if ($position) { |
194
|
|
|
$issue->position = $position; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
return $issue->save(); |
198
|
|
|
}; |
199
|
|
|
|
200
|
|
|
if ($request->ajax()) { |
201
|
|
|
$position = 1; |
202
|
|
|
try { |
203
|
|
|
foreach (json_decode($request->json) as $id) { |
204
|
|
|
$issue = Issue::find($id); |
205
|
|
|
$save($issue, $position); |
206
|
|
|
++$position; |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
return response()->json([ |
210
|
|
|
'success' => true, |
211
|
|
|
]); |
212
|
|
|
} catch (\Exception $e) { |
213
|
|
|
return response()->json([ |
214
|
|
|
'success' => false, |
215
|
|
|
]); |
216
|
|
|
} |
217
|
|
|
} else { |
218
|
|
|
$issue = Issue::slug($slug) |
219
|
|
|
->firstOrFail(); |
220
|
|
|
$save($issue); |
221
|
|
|
|
222
|
|
|
return back()->with('success', trans('Updated successfully')); |
223
|
|
|
} |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
public function destroy(Request $request) |
227
|
|
|
{ |
228
|
|
|
$issue = Issue::slug($request->slug)->firstOrFail(); |
229
|
|
|
|
230
|
|
|
if (isset($issue->userStory)) { |
231
|
|
|
$redirect = redirect()->route('user_stories.show', ['slug' => $issue->userStory->slug]); |
232
|
|
|
} else { |
233
|
|
|
$redirect = redirect()->route('sprints.show', ['slug' => $issue->sprint->slug]); |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
$issue->delete(); |
237
|
|
|
|
238
|
|
|
return $redirect; |
239
|
|
|
} |
240
|
|
|
} |
241
|
|
|
|
Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a
@return
annotation as described here.