GroupManageController::createNotice()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 17
c 0
b 0
f 0
rs 9.9
cc 2
nc 2
nop 1
1
<?php
2
3
namespace App\Http\Controllers\Ajax;
4
5
use App\Models\ContestModel;
6
use App\Models\GroupModel;
7
use App\Models\ResponseModel;
8
use App\Models\Eloquent\User;
9
use App\Models\Eloquent\Group;
10
use App\Models\Eloquent\Problem;
11
use App\Models\Eloquent\Messager\UniversalMessager;
12
use App\Http\Controllers\Controller;
13
use Illuminate\Http\Request;
14
use Illuminate\Support\Facades\Storage;
15
use Auth;
16
use Carbon;
17
use Exception;
18
use Validator;
19
20
class GroupManageController extends Controller
21
{
22
    /**
23
     * The Ajax Contest Arrange.
24
     *
25
     * @param Request $request web request
26
     *
27
     * @return JsonResponse
0 ignored issues
show
Bug introduced by
The type App\Http\Controllers\Ajax\JsonResponse was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
28
     */
29
    public function arrangeContest(Request $request)
30
    {
31
        $request->validate([
32
            'name' => 'required|max:255',
33
            'problems' => 'required|max:2550',
34
            'begin_time' => 'required|date',
35
            'status_visibility' => 'required|integer',
36
            'end_time' => 'required|date|after:begin_time',
37
            'gid' => 'required|integer',
38
            'description' => 'string',
39
            'public' => 'integer',
40
            'practice' => 'integer'
41
        ]);
42
43
        $all_data=$request->all();
44
45
        if (($all_data['public'] ?? 0) && ($all_data['practice'] ?? 0)) {
46
            return ResponseModel::err(4007);
0 ignored issues
show
Bug Best Practice introduced by
The expression return App\Models\ResponseModel::err(4007) returns the type Illuminate\Http\JsonResponse which is incompatible with the documented return type App\Http\Controllers\Ajax\JsonResponse.
Loading history...
47
        }
48
49
        $contestModel=new ContestModel();
50
        $groupModel=new GroupModel();
51
        $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id);
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
52
        if ($clearance<2) {
53
            return ResponseModel::err(2001);
0 ignored issues
show
Bug Best Practice introduced by
The expression return App\Models\ResponseModel::err(2001) returns the type Illuminate\Http\JsonResponse which is incompatible with the documented return type App\Http\Controllers\Ajax\JsonResponse.
Loading history...
54
        }
55
        $problems=explode(",", $all_data["problems"]);
56
        if (count($problems)>26) {
57
            return ResponseModel::err(4002);
0 ignored issues
show
Bug Best Practice introduced by
The expression return App\Models\ResponseModel::err(4002) returns the type Illuminate\Http\JsonResponse which is incompatible with the documented return type App\Http\Controllers\Ajax\JsonResponse.
Loading history...
58
        }
59
        $i=0;
60
        $problemSet=[];
61
        foreach ($problems as $p) {
62
            if (!empty($p)) {
63
                $i++;
64
                $problemSet[]=[
65
                    "number"=>$i,
66
                    "pcode"=>$p,
67
                    "points"=>100
68
                ];
69
            }
70
        }
71
72
        if (empty($problemSet)) {
73
            return ResponseModel::err(1003);
0 ignored issues
show
Bug Best Practice introduced by
The expression return App\Models\ResponseModel::err(1003) returns the type Illuminate\Http\JsonResponse which is incompatible with the documented return type App\Http\Controllers\Ajax\JsonResponse.
Loading history...
74
        }
75
76
        $cid=$contestModel->arrangeContest($all_data["gid"], [
77
            "assign_uid"=>Auth::user()->id,
78
            "name"=>$all_data["name"],
79
            "description"=>$all_data["description"],
80
            "status_visibility"=>$all_data["status_visibility"],
81
            "begin_time"=>$all_data["begin_time"],
82
            "end_time"=>$all_data["end_time"],
83
            "practice"=>$all_data["practice"] ?? 0,
84
            "public"=>$all_data["public"] ?? 0,
85
        ], $problemSet);
86
87
        return ResponseModel::success(200, 'Successful!', $cid);
0 ignored issues
show
Bug Best Practice introduced by
The expression return App\Models\Respon...0, 'Successful!', $cid) returns the type Illuminate\Http\JsonResponse which is incompatible with the documented return type App\Http\Controllers\Ajax\JsonResponse.
Loading history...
88
    }
