Passed
Push — master ( b831b6...96f132 )
by John
06:04 queued 21s
created

ProblemController::detail()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
nc 1
nop 1
dl 0
loc 4
c 0
b 0
f 0
cc 1
rs 10
1
<?php
2
3
namespace App\Admin\Controllers;
4
5
use App\Models\Eloquent\ProblemModel as EloquentProblemModel;
6
use App\Http\Controllers\Controller;
7
use App\Admin\Forms\ImportPOEM;
8
use Encore\Admin\Controllers\HasResourceActions;
9
use Encore\Admin\Form;
10
use Encore\Admin\Grid;
11
use Encore\Admin\Layout\Content;
12
use Encore\Admin\Show;
13
use Illuminate\Support\MessageBag;
14
use ZipArchive;
15
use Illuminate\Support\Facades\Storage;
16
17
class ProblemController extends Controller
18
{
19
    use HasResourceActions;
20
21
    /**
22
     * Index interface.
23
     *
24
     * @param Content $content
25
     * @return Content
26
     */
27
    public function index(Content $content)
28
    {
29
        return $content
30
            ->header('Problems')
31
            ->description('all problems')
32
            ->body($this->grid()->render());
33
    }
34
35
    /**
36
     * Show interface.
37
     *
38
     * @param mixed $id
39
     * @param Content $content
40
     * @return Content
41
     */
42
    public function show($id, Content $content)
43
    {
44
        return $content
45
            ->header('Problem Detail')
46
            ->description('the detail of problems')
47
            ->body($this->detail($id));
48
    }
49
50
    /**
51
     * Edit interface.
52
     *
53
     * @param mixed $id
54
     * @param Content $content
55
     * @return Content
56
     */
57
    public function edit($id, Content $content)
58
    {
59
        return $content
60
            ->header('Edit Problem')
61
            ->description('edit the detail of problems')
62
            ->body($this->form()->edit($id));
63
    }
64
65
    /**
66
     * Import interface.
67
     *
68
     * @param Content $content
69
     * @return Content
70
     */
71
    public function import(Content $content)
72
    {
73
        return $content
74
            ->header('Import New Problem')
75
            ->description('import a new problem from POEM or POETRY')
76
            ->body(new ImportPOEM());
77
    }
78
79
    /**
80
     * Create interface.
81
     *
82
     * @param Content $content
83
     * @return Content
84
     */
85
    public function create(Content $content)
86
    {
87
        return $content
88
            ->header('Create New Problem')
89
            ->description('create a new problem')
90
            ->body($this->form(true));
91
    }
92
93
    /**
94
     * Make a grid builder.
95
     *
96
     * @return Grid
97
     */
98
    protected function grid()
99
    {
100
        $grid=new Grid(new EloquentProblemModel);
101
        $grid->column('pid', "ID")->sortable();
102
        $grid->column('pcode', "PCode")->editable();
103
        $grid->title("Title")->editable();
104
        $grid->solved_count();
105
        $grid->time_limit("Time/ms")->editable();
106
        $grid->memory_limit("Memory/kb")->editable();
107
        $grid->OJ();
108
        $grid->update_date();
109
        $grid->tot_score("Score");
110
        $grid->partial("Partial")->display(function($partial) {
111
            return $partial ? 'Yes' : 'No';
112
        });
113
        $grid->markdown("Markdown")->display(function($markdown) {
114
            return $markdown ? 'Yes' : 'No';
115
        });
116
        $grid->order_index("order")->sortable();
117
        $grid->filter(function(Grid\Filter $filter) {
118
            $filter->disableIdFilter();
119
            $filter->like('pcode');
120
            $filter->like('title');
121
        });
122
123
        $grid->disableCreateButton();
124
125
        return $grid;
126
    }
127
128
    /**
129
     * Make a show builder.
130
     *
131
     * @param mixed $id
132
     * @return Show
133
     */
134
    protected function detail($id)
135
    {
136
        $show=new Show(EloquentProblemModel::findOrFail($id));
137
        return $show;
138
    }
139
140
    /**
141
     * Make a form builder for create view and edit.
142
     *
143
     * @return Form
144
     */
145
    protected function form($create = false)
146
    {
147
        $form=new Form(new EloquentProblemModel);
148
        $form->model()->makeVisible('password');
149
        $form->tab('Basic', function(Form $form){
150
            $form->text('pid')->readonly();
151
            $form->text('pcode')->rules('required');
152
            $form->text('title')->rules('required');
153
            $form->text('time_limit')->rules('required');
154
            $form->text('memory_limit')->rules('required');
155
            $form->textarea('description')->rows(5);
156
            $form->textarea('input','Sample Input')->rows(3);
157
            $form->textarea('output','Sample Output')->rows(3);
158
            $form->textarea('note')->rows(2);
159
            $form->display('OJ');
160
            $form->display('update_date');
161
            $form->text('tot_score')->rules('required');
162
            $form->select('partial', 'Partial Score')->options([
163
                0 => "No",
164
                1 => "Yes"
165
            ])->rules('required');
166
            $form->select('markdown', 'Markdown Support')->options([
167
                0 => "No",
168
                1 => "Yes"
169
            ])->rules('required');
170
            $form->file('test_case');
171
            $form->ignore(['test_case']);
172
        });
173
        if($create){
174
            $form->tools(function (Form\Tools $tools) {
175
                $tools->add('<a href="/'.config('admin.route.prefix').'/problems/import" class="btn btn-sm btn-success" style="margin-right:1rem"><i class="MDI file-powerpoint-box"></i>&nbsp;&nbsp;Import from file</a>');
0 ignored issues
show
Deprecated Code introduced by
The function Encore\Admin\Form\Tools::add() has been deprecated: use append instead. ( Ignorable by Annotation )

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

175
                /** @scrutinizer ignore-deprecated */ $tools->add('<a href="/'.config('admin.route.prefix').'/problems/import" class="btn btn-sm btn-success" style="margin-right:1rem"><i class="MDI file-powerpoint-box"></i>&nbsp;&nbsp;Import from file</a>');

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
176
            });
177
        }
178
        $form->saving(function (Form $form){
179
            $err = function ($msg) {
180
                $error = new MessageBag([
181
                    'title'   => 'Test case file parse faild.',
182
                    'message' => $msg,
183
                ]);
184
                return back()->with(compact('error'));
185
            };
186
            $pcode = $form->pcode;
187
            $p = EloquentProblemModel::where('pcode',$pcode)->first();
188
            $pid = $form->pid ?? null;
189
            if(!empty($p) && $p->pid != $pid){
190
                $error = new MessageBag([
191
                    'title'   => 'Error occur.',
192
                    'message' => 'Pcode has been token',
193
                ]);
194
                return back()->with(compact('error'));
195
            }
196
            $test_case = \request()->file('test_case');
197
            if(!empty($test_case)){
198
                if($test_case->extension() != 'zip'){
199
                    $err('You must upload a zip file iuclude test case info and content.');
200
                }
201
                $path = $test_case->path();
202
                $zip = new ZipArchive;
203
                if($zip->open($path) !== true) {
204
                    $err('You must upload a zip file without encrypt and can open successfully.');
205
                };
206
                if(($zip->getFromName('info')) === false){
207
                    $err('The zip files must include a file named info including info of test cases, and the format can see ZsgsDesign/NOJ wiki.');
208
                };
209
                $test_case_info = json_decode($zip->getFromName('info'),true);
210
                $test_cases = $test_case_info['test_cases'];
211
                foreach($test_cases as $index => $case) {
212
                    if(!isset($case['input_name']) || !isset($case['output_name'])) {
213
                        $err("Test case index {$index}: configuration missing input/output files name.");
214
                    }
215
                    if($zip->getFromName($case['input_name']) === false || $zip->getFromName($case['output_name']) === false ) {
216
                        $err("Test case index {$index}: missing input/output files that record in the configuration.");
217
                    }
218
                }
219
                if(!empty($form->pid)){
220
                    $problem = EloquentProblemModel::find($form->pid);
221
                    if(!empty($problem)){
222
                        $pcode = $problem->pcode;
223
                    }else{
224
                        $pcode = $form->pcode;
225
                    }
226
                }else{
227
                    $pcode = $form->pcode;
228
                }
229
230
                if(Storage::exists(base_path().'/storage/test_case/'.$pcode)){
0 ignored issues
show
Bug introduced by
Are you sure $pcode of type array|mixed|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

230
                if(Storage::exists(base_path().'/storage/test_case/'./** @scrutinizer ignore-type */ $pcode)){
Loading history...
231
                    Storage::deleteDirectory(base_path().'/storage/test_case/'.$pcode);
232
                }
233
                Storage::makeDirectory(base_path().'/storage/test_case/'.$pcode);
234
                $zip->extractTo(base_path().'/storage/test_case/'.$pcode.'/');
235
236
            }
237
        });
238
        return $form;
239
    }
240
}
241