89
90
    public function changeGroupName(Request $request)
91
    {
92
        $request->validate([
93
            'gid' => 'required|integer',
94
            'group_name' => 'max:50',
95
        ]);
96
97
        $all_data=$request->all();
98
99
        $groupModel=new GroupModel();
100
        $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id);
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
101
        if ($clearance<2) {
102
            return ResponseModel::err(2001);
103
        }
104
105
        $groupModel->changeGroupName($all_data["gid"], $all_data["group_name"]);
106
        return ResponseModel::success(200);
107
    }
108
109
    public function changeJoinPolicy(Request $request)
110
    {
111
        $request->validate([
112
            'gid' => 'required|integer',
113
            'join_policy' => 'required|integer',
114
        ]);
115
116
        $all_data=$request->all();
117
118
        $groupModel=new GroupModel();
119
        $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id);
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
120
        if ($clearance<2) {
121
            return ResponseModel::err(2001);
122
        }
123
124
        if ($all_data["join_policy"]<1 || $all_data["join_policy"]>3) {
125
            return ResponseModel::err(1007);
126
        }
127
128
        $groupModel->changeJoinPolicy($all_data["gid"], $all_data["join_policy"]);
129
        return ResponseModel::success(200);
130
    }
131
132
    public function changeGroupImage(Request $request)
133
    {
134
        $request->validate([
135
            'gid' => 'required|integer',
136
        ]);
137
138
        $all_data=$request->all();
139
140
        if (!empty($request->file('img')) && $request->file('img')->isValid()) {
141
            $extension=$request->file('img')->extension();
142
        } else {
143
            return ResponseModel::err(1005);
144
        }
145
146
        $allow_extension=['jpg', 'png', 'jpeg', 'gif', 'bmp'];
147
148
        $groupModel=new GroupModel();
149
        $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id);
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
150
        if ($clearance<2) {
151
            return ResponseModel::err(2001);
152
        }
153
154
        if (!in_array($extension, $allow_extension)) {
155
            return ResponseModel::err(1005);
156
        }
157
158
        $path=$request->file('img')->store('/static/img/group', 'NOJPublic');
159
160
        $group=GroupModel::find($all_data["gid"]);
161
        $old_path=$group->img;
162
        if ($old_path!='/static/img/group/default.png' && $old_path!='/static/img/group/noj.png' && $old_path!='/static/img/group/icpc.png') {
163
            Storage::disk('NOJPublic')->delete($old_path);
164
        }
165
166
        $group->img='/'.$path;
0 ignored issues
show
Bug introduced by
Are you sure $path of type false|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

166
        $group->img='/'./** @scrutinizer ignore-type */ $path;
Loading history...
167
        $group->save();
168
169
        return ResponseModel::success(200, null, '/'.$path);
170
171
    }
172
173
    public function changeMemberClearance(Request $request)
174
    {
175
        $request->validate([
176
            'gid' => 'required|integer',
177
            'uid' => 'required|integer',
178
            'permission' => 'required|integer|max:3|min:1',
179
        ]);
180
181
        $all_data=$request->all();
182
183
        $groupModel=new GroupModel();
184
185
        $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id);
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
186
        $target_clearance=$groupModel->judgeClearance($all_data["gid"], $all_data['uid']);
187
188
        if ($target_clearance==-3) {
189
            return ResponseModel::err(7004);
190
        }
191
192
        if ($target_clearance>=$clearance || $clearance<2 || $all_data['permission']>=$clearance) {
193
            return ResponseModel::err(2001);
194
        }
195
196
        $groupModel->changeClearance($all_data['uid'], $all_data["gid"], $all_data['permission']);
197
198
        $result_info=$groupModel->userProfile($all_data['uid'], $all_data["gid"]);
199
        return ResponseModel::success(200, null, $result_info);
200
    }
201
202
    public function approveMember(Request $request)
203
    {
204
        $request->validate([
205
            'gid' => 'required|integer',
206
            'uid' => 'required|integer',
207
        ]);
208
209
        $all_data=$request->all();
210
211
        $groupModel=new GroupModel();
212
        $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id);
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
213
        $targetClearance=$groupModel->judgeClearance($all_data["gid"], $all_data["uid"]);
214
        if ($clearance>1) {
215
            if ($targetClearance!=0) {
216
                return ResponseModel::err(7003);
217
            }
218
            $groupModel->changeClearance($all_data["uid"], $all_data["gid"], 1);
219
            return ResponseModel::success(200);
220
        }
221
        return ResponseModel::err(7002);
222
    }
223
224
    public function removeMember(Request $request)
225
    {
226
        $request->validate([
227
            'gid' => 'required|integer',
228
            'uid' => 'required|integer',
229
        ]);
230
231
        $all_data=$request->all();
232
233
        $groupModel=new GroupModel();
234
        $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id);
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
235
        $targetClearance=$groupModel->judgeClearance($all_data["gid"], $all_data["uid"]);
236
        if ($clearance<=1 || $clearance<=$targetClearance) {
237
            return ResponseModel::err(7002);
238
        }
239
240
        $groupModel->removeClearance($all_data["uid"], $all_data["gid"]);
241
        $groupModel->refreshElo($all_data["gid"]);
242
        return ResponseModel::success(200);
243
    }
244
245
    public function inviteMember(Request $request)
246
    {
247
        $request->validate([
248
            'gid' => 'required|integer',
249
            'email' => 'required|email',
250
        ]);
251
252
        $all_data=$request->all();
253
254
        $groupModel=new GroupModel();
255
        $is_user=$groupModel->isUser($all_data["email"]);
256
        if (!$is_user) {
257
            return ResponseModel::err(2006);
258
        }
259
        $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id);
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
260
        if ($clearance<2) {
261
            return ResponseModel::err(7002);
262
        }
263
        $targetClearance=$groupModel->judgeEmailClearance($all_data["gid"], $all_data["email"]);
264
        if ($targetClearance!=-3) {
265
            return ResponseModel::err(7003);
266
        }
267
        $groupModel->inviteMember($all_data["gid"], $all_data["email"]);
268
        $basic=$groupModel->basic($all_data['gid']);
269
        $url=route('group.detail', ['gcode' => $basic['gcode']]);
0 ignored issues
show
Unused Code introduced by
The assignment to $url is dead and can be removed.
Loading history...
270
        $receiverInfo=User::where('email', $all_data['email'])->first();
271
        $senderName=Auth::user()->name;
0 ignored issues
show
Bug introduced by
Accessing name on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
272
        sendMessage([
273
            'receiver' => $receiverInfo["id"],
274
            'sender' => config('app.official_sender'),
275
            'type' => 7,
276
            'level' => 4,
277
            'title' => __('message.group.invited.title', ['senderName' => $senderName, 'groupName' => $basic['name']]),
278
            'data' => [
279
                'group' => [
280
                    'gcode' => $basic['gcode'],
281
                    'name'  => $basic['name'],
282
                ],
283
            ]
284
        ]);
285
        return ResponseModel::success(200);
286
    }
287
288
    public function changeSubGroup(Request $request)
289
    {
290
        $request->validate([
291
            'gid'=>'required|integer',
292
            'uid'=>'required|integer',
293
            'sub'=>'nullable|max:60000'
294
        ]);
295
296
        $all_data=$request->all();
297
298
        $groupModel=new GroupModel();
299
        $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id);
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
300
        $targetClearance=$groupModel->judgeClearance($all_data["gid"], $all_data["uid"]);
301
        if ($clearance>1 && $clearance>=$targetClearance) {
302
            $groupModel->changeGroup($all_data["uid"], $all_data["gid"], $all_data["sub"]);
303
            return ResponseModel::success(200);
304
        }
305
        return ResponseModel::err(7002);
306
    }
307
308
    public function createNotice(Request $request)
309
    {
310
        $request->validate([
311
            'gid' => 'required|integer',
312
            'title' => 'required|min:3|max:50',
313
            'content' => 'required|min:3|max:60000',
314
        ]);
315
316
        $all_data=$request->all();
317
318
        $groupModel=new GroupModel();
319
        $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id);
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
320
        if ($clearance<2) {
321
            return ResponseModel::err(2001);
322
        }
323
        $groupModel->createNotice($all_data["gid"], Auth::user()->id, $all_data["title"], $all_data["content"]);
324
        return ResponseModel::success(200);
325
    }
326
327
    public function createHomework(Request $request)
328
    {
329
        try {
330
            $all = $request->all();
331
            $all['currently_at'] = strtotime('now');
332
            $validator = Validator::make($all, [
333
                'title'         => 'required|string|min:1|max:100',
334
                'description'   => 'required|string|min:1|max:65535',
335
                'ended_at'      => 'required|date|after:currently_at',
336
                'gid'           => 'required|integer|gte:1',
337
                'problems'      => 'required|array',
338
            ], [], [
339
                'title'         => 'Title',
340
                'description'   => 'Description',
341
                'ended_at'      => 'Ended Time',
342
                'currently_at'  => 'Current Time',
343
                'gid'           => 'Group ID',
344
                'problems'      => 'Problems',
345
            ]);
346
347
            if ($validator->fails()) {
348
                throw new Exception($validator->errors()->first());
349
            }
350
351
            if (count($request->problems) > 26) {
352
                throw new Exception('Please include no more than 26 problems.');
353
            }
354
355
            if (count($request->problems) < 1) {
356
                throw new Exception('Please include at least one problem.');
357
            }
358
359
            $proceedProblems = $request->problems;
360
            $proceedProblemCodes = [];
361
362
            foreach ($proceedProblems as &$problem) {
363
                if (!is_array($problem)) {
364
                    throw new Exception('Each problem object must be an array.');
365
                }
366
367
                $problem['pcode'] = mb_strtoupper(trim($problem['pcode']));
368
369
                if(array_search($problem['pcode'], $proceedProblemCodes) !== false) {
370
                    throw new Exception("Duplicate Problem");
371
                }
372
373
                $validator = Validator::make($problem, [
374
                    'pcode'         => 'required|string|min:1|max:100',
375
                    // 'alias'         => 'required|string|min:0|max:100|nullable',
376
                    // 'points'        => 'required|integer|gte:1',
377
                ], [], [
378
                    'pcode'         => 'Problem Code',
379
                    // 'alias'         => 'Alias',
380
                    // 'points'        => 'Points',
381
                ]);
382
383
                if ($validator->fails()) {
384
                    throw new Exception($validator->errors()->first());
385
                }
386
387
                $proceedProblemCodes[] = $problem['pcode'];
388
            }
389
390
            unset($problem);
391
392
            $problemsDict = Problem::whereIn('pcode', $proceedProblemCodes)->select('pid', 'pcode')->get()->pluck('pid', 'pcode');
393
394
            try {
395
                foreach($proceedProblems as &$proceedProblem) {
396
                    $proceedProblem['pid'] = $problemsDict[$proceedProblem['pcode']];
397
                    if(blank($proceedProblem['pid'])) {
398
                        throw new Exception();
399
                    }
400
                }
401
                unset($proceedProblem);
402
            } catch (Exception $e) {
403
                throw new Exception('Problem Not Found');
404
            }
405
        } catch (Exception $e) {
406
            return response()->json([
407
                'errors' => [
408
                    'description' => [
409
                        $e->getMessage()
410
                    ]
411
                ],
412
                'message' => "The given data was invalid."
413
            ], 422);
414
        }
415
416
        $groupModel = new GroupModel();
417
        $clearance = $groupModel->judgeClearance($request->gid, Auth::user()->id);
0 ignored issues
show
Bug introduced by
Accessing id on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
418
        if ($clearance < 2) {
419
            return ResponseModel::err(2001);
420
        }
421
422
        try {
423
            $homeworkInstance = Group::find($request->gid)->addHomework($request->title, $request->description, Carbon::parse($request->ended_at), $proceedProblems);
424
        } catch (Exception $e) {
425
            return ResponseModel::err(7009);
426
        }
427
428
        $homeworkInstance->sendMessage();
429
430
        return ResponseModel::success(200);
431
    }
432
}
433