diff --git a/.env.example b/.env.example index 2298d148c..c8a06baa0 100644 --- a/.env.example +++ b/.env.example @@ -3,15 +3,20 @@ APP_DISPLAY_NAME="NJUPT Online Judge" #Display Name APP_ENV=local #Current Environment Name APP_KEY=base64:6KvSj1hj/VJCNXnHECU16OVbcHk7h20O5TbsyOz5WuA= #App Key APP_DEBUG=true #Debug Mode -APP_URL=http://ojsystem.com/ +APP_URL=http://ojsystem.com +APP_MULTI_DOMAIN=true # Multi Domain Mode, Automatic match APP_URL, note that you still need to set APP_URL for console command proper running APP_LOCALE=en APP_BACKUP=false #Enable Scheduling Backup APP_LOGO="" #URL for site logo APP_DESC= +APP_THEME="default" # choose from https://njuptaaa.github.io/docs/#/noj/guide/theme +APP_ALLOW_OAUTH_TEMP_ACCOUNT=false + +FUNC_ENABLE_REGISTER=true BABEL_MIRROR=https://acm.njupt.edu.cn/babel #The mirror of babel marketplace -SESSION_DOMAIN=.ojsystem.com +SESSION_DOMAIN=.ojsystem.com # set null if multi-domain or http 419 LOG_CHANNEL=stack @@ -52,12 +57,25 @@ BAIDU_SITE_VERIFICATION="" GOOGLE_ANALYTICS="" +GITHUB_ENABLE=false GITHUB_KEY= GITHUB_SECRET= -GITHUB_CALLBACK_URL= +GITHUB_CALLBACK_URL= # should be like http://www.your-noj-website.com/oauth/github/callback -MOSS_USERID= +AAUTH_ENABLE=false +AAUTH_KEY= +AAUTH_SECRET= +AAUTH_CALLBACK_URL= # should be like http://www.your-noj-website.com/oauth/aauth/callback CONTACT_EMAIL="noj@njupt.edu.cn" CONTACT_QQ="Group 668108264" CONTACT_TEL= + +TERM_SUBJECT_FULL_NAME="NJUPT Online Judge" +TERM_SUBJECT_NAME="NOJ" +TERM_STREET="9 Wenyuan Road" +TERM_CITY="Nanjing" +TERM_PROVINCE="Jiangsu" +TERM_STATE="China" +TERM_ZIP="221000" +TERM_CONTACT_EMAIL="noj@njupt.edu.cn" diff --git a/app/Admin/Controllers/AbuseController.php b/app/Admin/Controllers/AbuseController.php index ea66d8e4d..13e53dd74 100644 --- a/app/Admin/Controllers/AbuseController.php +++ b/app/Admin/Controllers/AbuseController.php @@ -2,7 +2,6 @@ namespace App\Admin\Controllers; -use App\User; use App\Models\Eloquent\Abuse; use App\Models\Eloquent\Group; use App\Models\Eloquent\GroupBanned; @@ -23,7 +22,7 @@ class AbuseController extends AdminController * * @var string */ - protected $title = 'Abuses'; + protected $title='Abuses'; /** * Make a grid builder. @@ -32,7 +31,7 @@ class AbuseController extends AdminController */ protected function grid() { - $grid = new Grid(new Abuse); + $grid=new Grid(new Abuse); $grid->column('id', __('Id')); $grid->column('title', __('Title')); @@ -58,7 +57,7 @@ protected function grid() */ protected function detail($id) { - $show = new Show(Abuse::findOrFail($id)); + $show=new Show(Abuse::findOrFail($id)); $show->field('id', __('Id')); $show->field('title', __('Title')); @@ -81,7 +80,7 @@ protected function detail($id) */ protected function form() { - $form = new Form(new Abuse); + $form=new Form(new Abuse); $form->text('title', __('Title')); $form->number('cause', __('Cause')); @@ -92,23 +91,23 @@ protected function form() $form->ignore(['created_at']); - $form->saving(function (Form $form) { - $abuse = $form->model(); + $form->saving(function(Form $form) { + $abuse=$form->model(); //get gategory and subject id - $regex = '/^([A-Za-z]+) #(\d+)/'; - $matches = []; - preg_match($regex,$abuse->title,$matches); - $category = array_search(strtolower($matches[1]),Abuse::$supportCategory); - $subject_id = (int)$matches[2]; - switch($abuse->category) { + $regex='/^([A-Za-z]+) #(\d+)/'; + $matches=[]; + preg_match($regex, $abuse->title, $matches); + $category=array_search(strtolower($matches[1]), Abuse::$supportCategory); + $subject_id=(int) $matches[2]; + switch ($abuse->category) { case 0: - $gid = $subject_id; - $group = Group::find($gid); - if(empty($group)) { - return ; + $gid=$subject_id; + $group=Group::find($gid); + if (empty($group)) { + return; } - if($form->audit) { - $ban_time = request()->created_at; + if ($form->audit) { + $ban_time=request()->created_at; sendMessage([ 'sender' => 1, 'receiver' => $abuse->user_id, @@ -128,8 +127,8 @@ protected function form() 'reason' => $abuse->supplement, 'removed_at' => $ban_time ]); - return ; - }else{ + return; + } else { sendMessage([ 'sender' => 1, 'receiver' => $abuse->user_id, @@ -137,11 +136,11 @@ protected function form() 'content' => "Hi, Dear **{$abuse->user->name}**,\n\n We have checked your Abuse report about group **[{$group->name}]({$group->link})**.\n\n However, we regret to say that the information you submitted is not sufficient for us to take action.\n\n Of course, we will continue to follow up the investigation.\n\n Thank you for your contribution to our community environment.\n\n Sincerely, NOJ" ]); $abuse->delete(); - return ; + return; } return; case 1: - $ban_time = request()->created_at; + $ban_time=request()->created_at; UserBanned::create([ 'abuse_id' => $abuse->id, 'user_id' => $subject_id, @@ -170,15 +169,15 @@ public function edit($id, Content $content) protected function check_form() { - $form = new Form(new Abuse); - $form->display('id',__('Abuse id')); + $form=new Form(new Abuse); + $form->display('id', __('Abuse id')); $form->display('title', __('Title')); $form->display('cause', __('Cause')); $form->display('supplement', __('Supplement')); $form->display('link', __('Group Link')); $form->display('user_id', __('Submitter')); - $form->radio('audit','result')->options(['0' => 'Reject', '1'=> 'Pass']); - $form->datetime('created_at','ban until'); + $form->radio('audit', 'result')->options(['0' => 'Reject', '1'=> 'Pass']); + $form->datetime('created_at', 'ban until'); return $form; } diff --git a/app/Admin/Controllers/AnnouncementController.php b/app/Admin/Controllers/AnnouncementController.php new file mode 100644 index 000000000..2f6200d8e --- /dev/null +++ b/app/Admin/Controllers/AnnouncementController.php @@ -0,0 +1,135 @@ +header(__('admin.announcements.index.header')) + ->description(__('admin.announcements.index.description')) + ->body($this->grid()->render()); + } + + /** + * Show interface. + * + * @param mixed $id + * @param Content $content + * @return Content + */ + public function show($id, Content $content) + { + return $content + ->header(__('admin.announcements.show.header')) + ->description(__('admin.announcements.show.description')) + ->body($this->detail($id)); + } + + /** + * Edit interface. + * + * @param mixed $id + * @param Content $content + * @return Content + */ + public function edit($id, Content $content) + { + return $content + ->header(__('admin.announcements.edit.header')) + ->description(__('admin.announcements.edit.description')) + ->body($this->form()->edit($id)); + } + + /** + * Create interface. + * + * @param Content $content + * @return Content + */ + public function create(Content $content) + { + return $content + ->header(__('admin.announcements.create.header')) + ->description(__('admin.announcements.create.description')) + ->body($this->form()); + } + + /** + * Make a grid builder. + * + * @return Grid + */ + protected function grid() + { + $grid=new Grid(new Announcement()); + + $grid->column('anid', 'ANID'); + $grid->column('user', __('admin.announcements.user'))->display(function() { + return $this->user->name; + }); ; + $grid->column('title', __('admin.announcements.title'))->editable(); + $grid->column('created_at', __('admin.created_at')); + $grid->column('updated_at', __('admin.updated_at')); + + $grid->filter(function(Grid\Filter $filter) { + $filter->like('title', __('admin.announcements.title')); + $filter->equal('uid', __('admin.announcements.user'))->select(User::all()->pluck('name', 'id')); + }); + + return $grid; + } + + /** + * Make a show builder. + * + * @param mixed $id + * @return Show + */ + protected function detail($id) + { + $show=new Show(Announcement::findOrFail($id)); + + $show->field('anid', 'ANID'); + $show->field('user.name', __('admin.announcements.user')); + $show->field('title', __('admin.announcements.title')); + $show->field('content', __('admin.announcements.content')); + $show->field('created_at', __('admin.created_at')); + $show->field('updated_at', __('admin.updated_at')); + + return $show; + } + + /** + * Make a form builder. + * + * @return Form + */ + protected function form() + { + $form=new Form(new Announcement()); + $form->text('title', __('admin.announcements.title'))->required(); + $form->simplemde('content', __('admin.announcements.content'))->help(__('admin.announcements.help.markdown'))->required(); + $form->select('uid', __('admin.announcements.user'))->options(User::all()->pluck('name', 'id'))->required(); + return $form; + } +} diff --git a/app/Admin/Controllers/BabelController.php b/app/Admin/Controllers/BabelController.php index c5b248a2f..9f5304857 100644 --- a/app/Admin/Controllers/BabelController.php +++ b/app/Admin/Controllers/BabelController.php @@ -132,7 +132,7 @@ private static function marketspaceView() { $extensionList=ExtensionModel::list(); - if(empty($extensionList)){ + if (empty($extensionList)) { return view('admin::babel.empty'); } @@ -145,7 +145,7 @@ private static function marketspaceDetailView($code) { $details=ExtensionModel::remoteDetail($code); - if(empty($details)){ + if (empty($details)) { return view('admin::babel.empty'); } @@ -158,7 +158,7 @@ private static function executingView($extension) { $details=ExtensionModel::remoteDetail($extension); - if(empty($details)){ + if (empty($details)) { return view('admin::babel.empty'); } @@ -169,15 +169,15 @@ private static function executingView($extension) private static function executeArtisan($command) { - $fp = popen('php "'.base_path('artisan').'" '.$command, "r"); - while($b = fgets($fp, 2048)) { + $fp=popen('php "'.base_path('artisan').'" '.$command, "r"); + while ($b=fgets($fp, 2048)) { echo str_pad(json_encode([ "ret"=>200, "desc"=>"Succeed", "data"=>[ "message"=>$b ] - ])."\n",4096); + ])."\n", 4096); @ob_flush(); flush(); } diff --git a/app/Admin/Controllers/CodeTesterController.php b/app/Admin/Controllers/CodeTesterController.php new file mode 100644 index 000000000..7e6813507 --- /dev/null +++ b/app/Admin/Controllers/CodeTesterController.php @@ -0,0 +1,111 @@ +header(__('admin.tester.tester.header')); + $content=$content->description(__('admin.tester.tester.description')); + if (request()->isMethod('post')) { + $content=$content->body($this->run()); + } + return $content->body($this->form()); + } + + /** + * Make a form builder. + * + * @return Form + */ + protected function form() + { + $OJ=OJ::where(["ocode"=>"noj"])->get(); + $box=new Box(__('admin.tester.tester.title')); + if (blank($OJ)) { + $box->style('danger'); + $box->content(__('admin.tester.help.installfirst')); + return $box; + } + $oid=$OJ->first()->oid; + $box->style('success'); + $form=new Form(); + $form->select('oid', __('admin.tester.oj'))->options($OJ->pluck('name', 'oid'))->help(__('admin.tester.help.onlinejudge'))->rules('required'); + $form->select('pid', __('admin.tester.pid'))->options(Problem::where(["OJ"=>$oid])->get()->sortBy('readable_name')->pluck('readable_name', 'pid'))->rules('required'); + $form->select('coid', __('admin.tester.coid'))->options(Compiler::where(["oid"=>$oid])->get()->pluck('display_name', 'coid'))->rules('required'); + $form->textarea('solution', __('admin.tester.solution'))->rows(20)->rules('required'); + $form->action(route('admin.codetester.tester')); + $form->fill([ + 'oid'=>request()->oid, + 'pid'=>request()->pid, + 'coid'=>request()->coid, + 'solution'=>request()->solution, + ]); + $form->method('POST'); + $box->content($form); + return $box; + } + + /** + * Running Test. + * + * @return Response + */ + protected function run() + { + $babel=new Babel(); + request()->validate([ + 'oid' => 'required|integer', + 'pid' => 'required|integer', + 'coid' => 'required|integer', + 'solution' => 'required', + ]); + $runner=$babel->testrun([ + 'name' => 'noj', + 'pid' => request()->pid, + 'coid' => request()->coid, + 'solution' => request()->solution, + ]); + $verdict=$runner->verdict; + $boxRun=new Box(__('admin.tester.tester.run')); + $boxRun->style('info'); + $verdictData=[]; + foreach ($verdict['data'] as $v) { + $verdictData[]=[ + $v["test_case"], + $v["cpu_time"], + $v["real_time"], + $v["memory"], + $v["signal"], + $v["exit_code"], + $v["error"], + $v["result"], + ]; + } + $table=new Table(['Test Case', 'CPU Time(ms)', 'Real Time(ms)', 'Memory(byte)', 'Signal', 'Exit Code', 'Error', 'Result'], $verdictData); + $output="

Verdict: {$verdict['verdict']}

"; + if (!blank($verdict['compile_info'])) { + $output.="

Compiler Info:

".htmlspecialchars($verdict['compile_info'])."
"; + } + $output.=$table->render(); + $boxRun->content($output); + return $boxRun; + } +} diff --git a/app/Admin/Controllers/ContestController.php b/app/Admin/Controllers/ContestController.php index 835a0f198..6f848ef1f 100644 --- a/app/Admin/Controllers/ContestController.php +++ b/app/Admin/Controllers/ContestController.php @@ -2,8 +2,10 @@ namespace App\Admin\Controllers; -use App\Models\ContestModel; -use App\Models\Eloquent\Contest as EloquentContestModel; +use App\Models\Eloquent\Contest; +use App\Models\Eloquent\Problem; +use App\Models\Eloquent\Group; +use App\Models\Eloquent\User; use App\Http\Controllers\Controller; use Encore\Admin\Controllers\HasResourceActions; use Encore\Admin\Form; @@ -80,7 +82,7 @@ public function create(Content $content) */ protected function grid() { - $grid=new Grid(new EloquentContestModel); + $grid=new Grid(new Contest); $grid->column('cid', "ID")->sortable(); $grid->column("gid", "Group"); $grid->name("Name")->editable(); @@ -121,7 +123,7 @@ protected function grid() */ protected function detail($id) { - $show=new Show(EloquentContestModel::findOrFail($id)); + $show=new Show(Contest::findOrFail($id)); return $show; } @@ -132,12 +134,81 @@ protected function detail($id) */ protected function form() { - $form=new Form(new EloquentContestModel); - $form->model()->makeVisible('password'); + $form=new Form(new Contest); $form->tab('Basic', function(Form $form) { - $form->display('cid'); - // $form->number('gid')->rules('required'); - $form->text('name')->rules('required'); + $form->select('gid', 'Contest Creator Group')->options(Group::all()->pluck('name', 'gid'))->required(); + $form->select('assign_uid', 'Contest Assign User')->options(User::all()->pluck('name', 'id'))->required(); + $form->text('name', 'Contest Name')->required(); + + $form->divider(); + + $form->select('public', 'Contest Publicity')->options([ + 0 => "Private", + 1 => "Public" + ])->when(0, function(Form $form) { + $form->switch('practice', 'Practice Contest')->default(false); + + $form->hidden('verified', 'Verified Contest')->default(0); + $form->hidden('rated', 'Rated Contest')->default(0); + $form->hidden('anticheated', 'AntiCheated Contest')->default(0); + $form->hidden('featured', 'Featured Contest')->default(0); + })->when(1, function(Form $form) { + $form->hidden('practice', 'Practice Contest')->default(0); + + $form->switch('verified', 'Verified Contest')->default(true); + $form->switch('rated', 'Rated Contest')->default(false); + $form->switch('anticheated', 'AntiCheated Contest')->default(true); + $form->switch('featured', 'Featured Contest')->default(true); + })->default(0)->required(); + $form->switch('desktop', 'Enable NOJ Desktop (Experimental)')->default(false); + $form->hidden('is_rated', "is_rated")->default(0); + $form->hidden('pdf', 'Provide PDF')->default(0); + + $form->divider(); + + $form->simplemde('description', 'Contest Description')->required(); + $form->select('rule', 'Contest Rule')->options([ + 1 => "ICPC", + 2 => "IOI" + ])->default(0)->required(); + $form->datetimeRange('begin_time', 'end_time', 'Contest Time Arrangement')->required(); + + $form->divider(); + + $form->select('registration', 'Require Registration')->options([ + 0 => "No", + 1 => "Yes" + ])->default(0)->required(); + $form->datetime('registration_due', 'Registration Deadline')->default('1970-01-01 00:00:00'); + $form->select('registant_type', 'Registrant Type')->options([ + 0 => "Everyone Can Register", + 1 => "Only Same Group Can Register", + 2 => "Don't Allow Anyone to Register" + ])->default(2); + + $form->divider(); + + $form->number('froze_length', 'Forzen Time (Seconds)')->default(0)->required(); + $form->select('status_visibility', 'Status Visibility')->options([ + 0 => "Cannot View Any Status", + 1 => "Can Only View Own Status", + 2 => "Can View Everyone Status" + ])->default(1)->required(); + $form->switch('audit_status', 'Audit Status')->default(true); + $form->text('custom_title', 'Custom Navigation Title'); + $form->image('custom_icon', 'Custom Navigation Icon')->uniqueName()->move("static/img/contest"); + $form->image('img', 'Contest Focus Image')->uniqueName()->move("static/img/contest"); + $form->hasMany('problems', 'Contest Problems', function(Form\NestedForm $form) { + $form->number('number', 'Problem Numerical Index')->default(1)->required(); + $ncodeArr=[]; + foreach (range('A', 'Z') as $alpha) { + $ncodeArr[$alpha]=$alpha; + } + $form->select('ncode', 'Problem Alphabetical Index')->options($ncodeArr)->default("A")->required(); + $form->select('pid', 'Problem')->options(Problem::all()->pluck('readable_name', 'pid'))->required(); + $form->text('alias', 'Problem Alias Title'); + $form->number('points', 'Points Value')->default(100)->required(); + }); }); return $form; } diff --git a/app/Admin/Controllers/DashboardController.php b/app/Admin/Controllers/DashboardController.php index babd944ae..def2cd064 100644 --- a/app/Admin/Controllers/DashboardController.php +++ b/app/Admin/Controllers/DashboardController.php @@ -3,6 +3,8 @@ namespace App\Admin\Controllers; use App\Models\Update\UpdateModel; +use Illuminate\Support\Arr; +use PharIo\Version\Version; class DashboardController { @@ -13,15 +15,15 @@ public static function general() { $version=UpdateModel::checkUpdate(); - $status = [ - ['name' => 'NOJ Version', 'value' => version()], - ['name' => 'Lastest Version', 'value' => is_null($version)?'Failed to fetch latest version':$version["name"]], - ['name' => 'Problems', 'value' => \App\Models\Eloquent\Problem::count()], - ['name' => 'Solutions', 'value' => \App\Models\Eloquent\ProblemSolutionModel::count()], - ['name' => 'Submissions', 'value' => \App\Models\Eloquent\Submission::count()], - ['name' => 'Contests', 'value' => \App\Models\Eloquent\Contest::count()], - ['name' => 'Users', 'value' => \App\Models\Eloquent\UserModel::count()], - ['name' => 'Groups', 'value' => \App\Models\Eloquent\Group::count()], + $status=[ + ['name' => __("admin.home.version"), 'value' => version()], + ['name' => __("admin.home.latest"), 'value' => is_null($version) ? 'Failed to fetch latest version' : $version["name"]], + ['name' => __("admin.home.problems"), 'value' => \App\Models\Eloquent\Problem::count()], + ['name' => __("admin.home.solutions"), 'value' => \App\Models\Eloquent\ProblemSolution::count()], + ['name' => __("admin.home.submissions"), 'value' => \App\Models\Eloquent\Submission::count()], + ['name' => __("admin.home.contests"), 'value' => \App\Models\Eloquent\Contest::count()], + ['name' => __("admin.home.users"), 'value' => \App\Models\Eloquent\User::count()], + ['name' => __("admin.home.groups"), 'value' => \App\Models\Eloquent\Group::count()], ]; return view('admin::dashboard.general', [ @@ -29,4 +31,74 @@ public static function general() 'version'=>$version ]); } + + /** + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + */ + public static function environment() + { + $envs=[ + ['name' => __('admin.home.envs.php'), 'value' => 'PHP/'.PHP_VERSION], + ['name' => __('admin.home.envs.laravel'), 'value' => app()->version()], + ['name' => __('admin.home.envs.cgi'), 'value' => php_sapi_name()], + ['name' => __('admin.home.envs.uname'), 'value' => php_uname()], + ['name' => __('admin.home.envs.server'), 'value' => Arr::get($_SERVER, 'SERVER_SOFTWARE')], + + ['name' => __('admin.home.envs.cache'), 'value' => config('cache.default')], + ['name' => __('admin.home.envs.session'), 'value' => config('session.driver')], + ['name' => __('admin.home.envs.queue'), 'value' => config('queue.default')], + + ['name' => __('admin.home.envs.timezone'), 'value' => config('app.timezone')], + ['name' => __('admin.home.envs.locale'), 'value' => config('app.locale')], + ['name' => __('admin.home.envs.env'), 'value' => config('app.env')], + ['name' => __('admin.home.envs.url'), 'value' => config('app.url')], + + ['name' => __('admin.home.envs.tlsv13'), 'value' => ["Not Supported", "Supported"][in_array("tlsv1.3", stream_get_transports())]], + ]; + + foreach ($envs as &$env) { + $env['icon']="check-circle"; + $env['color']="wemd-teal-text"; + } + + // PHP Version Check + $installedVersion=new Version(PHP_VERSION); + $requireVersion=new Version("7.4.0"); + if (!($installedVersion->isGreaterThan($requireVersion) || $installedVersion->getVersionString()===$requireVersion->getVersionString())) { + $envs[0]['icon']="close-circle"; + $envs[0]['color']="wemd-pink-text"; + } + + // Cache Driver Check + if (config('cache.default')!="redis") { + $envs[5]['icon']="close-circle"; + $envs[5]['color']="wemd-pink-text"; + } + + // Session Driver Check + if (config('session.driver')!="redis") { + $envs[6]['icon']="close-circle"; + $envs[6]['color']="wemd-pink-text"; + } + + // Queue Driver Check + if (config('queue.default')!="database") { + $envs[7]['icon']="close-circle"; + $envs[7]['color']="wemd-pink-text"; + } + + // Locale Check + if (!in_array(strtolower(config('app.locale')), ['en', 'zh-cn'])) { + $envs[9]['icon']="close-circle"; + $envs[9]['color']="wemd-pink-text"; + } + + // TLSv1.3 Check + if ($envs[12]['value']=="Not Supported") { + $envs[12]['icon']="close-circle"; + $envs[12]['color']="wemd-pink-text"; + } + + return view('admin::dashboard.environment', compact('envs')); + } } diff --git a/app/Admin/Controllers/DojoController.php b/app/Admin/Controllers/DojoController.php new file mode 100644 index 000000000..b921803b8 --- /dev/null +++ b/app/Admin/Controllers/DojoController.php @@ -0,0 +1,157 @@ +header(__('admin.dojos.index.header')) + ->description(__('admin.dojos.index.description')) + ->body($this->grid()->render()); + } + + /** + * Show interface. + * + * @param mixed $id + * @param Content $content + * @return Content + */ + public function show($id, Content $content) + { + return $content + ->header(__('admin.dojos.show.header')) + ->description(__('admin.dojos.show.description')) + ->body($this->detail($id)); + } + + /** + * Edit interface. + * + * @param mixed $id + * @param Content $content + * @return Content + */ + public function edit($id, Content $content) + { + return $content + ->header(__('admin.dojos.edit.header')) + ->description(__('admin.dojos.edit.description')) + ->body($this->form()->edit($id)); + } + + /** + * Create interface. + * + * @param Content $content + * @return Content + */ + public function create(Content $content) + { + return $content + ->header(__('admin.dojos.create.header')) + ->description(__('admin.dojos.create.description')) + ->body($this->form()); + } + + /** + * Make a grid builder. + * + * @return Grid + */ + protected function grid() + { + $grid=new Grid(new Dojo); + $grid->column('id', "ID")->sortable(); + $grid->column("name", __('admin.dojos.name'))->editable(); + $grid->column("dojo_phase", __('admin.dojos.phase'))->display(function() { + return $this->phase->name; + }); + $grid->column("totproblem", __('admin.dojos.totproblem'))->display(function() { + return $this->tot_problem; + }); + $grid->column("passline", __('admin.dojos.passline')); + $grid->column("precondition", __('admin.dojos.precondition'))->display(function($precondition) { + $output=''; + foreach ($precondition as $p) { + $output.=''.Dojo::find($p)->name.' '; + } + return $output; + }); + $grid->column("order", __('admin.dojos.order'))->sortable(); + $grid->created_at(__('admin.created_at')); + $grid->updated_at(__('admin.updated_at')); + + $grid->filter(function(Grid\Filter $filter) { + $filter->column(6, function($filter) { + $filter->like('name', __('admin.dojos.name')); + }); + $filter->column(6, function($filter) { + $filter->equal('dojo_phase_id', __('admin.dojos.phase'))->select(DojoPhase::all()->pluck('name', 'cid')); + }); + }); + return $grid; + } + + /** + * Make a show builder. + * + * @param mixed $id + * @return Show + */ + protected function detail($id) + { + $show=new Show(Dojo::findOrFail($id)); + $show->id('ID'); + $show->name(__('admin.dojos.name')); + $show->description(__('admin.dojos.description')); + $show->dojo_phase_id(__('admin.dojos.phase')); + $show->passline(__('admin.dojos.passline')); + $show->order(__('admin.dojos.order')); + return $show; + } + + /** + * Make a form builder. + * + * @return Form + */ + protected function form() + { + $form=new Form(new Dojo); + $form->tab('Basic', function(Form $form) { + $form->display('id', 'ID'); + $form->text('name', __('admin.dojos.name'))->rules('required'); + $form->textarea('description', __('admin.dojos.description'))->rules('required'); + $form->select('dojo_phase_id', __('admin.dojos.phase'))->options(DojoPhase::all()->pluck('name', 'id'))->rules('required'); + $form->number('passline', __('admin.dojos.passline'))->default(0)->rules('required'); + $form->number('order', __('admin.dojos.order'))->default(0)->rules('required'); + $form->multipleSelect('precondition', __('admin.dojos.precondition'))->options(Dojo::all()->pluck('name', 'id')); + $form->hasMany('problems', __('admin.dojos.problems'), function(Form\NestedForm $form) { + $form->select('problem_id', __('admin.dojos.problem'))->options(Problem::all()->pluck('readable_name', 'pid'))->required(); + $form->number('order', __('admin.dojos.problemorder'))->default(0)->required(); + }); + }); + return $form; + } +} diff --git a/app/Admin/Controllers/DojoPhaseController.php b/app/Admin/Controllers/DojoPhaseController.php new file mode 100644 index 000000000..4bfa75bf6 --- /dev/null +++ b/app/Admin/Controllers/DojoPhaseController.php @@ -0,0 +1,134 @@ +header(__('admin.dojophases.index.header')) + ->description(__('admin.dojophases.index.description')) + ->body($this->grid()->render()); + } + + /** + * Show interface. + * + * @param mixed $id + * @param Content $content + * @return Content + */ + public function show($id, Content $content) + { + return $content + ->header(__('admin.dojophases.show.header')) + ->description(__('admin.dojophases.show.description')) + ->body($this->detail($id)); + } + + /** + * Edit interface. + * + * @param mixed $id + * @param Content $content + * @return Content + */ + public function edit($id, Content $content) + { + return $content + ->header(__('admin.dojophases.edit.header')) + ->description(__('admin.dojophases.edit.description')) + ->body($this->form()->edit($id)); + } + + /** + * Create interface. + * + * @param Content $content + * @return Content + */ + public function create(Content $content) + { + return $content + ->header(__('admin.dojophases.create.header')) + ->description(__('admin.dojophases.create.description')) + ->body($this->form()); + } + + /** + * Make a grid builder. + * + * @return Grid + */ + protected function grid() + { + $grid=new Grid(new DojoPhase); + $grid->column('id', "ID")->sortable(); + $grid->column("name", __('admin.dojophases.name'))->editable(); + + $grid->column("passline", __('admin.dojophases.passline')); + $grid->column("order", __('admin.dojophases.order'))->sortable(); + $grid->created_at(__('admin.created_at')); + $grid->updated_at(__('admin.updated_at')); + + $grid->filter(function(Grid\Filter $filter) { + $filter->column(6, function($filter) { + $filter->like('name', __('admin.dojophases.name')); + }); + }); + return $grid; + } + + /** + * Make a show builder. + * + * @param mixed $id + * @return Show + */ + protected function detail($id) + { + $show=new Show(DojoPhase::findOrFail($id)); + $show->id('ID'); + $show->name(__('admin.dojophases.name')); + $show->description(__('admin.dojophases.description')); + $show->passline(__('admin.dojophases.passline')); + $show->order(__('admin.dojophases.order')); + return $show; + } + + /** + * Make a form builder. + * + * @return Form + */ + protected function form() + { + $form=new Form(new DojoPhase); + $form->tab('Basic', function(Form $form) { + $form->display('id', 'ID'); + $form->text('name', __('admin.dojophases.name'))->rules('required'); + $form->textarea('description', __('admin.dojophases.description'))->rules('required'); + $form->number('passline', __('admin.dojophases.passline'))->default(0)->rules('required'); + $form->number('order', __('admin.dojophases.order'))->default(0)->rules('required'); + }); + return $form; + } +} diff --git a/app/Admin/Controllers/GroupController.php b/app/Admin/Controllers/GroupController.php index 4e955bd89..a57932f98 100644 --- a/app/Admin/Controllers/GroupController.php +++ b/app/Admin/Controllers/GroupController.php @@ -3,12 +3,15 @@ namespace App\Admin\Controllers; use App\Models\Eloquent\Group; +use App\Models\Eloquent\User; use App\Http\Controllers\Controller; use Encore\Admin\Controllers\HasResourceActions; use Encore\Admin\Form; use Encore\Admin\Grid; use Encore\Admin\Layout\Content; use Encore\Admin\Show; +use Illuminate\Support\MessageBag; +use App\Models\Eloquent\GroupMember; class GroupController extends Controller { @@ -124,8 +127,45 @@ protected function form() $form=new Form(new Group); $form->model()->makeVisible('password'); $form->tab('Basic', function(Form $form) { - $form->display('gid'); - $form->text('name')->rules('required'); + $form->text('gcode')->rules('required|alpha_dash|min:3|max:50'); + $form->text('name')->rules('required|min:3|max:50'); + $form->switch('public')->default(true); + $form->textarea('description')->rules('nullable|max:60000'); + $form->select('join_policy', 'Join Policy')->options([ + 0 => "Cannot Join", + 1 => "Invite Only", + 2 => "Apply Only", + 3 => "Invite & Apply" + ])->default(1); + $form->image('img', 'Custom Group Focus Image')->uniqueName()->move("static/img/group"); + if ($form->isCreating()) { + $form->select('leader_uid', 'Group Leader')->options(User::all()->pluck('name', 'id'))->required(); + } + $form->ignore(['leader_uid']); + $form->saving(function(Form $form) { + $err=function($msg, $title='Error occur.') { + $error=new MessageBag([ + 'title' => $title, + 'message' => $msg, + ]); + return back()->with(compact('error')); + }; + $gcode=$form->gcode; + $g=Group::where('gcode', $gcode)->first(); + //check gcode has been token. + $gid=$form->pid ?? null; + if (!empty($gcode) && !blank($g) && $g->gid!=$gid) { + $err('Gcode has been token', 'Error occur.'); + } + }); + $form->saved(function(Form $form) { + $form->model()->members()->saveMany([new GroupMember([ + 'gid' => $form->model()->gid, + 'uid' => request('leader_uid'), + 'role' => 3, + 'ranking' => 1500, + ])]); + }); }); return $form; } diff --git a/app/Admin/Controllers/HomeController.php b/app/Admin/Controllers/HomeController.php index 228233c08..618c1d5f1 100644 --- a/app/Admin/Controllers/HomeController.php +++ b/app/Admin/Controllers/HomeController.php @@ -13,8 +13,8 @@ class HomeController extends Controller public function index(Content $content) { return $content - ->header('Dashboard') - ->description('the general status of '.config("app.name")) + ->header(__('admin.home.dashboard')) + ->description(__('admin.home.description')) ->row(function(Row $row) { $row->column(4, function(Column $column) { @@ -22,7 +22,7 @@ public function index(Content $content) }); $row->column(4, function(Column $column) { - $column->append(Dashboard::environment()); + $column->append(DashboardController::environment()); }); // $row->column(4, function(Column $column) { diff --git a/app/Admin/Controllers/JudgeServerController.php b/app/Admin/Controllers/JudgeServerController.php new file mode 100644 index 000000000..a323be0e2 --- /dev/null +++ b/app/Admin/Controllers/JudgeServerController.php @@ -0,0 +1,166 @@ +header(__('admin.judgeservers.index.header')) + ->description(__('admin.judgeservers.index.description')) + ->body($this->grid()->render()); + } + + /** + * Show interface. + * + * @param mixed $id + * @param Content $content + * @return Content + */ + public function show($id, Content $content) + { + return $content + ->header(__('admin.judgeservers.show.header')) + ->description(__('admin.judgeservers.show.description')) + ->body($this->detail($id)); + } + + /** + * Edit interface. + * + * @param mixed $id + * @param Content $content + * @return Content + */ + public function edit($id, Content $content) + { + return $content + ->header(__('admin.judgeservers.edit.header')) + ->description(__('admin.judgeservers.edit.description')) + ->body($this->form()->edit($id)); + } + + /** + * Create interface. + * + * @param Content $content + * @return Content + */ + public function create(Content $content) + { + return $content + ->header(__('admin.judgeservers.create.header')) + ->description(__('admin.judgeservers.create.description')) + ->body($this->form()); + } + + /** + * Make a grid builder. + * + * @return Grid + */ + protected function grid() + { + $grid=new Grid(new JudgeServer()); + + $grid->column('jsid', 'JSID'); + $grid->column('scode', __('admin.judgeservers.scode')); + $grid->column('name', __('admin.judgeservers.name')); + $grid->column('host', __('admin.judgeservers.host')); + $grid->column('port', __('admin.judgeservers.port')); + $grid->column('token', __('admin.judgeservers.token')); + $grid->column('available', __('admin.judgeservers.availability'))->display(function($available) { + return $available ?__('admin.judgeservers.available') : __('admin.judgeservers.unavailable'); + }); + $grid->column('OJ', __('admin.judgeservers.oj'))->display(function() { + return $this->oj->name; + }); + $grid->column('usage', __('admin.judgeservers.usage'))->display(function($usage) { + return blank($usage) ? "-" : "$usage%"; + }); + $grid->column('status', __('admin.judgeservers.status'))->display(function($status) { + $status=JudgerModel::$status[$status]; + return ' '.$status['text']; + }); + $grid->column('status_update_at', __('admin.judgeservers.status_update_at')); + $grid->column('created_at', __('admin.created_at')); + $grid->column('updated_at', __('admin.updated_at')); + + return $grid; + } + + /** + * Make a show builder. + * + * @param mixed $id + * @return Show + */ + protected function detail($id) + { + $show=new Show(JudgeServer::findOrFail($id)); + + $show->field('jsid', 'JSID'); + $show->field('scode', __('admin.judgeservers.scode')); + $show->field('name', __('admin.judgeservers.name')); + $show->field('host', __('admin.judgeservers.host')); + $show->field('port', __('admin.judgeservers.port')); + $show->field('token', __('admin.judgeservers.token')); + $show->field('available', __('admin.judgeservers.availability'))->as(function($available) { + return $available ?__('admin.judgeservers.available') : __('admin.judgeservers.unavailable'); + }); + $show->field('oj.name', __('admin.judgeservers.oj')); + $show->field('usage', __('admin.judgeservers.usage'))->as(function($usage) { + return blank($usage) ? "-" : "$usage%"; + }); + $show->field('status', __('admin.judgeservers.status'))->unescape()->as(function($status) { + $status=JudgerModel::$status[$status]; + return ' '.$status['text']; + }); + $show->field('status_update_at', __('admin.judgeservers.status_update_at')); + $show->field('created_at', __('admin.created_at')); + $show->field('updated_at', __('admin.updated_at')); + + return $show; + } + + /** + * Make a form builder. + * + * @return Form + */ + protected function form() + { + $form=new Form(new JudgeServer()); + + $form->text('scode', __('admin.judgeservers.scode'))->required(); + $form->text('name', __('admin.judgeservers.name'))->required(); + $form->text('host', __('admin.judgeservers.host'))->required(); + $form->text('port', __('admin.judgeservers.port'))->required(); + $form->text('token', __('admin.judgeservers.token'))->required(); + $form->switch('available', __('admin.judgeservers.availability')); + $form->select('oid', __('admin.judgeservers.oj'))->options(OJ::all()->pluck('name', 'oid'))->help(__('admin.judgeservers.help.onlinejudge'))->required(); + $form->hidden('status', __('admin.judgeservers.status'))->default(0); + return $form; + } +} diff --git a/app/Admin/Controllers/JudgerController.php b/app/Admin/Controllers/JudgerController.php new file mode 100644 index 000000000..35eda338d --- /dev/null +++ b/app/Admin/Controllers/JudgerController.php @@ -0,0 +1,150 @@ +header(__('admin.judgers.index.header')) + ->description(__('admin.judgers.index.description')) + ->body($this->grid()->render()); + } + + /** + * Show interface. + * + * @param mixed $id + * @param Content $content + * @return Content + */ + public function show($id, Content $content) + { + return $content + ->header(__('admin.judgers.show.header')) + ->description(__('admin.judgers.show.description')) + ->body($this->detail($id)); + } + + /** + * Edit interface. + * + * @param mixed $id + * @param Content $content + * @return Content + */ + public function edit($id, Content $content) + { + return $content + ->header(__('admin.judgers.edit.header')) + ->description(__('admin.judgers.edit.description')) + ->body($this->form()->edit($id)); + } + + /** + * Create interface. + * + * @param Content $content + * @return Content + */ + public function create(Content $content) + { + return $content + ->header(__('admin.judgers.create.header')) + ->description(__('admin.judgers.create.description')) + ->body($this->form()); + } + + /** + * Make a grid builder. + * + * @return Grid + */ + protected function grid() + { + $grid=new Grid(new Judger()); + + $grid->column('jid', 'JID'); + $grid->column('handle', __('admin.judgers.handle'))->editable(); + $grid->column('password', __('admin.judgers.password'))->editable(); + $grid->column('available', __('admin.judgers.availability'))->display(function($available) { + return $available ? ' '.__('admin.judgers.available') : ' '.__('admin.judgers.unavailable'); + }); + $grid->column('oid', __('admin.judgers.oj'))->display(function() { + return $this->oj->name; + }); + $grid->column('user_id', __('admin.judgers.user_id'))->editable(); + $grid->column('created_at', __('admin.created_at')); + $grid->column('updated_at', __('admin.updated_at')); + + $grid->filter(function(Grid\Filter $filter) { + $filter->like('handle', __('admin.judgers.handle')); + $filter->like('password', __('admin.judgers.password')); + $filter->like('user_id', __('admin.judgers.user_id')); + $filter->equal('oid', __('admin.judgers.oj'))->select(OJ::all()->pluck('name', 'oid')); + }); + + return $grid; + } + + /** + * Make a show builder. + * + * @param mixed $id + * @return Show + */ + protected function detail($id) + { + $show=new Show(Judger::findOrFail($id)); + + $show->field('jid', 'JID'); + $show->field('handle', __('admin.judgers.handle')); + $show->field('password', __('admin.judgers.password')); + $show->field('available', __('admin.judgers.availability'))->as(function($available) { + return $available ?__('admin.judgers.available') : __('admin.judgers.unavailable'); + }); + $show->field('oj.name', __('admin.judgers.oj')); + $show->field('user_id', __('admin.judgers.user_id')); + $show->field('created_at', __('admin.created_at')); + $show->field('updated_at', __('admin.updated_at')); + + return $show; + } + + /** + * Make a form builder. + * + * @return Form + */ + protected function form() + { + $form=new Form(new Judger()); + $form->text('handle', __('admin.judgers.handle'))->help(__('admin.judgers.help.handle'))->required(); + $form->text('password', __('admin.judgers.password'))->help(__('admin.judgers.help.password'))->required(); + $form->switch('available', __('admin.judgers.availability'))->default(true); + $form->select('oid', __('admin.judgers.oj'))->options(OJ::all()->pluck('name', 'oid'))->required(); + $form->text('user_id', __('admin.judgers.user_id'))->help(__('admin.judgers.help.user_id')); + $form->hidden('using')->default(0); + return $form; + } +} diff --git a/app/Admin/Controllers/ProblemController.php b/app/Admin/Controllers/ProblemController.php index a838bf84e..3a6c8a267 100644 --- a/app/Admin/Controllers/ProblemController.php +++ b/app/Admin/Controllers/ProblemController.php @@ -143,11 +143,11 @@ protected function detail($id) * * @return Form */ - protected function form($create = false) + protected function form($create=false) { $form=new Form(new EloquentProblemModel); $form->model()->makeVisible('password'); - $form->tab('Basic', function(Form $form){ + $form->tab('Basic', function(Form $form) { $form->text('pid')->readonly(); $form->text('pcode')->rules('required'); $form->text('title')->rules('required'); @@ -157,7 +157,7 @@ protected function form($create = false) $form->simplemde('input'); $form->simplemde('output'); $form->simplemde('note'); - $form->hasMany('problemSamples', 'samples', function (Form\NestedForm $form) { + $form->hasMany('problemSamples', 'samples', function(Form\NestedForm $form) { $form->textarea('sample_input', 'sample input')->rows(3); $form->textarea('sample_output', 'sample output')->rows(3); $form->textarea('sample_note', 'sample note')->rows(3); @@ -167,10 +167,10 @@ protected function form($create = false) $table->textarea('sample_output', 'sample output'); $table->textarea('sample_note', 'sample note'); }); */ - $ojs_temp = EloquentOJModel::select('oid', 'name')->get()->all(); - $ojs = []; - foreach($ojs_temp as $v){ - $ojs[$v->oid] = $v->name; + $ojs_temp=EloquentOJModel::select('oid', 'name')->get()->all(); + $ojs=[]; + foreach ($ojs_temp as $v) { + $ojs[$v->oid]=$v->name; } $form->select('oj', 'OJ')->options($ojs)->default(1)->rules('required'); /* $form->display('update_date'); */ @@ -189,7 +189,7 @@ protected function form($create = false) 0 => 'NO', 1 => 'YES', ])->default(0)->rules('required'); - $form->clang('spj_src','SPJ Source Code'); + $form->clang('spj_src', 'SPJ Source Code'); $form->file('test_case')->rules('required'); $form->ignore(['test_case']); @@ -211,125 +211,128 @@ protected function form($create = false) $tools->append('  Import from file'); }); } */ - $form->saving(function (Form $form){ - $err = function ($msg, $title = 'Test case file parse faild.') { - $error = new MessageBag([ + $form->saving(function(Form $form) { + $err=function($msg, $title='Test case file parse faild.') { + $error=new MessageBag([ 'title' => $title, 'message' => $msg, ]); return back()->with(compact('error')); }; - $pcode = $form->pcode; - $p = EloquentProblemModel::where('pcode',$pcode)->first(); + $pcode=$form->pcode; + $p=EloquentProblemModel::where('pcode', $pcode)->first(); //check pcode has been token. - $pid = $form->pid ?? null; - if(!empty($p) && $p->pid != $pid){ + $pid=$form->pid ?? null; + if (!empty($p) && $p->pid!=$pid) { $err('Pcode has been token', 'Error occur.'); } - $test_case = \request()->file('test_case'); + $test_case=\request()->file('test_case'); //Make sure the user enters SPJ_SRc in spj problem. - if($form->spj && empty($form->spj_src)) { + if ($form->spj && empty($form->spj_src)) { $err('The SPJ problem must provide spj_src', 'create problem error'); } //check info file. Try to generate if it does not exist. - $info_content = []; - if(!empty($test_case)){ - if($test_case->extension() != 'zip'){ + $info_content=[]; + if (!empty($test_case)) { + if ($test_case->extension()!='zip') { $err('You must upload a zip file iuclude test case info and content.'); } - $path = $test_case->path(); - $zip = new ZipArchive; - if($zip->open($path) !== true) { + $path=$test_case->path(); + $zip=new ZipArchive; + if ($zip->open($path)!==true) { $err('You must upload a zip file without encrypt and can open successfully.'); }; - $info_content = []; - if(($zip->getFromName('info')) === false){ - if(!$form->spj){ - $info_content = [ + $info_content=[]; + if (($zip->getFromName('info'))===false) { + if (!$form->spj) { + $info_content=[ 'spj' => false, 'test_cases' => [] ]; - $files = []; - for ($i = 0; $i < $zip->numFiles; $i++) { - $filename = $zip->getNameIndex($i); - $files[] = $filename; + $files=[]; + for ($i=0; $i<$zip->numFiles; $i++) { + $filename=$zip->getNameIndex($i); + $files[]=$filename; } - $files_in = array_filter($files, function ($filename) { - return strpos('.in', $filename) != -1; + $files_in=array_filter($files, function($filename) { + return strpos('.in', $filename)!=-1; }); sort($files_in); - $testcase_index = 1; - foreach($files_in as $filename_in){ - $filename = basename($filename_in, '.in'); - $filename_out = $filename.'.out'; - if(($zip->getFromName($filename_out)) === false) { + $testcase_index=1; + if (!count($files_in)) { + $err('Cannot detect any .in file, please make sure they are placed under the root directory of the zip file.'); + } + foreach ($files_in as $filename_in) { + $filename=basename($filename_in, '.in'); + $filename_out=$filename.'.out'; + if (($zip->getFromName($filename_out))===false) { continue; } - $test_case_in = preg_replace('~(*BSR_ANYCRLF)\R~',"\n", $zip->getFromName($filename_in)); - $test_case_out = preg_replace('~(*BSR_ANYCRLF)\R~',"\n", $zip->getFromName($filename_out)); - $info_content['test_cases']["{$testcase_index}"] = [ + $test_case_in=preg_replace('~(*BSR_ANYCRLF)\R~', "\n", $zip->getFromName($filename_in)); + $test_case_out=preg_replace('~(*BSR_ANYCRLF)\R~', "\n", $zip->getFromName($filename_out)); + $info_content['test_cases']["{$testcase_index}"]=[ 'input_size' => strlen($test_case_in), 'input_name' => $filename_in, 'output_size' => strlen($test_case_out), 'output_name' => $filename_out, 'stripped_output_md5' => md5(utf8_encode(rtrim($test_case_out))) ]; - $testcase_index += 1; + $testcase_index+=1; } - }else{ - $info_content = [ + } else { + $info_content=[ 'spj' => true, 'test_cases' => [] ]; - $files = []; - for ($i = 0; $i < $zip->numFiles; $i++) { - $filename = $zip->getNameIndex($i); - $files[] = $filename; + $files=[]; + for ($i=0; $i<$zip->numFiles; $i++) { + $filename=$zip->getNameIndex($i); + $files[]=$filename; } - $files_in = array_filter($files, function ($filename) { - return strpos($filename, '.in') !== false; + $files_in=array_filter($files, function($filename) { + return strpos($filename, '.in')!==false; }); sort($files_in); - $testcase_index = 1; - foreach($files_in as $filename_in){ - $test_case_in = $zip->getFromName($filename_in); - $info_content['test_cases']["{$testcase_index}"] = [ + $testcase_index=1; + foreach ($files_in as $filename_in) { + $test_case_in=$zip->getFromName($filename_in); + $info_content['test_cases']["{$testcase_index}"]=[ 'input_size' => strlen($test_case_in), 'input_name' => $filename_in ]; - $testcase_index += 1; + $testcase_index+=1; } } $zip->addFromString('info', json_encode($info_content)); $zip->close(); //$err('The zip files must include a file named info including info of test cases, and the format can see ZsgsDesign/NOJ wiki.'); - }else{ - $info_content = json_decode($zip->getFromName('info'),true); + } else { + $info_content=json_decode($zip->getFromName('info'), true); }; $zip->open($path); //If there is an INFO file, check that the contents of the file match the actual situation - $test_cases = $info_content['test_cases']; + $test_cases=$info_content['test_cases']; //dd($test_cases); - foreach($test_cases as $index => $case) { - if(!isset($case['input_name']) || (!$form->spj && !isset($case['output_name']))) { + foreach ($test_cases as $index => $case) { + if (!isset($case['input_name']) || (!$form->spj && !isset($case['output_name']))) { $err("Test case index {$index}: configuration missing input/output files name."); } - if($zip->getFromName($case['input_name']) === false || (!$form->spj && $zip->getFromName($case['output_name']) === false)) { + if ($zip->getFromName($case['input_name'])===false || (!$form->spj && $zip->getFromName($case['output_name'])===false)) { $err("Test case index {$index}: missing input/output files that record in the configuration."); } } - if(!empty($form->pid)){ - $problem = EloquentProblemModel::find($form->pid); - if(!empty($problem)){ - $pcode = $problem->pcode; - }else{ - $pcode = $form->pcode; + if (!empty($form->pid)) { + $problem=EloquentProblemModel::find($form->pid); + if (!empty($problem)) { + $pcode=$problem->pcode; + } else { + $pcode=$form->pcode; } - }else{ - $pcode = $form->pcode; + } else { + $pcode=$form->pcode; } - if(Storage::exists(base_path().'/storage/test_case/'.$pcode)){ + if (Storage::exists(base_path().'/storage/test_case/'.$pcode)) { Storage::deleteDirectory(base_path().'/storage/test_case/'.$pcode); } Storage::makeDirectory(base_path().'/storage/test_case/'.$pcode); @@ -337,19 +340,19 @@ protected function form($create = false) } //Set the spj-related data - if($form->spj){ - $form->spj_lang = 'c'; - $form->spj_version = "{$form->pcode}#".time(); + if ($form->spj) { + $form->spj_lang='c'; + $form->spj_version="{$form->pcode}#".time(); } //Set default data - $form->tot_score = count($info_content['test_cases']); - $form->markdown = true; - $form->input_type = 'standard input'; - $form->output_type = 'standard output'; - $form->solved_count = 0; - $form->difficulty = -1; - $form->partial = 1; - $form->file = 0; + $form->tot_score=count($info_content['test_cases']); + $form->markdown=true; + $form->input_type='standard input'; + $form->output_type='standard output'; + $form->solved_count=0; + $form->difficulty=-1; + $form->partial=1; + $form->file=0; }); return $form; } diff --git a/app/Admin/Controllers/SettingsController.php b/app/Admin/Controllers/SettingsController.php new file mode 100644 index 000000000..4f9e5b398 --- /dev/null +++ b/app/Admin/Controllers/SettingsController.php @@ -0,0 +1,56 @@ +header(__('admin.settings.index.header')); + $content=$content->description(__('admin.settings.index.description')); + if (request()->isMethod('post')) { + $this->writeSettings(); + admin_toastr(__('admin.settings.tooltip.success.message'), 'success'); + } + return $content->body($this->form()); + } + + /** + * Make a form builder. + * + * @return Form + */ + protected function form() + { + $box=new Box(__('admin.settings.form.header')); + $box->style('success'); + $form=new Form(); + $form->simplemde('terms', __('admin.settings.form.terms'))->default(setting('terms'))->help(__('admin.settings.help.terms')); + $form->method('POST'); + $form->action(route('admin.settings.index')); + $form->disableReset(); + $box->content($form); + return $box; + } + + protected function writeSettings() + { + setting(['terms' => request()->terms]); + } +} diff --git a/app/Admin/Controllers/SolutionController.php b/app/Admin/Controllers/SolutionController.php index 15cc3a577..8a2849575 100644 --- a/app/Admin/Controllers/SolutionController.php +++ b/app/Admin/Controllers/SolutionController.php @@ -2,8 +2,9 @@ namespace App\Admin\Controllers; -use App\Models\ProblemModel; -use App\Models\Eloquent\SolutionModel as EloquentSolutionModel; +use App\Models\Eloquent\Solution; +use App\Models\Eloquent\Problem; +use App\Models\Eloquent\User; use App\Http\Controllers\Controller; use Encore\Admin\Controllers\HasResourceActions; use Encore\Admin\Form; @@ -80,7 +81,7 @@ public function create(Content $content) */ protected function grid() { - $grid=new Grid(new EloquentSolutionModel); + $grid=new Grid(new Solution); $grid->psoid("ID")->sortable(); $grid->uid("Uid")->editable(); $grid->pid("Pid")->editable(); @@ -113,7 +114,7 @@ protected function grid() */ protected function detail($id) { - $show=new Show(EloquentSolutionModel::findOrFail($id)); + $show=new Show(Solution::findOrFail($id)); return $show; } @@ -124,25 +125,21 @@ protected function detail($id) */ protected function form() { - $form=new Form(new EloquentSolutionModel); + $form=new Form(new Solution); $form->model()->makeVisible('password'); $form->tab('Basic', function(Form $form) { $form->display("psoid"); - $form->text("uid")->rules('required'); - $form->text("pid")->rules('required'); - $form->text("content")->rules('required'); - $form->text("audit")->rules('required'); - $form->text("votes")->rules('required'); + $form->select('uid', 'Author')->options(User::all()->pluck('name', 'id'))->required(); + $form->select('pid', 'Problem')->options(Problem::all()->pluck('readable_name', 'pid'))->required(); + $form->simplemde("content")->rules('required'); + $form->select("audit")->options([ + '0' => 'Waiting', + '1' => 'Accepted', + '2' => 'Declined', + ])->default(1)->required(); + $form->number("votes")->rules('required'); $form->display("created_at"); $form->display("updated_at"); - $form->select('partial', 'Partial Score')->options([ - 0 => "No", - 1 => "Yes" - ])->rules('required'); - $form->select('markdown', 'Markdown Support')->options([ - 0 => "No", - 1 => "Yes" - ])->rules('required'); }); return $form; } diff --git a/app/Admin/Controllers/SubmissionController.php b/app/Admin/Controllers/SubmissionController.php index 2ccd5f532..95bb041ff 100644 --- a/app/Admin/Controllers/SubmissionController.php +++ b/app/Admin/Controllers/SubmissionController.php @@ -2,7 +2,12 @@ namespace App\Admin\Controllers; -use App\Models\Eloquent\Submission as EloquentSubmissionModel; +use App\Models\Eloquent\Submission; +use App\Models\Eloquent\Contest; +use App\Models\Eloquent\Judger; +use App\Models\Eloquent\Compiler; +use App\Models\Eloquent\User; +use App\Models\Eloquent\Problem; use App\Http\Controllers\Controller; use Encore\Admin\Controllers\HasResourceActions; use Encore\Admin\Form; @@ -23,8 +28,8 @@ class SubmissionController extends Controller public function index(Content $content) { return $content - ->header('Submissions') - ->description('all submissions') + ->header(__('admin.submissions.index.header')) + ->description(__('admin.submissions.index.description')) ->body($this->grid()->render()); } @@ -38,8 +43,8 @@ public function index(Content $content) public function show($id, Content $content) { return $content - ->header('Submission Detail') - ->description('the detail of submissions') + ->header(__('admin.submissions.show.header')) + ->description(__('admin.submissions.show.description')) ->body($this->detail($id)); } @@ -53,8 +58,8 @@ public function show($id, Content $content) public function edit($id, Content $content) { return $content - ->header('Edit Submission') - ->description('edit the detail of submissions') + ->header(__('admin.submissions.edit.header')) + ->description(__('admin.submissions.edit.description')) ->body($this->form()->edit($id)); } @@ -67,8 +72,8 @@ public function edit($id, Content $content) public function create(Content $content) { return $content - ->header('Create New Submission') - ->description('create a new submission') + ->header(__('admin.submissions.create.header')) + ->description(__('admin.submissions.create.description')) ->body($this->form()); } @@ -79,32 +84,54 @@ public function create(Content $content) */ protected function grid() { - $grid=new Grid(new EloquentSubmissionModel); + $grid=new Grid(new Submission); $grid->column('sid', "ID")->sortable(); - $grid->time("Time"); - $grid->memory("Memory"); - $grid->verdict("Verdict")->display(function ($verdict) { + $grid->column("time", __('admin.submissions.time'))->display(function($time) { + return __('admin.submissions.timeFormat', ['time'=>$time]); + }); + $grid->column("memory", __('admin.submissions.memory'))->display(function($memory) { + return __('admin.submissions.memoryFormat', ['memory'=>$memory]); + }); + $grid->column('verdict', __('admin.submissions.verdict'))->display(function($verdict) { return ' '.$verdict; }); - $grid->language("Language"); - $grid->submission_date("Submission Date")->display(function ($submission_date) { + $grid->column("language", __('admin.submissions.language')); + $grid->column("submission_date", __('admin.submissions.submission_date'))->display(function($submission_date) { return date("Y-m-d H:i:s", $submission_date); }); - ; - $grid->uid("UID"); - $grid->cid("CID"); - $grid->pid("PID"); - $grid->jid("JID"); - $grid->coid("COID"); - $grid->score("Raw Score"); - $grid->filter(function (Grid\Filter $filter) { - $filter->column(6, function ($filter) { - $filter->like('verdict'); + $grid->column("user_name", __('admin.submissions.user_name'))->display(function() { + return $this->user->name; + }); + $grid->column("contest_name", __('admin.submissions.contest_name'))->display(function() { + if (!is_null($this->contest)) { + return $this->contest->name; + } + }); + $grid->column("readable_name", __('admin.submissions.readable_name'))->display(function() { + return $this->problem->readable_name; + }); + $grid->column("judger_name", __('admin.submissions.judger_name'))->display(function() { + return $this->judger_name; + }); + $grid->column("share", __('admin.submissions.share'))->editable('select', [ + 0 => __('admin.submissions.disableshare'), + 1 => __('admin.submissions.enableshare') + ]); + $grid->column("parsed_score", __('admin.submissions.parsed_score'))->display(function() { + return $this->parsed_score; + }); + $grid->filter(function(Grid\Filter $filter) { + $filter->column(6, function($filter) { + $filter->like('verdict', __('admin.submissions.verdict')); }); - $filter->column(6, function ($filter) { - $filter->equal('cid', 'Contest ID'); - $filter->equal('uid', 'User ID'); - $filter->equal('pid', 'Problem ID'); + $filter->column(6, function($filter) { + $filter->equal('cid', __('admin.submissions.cid'))->select(Contest::all()->pluck('name', 'cid')); + $filter->equal('uid', __('admin.submissions.uid'))->select(User::all()->pluck('name', 'id')); + $filter->equal('pid', __('admin.submissions.pid'))->select(Problem::all()->pluck('readable_name', 'pid')); + $filter->equal('share', __('admin.submissions.share'))->select([ + 0 => __('admin.submissions.disableshare'), + 1 => __('admin.submissions.enableshare') + ]); }); }); return $grid; @@ -118,34 +145,33 @@ protected function grid() */ protected function detail($id) { - $show=new Show(EloquentSubmissionModel::findOrFail($id)); + $show=new Show(Submission::findOrFail($id)); $show->sid('SID'); - $show->time(); - $show->memory(); - $show->verdict(); - $show->color(); - $show->language(); - $show->submission_date(); - $show->remote_id(); - $this->codify($show->solution(), $show->getModel()->compiler->lang); + $show->time(__('admin.submissions.time')); + $show->memory(__('admin.submissions.memory')); + $show->verdict(__('admin.submissions.verdict')); + $show->language(__('admin.submissions.language')); + $show->submission_date(__('admin.submissions.submission_date')); + $show->remote_id(__('admin.submissions.remote_id')); + $this->codify($show->solution(__('admin.submissions.solution')), $show->getModel()->compiler->lang); if (!blank($show->getModel()->compile_info)) { $this->codify($show->compile_info()); } - $show->uid('UID'); - $show->pid('PID'); - $show->cid('CID'); - $show->jid('JID'); - $show->coid('COID'); - $show->vcid('VCID'); - $show->score(); - $show->share()->using(['No','Yes']); + $show->uid(__('admin.submissions.uid')); + $show->pid(__('admin.submissions.pid')); + $show->cid(__('admin.submissions.cid')); + $show->jid(__('admin.submissions.jid')); + $show->coid(__('admin.submissions.coid')); + $show->vcid(__('admin.submissions.vcid')); + $show->score(__('admin.submissions.parsed_score')); + $show->share(__('admin.submissions.share'))->using([__('admin.submissions.disableshare'), __('admin.submissions.enableshare')]); return $show; } private function codify($field, $lang=null) { - $field->unescape()->as(function ($value) use ($field,$lang) { - $field->border = false; + $field->unescape()->as(function($value) use ($field, $lang) { + $field->border=false; $hash=md5($value); if (blank($value)) { $value=" "; @@ -184,22 +210,25 @@ private function codify($field, $lang=null) */ protected function form() { - $form=new Form(new EloquentSubmissionModel); - $form->model()->makeVisible('password'); - $form->tab('Basic', function (Form $form) { - $form->display('sid'); - $form->text('time')->rules('required'); - $form->text('memory')->rules('required'); - $form->text('verdict')->rules('required'); - $form->text('color')->rules('required'); - $form->text('language')->rules('required'); - $form->display('submission_date'); - $form->number('uid')->rules('required'); - $form->number('cid'); - $form->number('pid')->rules('required'); - $form->number('jid')->rules('required'); - $form->number('coid')->rules('required'); - $form->number('score')->rules('required'); + $form=new Form(new Submission); + $form->tab('Basic', function(Form $form) { + $form->display('sid', 'SID'); + $form->text('time', __('admin.submissions.time'))->rules('required'); + $form->text('memory', __('admin.submissions.memory'))->rules('required'); + $form->text('verdict', __('admin.submissions.verdict'))->rules('required'); + $form->text('color', __('admin.submissions.color'))->rules('required'); + $form->textarea('language', __('admin.submissions.language'))->rules('required'); + $form->display('submission_date', __('admin.submissions.submission_date')); + $form->select('uid', __('admin.submissions.uid'))->options(User::all()->pluck('name', 'id'))->required(); + $form->select('cid', __('admin.submissions.cid'))->options(Contest::all()->pluck('name', 'cid')); + $form->select('pid', __('admin.submissions.pid'))->options(Problem::all()->pluck('readable_name', 'pid'))->rules('required'); + $form->select('jid', __('admin.submissions.jid'))->options(Judger::all()->pluck('readable_name', 'jid')); + $form->select('coid', __('admin.submissions.coid'))->options(Compiler::all()->pluck('readable_name', 'coid'))->rules('required'); + $form->number('score', __('admin.submissions.rawscore'))->rules('required'); + $form->select('share', __('admin.submissions.share'))->options([ + 0 => __('admin.submissions.disableshare'), + 1 => __('admin.submissions.enableshare') + ])->default(0)->rules('required'); }); return $form; } diff --git a/app/Admin/Controllers/UserController.php b/app/Admin/Controllers/UserController.php index 21a39b0ec..42137d182 100644 --- a/app/Admin/Controllers/UserController.php +++ b/app/Admin/Controllers/UserController.php @@ -2,8 +2,7 @@ namespace App\Admin\Controllers; -use App\Models\UserModel; -use App\Models\Eloquent\UserModel as EloquentUserModel; +use App\Models\Eloquent\User; use App\Http\Controllers\Controller; use Encore\Admin\Controllers\HasResourceActions; use Encore\Admin\Form; @@ -24,8 +23,8 @@ class UserController extends Controller public function index(Content $content) { return $content - ->header('Users') - ->description('all users') + ->header(__('admin.users.index.header')) + ->description(__('admin.users.index.description')) ->body($this->grid()->render()); } @@ -39,8 +38,8 @@ public function index(Content $content) public function show($id, Content $content) { return $content - ->header('User Detail') - ->description('the detail of users') + ->header(__('admin.users.show.header')) + ->description(__('admin.users.show.description')) ->body($this->detail($id)); } @@ -54,8 +53,8 @@ public function show($id, Content $content) public function edit($id, Content $content) { return $content - ->header('Edit User') - ->description('edit the detail of users') + ->header(__('admin.users.edit.header')) + ->description(__('admin.users.edit.description')) ->body($this->form()->edit($id)); } @@ -68,8 +67,8 @@ public function edit($id, Content $content) public function create(Content $content) { return $content - ->header('Create New User') - ->description('create a new user') + ->header(__('admin.users.create.header')) + ->description(__('admin.users.create.description')) ->body($this->form()); } @@ -80,16 +79,16 @@ public function create(Content $content) */ protected function grid() { - $grid=new Grid(new EloquentUserModel); + $grid=new Grid(new User); $grid->id('ID')->sortable(); - $grid->name()->editable(); - $grid->email(); - $grid->created_at(); - $grid->updated_at(); + $grid->name(__('admin.users.name'))->editable(); + $grid->email(__('admin.users.email')); + $grid->created_at(__('admin.created_at')); + $grid->updated_at(__('admin.updated_at')); $grid->filter(function(Grid\Filter $filter) { $filter->disableIdFilter(); - $filter->like('name'); - $filter->like('email')->email(); + $filter->like('name', __('admin.users.name')); + $filter->like('email', __('admin.users.email'))->email(); }); return $grid; } @@ -102,7 +101,7 @@ protected function grid() */ protected function detail($id) { - $show=new Show(EloquentUserModel::findOrFail($id)); + $show=new Show(User::findOrFail($id)); return $show; } @@ -113,17 +112,21 @@ protected function detail($id) */ protected function form() { - $form=new Form(new EloquentUserModel); + $form=new Form(new User); $form->model()->makeVisible('password'); - $form->tab('Basic', function(Form $form) { - $form->display('id'); - $form->text('name')->rules('required'); - $form->email('email')->rules('required'); - $form->display('created_at'); - $form->display('updated_at'); - })->tab('Password', function(Form $form) { - $form->password('password')->rules('confirmed'); - $form->password('password_confirmation'); + $form->tab(__('admin.users.basic'), function(Form $form) { + if ($form->isEditing()) { + $form->display('id', 'ID'); + } + $form->text('name', __('admin.users.name'))->rules('required'); + $form->email('email', __('admin.users.email'))->rules('required'); + if ($form->isEditing()) { + $form->display('created_at', __('admin.created_at')); + $form->display('updated_at', __('admin.updated_at')); + } + })->tab(__('admin.users.password'), function(Form $form) { + $form->password('password', __('admin.password'))->rules('confirmed'); + $form->password('password_confirmation', __('admin.password_confirmation')); }); $form->ignore(['password_confirmation']); $form->saving(function(Form $form) { diff --git a/app/Admin/Forms/ImportPOEM.php b/app/Admin/Forms/ImportPOEM.php index 6c0ee0c75..acd9df97c 100644 --- a/app/Admin/Forms/ImportPOEM.php +++ b/app/Admin/Forms/ImportPOEM.php @@ -17,7 +17,7 @@ class ImportPOEM extends Form * * @var string */ - public $title = 'Import'; + public $title='Import'; /** * Handle the form request. @@ -28,29 +28,29 @@ class ImportPOEM extends Form */ public function handle(Request $request) { - $err = function ($msg) { - $error = new MessageBag([ + $err=function($msg) { + $error=new MessageBag([ 'title' => 'POEM parse failed.', 'message' => $msg, ]); return back()->with(compact('error')); }; - $success_message = ''; + $success_message=''; - $file = $request->file('Files'); - if(!$file->isValid()){ + $file=$request->file('Files'); + if (!$file->isValid()) { $err('Invalid POEM files'); } - $path = $file->getRealPath(); - $poetryRaw = file_get_contents($path); - $parser = new POEMParser(); - $poem = $parser->parse($poetryRaw); - if(empty($poem)){ + $path=$file->getRealPath(); + $poetryRaw=file_get_contents($path); + $parser=new POEMParser(); + $poem=$parser->parse($poetryRaw); + if (empty($poem)) { $err('Malformed POEM files'); } - $success_message .= " + $success_message.=" POEM standard : {$poem['standard']}
generator : {$poem['generator']}
url : {$poem['url']}
@@ -58,31 +58,31 @@ public function handle(Request $request) problems:
"; - $memory_unit = [ + $memory_unit=[ 'kb' => 1, 'mb' => 1024, - 'gb' => 1024*1024 + 'gb' => 1024 * 1024 ]; - $time_unit = [ + $time_unit=[ 'ms' => 1, 's' => 1000, 'm' => 60000, 'h' => 3600000 ]; - $prefix = 'NOJ'; - $p = ProblemModel::where('pcode','like',$prefix.'%')->orderBy('pcode','desc')->select('pcode')->first(); - if(empty($p)){ - $count = 1000; - }else{ - $count = (int) str_replace($prefix,'',$p['pcode']); + $prefix='NOJ'; + $p=ProblemModel::where('pcode', 'like', $prefix.'%')->orderBy('pcode', 'desc')->select('pcode')->first(); + if (empty($p)) { + $count=1000; + } else { + $count=(int) str_replace($prefix, '', $p['pcode']); } foreach ($poem['problems'] as $problem) { //insert problem - $title = $problem['title']; - $pro = [ - 'pcode' => $prefix . (++$count), + $title=$problem['title']; + $pro=[ + 'pcode' => $prefix.(++$count), 'solved_count' => 0, 'difficulty' => -1, 'file' => 0, @@ -101,49 +101,49 @@ public function handle(Request $request) 'force_raw' => $problem['extra']['forceRaw'], 'partial' => $problem['extra']['partial'] ]; - $pid = ProblemModel::insertGetId($pro); + $pid=ProblemModel::insertGetId($pro); //migrate sample - $sample_count = 0; - foreach($problem['sample'] as $sample){ - $sam = [ + $sample_count=0; + foreach ($problem['sample'] as $sample) { + $sam=[ 'pid' => $pid, 'sample_input' => $sample['input'], 'sample_output' => $sample['output'], ]; - $psid = DB::table('problem_sample')->insert($sam); - $sample_count += 1; + $psid=DB::table('problem_sample')->insert($sam); + $sample_count+=1; } //create test case file - if(Storage::exists(storage_path().'/test_case/'.$pro['pcode'])){ + if (Storage::exists(storage_path().'/test_case/'.$pro['pcode'])) { Storage::deleteDirectory(storage_path().'/test_case/'.$pro['pcode']); } Storage::makeDirectory(storage_path().'/test_case/'.$pro['pcode']); - $test_case_count = 0; - $test_case_info = [ + $test_case_count=0; + $test_case_info=[ 'spj' => false, 'test_cases' => [] ]; - foreach($problem['testCases'] as $test_case){ - $test_case_count += 1; - $test_case_arr = [ + foreach ($problem['testCases'] as $test_case) { + $test_case_count+=1; + $test_case_arr=[ 'input_name' => "data{$test_case_count}.in", 'output_name' => "data{$test_case_count}.out", 'input_size' => strlen($test_case['input']), 'output_size' => strlen($test_case['output']), 'stripped_output_md5' => md5(trim($test_case['output'])) ]; - array_push($test_case_info['test_cases'],$test_case_arr); + array_push($test_case_info['test_cases'], $test_case_arr); Storage::disk('test_case')->put('/'.$pro['pcode'].'/'.$test_case_arr['input_name'], $test_case['input']); Storage::disk('test_case')->put('/'.$pro['pcode'].'/'.$test_case_arr['output_name'], $test_case['output']); } Storage::disk('test_case')->put('/'.$pro['pcode'].'/info', json_encode($test_case_info)); //migrate solutions - $solution_count = 0; - foreach($problem['solution'] as $solution) { - $s = [ + $solution_count=0; + foreach ($problem['solution'] as $solution) { + $s=[ 'uid' => 1, 'pid' => $pid, 'content' => '``` '.$solution['source'], @@ -152,10 +152,10 @@ public function handle(Request $request) 'created_at' => date('Y-m-d H:i:s') ]; DB::table('problem_solution')->insert($s); - $solution_count += 1; + $solution_count+=1; } - $success_message .= '    '. + $success_message.='    '. $pro['pcode'].': " '.$title.'" with '.$sample_count.' samples, @@ -163,7 +163,7 @@ public function handle(Request $request) '.$solution_count.' solutions
'; } - admin_success('Import successfully',$success_message); + admin_success('Import successfully', $success_message); return back(); } diff --git a/app/Admin/menu.json b/app/Admin/menu.json index e370fae60..0bb4c1c28 100644 --- a/app/Admin/menu.json +++ b/app/Admin/menu.json @@ -3,7 +3,7 @@ "id": 1, "parent_id": 0, "order": 1, - "title": "Index", + "title": "admin.menu_titles.dashboard", "icon": "MDI view-dashboard", "uri": "\/", "permission": null, @@ -15,7 +15,7 @@ "id": 2, "parent_id": 0, "order": 2, - "title": "Admin", + "title": "admin.menu_titles.adminCatg", "icon": "MDI clipboard-check", "uri": "", "permission": null, @@ -27,7 +27,7 @@ "id": 3, "parent_id": 2, "order": 3, - "title": "Users", + "title": "admin.menu_titles.users", "icon": "MDI account-settings-variant", "uri": "auth\/users", "permission": null, @@ -39,7 +39,7 @@ "id": 15, "parent_id": 2, "order": 15, - "title": "Abuses", + "title": "admin.menu_titles.abuses", "icon": "MDI alert-circle-outline", "uri": "\/abuses", "permission": null, @@ -53,7 +53,7 @@ "id": 8, "parent_id": 0, "order": 8, - "title": "Users", + "title": "admin.menu_titles.users", "icon": "MDI account", "uri": "\/users", "permission": null, @@ -61,11 +61,23 @@ "updated_at": "2019-04-10 17:01:18", "roles": [] }, + { + "id": 33, + "parent_id": 0, + "order": 8, + "title": "admin.menu_titles.announcements", + "icon": "MDI newspaper", + "uri": "\/announcements", + "permission": null, + "created_at": "2019-04-10 16:45:06", + "updated_at": "2019-04-10 17:01:18", + "roles": [] + }, { "id": 9, "parent_id": 0, "order": 9, - "title": "Problems", + "title": "admin.menu_titles.problemsCatg", "icon": "MDI book-multiple", "uri": "", "permission": null, @@ -77,7 +89,7 @@ "id": 9, "parent_id": 0, "order": 9, - "title": "Problems", + "title": "admin.menu_titles.problems", "icon": "MDI apple-keyboard-command", "uri": "\/problems", "permission": null, @@ -89,7 +101,7 @@ "id": 27, "parent_id": 0, "order": 27, - "title": "Solutions", + "title": "admin.menu_titles.solutions", "icon": "MDI comment-check-outline", "uri": "\/solutions?audit=0&per_page=30", "permission": null, @@ -103,7 +115,7 @@ "id": 10, "parent_id": 0, "order": 10, - "title": "Submissions", + "title": "admin.menu_titles.submissions", "icon": "MDI bookmark-outline", "uri": "\/submissions", "permission": null, @@ -115,7 +127,7 @@ "id": 11, "parent_id": 0, "order": 11, - "title": "Contests", + "title": "admin.menu_titles.contests", "icon": "MDI trophy-variant", "uri": "\/contests", "permission": null, @@ -127,7 +139,7 @@ "id": 12, "parent_id": 0, "order": 12, - "title": "Groups", + "title": "admin.menu_titles.groups", "icon": "MDI account-multiple", "uri": "\/groups", "permission": null, @@ -135,11 +147,85 @@ "updated_at": "2019-04-10 17:01:18", "roles": [] }, + { + "id": 28, + "parent_id": 0, + "order": 12, + "title": "admin.menu_titles.dojoCatg", + "icon": "MDI coffee", + "uri": "", + "permission": null, + "created_at": "2019-04-10 17:00:09", + "updated_at": "2019-04-10 17:01:18", + "roles": [], + "children": [ + { + "id": 31, + "parent_id": 28, + "order": 31, + "title": "admin.menu_titles.dojos", + "icon": "MDI coffee-outline", + "uri": "dojos", + "permission": null, + "created_at": "2019-04-11 12:53:03", + "updated_at": "2019-04-12 09:30:12", + "roles": [] + }, + { + "id": 32, + "parent_id": 28, + "order": 32, + "title": "admin.menu_titles.dojophases", + "icon": "MDI coffee-to-go", + "uri": "dojophases", + "permission": null, + "created_at": "2019-04-11 12:53:03", + "updated_at": "2019-04-12 09:30:12", + "roles": [] + } + ] + }, + { + "id": 29, + "parent_id": 0, + "order": 12, + "title": "admin.menu_titles.judgeserver", + "icon": "MDI server-network", + "uri": "\/judge-server", + "permission": null, + "created_at": "2019-04-10 17:00:09", + "updated_at": "2019-04-10 17:01:18", + "roles": [] + }, + { + "id": 30, + "parent_id": 0, + "order": 12, + "title": "admin.menu_titles.judger", + "icon": "MDI web", + "uri": "\/judger", + "permission": null, + "created_at": "2019-04-10 17:00:09", + "updated_at": "2019-04-10 17:01:18", + "roles": [] + }, + { + "id": 34, + "parent_id": 0, + "order": 12, + "title": "admin.menu_titles.tester", + "icon": "MDI test-tube", + "uri": "\/codetester", + "permission": null, + "created_at": "2019-04-10 17:00:09", + "updated_at": "2019-04-10 17:01:18", + "roles": [] + }, { "id": 13, "parent_id": 0, "order": 13, - "title": "Helpers", + "title": "admin.menu_titles.helpers", "icon": "MDI settings-box", "uri": "", "permission": null, @@ -151,7 +237,7 @@ "id": 14, "parent_id": 13, "order": 14, - "title": "Scaffold", + "title": "admin.menu_titles.scaffold", "icon": "MDI keyboard", "uri": "helpers\/scaffold", "permission": null, @@ -163,7 +249,7 @@ "id": 15, "parent_id": 13, "order": 15, - "title": "Database terminal", + "title": "admin.menu_titles.database", "icon": "MDI database", "uri": "helpers\/terminal\/database", "permission": null, @@ -175,7 +261,7 @@ "id": 16, "parent_id": 13, "order": 16, - "title": "Laravel artisan", + "title": "admin.menu_titles.artisan", "icon": "MDI code-tags", "uri": "helpers\/terminal\/artisan", "permission": null, @@ -187,7 +273,7 @@ "id": 17, "parent_id": 13, "order": 17, - "title": "Routes", + "title": "admin.menu_titles.routes", "icon": "MDI view-list", "uri": "helpers\/routes", "permission": null, @@ -201,7 +287,7 @@ "id": 18, "parent_id": 0, "order": 18, - "title": "Log viewer", + "title": "admin.menu_titles.logs", "icon": "MDI alert-circle", "uri": "logs", "permission": null, @@ -213,7 +299,7 @@ "id": 20, "parent_id": 0, "order": 20, - "title": "Media manager", + "title": "admin.menu_titles.media", "icon": "MDI file", "uri": "media", "permission": null, @@ -225,7 +311,7 @@ "id": 21, "parent_id": 0, "order": 21, - "title": "Scheduling", + "title": "admin.menu_titles.scheduling", "icon": "MDI clock", "uri": "scheduling", "permission": null, @@ -237,7 +323,7 @@ "id": 22, "parent_id": 0, "order": 22, - "title": "Backup", + "title": "admin.menu_titles.backup", "icon": "MDI backup-restore", "uri": "backup", "permission": null, @@ -249,7 +335,7 @@ "id": 23, "parent_id": 0, "order": 23, - "title": "Redis Manager", + "title": "admin.menu_titles.redis", "icon": "MDI database", "uri": "redis", "permission": null, @@ -261,7 +347,7 @@ "id": 24, "parent_id": 0, "order": 24, - "title": "Babel Extension", + "title": "admin.menu_titles.babelCatg", "icon": "MDI cube-outline", "uri": "babel", "permission": null, @@ -273,7 +359,7 @@ "id": 25, "parent_id": 24, "order": 25, - "title": "Extension Manager", + "title": "admin.menu_titles.babelinstalled", "icon": "MDI cube-send", "uri": "babel\/installed", "permission": null, @@ -285,7 +371,7 @@ "id": 26, "parent_id": 24, "order": 26, - "title": "Babel Marketspace", + "title": "admin.menu_titles.babelmarketspace", "icon": "MDI store", "uri": "babel\/marketspace", "permission": null, @@ -294,5 +380,17 @@ "roles": [] } ] + }, + { + "id": 35, + "parent_id": 0, + "order": 27, + "title": "admin.menu_titles.settings", + "icon": "MDI settings", + "uri": "settings", + "permission": null, + "created_at": "2019-04-22 13:13:45", + "updated_at": "2019-04-22 13:13:45", + "roles": [] } ] diff --git a/app/Admin/routes.php b/app/Admin/routes.php index 555c18138..725d266ac 100644 --- a/app/Admin/routes.php +++ b/app/Admin/routes.php @@ -10,17 +10,25 @@ 'middleware' => config('admin.route.middleware'), ], function(Router $router) { - $router->get('/', 'HomeController@index'); + $router->get('/', 'HomeController@index')->name('admin.index'); $router->resource('users', UserController::class); + $router->resource('announcements', AnnouncementController::class); $router->get('problems/import', 'ProblemController@import'); $router->resource('problems', ProblemController::class); $router->resource('solutions', SolutionController::class); $router->resource('submissions', SubmissionController::class); $router->resource('contests', ContestController::class); $router->resource('groups', GroupController::class); + $router->resource('dojos', DojoController::class); + $router->resource('dojophases', DojoPhaseController::class); + $router->resource('judge-server', JudgeServerController::class); + $router->resource('judger', JudgerController::class); $router->resource('abuses', AbuseController::class); - Route::group(['prefix' => 'babel'], function (Router $router) { + Route::match(['GET', 'POST'], 'codetester', 'CodeTesterController@tester')->name('admin.codetester.tester'); + Route::match(['GET', 'POST'], 'settings', 'SettingsController@index')->name('admin.settings.index'); + + Route::group(['prefix' => 'babel'], function(Router $router) { $router->get('/', 'BabelController@index')->name('admin.babel.index'); $router->get('installed', 'BabelController@installed')->name('admin.babel.installed'); $router->get('marketspace', 'BabelController@marketspace')->name('admin.babel.marketspace'); diff --git a/app/Babel/Babel.php b/app/Babel/Babel.php index a49ace487..67f6aec23 100644 --- a/app/Babel/Babel.php +++ b/app/Babel/Babel.php @@ -6,6 +6,7 @@ use App\Babel\Judge\Judger; use App\Babel\Synchronize\Synchronizer; use App\Babel\Monit\Monitor; +use App\Babel\TestRun\TestRunner; class Babel { @@ -33,4 +34,9 @@ public function monitor($conf) { return new Monitor($conf); } + + public function testrun($conf) + { + return new TestRunner($conf); + } } diff --git a/app/Babel/Crawl/Crawler.php b/app/Babel/Crawl/Crawler.php index 5dfcd65e3..df0038af5 100644 --- a/app/Babel/Crawl/Crawler.php +++ b/app/Babel/Crawl/Crawler.php @@ -32,7 +32,7 @@ public static function create($conf, $commandLineObject=null) } catch (ErrorException $e) { } catch (Exception $e) { } - $className = "App\\Babel\\Extension\\$name\\$crawlerProvider"; + $className="App\\Babel\\Extension\\$name\\$crawlerProvider"; if (class_exists($className)) { $temp=new $className(); $temp->importCommandLine($commandLineObject); diff --git a/app/Babel/Crawl/CrawlerBase.php b/app/Babel/Crawl/CrawlerBase.php index b8d782c44..0a39b7bca 100644 --- a/app/Babel/Crawl/CrawlerBase.php +++ b/app/Babel/Crawl/CrawlerBase.php @@ -90,11 +90,11 @@ private function _cacheImage($data) if (!isset($data["ori"]) || !isset($data["path"]) || !isset($data["baseurl"]) || !isset($data["space_deli"]) || !isset($data["cookie"])) { throw new Exception("data is not completely exist in cacheImage"); } - $ori = $data["ori"]; - $path = $data["path"]; - $baseurl = $data["baseurl"]; - $space_deli = $data["space_deli"]; - $cookie = $data["cookie"]; + $ori=$data["ori"]; + $path=$data["path"]; + $baseurl=$data["baseurl"]; + $space_deli=$data["space_deli"]; + $cookie=$data["cookie"]; $para["path"]=$path; $para["base"]=$baseurl; @@ -107,7 +107,7 @@ private function _cacheImage($data) $reg="/< *im[a]?g[^>]*src *= *[\"\\']?([^\"\\'>]*)[^>]*>/si"; } - return preg_replace_callback($reg, function ($matches) use ($para) { + return preg_replace_callback($reg, function($matches) use ($para) { global $config; $url=trim($matches[1]); if (stripos($url, "http://")===false && stripos($url, "https://")===false) { @@ -140,24 +140,24 @@ private function _cacheImage($data) public function procInfo($data) { if (isset($data["path"])) { - $path = $data["path"]; + $path=$data["path"]; } else { throw new Exception("path is not exist in data"); } if (isset($data["baseurl"])) { - $baseurl = $data["baseurl"]; + $baseurl=$data["baseurl"]; } else { throw new Exception("baseurl is not exist in data"); } if (isset($data["space_deli"])) { - $space_deli = $data["space_deli"]; + $space_deli=$data["space_deli"]; } else { - $space_deli = true; + $space_deli=true; } if (isset($data["cookie"])) { - $cookie = $data["cookie"]; + $cookie=$data["cookie"]; } else { - $cookie = ""; + $cookie=""; } $this->pro["description"]=$this->_cacheImage($this->pro["description"], $path, $baseurl, $space_deli, $cookie); diff --git a/app/Babel/Extension/noj/JudgeClient.php b/app/Babel/Extension/noj/JudgeClient.php index 66da13e1d..b5bd5d751 100644 --- a/app/Babel/Extension/noj/JudgeClient.php +++ b/app/Babel/Extension/noj/JudgeClient.php @@ -43,8 +43,8 @@ public function judge($src, $language, $testCaseId, $config=[]) 'language_config' => $languageConfig, 'src' => $src, 'test_case_id' => $testCaseId, - 'max_cpu_time' => $languageConfig['compile']['max_cpu_time'], - 'max_memory' => $languageConfig['compile']['max_memory'], + 'max_cpu_time' => is_null($languageConfig['compile']) ?null:$languageConfig['compile']['max_cpu_time'], + 'max_memory' => is_null($languageConfig['compile']) ?null:$languageConfig['compile']['max_memory'], 'spj_version' => null, 'spj_config' => null, 'spj_compile_config' => null, @@ -64,7 +64,7 @@ public function compileSpj($src, $spjVersion, $spjCompileConfig) } public function getLanguageConfigByLanguage($language, $spj=false) { - return $this->getLanguageConfigByKey($language.($spj?'_lang_spj_config':'_lang_config')); + return $this->getLanguageConfigByKey($language.($spj ? '_lang_spj_config' : '_lang_config')); } public function getLanguageConfigByKey($key) { diff --git a/app/Babel/Extension/noj/Languages.php b/app/Babel/Extension/noj/Languages.php index b3e11dbcf..a81fce10b 100644 --- a/app/Babel/Extension/noj/Languages.php +++ b/app/Babel/Extension/noj/Languages.php @@ -14,7 +14,7 @@ public static function get() 'max_cpu_time' => 3000, 'max_real_time' => 10000, 'max_memory' => 1024 * 1024 * 1024, - 'compile_command' => '/usr/bin/gcc -DONLINE_JUDGE -O2 -w -fmax-errors=3 -std=c99 -static {src_path} -lm -o {exe_path}', + 'compile_command' => '/usr/bin/gcc -DONLINE_JUDGE -O2 -w -fmax-errors=3 -std=c99 {src_path} -lm -o {exe_path}', ], 'run' => [ 'command' => '{exe_path}', @@ -50,6 +50,7 @@ public static function get() 'run' => [ 'command' => '{exe_path}', 'seccomp_rule' => 'c_cpp', + 'env' => $default_env, 'memory_limit_check_only' => 1 ] ], @@ -64,7 +65,7 @@ public static function get() 'compile_command' => '/usr/bin/javac {src_path} -d {exe_dir} -encoding UTF8' ], 'run' => [ - 'command' => '/usr/bin/java -cp {exe_dir} -Xss1M -Xms16M -Xmx{max_memory}k -Djava.security.manager -Djava.security.policy==/etc/java_policy -Djava.awt.headless=true Main', + 'command' => '/usr/bin/java -cp {exe_dir} -XX:MaxRAM={max_memory}k -Djava.security.manager -Dfile.encoding=UTF-8 -Djava.security.policy==/etc/java_policy -Djava.awt.headless=true Main', 'seccomp_rule' => null, 'env' => $default_env, 'memory_limit_check_only' => 1 @@ -81,7 +82,7 @@ public static function get() ], 'run' => [ 'command' => '/usr/bin/python {exe_path}', - 'seccomp_rule' => null, + 'seccomp_rule' => 'general', 'env' => $default_env ] ], @@ -97,14 +98,14 @@ public static function get() 'run' => [ 'command' => '/usr/bin/python3.7 {exe_path}', 'seccomp_rule' => 'general', - 'env' => array_merge(['MALLOC_ARENA_MAX=1'], $default_env) + 'env' => array_merge(['MALLOC_ARENA_MAX=1', 'PYTHONIOENCODING=UTF-8'], $default_env) ] ], 'php7_lang_config' => [ 'compile' => null, 'run' => [ 'exe_name' => 'solution.php', - 'command' => '/usr/bin/php {exe_path}', + 'command' => '/usr/bin/php -d error_reporting=0 -f {exe_path}', 'seccomp_rule' => null, 'env' => $default_env, 'memory_limit_check_only' => 1 @@ -120,21 +121,118 @@ public static function get() ] ], 'go_lang_config' => [ - 'name' => 'go', 'compile' => [ 'src_name' => 'main.go', 'exe_name' => 'main', 'max_cpu_time' => 3000, 'max_real_time' => 10000, - 'max_memory' => 1024 * 1024 * 1024, + 'max_memory' => -1, 'compile_command' => '/usr/bin/go build -o {exe_path} {src_path}', + 'env' => ["GOCACHE=/tmp", "GOPATH=/root/go"] ], 'run' => [ 'command' => '{exe_path}', + 'seccomp_rule' => "", + 'env' => array_merge(["GODEBUG=madvdontneed=1", "GOCACHE=off"], $default_env), + 'memory_limit_check_only' => 1 + ] + ], + 'csharp_lang_config' => [ + 'compile' => [ + 'src_name' => 'main.cs', + 'exe_name' => 'main', + 'max_cpu_time' => 3000, + 'max_real_time' => 10000, + 'max_memory' => 1024 * 1024 * 1024, + 'compile_command' => '/usr/bin/mcs -optimize+ -out:{exe_path} {src_path}' + ], + 'run' => [ + 'command' => '/usr/bin/mono {exe_path}', 'seccomp_rule' => null, + 'env' => $default_env, + 'memory_limit_check_only' => 1 + ] + ], + 'ruby_lang_config' => [ + 'compile' => null, + 'run' => [ + 'exe_name' => 'solution.rb', + 'command' => '/usr/bin/ruby {exe_path}', + 'seccomp_rule' => null, + 'memory_limit_check_only' => 1 + ] + ], + 'rust_lang_config' => [ + 'compile' => [ + 'src_name' => 'main.rs', + 'exe_name' => 'main', + 'max_cpu_time' => 3000, + 'max_real_time' => 10000, + 'max_memory' => 1024 * 1024 * 1024, + 'compile_command' => '/usr/bin/rustc -O -o {exe_path} {src_path}' + ], + 'run' => [ + 'command' => '{exe_path}', + 'seccomp_rule' => "general", + 'env' => $default_env, + 'memory_limit_check_only' => 1 + ] + ], + 'haskell_lang_config' => [ + 'compile' => [ + 'src_name' => 'main.hs', + 'exe_name' => 'main', + 'max_cpu_time' => 3000, + 'max_real_time' => 10000, + 'max_memory' => 1024 * 1024 * 1024, + 'compile_command' => '/usr/bin/ghc -O -outputdir /tmp -o {exe_path} {src_path}' + ], + 'run' => [ + 'command' => '{exe_path}', + 'seccomp_rule' => "general", + 'env' => $default_env, + 'memory_limit_check_only' => 1 + ] + ], + 'pascal_lang_config' => [ + 'compile' => [ + 'src_name' => 'main.pas', + 'exe_name' => 'main', + 'max_cpu_time' => 3000, + 'max_real_time' => 10000, + 'max_memory' => 1024 * 1024 * 1024, + 'compile_command' => '/usr/bin/fpc -O2 -o{exe_path} {src_path}' + ], + 'run' => [ + 'command' => '{exe_path}', + 'seccomp_rule' => "general", + 'env' => $default_env + ] + ], + 'plaintext_lang_config' => [ + 'compile' => null, + 'run' => [ + 'exe_name' => 'solution.txt', + 'command' => '/bin/cat {exe_path}', + 'seccomp_rule' => "general", + 'memory_limit_check_only' => 1 + ] + ], + 'basic_lang_config' => [ + 'compile' => [ + 'src_name' => 'main.bas', + 'exe_name' => 'main', + 'max_cpu_time' => 3000, + 'max_real_time' => 10000, + 'max_memory' => 1024 * 1024 * 1024, + 'compile_command' => '/usr/local/bin/fbc {src_path}' + ], + 'run' => [ + 'command' => '{exe_path}', + 'seccomp_rule' => "general", 'env' => $default_env ] - ] + ], ]; } } diff --git a/app/Babel/Extension/noj/Monitor.php b/app/Babel/Extension/noj/Monitor.php index a4de7d096..2eee6ef4d 100644 --- a/app/Babel/Extension/noj/Monitor.php +++ b/app/Babel/Extension/noj/Monitor.php @@ -5,6 +5,7 @@ use App\Models\OJModel; use App\Models\JudgerModel; use Exception; +use Log; class Monitor extends MonitorBase { @@ -79,7 +80,7 @@ private function ping($url, $port, $token) curl_close($curl); if ($err) { - \Log::error($err); + Log::error($err); return []; } else { return [ diff --git a/app/Babel/Extension/noj/Submitter.php b/app/Babel/Extension/noj/Submitter.php index 1306cd7cd..51ec4e8ed 100644 --- a/app/Babel/Extension/noj/Submitter.php +++ b/app/Babel/Extension/noj/Submitter.php @@ -80,7 +80,7 @@ public function submit() "spj_compile_config" => null, "spj_src" => null ]; - if($probBasic["spj"] && $probBasic["spj_version"]){ + if ($probBasic["spj"] && $probBasic["spj_version"]) { $submit_data["spj_version"]=$probBasic["spj_version"]; $submit_data["spj_config"]=$probBasic["spj_lang"]; $submit_data["spj_compile_config"]=[ @@ -177,7 +177,7 @@ public function submit() $tempTime=max($tempTime, $t["cpu_time"]); } $this->sub['verdict']="Accepted"; - $this->sub['score']=1; + // $this->sub['score']=1; $this->sub['time']=$tempTime; $this->sub['memory']=round($tempMemory / 1024); } diff --git a/app/Babel/Extension/noj/TestRunner.php b/app/Babel/Extension/noj/TestRunner.php new file mode 100644 index 000000000..9c79cf9ef --- /dev/null +++ b/app/Babel/Extension/noj/TestRunner.php @@ -0,0 +1,120 @@ + "Compile Error", + -1 => "Wrong Answer", + 0 => "Accepted", + 1 => "Time Limit Exceed", + 2 => "Real Time Limit Exceed", + 3 => "Memory Limit Exceed", + 4 => "Runtime Error", + 5 => "System Error", + 6 => "Pending", + 7 => "Judging", + 8 => "Partially Accepted" + ]; + + public function __construct($config) + { + $this->oid=OJModel::oid($this->ocode); + $this->pid=$config['pid']; + $this->coid=$config['coid']; + $this->solution=$config['solution']; + } + + public function run() + { + $judgerModel=new JudgerModel(); + $compilerModel=new CompilerModel(); + $problemModel=new ProblemModel(); + $language=$compilerModel->detail($this->coid)['lcode']; + $bestServer=$judgerModel->server($this->oid); + if (is_null($bestServer)) { + $this->verdict=[ + "verdict"=>"Compile Error", + "compile_info"=>"No Available Judger.", + "data"=>[] + ]; + return; + } + $probBasic=$problemModel->basic($this->pid); + $submitURL="http://".$bestServer["host"].":".$bestServer["port"]; + $submit_data=[ + "solution" => $this->solution, + "language" => $language, + "max_cpu_time" => $probBasic["time_limit"] * ($language=="java" ? 3 : 1), + "max_memory" => $probBasic["memory_limit"] * 1024, + "test_case_id" => $probBasic["pcode"], + "token" => $bestServer["token"], + "spj_version" => null, + "spj_config" => null, + "spj_compile_config" => null, + "spj_src" => null + ]; + if ($probBasic["spj"] && $probBasic["spj_version"]) { + $submit_data["spj_version"]=$probBasic["spj_version"]; + $submit_data["spj_config"]=$probBasic["spj_lang"]; + $submit_data["spj_compile_config"]=[ + "src_name" => "spj-{spj_version}.c", + "exe_name" => "spj-{spj_version}", + "max_cpu_time" => 3000, + "max_real_time" => 5000, + "max_memory" => 1073741824, + "compile_command" => "/usr/bin/gcc -DONLINE_JUDGE -O2 -w -fmax-errors=3 -std=c99 {src_path} -lm -o {exe_path}" + ]; // fixed at C99, future linked with spj_lang + $submit_data["spj_src"]=$probBasic["spj_src"]; + } + $judgeClient=new JudgeClient($submit_data["token"], $submitURL); + $temp=$judgeClient->judge($submit_data["solution"], $submit_data["language"], $submit_data["test_case_id"], [ + 'output' => false, + 'max_cpu_time'=>$submit_data['max_cpu_time'], + 'max_memory'=>$submit_data['max_memory'], + 'spj_version'=>$submit_data['spj_version'], + 'spj_config'=>$submit_data['spj_config'], + 'spj_compile_config'=>$submit_data['spj_compile_config'], + 'spj_src'=>$submit_data['spj_src'] + ]); + if (!is_null($temp["err"])) { + if (strpos($temp["data"], 'Compiler runtime error, info: ')!==false) { + $tempRes=json_decode(explode('Compiler runtime error, info: ', $temp["data"])[1], true); + $this->verdict['verdict']=$this->verdictDict[$tempRes["result"]]; + $this->verdict['compile_info']=null; + } else { + $this->verdict['verdict']=$this->verdictDict["-2"]; + $this->verdict['compile_info']=$temp["data"]; + } + $this->verdict['data']=[]; + return $this->verdict; + } + + $this->verdict['verdict']="Accepted"; + foreach ($temp["data"] as $record) { + if ($record["result"]) { + // well... WA or anyway + $this->verdict['verdict']=$this->verdictDict[$record["result"]]; + break; + } + } + + $this->verdict['data']=$temp["data"]; + $this->verdict['compile_info']=null; + foreach ($this->verdict['data'] as &$record) { + $record["result"]=$this->verdictDict[$record["result"]]; + } + return $this->verdict; + } +} diff --git a/app/Babel/Extension/noj/babel.json b/app/Babel/Extension/noj/babel.json index 01aa616a6..0d7c44412 100644 --- a/app/Babel/Extension/noj/babel.json +++ b/app/Babel/Extension/noj/babel.json @@ -14,7 +14,8 @@ "provider": { "submitter": "Submitter", "installer": "Installer", - "monitor": "Monitor" + "monitor": "Monitor", + "testrunner": "TestRunner" }, "require": { "NOJ": "__cur__" diff --git a/app/Babel/Extension/noj/compiler/1616243142.json b/app/Babel/Extension/noj/compiler/1616243142.json new file mode 100644 index 000000000..34fc8b7b3 --- /dev/null +++ b/app/Babel/Extension/noj/compiler/1616243142.json @@ -0,0 +1,10 @@ +{ + "modifications":[{ + "code":"csharp", + "compability":"csharp", + "language":"csharp", + "icon":"devicon-csharp-plain", + "display":"C#", + "method":"add" + }] +} diff --git a/app/Babel/Extension/noj/compiler/1616298361.json b/app/Babel/Extension/noj/compiler/1616298361.json new file mode 100644 index 000000000..27e45055f --- /dev/null +++ b/app/Babel/Extension/noj/compiler/1616298361.json @@ -0,0 +1,17 @@ +{ + "modifications":[{ + "code":"ruby", + "compability":"ruby", + "language":"ruby", + "icon":"devicon-ruby-plain", + "display":"Ruby", + "method":"add" + },{ + "code":"rust", + "compability":"rust", + "language":"rust", + "icon":"devicon-rust-plain", + "display":"Rust", + "method":"add" + }] +} diff --git a/app/Babel/Extension/noj/compiler/1616485388.json b/app/Babel/Extension/noj/compiler/1616485388.json new file mode 100644 index 000000000..a2d4386b5 --- /dev/null +++ b/app/Babel/Extension/noj/compiler/1616485388.json @@ -0,0 +1,10 @@ +{ + "modifications":[{ + "code":"haskell", + "compability":"haskell", + "language":"haskell", + "icon":"devicon-haskell-plain", + "display":"Haskell", + "method":"add" + }] +} diff --git a/app/Babel/Extension/noj/compiler/1616512951.json b/app/Babel/Extension/noj/compiler/1616512951.json new file mode 100644 index 000000000..803a0d9d6 --- /dev/null +++ b/app/Babel/Extension/noj/compiler/1616512951.json @@ -0,0 +1,10 @@ +{ + "modifications":[{ + "code":"pascal", + "compability":"pascal", + "language":"pascal", + "icon":"devicon-devicon-plain", + "display":"Free Pascal", + "method":"add" + }] +} diff --git a/app/Babel/Extension/noj/compiler/1616514412.json b/app/Babel/Extension/noj/compiler/1616514412.json new file mode 100644 index 000000000..065a808a4 --- /dev/null +++ b/app/Babel/Extension/noj/compiler/1616514412.json @@ -0,0 +1,10 @@ +{ + "modifications":[{ + "code":"plaintext", + "compability":"plaintext", + "language":"plaintext", + "icon":"devicon-vim-plain", + "display":"Plain Text", + "method":"add" + }] +} diff --git a/app/Babel/Extension/noj/compiler/1616557725.json b/app/Babel/Extension/noj/compiler/1616557725.json new file mode 100644 index 000000000..e28035886 --- /dev/null +++ b/app/Babel/Extension/noj/compiler/1616557725.json @@ -0,0 +1,7 @@ +{ + "modifications":[{ + "code":"pascal", + "icon":"langicon-delphi", + "method":"modify" + }] +} diff --git a/app/Babel/Extension/noj/compiler/1616566374.json b/app/Babel/Extension/noj/compiler/1616566374.json new file mode 100644 index 000000000..1ccc94677 --- /dev/null +++ b/app/Babel/Extension/noj/compiler/1616566374.json @@ -0,0 +1,10 @@ +{ + "modifications":[{ + "code":"basic", + "compability":"basic", + "language":"vb", + "icon":"langicon-basic", + "display":"Free Basic", + "method":"add" + }] +} diff --git a/app/Babel/Install/InstallerBase.php b/app/Babel/Install/InstallerBase.php index 88b61e491..6fb2c276c 100644 --- a/app/Babel/Install/InstallerBase.php +++ b/app/Babel/Install/InstallerBase.php @@ -39,8 +39,8 @@ protected function _install($ocode) //writing database $this->transactionDB(); - }catch(Throwable $e){ - if ($e->getMessage()!==""){ + } catch (Throwable $e) { + if ($e->getMessage()!=="") { $this->command->line("\n {$e->getMessage()} \n"); } } @@ -59,12 +59,12 @@ protected function _uninstall($ocode) public function __construct($class) { $this->command=$class; - $this->versionParser = new VersionConstraintParser(); + $this->versionParser=new VersionConstraintParser(); } private function parseVersion() { - if(empty($this->babelConfig)){ + if (empty($this->babelConfig)) { throw new Exception('Missing babel.json Config file.'); } @@ -134,7 +134,7 @@ private function transactionDB() DB::commit(); - }catch(Throwable $e){ + } catch (Throwable $e) { DB::rollback(); if ($e->getMessage()!=="") { $this->command->line("\n {$e->getMessage()} \n"); diff --git a/app/Babel/Install/InstallerWorker.php b/app/Babel/Install/InstallerWorker.php index 3683b0863..34428ce3d 100644 --- a/app/Babel/Install/InstallerWorker.php +++ b/app/Babel/Install/InstallerWorker.php @@ -84,9 +84,9 @@ public function importCompilerInfo($info) $installed_timestamp=intval($info["compiler_timestamp"]); } $latest_timestamp=$installed_timestamp; - $ConpilerConfig = glob(babel_path("Extension/$ocode/compiler/*.*")); + $ConpilerConfig=glob(babel_path("Extension/$ocode/compiler/*.*")); foreach ($ConpilerConfig as $file) { - if (intval(basename($file)) > $installed_timestamp) { + if (intval(basename($file))>$installed_timestamp) { try { $this->commitCompiler($file, json_decode(file_get_contents($file), true)); $latest_timestamp=intval(basename($file)); diff --git a/app/Babel/Judge/Judger.php b/app/Babel/Judge/Judger.php index e871b6527..aadb94b79 100644 --- a/app/Babel/Judge/Judger.php +++ b/app/Babel/Judge/Judger.php @@ -56,7 +56,7 @@ public static function create($ocode) } catch (ErrorException $e) { } catch (Exception $e) { } - $className = "App\\Babel\\Extension\\$name\\$judgerProvider"; + $className="App\\Babel\\Extension\\$name\\$judgerProvider"; if (class_exists($className)) { return new $className(); } else { diff --git a/app/Babel/Monit/Monitor.php b/app/Babel/Monit/Monitor.php index 55f5aa64b..206b44de9 100644 --- a/app/Babel/Monit/Monitor.php +++ b/app/Babel/Monit/Monitor.php @@ -33,7 +33,7 @@ public static function create($conf) } catch (ErrorException $e) { } catch (Exception $e) { } - $className = "App\\Babel\\Extension\\$name\\$monitorProvider"; + $className="App\\Babel\\Extension\\$name\\$monitorProvider"; if (class_exists($className)) { return new $className(); } else { diff --git a/app/Babel/Monit/MonitorBase.php b/app/Babel/Monit/MonitorBase.php index ad18c3985..d16bc53cf 100644 --- a/app/Babel/Monit/MonitorBase.php +++ b/app/Babel/Monit/MonitorBase.php @@ -2,7 +2,7 @@ namespace App\Babel\Monit; -use App\Models\Eloquent\JudgeServerModel; +use App\Models\Eloquent\JudgeServer; use ErrorException; use Exception; use Throwable; @@ -11,7 +11,7 @@ class MonitorBase { public function updateStatus($jsid, $status, $usage=null) { - $judgeServer=JudgeServerModel::find($jsid); + $judgeServer=JudgeServer::find($jsid); if (is_null($judgeServer)) { return false; } else { diff --git a/app/Babel/Submit/Curl.php b/app/Babel/Submit/Curl.php index 7ab846050..c05c1c212 100644 --- a/app/Babel/Submit/Curl.php +++ b/app/Babel/Submit/Curl.php @@ -18,11 +18,11 @@ public function __construct() public function login($all_data) { - if(isset($all_data["url"])) $url = $all_data["url"]; else throw new Exception("url is not exist in all_data"); - if(isset($all_data["data"])) $data = $all_data["data"]; else throw new Exception("data is not exist in all_data"); - if(isset($all_data["oj"])) $oj = $all_data["oj"]; else throw new Exception("oj is not exist in all_data"); - if(isset($all_data["ret"])) $ret = $all_data["ret"]; else $ret = 'false'; - if(isset($all_data["handle"])) $handle = $all_data["handle"]; else $handle = "default"; + if (isset($all_data["url"])) $url=$all_data["url"]; else throw new Exception("url is not exist in all_data"); + if (isset($all_data["data"])) $data=$all_data["data"]; else throw new Exception("data is not exist in all_data"); + if (isset($all_data["oj"])) $oj=$all_data["oj"]; else throw new Exception("oj is not exist in all_data"); + if (isset($all_data["ret"])) $ret=$all_data["ret"]; else $ret='false'; + if (isset($all_data["handle"])) $handle=$all_data["handle"]; else $handle="default"; $datapost=curl_init(); $headers=array("Expect:"); @@ -54,12 +54,12 @@ public function login($all_data) public function grab_page($all_data) { - if(isset($all_data["site"])) $site = $all_data["site"]; else throw new Exception("site is not exist in all_data"); - if(isset($all_data["oj"])) $oj = $all_data["oj"]; else throw new Exception("oj is not exist in all_data"); - if(isset($all_data["headers"])) $headers = $all_data["headers"]; else $headers = []; - if(isset($all_data["handle"])) $handle = $all_data["handle"]; else $handle = "default"; - if(isset($all_data["follow"])) $follow = $all_data["follow"]; else $follow = false; - if(isset($all_data["vcid"])) $vcid = $all_data["vcid"]."_"; else $vcid = ""; + if (isset($all_data["site"])) $site=$all_data["site"]; else throw new Exception("site is not exist in all_data"); + if (isset($all_data["oj"])) $oj=$all_data["oj"]; else throw new Exception("oj is not exist in all_data"); + if (isset($all_data["headers"])) $headers=$all_data["headers"]; else $headers=[]; + if (isset($all_data["handle"])) $handle=$all_data["handle"]; else $handle="default"; + if (isset($all_data["follow"])) $follow=$all_data["follow"]; else $follow=false; + if (isset($all_data["vcid"])) $vcid=$all_data["vcid"]."_"; else $vcid=""; $handle=urlencode($handle); @@ -86,16 +86,16 @@ public function grab_page($all_data) public function post_data($all_data) { - if(isset($all_data["site"])) $site = $all_data["site"]; else throw new Exception("site is not exist in all_data"); - if(isset($all_data["data"])) $data = $all_data["data"]; else throw new Exception("data is not exist in all_data"); - if(isset($all_data["oj"])) $oj = $all_data["oj"]; else throw new Exception("oj is not exist in all_data"); - if(isset($all_data["ret"])) $ret = $all_data["ret"]; else $ret = false; - if(isset($all_data["follow"])) $follow = $all_data["follow"]; else $follow = true; - if(isset($all_data["returnHeader"])) $returnHeader = $all_data["returnHeader"]; else $returnHeader = true; - if(isset($all_data["postJson"])) $postJson = $all_data["postJson"]; else $postJson = false; - if(isset($all_data["extraHeaders"])) $extraHeaders = $all_data["extraHeaders"]; else $extraHeaders = []; - if(isset($all_data["handle"])) $handle = $all_data["handle"]; else $handle = "default"; - if(isset($all_data["vcid"])) $vcid = $all_data["vcid"]."_"; else $vcid = ""; + if (isset($all_data["site"])) $site=$all_data["site"]; else throw new Exception("site is not exist in all_data"); + if (isset($all_data["data"])) $data=$all_data["data"]; else throw new Exception("data is not exist in all_data"); + if (isset($all_data["oj"])) $oj=$all_data["oj"]; else throw new Exception("oj is not exist in all_data"); + if (isset($all_data["ret"])) $ret=$all_data["ret"]; else $ret=false; + if (isset($all_data["follow"])) $follow=$all_data["follow"]; else $follow=true; + if (isset($all_data["returnHeader"])) $returnHeader=$all_data["returnHeader"]; else $returnHeader=true; + if (isset($all_data["postJson"])) $postJson=$all_data["postJson"]; else $postJson=false; + if (isset($all_data["extraHeaders"])) $extraHeaders=$all_data["extraHeaders"]; else $extraHeaders=[]; + if (isset($all_data["handle"])) $handle=$all_data["handle"]; else $handle="default"; + if (isset($all_data["vcid"])) $vcid=$all_data["vcid"]."_"; else $vcid=""; $handle=urlencode($handle); diff --git a/app/Babel/Submit/Submitter.php b/app/Babel/Submit/Submitter.php index a088b48c8..979af9cb5 100644 --- a/app/Babel/Submit/Submitter.php +++ b/app/Babel/Submit/Submitter.php @@ -51,7 +51,7 @@ public static function create($oj, & $sub, $all_data) } catch (ErrorException $e) { } catch (Exception $e) { } - $className = "App\\Babel\\Extension\\$oj\\$submitterProvider"; + $className="App\\Babel\\Extension\\$oj\\$submitterProvider"; if (class_exists($className)) { return new $className($sub, $all_data); } else { diff --git a/app/Babel/Synchronize/Synchronizer.php b/app/Babel/Synchronize/Synchronizer.php index 113e20542..586df4025 100644 --- a/app/Babel/Synchronize/Synchronizer.php +++ b/app/Babel/Synchronize/Synchronizer.php @@ -23,7 +23,7 @@ public static function create($oj, $all_data) } catch (ErrorException $e) { } catch (Exception $e) { } - $className = "App\\Babel\\Extension\\$oj\\$synchronizerProvider"; + $className="App\\Babel\\Extension\\$oj\\$synchronizerProvider"; if (class_exists($className)) { return new $className($all_data); } else { diff --git a/app/Babel/TestRun/TestRunner.php b/app/Babel/TestRun/TestRunner.php new file mode 100644 index 000000000..928cd7f42 --- /dev/null +++ b/app/Babel/TestRun/TestRunner.php @@ -0,0 +1,39 @@ +verdict=$runner->run(); + } + } + + public static function create($conf) + { + $name=$conf["name"]; + $runnerProvider="TestRunner"; + try { + $BabelConfig=json_decode(file_get_contents(babel_path("Extension/$name/babel.json")), true); + $runnerProvider=$BabelConfig["provider"]["testrunner"]; + } catch (Throwable $e) { + } catch (ErrorException $e) { + } catch (Exception $e) { + } + $className="App\\Babel\\Extension\\$name\\$runnerProvider"; + if (class_exists($className)) { + return new $className($conf); + } else { + return null; + } + } +} diff --git a/app/Babel/spoj b/app/Babel/spoj deleted file mode 160000 index 42b0e099c..000000000 --- a/app/Babel/spoj +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 42b0e099cb9be33011db6afba15384cc0344e31c diff --git a/app/Console/Commands/Babel/BabelCommand.php b/app/Console/Commands/Babel/BabelCommand.php index 7363a3232..76449f1ff 100644 --- a/app/Console/Commands/Babel/BabelCommand.php +++ b/app/Console/Commands/Babel/BabelCommand.php @@ -13,19 +13,19 @@ class BabelCommand extends Command * * @var string */ - protected $signature = 'babel'; + protected $signature='babel'; /** * The console command description. * * @var string */ - protected $description = 'List all babel commands'; + protected $description='List all babel commands'; /** * @var string */ - public static $logo = <<line(static::$logo); - $this->line(sprintf('NOJ version %s',version())); + $this->line(sprintf('NOJ version %s', version())); $this->comment(''); $this->comment('Available commands:'); @@ -57,7 +57,7 @@ public function handle() */ protected function listBabelCommands() { - $commands = collect(Artisan::all())->mapWithKeys(function ($command, $key) { + $commands=collect(Artisan::all())->mapWithKeys(function($command, $key) { if (Str::startsWith($key, 'babel:')) { return [$key => $command]; } @@ -65,7 +65,7 @@ protected function listBabelCommands() return []; })->toArray(); - $width = $this->getColumnWidth($commands); + $width=$this->getColumnWidth($commands); /** @var Command $command */ foreach ($commands as $command) { @@ -80,16 +80,16 @@ protected function listBabelCommands() */ private function getColumnWidth(array $commands) { - $widths = []; + $widths=[]; foreach ($commands as $command) { - $widths[] = static::strlen($command->getName()); + $widths[]=static::strlen($command->getName()); foreach ($command->getAliases() as $alias) { - $widths[] = static::strlen($alias); + $widths[]=static::strlen($alias); } } - return $widths ? max($widths) + 2 : 0; + return $widths ? max($widths)+2 : 0; } /** @@ -101,7 +101,7 @@ private function getColumnWidth(array $commands) */ public static function strlen($string) { - if (false === $encoding = mb_detect_encoding($string, null, true)) { + if (false===$encoding=mb_detect_encoding($string, null, true)) { return strlen($string); } diff --git a/app/Console/Commands/Babel/BabelRequire.php b/app/Console/Commands/Babel/BabelRequire.php index 66c36040f..bb2b119aa 100644 --- a/app/Console/Commands/Babel/BabelRequire.php +++ b/app/Console/Commands/Babel/BabelRequire.php @@ -14,14 +14,14 @@ class BabelRequire extends Command * * @var string */ - protected $signature = 'babel:require {extension : The package name of the extension} {--exception}'; + protected $signature='babel:require {extension : The package name of the extension} {--ignore-platform-reqs : Ignore the Platform Requirements when install} {--exception}'; /** * The console command description. * * @var string */ - protected $description = 'Download a given Babel Extension to NOJ'; + protected $description='Download a given Babel Extension to NOJ'; /** * Create a new command instance. @@ -40,9 +40,10 @@ public function __construct() */ public function handle() { - $extension = $this->argument('extension'); - $exception = $this->option('exception'); - $output = new BufferedOutput(); + $extension=$this->argument('extension'); + $exception=$this->option('exception'); + $ignoreReqs=$this->option('ignore-platform-reqs'); + $output=new BufferedOutput(); if (is_dir(babel_path("Extension/$extension/"))) { if (!$exception) { $this->line("\n Exception : An extension named $extension already took place, did you mean php artisan bable:update $extension?\n"); @@ -74,7 +75,7 @@ public function handle() mkdir(babel_path("Tmp/$extension/")); } try { - $zipFile = new ZipFile(); + $zipFile=new ZipFile(); $zipFile->openFile(babel_path("Tmp/$filename"))->extractTo(babel_path("Tmp/$extension/"))->close(); $babelPath=glob_recursive(babel_path("Tmp/$extension/babel.json")); if (empty($babelPath)) { @@ -108,7 +109,10 @@ public function handle() } $this->postProc($filename, $extension); $this->line("Downloaded $extension({$targetPackage['version']})"); - $this->call("babel:install", ['extension' => $extension]); + $this->call("babel:install", [ + 'extension' => $extension, + '--ignore-platform-reqs' => $ignoreReqs, + ]); $output->fetch(); } @@ -123,8 +127,8 @@ private function delDir($dir) if (!is_dir($dir)) { return; } - $it = new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS); - $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST); + $it=new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS); + $files=new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST); foreach ($files as $file) { if ($file->isDir()) { rmdir($file->getRealPath()); diff --git a/app/Console/Commands/Babel/Crawl.php b/app/Console/Commands/Babel/Crawl.php index 1dd425523..b0be399d6 100644 --- a/app/Console/Commands/Babel/Crawl.php +++ b/app/Console/Commands/Babel/Crawl.php @@ -5,7 +5,6 @@ use Illuminate\Console\Command; use App\Babel\Babel; use Exception; -use function GuzzleHttp\json_decode; class Crawl extends Command { @@ -14,7 +13,7 @@ class Crawl extends Command * * @var string */ - protected $signature = 'babel:crawl + protected $signature='babel:crawl {extension : The package name of the extension} {--action=crawl_problem : The action of the Crawler} {--con=all : The target problemset of the Crawler} @@ -26,7 +25,7 @@ class Crawl extends Command * * @var string */ - protected $description = 'Crawl problems for a given Babel Extension to NOJ'; + protected $description='Crawl problems for a given Babel Extension to NOJ'; /** * Create a new command instance. @@ -45,11 +44,11 @@ public function __construct() */ public function handle() { - $extension = $this->argument('extension'); - $action = $this->option('action'); - $con = $this->option('con'); - [$from, $to] = sscanf($this->option('range'),"%d:%d"); - $cached = $this->option('cached'); + $extension=$this->argument('extension'); + $action=$this->option('action'); + $con=$this->option('con'); + [$from, $to]=sscanf($this->option('range'), "%d:%d"); + $cached=$this->option('cached'); $babel=new Babel(); $babel->crawl([ "name" => $extension, diff --git a/app/Console/Commands/Babel/Install.php b/app/Console/Commands/Babel/Install.php index d53b27aed..ad491091d 100644 --- a/app/Console/Commands/Babel/Install.php +++ b/app/Console/Commands/Babel/Install.php @@ -4,7 +4,6 @@ use Illuminate\Console\Command; use Exception; -use function GuzzleHttp\json_decode; use Symfony\Component\Console\Output\BufferedOutput; class Install extends Command @@ -14,14 +13,14 @@ class Install extends Command * * @var string */ - protected $signature = 'babel:install {extension : The package name of the extension} {--ignore-platform-reqs : Ignore the Platform Requirements when install}'; + protected $signature='babel:install {extension : The package name of the extension} {--ignore-platform-reqs : Ignore the Platform Requirements when install}'; /** * The console command description. * * @var string */ - protected $description = 'Install a given Babel Extension to NOJ'; + protected $description='Install a given Babel Extension to NOJ'; /** * Create a new command instance. @@ -40,16 +39,19 @@ public function __construct() */ public function handle() { - $extension = $this->argument('extension'); - $ignoreReqs = $this->option('ignore-platform-reqs'); - $output = new BufferedOutput(); + $extension=$this->argument('extension'); + $ignoreReqs=$this->option('ignore-platform-reqs'); + $output=new BufferedOutput(); $installerProvider="Installer"; try { $BabelConfig=json_decode(file_get_contents(babel_path("Extension/$extension/babel.json")), true); } catch (Exception $e) { $this->line("\n Exception : babel.json parse error, The extension may not exist.\n"); if ($this->confirm("Would you like to download it from the marketspace first?")) { - $this->call("babel:require", ['extension' => $extension]); + $this->call("babel:require", [ + 'extension' => $extension, + '--ignore-platform-reqs' => $ignoreReqs, + ]); $output->fetch(); } return; @@ -69,7 +71,7 @@ public function handle() public static function create($oj, $installerProvider, $class) { - $className = "App\\Babel\\Extension\\$oj\\$installerProvider"; + $className="App\\Babel\\Extension\\$oj\\$installerProvider"; if (class_exists($className)) { return new $className($class); } else { diff --git a/app/Console/Commands/Babel/Judge.php b/app/Console/Commands/Babel/Judge.php new file mode 100644 index 000000000..6072a9b4f --- /dev/null +++ b/app/Console/Commands/Babel/Judge.php @@ -0,0 +1,52 @@ +line("[$time] Processing: NOJ Babel Judge Sync"); + $babel->judge(); + $time=date("Y-m-d H:i:s"); + $this->line("[$time] Processed: NOJ Babel Judge Sync"); + sleep(5); + } + } +} diff --git a/app/Console/Commands/Babel/RefreshRank.php b/app/Console/Commands/Babel/RefreshRank.php index 3f699aa9a..b88b0b0c4 100644 --- a/app/Console/Commands/Babel/RefreshRank.php +++ b/app/Console/Commands/Babel/RefreshRank.php @@ -5,7 +5,6 @@ use Illuminate\Console\Command; use App\Babel\Babel; use Exception; -use function GuzzleHttp\json_decode; class RefreshRank extends Command { @@ -14,14 +13,14 @@ class RefreshRank extends Command * * @var string */ - protected $signature = 'babel:rerank {extension : The package name of the extension} {--vcid= : The target contest of the Crawler} {--gid=1 : The holding group} {--cid= : The NOJ contest}'; + protected $signature='babel:rerank {extension : The package name of the extension} {--vcid= : The target contest of the Crawler} {--gid=1 : The holding group} {--cid= : The NOJ contest}'; /** * The console command description. * * @var string */ - protected $description = 'Refresh Rank from a remote contest'; + protected $description='Refresh Rank from a remote contest'; /** * Create a new command instance. @@ -40,18 +39,18 @@ public function __construct() */ public function handle() { - $extension = $this->argument('extension'); - $vcid = $this->option('vcid'); - $gid = $this->option('gid'); - $cid = $this->option('cid'); - $className = "App\\Babel\\Extension\\$extension\\Synchronizer"; - $all_data = [ + $extension=$this->argument('extension'); + $vcid=$this->option('vcid'); + $gid=$this->option('gid'); + $cid=$this->option('cid'); + $className="App\\Babel\\Extension\\$extension\\Synchronizer"; + $all_data=[ 'oj'=>$extension, 'vcid'=>$vcid, 'gid'=>$gid, 'cid'=>$cid, ]; - $Sync = new $className($all_data); + $Sync=new $className($all_data); $Sync->crawlRank(); } } diff --git a/app/Console/Commands/Babel/SyncContest.php b/app/Console/Commands/Babel/SyncContest.php index f6a40de4b..fda3f6353 100644 --- a/app/Console/Commands/Babel/SyncContest.php +++ b/app/Console/Commands/Babel/SyncContest.php @@ -5,7 +5,6 @@ use Illuminate\Console\Command; use App\Babel\Babel; use Exception; -use function GuzzleHttp\json_decode; class SyncContest extends Command { @@ -14,14 +13,14 @@ class SyncContest extends Command * * @var string */ - protected $signature = 'babel:sync {extension : The package name of the extension} {--vcid= : The target contest of the Crawler} {--gid=1 : The holding group}'; + protected $signature='babel:sync {extension : The package name of the extension} {--vcid= : The target contest of the Crawler} {--gid=1 : The holding group}'; /** * The console command description. * * @var string */ - protected $description = 'Crawl contests for a given Babel Extension to NOJ'; + protected $description='Crawl contests for a given Babel Extension to NOJ'; /** * Create a new command instance. @@ -40,16 +39,16 @@ public function __construct() */ public function handle() { - $extension = $this->argument('extension'); - $vcid = $this->option('vcid'); - $gid = $this->option('gid'); - $className = "App\\Babel\\Extension\\$extension\\Synchronizer"; - $all_data = [ + $extension=$this->argument('extension'); + $vcid=$this->option('vcid'); + $gid=$this->option('gid'); + $className="App\\Babel\\Extension\\$extension\\Synchronizer"; + $all_data=[ 'oj'=>$extension, 'vcid'=>$vcid, 'gid'=>$gid, ]; - $Sync = new $className($all_data); + $Sync=new $className($all_data); $Sync->crawlContest(); } } diff --git a/app/Console/Commands/Babel/SyncProblems.php b/app/Console/Commands/Babel/SyncProblems.php index 0a893be02..382a0150a 100644 --- a/app/Console/Commands/Babel/SyncProblems.php +++ b/app/Console/Commands/Babel/SyncProblems.php @@ -5,7 +5,6 @@ use Illuminate\Console\Command; use App\Babel\Babel; use Exception; -use function GuzzleHttp\json_decode; class SyncProblems extends Command { @@ -14,14 +13,14 @@ class SyncProblems extends Command * * @var string */ - protected $signature = 'babel:syncpro {extension : The package name of the extension} {--vcid= : The target contest of the Crawler} {--gid= : The holding group} {--cid= : The contest in NOJ}'; + protected $signature='babel:syncpro {extension : The package name of the extension} {--vcid= : The target contest of the Crawler} {--gid= : The holding group} {--cid= : The contest in NOJ}'; /** * The console command description. * * @var string */ - protected $description = 'Crawl contests for a given Babel Extension to NOJ'; + protected $description='Crawl contests for a given Babel Extension to NOJ'; /** * Create a new command instance. @@ -40,18 +39,18 @@ public function __construct() */ public function handle() { - $extension = $this->argument('extension'); - $vcid = $this->option('vcid'); - $gid = $this->option('gid'); - $cid = $this->option('cid'); - $className = "App\\Babel\\Extension\\$extension\\Synchronizer"; - $all_data = [ + $extension=$this->argument('extension'); + $vcid=$this->option('vcid'); + $gid=$this->option('gid'); + $cid=$this->option('cid'); + $className="App\\Babel\\Extension\\$extension\\Synchronizer"; + $all_data=[ 'oj'=>$extension, 'vcid'=>$vcid, 'gid'=>$gid, 'cid'=>$cid, ]; - $Sync = new $className($all_data); + $Sync=new $className($all_data); $Sync->scheduleCrawl(); } } diff --git a/app/Console/Commands/Babel/Uninstall.php b/app/Console/Commands/Babel/Uninstall.php index c4f568178..9522c9098 100644 --- a/app/Console/Commands/Babel/Uninstall.php +++ b/app/Console/Commands/Babel/Uninstall.php @@ -12,14 +12,14 @@ class Uninstall extends Command * * @var string */ - protected $signature = 'babel:uninstall {extension : The package name of the extension}'; + protected $signature='babel:uninstall {extension : The package name of the extension}'; /** * The console command description. * * @var string */ - protected $description = 'Uninstall a given Babel Extension to NOJ'; + protected $description='Uninstall a given Babel Extension to NOJ'; /** * Create a new command instance. @@ -38,7 +38,7 @@ public function __construct() */ public function handle() { - $extension = $this->argument('extension'); + $extension=$this->argument('extension'); $submitter=self::create($extension, $this); if (!is_null($submitter)) { $submitter->uninstall(); @@ -56,7 +56,7 @@ public static function create($oj, $class) } catch (ErrorException $e) { } catch (Exception $e) { } - $className = "App\\Babel\\Extension\\$oj\\$installerProvider"; + $className="App\\Babel\\Extension\\$oj\\$installerProvider"; if (class_exists($className)) { return new $className($class); } else { diff --git a/app/Console/Commands/Babel/Update.php b/app/Console/Commands/Babel/Update.php index a9419dd70..5d5d5759e 100644 --- a/app/Console/Commands/Babel/Update.php +++ b/app/Console/Commands/Babel/Update.php @@ -4,7 +4,6 @@ use Illuminate\Console\Command; use Exception; -use function GuzzleHttp\json_decode; use Symfony\Component\Console\Output\BufferedOutput; class Update extends Command @@ -14,14 +13,14 @@ class Update extends Command * * @var string */ - protected $signature = 'babel:update {extension : The package name of the extension}'; + protected $signature='babel:update {extension : The package name of the extension}'; /** * The console command description. * * @var string */ - protected $description = 'Update a given Babel Extension to NOJ'; + protected $description='Update a given Babel Extension to NOJ'; /** * Create a new command instance. @@ -40,8 +39,8 @@ public function __construct() */ public function handle() { - $extension = $this->argument('extension'); - $output = new BufferedOutput(); + $extension=$this->argument('extension'); + $output=new BufferedOutput(); $this->line("Updating $extension"); try { $BabelConfig=json_decode(file_get_contents(babel_path("Extension/$extension/babel.json")), true); @@ -90,8 +89,8 @@ private function delDir($dir) if (!is_dir($dir)) { return; } - $it = new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS); - $files = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST); + $it=new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS); + $files=new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::CHILD_FIRST); foreach ($files as $file) { if ($file->isDir()) { rmdir($file->getRealPath()); diff --git a/app/Console/Commands/Manage/BanUser.php b/app/Console/Commands/Manage/BanUser.php index 61c097dc1..480d461a4 100644 --- a/app/Console/Commands/Manage/BanUser.php +++ b/app/Console/Commands/Manage/BanUser.php @@ -4,7 +4,7 @@ use Illuminate\Console\Command; use App\Models\Eloquent\UserBanned; -use App\User; +use App\Models\Eloquent\User; class BanUser extends Command { @@ -13,14 +13,14 @@ class BanUser extends Command * * @var string */ - protected $signature = 'manage:ban {--uid=: the user you want to ban} {--time=: Unban time, Supports time that can be resolved by the strtotime method} {--reason=: reason}'; + protected $signature='manage:ban {--uid= : the user you want to ban} {--time= : Unban time, Supports time that can be resolved by the strtotime method} {--reason= : reason}'; /** * The console command description. * * @var string */ - protected $description = 'Ban a user'; + protected $description='Ban a user'; /** * Create a new command instance. @@ -39,23 +39,23 @@ public function __construct() */ public function handle() { - $uid=(int)$this->option('uid'); + $uid=(int) $this->option('uid'); $reason=$this->option('reason'); $time=$this->option('time'); - $user = User::find($uid); - if(empty($user)) { + $user=User::find($uid); + if (empty($user)) { $this->line("\n Exception : User Not Found\n"); return; } - try{ - $ban_time = date('Y-m-d H:i:s',strtotime($time)); + try { + $ban_time=date('Y-m-d H:i:s', strtotime($time)); UserBanned::create([ 'user_id' => $user->id, 'reason' => $reason, 'removed_at' => $ban_time ]); $this->line("The user {$user->name} will be banned until {$ban_time}"); - }catch(Throwable $e){ + } catch (Throwable $e) { $this->line("\n Exception : Wrong Time.\n"); return; } diff --git a/app/Console/Commands/Manage/CreateAdminCommand.php b/app/Console/Commands/Manage/CreateAdminCommand.php index 4043b3129..db050eccb 100644 --- a/app/Console/Commands/Manage/CreateAdminCommand.php +++ b/app/Console/Commands/Manage/CreateAdminCommand.php @@ -11,25 +11,25 @@ class CreateAdminCommand extends Command * * @var string */ - protected $signature = 'manage:create-admin'; + protected $signature='manage:create-admin'; /** * The console command description. * * @var string */ - protected $description = 'Create a admin user'; + protected $description='Create a admin user'; /** * Execute the console command. */ public function handle() { - $userModel = config('admin.database.users_model'); - $username = $this->ask('Please enter a username to login'); - $password = bcrypt($this->secret('Please enter a password to login')); - $name = $this->ask('Please enter a name to display'); - $user = new $userModel(compact('username', 'password', 'name')); + $userModel=config('admin.database.users_model'); + $username=$this->ask('Please enter a username to login'); + $password=bcrypt($this->secret('Please enter a password to login')); + $name=$this->ask('Please enter a name to display'); + $user=new $userModel(compact('username', 'password', 'name')); $user->save(); $this->info("Admin User [$name] created successfully."); } diff --git a/app/Console/Commands/Manage/Permission.php b/app/Console/Commands/Manage/Permission.php new file mode 100644 index 000000000..a89ccdd9e --- /dev/null +++ b/app/Console/Commands/Manage/Permission.php @@ -0,0 +1,126 @@ +option('uid'); + $permission_id=$this->option('permission'); + $action=$this->option('action'); + + if (!in_array($action, ['list', 'grant', 'revoke'])) { + $this->line("\n Exception : Unknown Action\n"); + return; + } + + if ($action=='list') { + $this->listPermission(); + return; + } + + $userInfo=User::find($uid); + if (is_null($userInfo)) { + $this->line("\n Exception : User Not Found\n"); + return; + } + + if (!isset(UserPermission::$permInfo[$permission_id])) { + $this->line("\n Exception : Unknown Permission\n"); + return; + } + $permissionInfo=UserPermission::$permInfo[$permission_id]; + + if ($action=='grant') { + $this->grantPermission($uid, $permission_id, $permissionInfo); + } else { + $this->revokePermission($uid, $permission_id, $permissionInfo); + } + } + + protected function listPermission() + { + $headers=['ID', 'Permission']; + $permInfo=[]; + foreach (UserPermission::$permInfo as $permID=>$permDesc) { + $permInfo[]=[$permID, $permDesc]; + } + $this->table($headers, $permInfo); + } + + protected function grantPermission($uid, $permission_id, $permissionInfo) + { + $this->line("Granting: $permissionInfo"); + + $permissionExists=UserPermission::where([ + 'user_id' => $uid, + 'permission_id' => $permission_id, + ])->count(); + + if (!$permissionExists) { + UserPermission::create([ + 'user_id' => $uid, + 'permission_id' => $permission_id, + ]); + } + + $this->line("Granted: $permissionInfo"); + } + + protected function revokePermission($uid, $permission_id, $permissionInfo) + { + $this->line("Revoking: $permissionInfo"); + + $permissionExists=UserPermission::where([ + 'user_id' => $uid, + 'permission_id' => $permission_id, + ])->count(); + + if ($permissionExists) { + UserPermission::where([ + 'user_id' => $uid, + 'permission_id' => $permission_id, + ])->delete(); + } + + $this->line("Revoked: $permissionInfo"); + } +} diff --git a/app/Console/Commands/Manage/ResetPass.php b/app/Console/Commands/Manage/ResetPass.php index 13cd9c155..63c0cd014 100644 --- a/app/Console/Commands/Manage/ResetPass.php +++ b/app/Console/Commands/Manage/ResetPass.php @@ -4,9 +4,8 @@ use Illuminate\Console\Command; use Exception; -use function GuzzleHttp\json_decode; use Symfony\Component\Console\Output\BufferedOutput; -use App\Models\UserModel; +use App\Models\Eloquent\User; use Illuminate\Support\Str; use Illuminate\Support\Facades\Hash; @@ -17,14 +16,14 @@ class ResetPass extends Command * * @var string */ - protected $signature = 'manage:resetpass {--uid=: the user you want to reset} {--digit=: the number of the password, should be larger than 8}'; + protected $signature='manage:resetpass {--uid= : the user you want to reset} {--digit= : the number of the password, should be larger than 8}'; /** * The console command description. * * @var string */ - protected $description = 'Reset user passwords of NOJ'; + protected $description='Reset user passwords of NOJ'; /** * Create a new command instance. @@ -45,7 +44,7 @@ public function handle() { $uid=$this->option('uid'); $digit=intval($this->option('digit')); - $userInfo=UserModel::find($uid); + $userInfo=User::find($uid); if (is_null($userInfo)) { $this->line("\n Exception : User Not Found\n"); return; diff --git a/app/Console/Commands/upgrade.php b/app/Console/Commands/upgrade.php index db956ef92..29b1171b9 100644 --- a/app/Console/Commands/upgrade.php +++ b/app/Console/Commands/upgrade.php @@ -11,14 +11,14 @@ class upgrade extends Command * * @var string */ - protected $signature = 'upgrade'; + protected $signature='upgrade'; /** * The console command description. * * @var string */ - protected $description = 'Upgrade to the Latest of NOJ'; + protected $description='Upgrade to the Latest of NOJ'; /** * Create a new command instance. @@ -37,7 +37,7 @@ public function __construct() */ public function handle() { - $bar = $this->output->createProgressBar(8); + $bar=$this->output->createProgressBar(8); $bar->setFormat("%current%/%max% [%bar%] %percent:3s%%\n%message%"); $bar->setMessage("Enable Maintenance Mode."); diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 52db78c68..8f0debd86 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -4,7 +4,7 @@ use Illuminate\Console\Scheduling\Schedule; use App\Babel\Babel; -use App\Models\Eloquent\JudgeServerModel as EloquentJudgeServerModel; +use App\Models\Eloquent\JudgeServer as EloquentJudgeServerModel; use App\Models\RankModel; use App\Models\SiteMapModel; use App\Models\ContestModel; @@ -34,44 +34,36 @@ class Kernel extends ConsoleKernel */ protected function schedule(Schedule $schedule) { - $schedule->call(function () { - $babel=new Babel(); - for ($i=1; $i<=12; $i++) { - $babel->judge(); - sleep(5); - } - // file_put_contents(storage_path('app/task-schedule.output'),"Successfully Synced Judger"); - })->everyMinute()->description("Sync Judger"); - $schedule->call(function () { + $schedule->call(function() { $rankModel=new RankModel(); $rankModel->rankList(); // file_put_contents(storage_path('app/task-schedule.output'),"Successfully Updated Rank"); })->dailyAt('02:00')->description("Update Rank"); - $schedule->call(function () { + $schedule->call(function() { $siteMapModel=new SiteMapModel(); // file_put_contents(storage_path('app/task-schedule.output'),"Successfully Updated SiteMap"); })->dailyAt('02:00')->description("Update SiteMap"); - $schedule->call(function () { + $schedule->call(function() { $groupModel=new GroupModel(); $groupModel->cacheTrendingGroups(); // file_put_contents(storage_path('app/task-schedule.output'),"Successfully Cached Trending Groups"); })->dailyAt('03:00')->description("Update Trending Groups"); $schedule->call(function() { - $groupModel = new GroupModel(); - $ret = $groupModel->refreshAllElo(); + $groupModel=new GroupModel(); + $ret=$groupModel->refreshAllElo(); foreach ($ret as $gid => $group) { - if(empty($group['result'])){ + if (empty($group['result'])) { Log::channel('group_elo')->info('Refreshed Group Elo (Empty) : ('.$gid.')'.$group['name']); - }else{ + } else { Log::channel('group_elo')->info('Refreshing Group Elo: ('.$gid.')'.$group['name']); foreach ($group['result'] as $contest) { - if($contest['ret'] == 'success'){ + if ($contest['ret']=='success') { Log::channel('group_elo')->info(' Elo Clac Successfully : ('.$contest['cid'].')'.$contest['name']); - }else{ + } else { Log::channel('group_elo')->info(' Elo Clac Faild (Judge Not Over) : ('.$contest['cid'].')'.$contest['name'].' sids:'); foreach ($contest['submissions'] as $sid) { Log::channel('group_elo')->info(' '.$sid['sid']); @@ -82,46 +74,46 @@ protected function schedule(Schedule $schedule) } })->dailyAt('04:00')->description("Update Group Elo"); - $schedule->call(function () { - $contestModel = new ContestModel(); - $syncList = $contestModel->runningContest(); + $schedule->call(function() { + $contestModel=new ContestModel(); + $syncList=$contestModel->runningContest(); foreach ($syncList as $syncContest) { if (!isset($syncContest['vcid'])) { - $contest = EloquentContestModel::find($syncContest['cid']); - $contestRankRaw = $contest->rankRefresh(); + $contest=EloquentContestModel::find($syncContest['cid']); + $contestRankRaw=$contest->rankRefresh(); $cid=$syncContest['cid']; Cache::tags(['contest', 'rank'])->put($cid, $contestRankRaw); Cache::tags(['contest', 'rank'])->put("contestAdmin$cid", $contestRankRaw); - continue ; + continue; } - $className = "App\\Babel\\Extension\\hdu\\Synchronizer"; // TODO Add OJ judgement. - $all_data = [ + $className="App\\Babel\\Extension\\hdu\\Synchronizer"; // TODO Add OJ judgement. + $all_data=[ 'oj'=>"hdu", 'vcid'=>$syncContest['vcid'], 'gid'=>$syncContest['gid'], 'cid'=>$syncContest['cid'], ]; - $hduSync = new $className($all_data); + $hduSync=new $className($all_data); $hduSync->crawlRank(); $hduSync->crawlClarification(); } // file_put_contents(storage_path('app/task-schedule.output'),"Successfully Synced Remote Rank and Clarification"); })->everyMinute()->description("Sync Remote Rank and Clarification"); - $schedule->call(function () { - $contestModel = new ContestModel(); - $syncList = $contestModel->runningContest(); + $schedule->call(function() { + $contestModel=new ContestModel(); + $syncList=$contestModel->runningContest(); foreach ($syncList as $syncContest) { if (isset($syncContest['crawled'])) { if (!$syncContest['crawled']) { - $className = "App\\Babel\\Extension\\hdu\\Synchronizer"; - $all_data = [ + $className="App\\Babel\\Extension\\hdu\\Synchronizer"; + $all_data=[ 'oj'=>"hdu", 'vcid'=>$syncContest['vcid'], 'gid'=>$syncContest['gid'], 'cid'=>$syncContest['cid'], ]; - $hduSync = new $className($all_data); + $hduSync=new $className($all_data); $hduSync->scheduleCrawl(); $contestModel->updateCrawlStatus($syncContest['cid']); } @@ -129,7 +121,7 @@ protected function schedule(Schedule $schedule) } })->everyMinute()->description("Sync Contest Problem"); - $schedule->call(function () { + $schedule->call(function() { $oidList=EloquentJudgeServerModel::column('oid'); $babel=new Babel(); foreach ($oidList as $oid) { diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 4d819c700..b831a26b7 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -46,7 +46,7 @@ public function report(Exception $exception) */ public function render($request, Exception $exception) { - if(!env("APP_DEBUG") && $request->is('api/*')) { + if (!env("APP_DEBUG") && $request->is('api/*')) { return response(json_encode([ 'success' => false, 'message' => 'Server Error', @@ -56,7 +56,7 @@ public function render($request, Exception $exception) 'msg' => 'Server Error', 'data'=>[] ] - ]),500)->header('Content-Type','application/json'); + ]), 500)->header('Content-Type', 'application/json'); }; return parent::render($request, $exception); } diff --git a/app/Exports/AccountExport.php b/app/Exports/AccountExport.php index 432fee0b3..35895cc5e 100644 --- a/app/Exports/AccountExport.php +++ b/app/Exports/AccountExport.php @@ -11,7 +11,7 @@ class AccountExport implements FromArray, WithHeadings public function __construct(array $data) { - $this->data = $data; + $this->data=$data; } public function array(): array diff --git a/app/Exports/GroupAnalysisExport.php b/app/Exports/GroupAnalysisExport.php index 9fcc5e4b6..cfe305d8d 100644 --- a/app/Exports/GroupAnalysisExport.php +++ b/app/Exports/GroupAnalysisExport.php @@ -16,27 +16,27 @@ class GroupAnalysisExport implements FromCollection, WithEvents, WithStrictNullC private $member_data; private $config; - public function __construct($data, $config = []) + public function __construct($data, $config=[]) { - if ($config['mode'] == 'contest') { - $this->contest_data = $data['contest_data']; - $this->member_data = $data['member_data']; + if ($config['mode']=='contest') { + $this->contest_data=$data['contest_data']; + $this->member_data=$data['member_data']; } else { - $this->member_data = $data['member_data']; - $this->tag_problems = $data['tag_problems']; + $this->member_data=$data['member_data']; + $this->tag_problems=$data['tag_problems']; } - $this->config = $config; + $this->config=$config; } /** - * @return array - */ + * @return array + */ public function registerEvents(): array { return [ - AfterSheet::class => function (AfterSheet $event) { - if ($this->config['mode'] === 'contest') { - $mergeCell = ['A1:A2','B1:E1']; + AfterSheet::class => function(AfterSheet $event) { + if ($this->config['mode']==='contest') { + $mergeCell=['A1:A2', 'B1:E1']; foreach ($this->contest_data as $c) { array_push($mergeCell, $this->mergeCellColumnNext()); } @@ -47,50 +47,50 @@ public function registerEvents(): array } /** - * @return \Illuminate\Support\Collection - */ + * @return \Illuminate\Support\Collection + */ public function collection() { - $maxium = $this->config['maxium'] ?? false; - $percent = $this->config['percent'] ?? false; + $maxium=$this->config['maxium'] ?? false; + $percent=$this->config['percent'] ?? false; - if ($this->config['mode'] == 'contest') { - $row_1 = ['Member','Total','','','']; - $row_2 = ['','Elo','Rank','Solved','Penalty']; + if ($this->config['mode']=='contest') { + $row_1=['Member', 'Total', '', '', '']; + $row_2=['', 'Elo', 'Rank', 'Solved', 'Penalty']; foreach ($this->contest_data as $contest) { - array_push($row_1, $contest['name'], '',''); - array_push($row_2, 'Rank','Solved', 'Penalty'); + array_push($row_1, $contest['name'], '', ''); + array_push($row_2, 'Rank', 'Solved', 'Penalty'); } - $data = [$row_1,$row_2]; + $data=[$row_1, $row_2]; foreach ($this->member_data as $member) { - $display_name = $member['name']; + $display_name=$member['name']; if (!empty($member['nick_name'])) { - $display_name .= ' ('.$member['nick_name'].')'; + $display_name.=' ('.$member['nick_name'].')'; } - $row = [ + $row=[ $display_name, $member['elo'], !empty($member['rank_ave']) ? round($member['rank_ave'], 1) : '-', - $percent === 'true' ? ($member['problem_all'] != 0 ? round($member['solved_all'] / $member['problem_all'] * 100, 1) : '-'). ' %' - : ($maxium === 'true' ? $member['solved_all'] . ' / ' . $member['problem_all'] : $member['solved_all']), + $percent==='true' ? ($member['problem_all']!=0 ? round($member['solved_all'] / $member['problem_all'] * 100, 1) : '-').' %' + : ($maxium==='true' ? $member['solved_all'].' / '.$member['problem_all'] : $member['solved_all']), round($member['penalty']), ]; foreach ($this->contest_data as $contest) { if (in_array($contest['cid'], array_keys($member['contest_detial']))) { - $contest_detial = $member['contest_detial'][$contest['cid']]; + $contest_detial=$member['contest_detial'][$contest['cid']]; array_push( $row, $contest_detial['rank'], - $percent === 'true' ? (round($contest_detial['solved'] / $contest_detial['problems'] * 100, 1) . ' %') - : ($maxium === 'true' ? $contest_detial['solved'].' / '.$contest_detial['problems'] : $contest_detial['solved']), + $percent==='true' ? (round($contest_detial['solved'] / $contest_detial['problems'] * 100, 1).' %') + : ($maxium==='true' ? $contest_detial['solved'].' / '.$contest_detial['problems'] : $contest_detial['solved']), round($contest_detial['penalty']) ); } else { array_push( $row, '-', - $percent === 'true' ? '- %' - : ($maxium === 'true' ? '- / -' : ' - '), + $percent==='true' ? '- %' + : ($maxium==='true' ? '- / -' : ' - '), 0 ); } @@ -98,27 +98,27 @@ public function collection() array_push($data, $row); } } else { - $row_1 = ['Member']; - $row_2 = ['']; + $row_1=['Member']; + $row_2=['']; foreach ($this->tag_problems as $tag => $tag_problem_set) { array_push($row_1, $tag); array_push($row_2, 'Solved'); } - $data = [$row_1,$row_2]; + $data=[$row_1, $row_2]; foreach ($this->member_data as $member) { - $display_name = $member['name']; + $display_name=$member['name']; if (!empty($member['nick_name'])) { - $display_name .= ' ('.$member['nick_name'].')'; + $display_name.=' ('.$member['nick_name'].')'; } - $row = [ + $row=[ $display_name, ]; foreach ($member['completion'] as $tag => $tag_completion) { - $count = count($tag_completion); - $solved = eval('return '.join('+', array_values($tag_completion)).';'); + $count=count($tag_completion); + $solved=eval('return '.join('+', array_values($tag_completion)).';'); array_push( $row, - $percent === 'true' ? (round($solved / $count * 100, 1) . ' %') : ($maxium === 'true' ? $solved .' / '.$count : $solved) + $percent==='true' ? (round($solved / $count * 100, 1).' %') : ($maxium==='true' ? $solved.' / '.$count : $solved) ); } array_push($data, $row); @@ -129,33 +129,33 @@ public function collection() private function mergeCellColumnNext() { - static $columns = [ - [2],[4] + static $columns=[ + [2], [4] ]; - $columns_str = ['','']; - $chars = str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + $columns_str=['', '']; + $chars=str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZ'); foreach ($columns as $key => &$column) { - $column[0] += 3; - if ($column[0] > 25) { + $column[0]+=3; + if ($column[0]>25) { if (isset($column[1])) { - $column[1] += 1; - if ($column[1] > 25) { + $column[1]+=1; + if ($column[1]>25) { if (isset($column[2])) { - $column[2] += 1; + $column[2]+=1; } else { - $column[2] = 0; + $column[2]=0; } } } else { - $column[1] = 0; + $column[1]=0; } } - $columns_str[$key] = ''; - $reverse_column = array_reverse($column); + $columns_str[$key]=''; + $reverse_column=array_reverse($column); foreach ($reverse_column as $ord) { - $columns_str[$key] .= $chars[$ord]; + $columns_str[$key].=$chars[$ord]; } - $columns_str[$key] .= '1'; + $columns_str[$key].='1'; } return $columns_str[0].':'.$columns_str[1]; } diff --git a/app/Helpers/functions.php b/app/Helpers/functions.php index 953801d39..0f732225f 100644 --- a/app/Helpers/functions.php +++ b/app/Helpers/functions.php @@ -26,6 +26,8 @@ use GrahamCampbell\Markdown\Facades\Markdown; use App\Models\Eloquent\Message; use App\Models\Latex\LatexModel; +use App\Models\Eloquent\Tool\Theme; +use App\Models\Eloquent\Tool\AppSettings; if (!function_exists('version')) { function version() @@ -64,20 +66,20 @@ function emailVerified() } } -if (! function_exists('babel_path')) { +if (!function_exists('babel_path')) { /** * Get the path to the application folder. * * @param string $path * @return string */ - function babel_path($path = '') + function babel_path($path='') { return app('path').DIRECTORY_SEPARATOR.'Babel'.($path ? DIRECTORY_SEPARATOR.$path : $path); } } -if (! function_exists('glob_recursive')) { +if (!function_exists('glob_recursive')) { /** * Find pathnames matching a pattern recursively. * @@ -85,11 +87,11 @@ function babel_path($path = '') * @param int $flags Valid flags: GLOB_MARK * @return array|false an array containing the matched files/directories, an empty array if no file matched or false on error. */ - function glob_recursive($pattern, $flags = 0) + function glob_recursive($pattern, $flags=0) { - $files = glob($pattern, $flags); - foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) { - $files = array_merge($files, glob_recursive($dir.'/'.basename($pattern), $flags)); + $files=glob($pattern, $flags); + foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR | GLOB_NOSORT) as $dir) { + $files=array_merge($files, glob_recursive($dir.'/'.basename($pattern), $flags)); } return $files; } @@ -123,8 +125,8 @@ function getOpenSearchXML() function delFile($dirName) { if (file_exists($dirName) && $handle=opendir($dirName)) { - while (false!==($item = readdir($handle))) { - if ($item!= "." && $item != "..") { + while (false!==($item=readdir($handle))) { + if ($item!="." && $item!="..") { if (file_exists($dirName.'/'.$item) && is_dir($dirName.'/'.$item)) { delFile($dirName.'/'.$item); } else { @@ -142,7 +144,7 @@ function delFile($dirName) if (!function_exists('convertMarkdownToHtml')) { function convertMarkdownToHtml($md) { - return is_string($md)?Markdown::convertToHtml($md):''; + return is_string($md) ?Markdown::convertToHtml($md) : ''; } } @@ -186,7 +188,7 @@ function formatHumanReadableTime($date) $periods[$j]=__("helper.time.singular.$periods[$j]"); } - return __("helper.time.formatter",[ + return __("helper.time.formatter", [ "time" => $difference, "unit" => $periods[$j], "tense" => $tense, @@ -211,18 +213,53 @@ function formatProblemSolvedTime($seconds) if (!function_exists('latex2Image')) { function latex2Image($content) { - $callback = function ($matches) use (&$patch, &$display) { - [$url,$width,$height]=LatexModel::info("$patch$matches[1]$patch"); + $callback=function($matches) use (&$patch, &$display) { + [$url, $width, $height]=LatexModel::info("$patch$matches[1]$patch"); return ""; }; - $patch = '$'; - $display = 'inline-block'; - $content = preg_replace_callback('/\\$\\$\\$(.*?)\\$\\$\\$/', $callback, $content); - $content = preg_replace_callback('/\\\\\\((.*?)\\\\\\)/', $callback, $content); - $patch = '$$'; - $display = 'block'; - $content = preg_replace_callback('/\\$\\$(.*?)\\$\\$/', $callback, $content); - $content = preg_replace_callback('/\\\\\\[(.*?)\\\\\\]/', $callback, $content); + $patch='$'; + $display='inline-block'; + $content=preg_replace_callback('/\\$\\$\\$(.*?)\\$\\$\\$/', $callback, $content); + $content=preg_replace_callback('/\\\\\\((.*?)\\\\\\)/', $callback, $content); + $patch='$$'; + $display='block'; + $content=preg_replace_callback('/\\$\\$(.*?)\\$\\$/', $callback, $content); + $content=preg_replace_callback('/\\\\\\[(.*?)\\\\\\]/', $callback, $content); return $content; } } + +if (!function_exists('vscodeLocale')) { + function vscodeLocale() + { + $locale=Str::lower(App::getLocale()); + $vscodelocale=''; + if (in_array($locale, ['de', 'es', 'fr', 'it', 'ja', 'ko', 'ru', 'zh-cn', 'zh-tw'])) { + $vscodelocale=$locale; + } + return $vscodelocale; + } +} + +if (!function_exists('getTheme')) { + function getTheme($id=null) + { + if (is_null($id)) { + $id=config('app.theme'); + } + return Theme::getTheme($id); + } +} + +if (!function_exists('setting')) { + function setting($identifier, $default=null) + { + if (is_array($identifier)) { + foreach ($identifier as $key=>$content) { + AppSettings::set($key, $content); + } + return true; + } + return AppSettings::get($identifier, $default); + } +} diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 10d142a20..cf87c3750 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -4,6 +4,8 @@ use Illuminate\Http\Request; use App\Models\AccountModel; +use App\Models\Eloquent\UserExtra; +use App\Models\Eloquent\Tool\Socialite; use Auth; class AccountController extends Controller @@ -28,8 +30,8 @@ public function dashboard() $accountModel=new AccountModel(); $info=$accountModel->detail(Auth::user()->id); $feed=$accountModel->feed(Auth::user()->id); - $extraInfo = $accountModel->getExtra(Auth::user()->id, ['gender', 'contanct', 'school', 'country', 'location'],100); - $socialiteInfo = $accountModel->getSocialiteInfo(Auth::user()->id,100); + $extraInfo=Auth::user()->getExtra(['gender', 'contact', 'school', 'country', 'location'], 100); + $socialiteInfo=Auth::user()->getSocialiteInfo(100); return view("account.dashboard", [ 'page_title'=>"DashBoard", 'site_title'=>config("app.name"), @@ -39,7 +41,9 @@ public function dashboard() 'settingsView' => false, 'feed'=>$feed, 'extra_info' => $extraInfo, + 'extraDict' => UserExtra::$extraDict, 'socialite_info' => $socialiteInfo, + 'socialites' => Socialite::getAvailable(), ]); } @@ -52,11 +56,11 @@ public function settings() { $accountModel=new AccountModel(); $info=$accountModel->detail(Auth::user()->id); - if(!empty(session('last_email_send'))){ - $email_cooldown = 300 - (time() - session('last_email_send')); + if (!empty(session('last_email_send'))) { + $email_cooldown=300-(time()-session('last_email_send')); } - $extraInfo = $accountModel->getExtra(Auth::user()->id, ['gender', 'contanct', 'school', 'country', 'location'],100); - $socialiteInfo = $accountModel->getSocialiteInfo(Auth::user()->id,100); + $extraInfo=Auth::user()->getExtra(['gender', 'contact', 'school', 'country', 'location'], 100); + $socialiteInfo=Auth::user()->getSocialiteInfo(100); return view("account.dashboard", [ 'page_title'=>"Settings", 'site_title'=>config("app.name"), @@ -66,7 +70,9 @@ public function settings() 'settingsView' => true, 'email_cooldown' => $email_cooldown ?? null, 'extra_info' => $extraInfo, + 'extraDict' => UserExtra::$extraDict, 'socialite_info' => $socialiteInfo, + 'socialites' => Socialite::getAvailable(), ]); } } diff --git a/app/Http/Controllers/Ajax/AbuseController.php b/app/Http/Controllers/Ajax/AbuseController.php index 702aa8299..3a4ef4914 100644 --- a/app/Http/Controllers/Ajax/AbuseController.php +++ b/app/Http/Controllers/Ajax/AbuseController.php @@ -17,8 +17,8 @@ class AbuseController extends Controller { protected static $cause=[]; - public static function findCause($causeDesc){ - if(empty($cause)){ + public static function findCause($causeDesc) { + if (empty($cause)) { self::$cause=array_flip(Abuse::$cause); } $causeID=Arr::get(self::$cause, $causeDesc, 0); @@ -34,24 +34,24 @@ public function report(Request $request) "subject_id" => "required|integer" ]); $category2link=[ - 'group'=>function($id){ - return route('group.detail',['gcode'=>Group::findOrFail($id)->gcode]); + 'group'=>function($id) { + return route('group.detail', ['gcode'=>Group::findOrFail($id)->gcode]); }, - 'user'=>function($id){ - return route('user.view',['uid' => $id]); + 'user'=>function($id) { + return route('user.view', ['uid' => $id]); } ]; - $supplement = $request->input('supplement'); - $category = $request->input('category'); - $subject_id = $request->input('subject_id'); + $supplement=$request->input('supplement'); + $category=$request->input('category'); + $subject_id=$request->input('subject_id'); try { - $link = $category2link[$category]($subject_id); - } catch(Throwable $e){ + $link=$category2link[$category]($subject_id); + } catch (Throwable $e) { return ResponseModel::err(9001); } - $uid = Auth::user()->id; - [$causeID, $causeDesc] = self::findCause('General'); - $abuseRecord = Abuse::create([ + $uid=Auth::user()->id; + [$causeID, $causeDesc]=self::findCause('General'); + $abuseRecord=Abuse::create([ 'title' => Str::title($category)." #$subject_id Abused - $causeDesc", 'category' => array_search($category, Abuse::$supportCategory), 'cause' => $causeID, diff --git a/app/Http/Controllers/Ajax/AccountController.php b/app/Http/Controllers/Ajax/AccountController.php index 9566babb2..2bab665a4 100644 --- a/app/Http/Controllers/Ajax/AccountController.php +++ b/app/Http/Controllers/Ajax/AccountController.php @@ -4,19 +4,18 @@ use App\Http\Controllers\Controller; use App\Models\ResponseModel; -use App\Models\UserModel; -use App\Models\AccountModel; use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Support\Facades\Validator; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Hash; +use Illuminate\Validation\Rule; use Auth; class AccountController extends Controller { - public function updateAvatar(Request $request){ + public function updateAvatar(Request $request) { $isValid=$request->file('avatar')->isValid(); if ($isValid) { $extension=$request->file('avatar')->extension(); @@ -43,94 +42,110 @@ public function updateAvatar(Request $request){ } } - public function changeBasicInfo(Request $request){ - // if(!$request->has('username')){ - // return ResponseModel::err(1003); - // } - // $username = $request->input('username'); - $describes = $request->input('describes'); - if(strlen($describes) > 255){ - return ResponseModel::err(1006); - } - // $old_username=Auth::user()->name; - // if($old_username != $username && !empty(UserModel::where('name',$username)->first())){ - // return ResponseModel::err(2003); - // } + public function changeBasicInfo(Request $request) { + $request->validate([ + "username" => [ + "required", + "string", + "max:16", + "min:1", + Rule::unique('users', 'name')->ignore(Auth::user()->id) + ], + "describes" => "required|string|max:255" + ]); + $username=$request->input('username'); + $describes=$request->input('describes'); $user=Auth::user(); - // $user->name = $username; - $user->describes = $describes; + if (!Auth::user()->contest_account) { + $user->name=$username; + } + $user->describes=$describes; $user->save(); return ResponseModel::success(); } - public function changePassword(Request $request){ - if(!$request->has('old_password') || !$request->has('new_password') || !$request->has('confirm_password')){ + public function changePassword(Request $request) { + if (!$request->has('old_password') || !$request->has('new_password') || !$request->has('confirm_password')) { return ResponseModel::err(1003); } - $old_password = $request->input('old_password'); - $new_password = $request->input('new_password'); - $confirm_password = $request->input('confirm_password'); - if($new_password != $confirm_password){ + $old_password=$request->input('old_password'); + $new_password=$request->input('new_password'); + $confirm_password=$request->input('confirm_password'); + if ($new_password!=$confirm_password) { return ResponseModel::err(2004); } - if(strlen($new_password) < 8 || strlen($old_password) < 8){ + if (strlen($new_password)<8 || strlen($old_password)<8) { return ResponseModel::err(1006); } - $user = Auth::user(); - if(!Hash::check($old_password, $user->password)){ + $user=Auth::user(); + if ($user->hasIndependentPassword() && !Hash::check($old_password, $user->password)) { return ResponseModel::err(2005); } - $user->password = Hash::make($new_password); + $user->password=Hash::make($new_password); $user->save(); return ResponseModel::success(); } - public function checkEmailCooldown(Request $request){ - $last_send = $request->session()->get('last_email_send'); - if(empty($last_send) || time() - $last_send >= 300){ - $request->session()->put('last_email_send',time()); - return ResponseModel::success(200,null,0); - }else{ - $cooldown = 300 - (time() - $last_send); - return ResponseModel::success(200,null,$cooldown); + public function checkEmailCooldown(Request $request) { + $last_send=$request->session()->get('last_email_send'); + if (empty($last_send) || time()-$last_send>=300) { + $request->session()->put('last_email_send', time()); + return ResponseModel::success(200, null, 0); + } else { + $cooldown=300-(time()-$last_send); + return ResponseModel::success(200, null, $cooldown); } } - public function changeExtraInfo(Request $request){ - $input = $request->input(); - $allow_change = ['gender','contact','school','country','location']; - foreach($input as $key => $value){ - if(!in_array($key,$allow_change)){ + public function changeExtraInfo(Request $request) { + $input=$request->input(); + $allow_change=['gender', 'contact', 'school', 'country', 'location']; + foreach ($input as $key => $value) { + if (!in_array($key, $allow_change)) { return ResponseModel::error(1007); } } - $account_model = new AccountModel(); - $user_id = Auth::user()->id; foreach ($input as $key => $value) { - if(strlen($value) != 0){ - $account_model->setExtra($user_id,$key,$value,0); - }else{ - $account_model->setExtra($user_id,$key,null); + if (strlen($value)!=0) { + Auth::user()->setExtra($key, $value, 0); + } else { + Auth::user()->setExtra($key, null); } } return ResponseModel::success(); } - public function saveEditorWidth(Request $request){ - $input = $request->input(); - $allow_change = ['editor_left_width']; - foreach($input as $key => $value){ - if(!in_array($key,$allow_change)){ + public function saveEditorWidth(Request $request) { + $input=$request->input(); + $allow_change=['editor_left_width']; + foreach ($input as $key => $value) { + if (!in_array($key, $allow_change)) { + return ResponseModel::error(1007); + } + } + foreach ($input as $key => $value) { + if (strlen($value)!=0) { + Auth::user()->setExtra($key, $value, 0); + } else { + Auth::user()->setExtra($key, null); + } + } + return ResponseModel::success(); + } + + public function saveEditorTheme(Request $request) { + $input=$request->input(); + $allow_change=['editor_theme']; + foreach ($input as $key => $value) { + if (!in_array($key, $allow_change)) { return ResponseModel::error(1007); } } - $account_model = new AccountModel(); - $user_id = Auth::user()->id; foreach ($input as $key => $value) { - if(strlen($value) != 0){ - $account_model->setExtra($user_id,$key,$value,0); - }else{ - $account_model->setExtra($user_id,$key,null); + if (strlen($value)!=0) { + Auth::user()->setExtra($key, $value, 0); + } else { + Auth::user()->setExtra($key, null); } } return ResponseModel::success(); diff --git a/app/Http/Controllers/Ajax/ContestAdminController.php b/app/Http/Controllers/Ajax/ContestAdminController.php index ed59080d3..d94093262 100644 --- a/app/Http/Controllers/Ajax/ContestAdminController.php +++ b/app/Http/Controllers/Ajax/ContestAdminController.php @@ -27,22 +27,22 @@ public function assignMember(Request $request) 'cid' => 'required|integer', 'uid' => 'required|integer' ]); - $cid = $request->input('cid'); - $uid = $request->input('uid'); + $cid=$request->input('cid'); + $uid=$request->input('uid'); - $groupModel = new GroupModel(); - $contestModel = new ContestModel(); + $groupModel=new GroupModel(); + $contestModel=new ContestModel(); - $contest_info = $contestModel->basic($cid); - if($contestModel->judgeClearance($cid,Auth::user()->id) != 3){ + $contest_info=$contestModel->basic($cid); + if ($contestModel->judgeClearance($cid, Auth::user()->id)!=3) { return ResponseModel::err(2001); } - if($groupModel->judgeClearance($contest_info['gid'],$uid) < 2){ + if ($groupModel->judgeClearance($contest_info['gid'], $uid)<2) { return ResponseModel::err(7004); } - $contestModel->assignMember($cid,$uid); + $contestModel->assignMember($cid, $uid); return ResponseModel::success(200); } @@ -51,30 +51,30 @@ public function details(Request $request) $request->validate([ 'cid' => 'required|integer', ]); - $cid = $request->input('cid'); + $cid=$request->input('cid'); - $contestModel = new ContestModel(); - $groupModel = new GroupModel(); + $contestModel=new ContestModel(); + $groupModel=new GroupModel(); - $contest_problems = $contestModel->problems($cid); - $contest_detail = $contestModel->basic($cid); - $contest_detail['problems'] = $contest_problems; - $assign_uid = $contest_detail['assign_uid']; - $clearance = $contestModel->judgeClearance($cid,Auth::user()->id); - if($clearance != 3){ + $contest_problems=$contestModel->problems($cid); + $contest_detail=$contestModel->basic($cid); + $contest_detail['problems']=$contest_problems; + $assign_uid=$contest_detail['assign_uid']; + $clearance=$contestModel->judgeClearance($cid, Auth::user()->id); + if ($clearance!=3) { return ResponseModel::err(2001); } - if($assign_uid != 0){ - $assignee = $groupModel->userProfile($assign_uid,$contest_detail['gid']); - }else{ - $assignee = null; + if ($assign_uid!=0) { + $assignee=$groupModel->userProfile($assign_uid, $contest_detail['gid']); + } else { + $assignee=null; } - $ret = [ + $ret=[ 'contest_info' => $contest_detail, 'assignee' => $assignee, - 'is_admin' => $clearance == 3, + 'is_admin' => $clearance==3, ]; - return ResponseModel::success(200,null,$ret); + return ResponseModel::success(200, null, $ret); } public function rejudge(Request $request) @@ -109,15 +109,15 @@ public function update(Request $request) 'end_time' => 'required|date|after:begin_time', 'description' => 'string' ]); - $all_data = $request->all(); - $cid = $all_data['cid']; + $all_data=$request->all(); + $cid=$all_data['cid']; - $contestModel = new ContestModel(); - if($contestModel->judgeClearance($all_data['cid'],Auth::user()->id) != 3){ + $contestModel=new ContestModel(); + if ($contestModel->judgeClearance($all_data['cid'], Auth::user()->id)!=3) { return ResponseModel::err(2001); } - if($contestModel->remainingTime($cid) > 0){ + if ($contestModel->remainingTime($cid)>0) { $problems=explode(",", $all_data["problems"]); if (count($problems)>26) { return ResponseModel::err(4002); @@ -134,32 +134,32 @@ public function update(Request $request) ]; } } - $allow_update = ['name','description','begin_time','end_time', 'status_visibility']; + $allow_update=['name', 'description', 'begin_time', 'end_time', 'status_visibility']; - foreach($all_data as $key => $value){ - if(!in_array($key,$allow_update)){ + foreach ($all_data as $key => $value) { + if (!in_array($key, $allow_update)) { unset($all_data[$key]); } } - $contestModel->contestUpdate($cid,$all_data,$problemSet); + $contestModel->contestUpdate($cid, $all_data, $problemSet); return ResponseModel::success(200); - }else{ - $allow_update = ['name','description']; + } else { + $allow_update=['name', 'description']; - foreach($all_data as $key => $value){ - if(!in_array($key,$allow_update)){ + foreach ($all_data as $key => $value) { + if (!in_array($key, $allow_update)) { unset($all_data[$key]); } } - $contestModel->contestUpdate($cid,$all_data,false); - return ResponseModel::success(200,' + $contestModel->contestUpdate($cid, $all_data, false); + return ResponseModel::success(200, ' Successful! However, only the name and description of the match can be changed for the match that has been finished. '); } } - public function issueAnnouncement(Request $request){ + public function issueAnnouncement(Request $request) { $request->validate([ 'cid' => 'required|integer', 'title' => 'required|string|max:250', @@ -179,7 +179,7 @@ public function issueAnnouncement(Request $request){ } } - public function replyClarification(Request $request){ + public function replyClarification(Request $request) { $request->validate([ 'cid' => 'required|integer', 'ccid' => 'required|integer', @@ -199,7 +199,7 @@ public function replyClarification(Request $request){ } } - public function setClarificationPublic(Request $request){ + public function setClarificationPublic(Request $request) { $request->validate([ 'cid' => 'required|integer', 'ccid' => 'required|integer', @@ -232,7 +232,7 @@ public function generateContestAccount(Request $request) $groupModel=new GroupModel(); $contestModel=new ContestModel(); $verified=$contestModel->isVerified($all_data["cid"]); - if(!$verified){ + if (!$verified) { return ResponseModel::err(2001); } $gid=$contestModel->gid($all_data["cid"]); @@ -253,18 +253,18 @@ public function getScrollBoardData(Request $request) $request->validate([ 'cid' => 'required|integer', ]); - $cid = $request->input('cid'); - $contestModel = new ContestModel(); - if($contestModel->judgeClearance($cid,Auth::user()->id) != 3){ + $cid=$request->input('cid'); + $contestModel=new ContestModel(); + if ($contestModel->judgeClearance($cid, Auth::user()->id)!=3) { return ResponseModel::err(2001); } - if($contestModel->remainingTime($cid) >= 0){ + if ($contestModel->remainingTime($cid)>=0) { return ResponseModel::err(4008); } - if($contestModel->basic($cid)['froze_length'] == 0){ + if ($contestModel->basic($cid)['froze_length']==0) { return ResponseModel::err(4009); } - $data = $contestModel->getScrollBoardData($cid); + $data=$contestModel->getScrollBoardData($cid); return ResponseModel::success(200, null, $data); } @@ -273,20 +273,20 @@ public function downloadCode(Request $request) $request->validate([ "cid"=>"required|integer", ]); - $cid = $request->input('cid'); + $cid=$request->input('cid'); $groupModel=new GroupModel(); $contestModel=new ContestModel(); - if($contestModel->judgeClearance($cid,Auth::user()->id) != 3){ + if ($contestModel->judgeClearance($cid, Auth::user()->id)!=3) { return ResponseModel::err(2001); } $zip_name=$contestModel->zipName($cid); - if(!(Storage::disk("private")->exists("contestCodeZip/$cid/".$cid.".zip"))){ - $contestModel->GenerateZip("contestCodeZip/$cid/",$cid,"contestCode/$cid/",$zip_name); + if (!(Storage::disk("private")->exists("contestCodeZip/$cid/".$cid.".zip"))) { + $contestModel->GenerateZip("contestCodeZip/$cid/", $cid, "contestCode/$cid/", $zip_name); } $files=Storage::disk("private")->files("contestCodeZip/$cid/"); - response()->download(base_path("/storage/app/private/".$files[0]),$zip_name,[ + response()->download(base_path("/storage/app/private/".$files[0]), $zip_name, [ "Content-Transfer-Encoding" => "binary", "Content-Type"=>"application/octet-stream", "filename"=>$zip_name @@ -299,15 +299,15 @@ public function downloadPlagiarismReport(Request $request) $request->validate([ "cid"=>"required|integer", ]); - $cid = $request->input('cid'); + $cid=$request->input('cid'); $contestModel=new ContestModel(); - if($contestModel->judgeClearance($cid,Auth::user()->id) != 3){ + if ($contestModel->judgeClearance($cid, Auth::user()->id)!=3) { return ResponseModel::err(2001); } $name=$contestModel->basic($cid)["name"]; - return response()->download(storage_path("app/contest/anticheat/$cid/report/report.zip"), "$name Code Plagiarism.zip"); + return response()->download(storage_path("app/contest/anticheat/$cid/report/report.zip"), __("contest.inside.admin.anticheat.downloadFile", ["name" => $name]).".zip"); } public function generatePDF(Request $request) @@ -317,17 +317,19 @@ public function generatePDF(Request $request) "config.cover"=>"required", "config.advice"=>"required", ]); - $cid = $request->input('cid'); - $config = [ + $cid=$request->input('cid'); + $config=[ 'cover'=>$request->input('config.cover')=='true', 'advice'=>$request->input('config.advice')=='true' ]; $contestModel=new ContestModel(); - if ($contestModel->judgeClearance($cid,Auth::user()->id) != 3){ + if ($contestModel->judgeClearance($cid, Auth::user()->id)!=3) { return ResponseModel::err(2001); } - if(!is_null(Cache::tags(['contest', 'admin', 'PDFGenerate'])->get($cid))) return ResponseModel::err(8001); - $generateProcess=new GeneratePDF($cid,$config); + if (!is_null(Cache::tags(['contest', 'admin', 'PDFGenerate'])->get($cid))) { + return ResponseModel::err(8001); + } + $generateProcess=new GeneratePDF($cid, $config); dispatch($generateProcess)->onQueue('normal'); Cache::tags(['contest', 'admin', 'PDFGenerate'])->put($cid, $generateProcess->getJobStatusId()); return ResponseModel::success(200, null, [ @@ -340,13 +342,15 @@ public function anticheat(Request $request) $request->validate([ "cid"=>"required|integer" ]); - $cid = $request->input('cid'); + $cid=$request->input('cid'); $contestModel=new ContestModel(); - if ($contestModel->judgeClearance($cid,Auth::user()->id) != 3){ + if ($contestModel->judgeClearance($cid, Auth::user()->id)!=3) { return ResponseModel::err(2001); } - if(!is_null(Cache::tags(['contest', 'admin', 'anticheat'])->get($cid))) return ResponseModel::err(8001); - if(EloquentContestModel::find($cid)->isJudgingComplete()) { + if (!is_null(Cache::tags(['contest', 'admin', 'anticheat'])->get($cid))) { + return ResponseModel::err(8001); + } + if (EloquentContestModel::find($cid)->isJudgingComplete()) { $anticheatProcess=new AntiCheat($cid); dispatch($anticheatProcess)->onQueue('normal'); Cache::tags(['contest', 'admin', 'anticheat'])->put($cid, $anticheatProcess->getJobStatusId()); diff --git a/app/Http/Controllers/Ajax/ContestController.php b/app/Http/Controllers/Ajax/ContestController.php index 74ac19935..96305dd22 100644 --- a/app/Http/Controllers/Ajax/ContestController.php +++ b/app/Http/Controllers/Ajax/ContestController.php @@ -42,7 +42,7 @@ public function updateProfessionalRate(Request $request) $all_data=$request->all(); $contestModel=new ContestModel(); - return $contestModel->updateProfessionalRate($all_data["cid"])?ResponseModel::success(200):ResponseModel::err(1001); + return $contestModel->updateProfessionalRate($all_data["cid"]) ?ResponseModel::success(200) : ResponseModel::err(1001); } public function requestClarification(Request $request) @@ -78,16 +78,16 @@ public function registContest(Request $request) $groupModel=new GroupModel(); $basic=$contestModel->basic($all_data["cid"]); - if(!$basic["registration"]){ + if (!$basic["registration"]) { return ResponseModel::err(4003); } - if(strtotime($basic["registration_due"])isMember($basic["gid"], Auth::user()->id)){ + if ($basic["registant_type"]==1 && !$groupModel->isMember($basic["gid"], Auth::user()->id)) { return ResponseModel::err(4005); } @@ -101,14 +101,14 @@ public function getAnalysisData(Request $request) $request->validate([ 'cid' => 'required|integer' ]); - $cid = $request->input('cid'); + $cid=$request->input('cid'); $contestModel=new ContestModel(); $clearance=$contestModel->judgeClearance($cid, Auth::user()->id); - if ($clearance < 1) { + if ($clearance<1) { return ResponseModel::err(7002); } - return ResponseModel::success(200,null,$contestModel->praticeAnalysis($cid)); + return ResponseModel::success(200, null, $contestModel->praticeAnalysis($cid)); } public function downloadPDF(Request $request) @@ -116,11 +116,11 @@ public function downloadPDF(Request $request) $request->validate([ 'cid' => 'required|integer' ]); - $cid = $request->input('cid'); + $cid=$request->input('cid'); $info=EloquentContestModel::find($cid); - if (!$info->pdf){ + if (!$info->pdf) { return abort('403'); } diff --git a/app/Http/Controllers/Ajax/DojoController.php b/app/Http/Controllers/Ajax/DojoController.php index afd04ff8a..d18b89d09 100644 --- a/app/Http/Controllers/Ajax/DojoController.php +++ b/app/Http/Controllers/Ajax/DojoController.php @@ -19,18 +19,18 @@ public function complete(Request $request) "dojo_id" => "required|integer" ]); - $dojo_id = $request->input('dojo_id'); + $dojo_id=$request->input('dojo_id'); try { if (!Dojo::findOrFail($dojo_id)->canPass()) { return ResponseModel::err(10001); } - }catch(Throwable $e){ + } catch (Throwable $e) { return ResponseModel::err(10002); } - $user_id = Auth::user()->id; - $dojoRecord = DojoPass::firstOrCreate([ + $user_id=Auth::user()->id; + $dojoRecord=DojoPass::firstOrCreate([ 'dojo_id' => $dojo_id, 'user_id' => $user_id, ]); diff --git a/app/Http/Controllers/Ajax/GroupAdminController.php b/app/Http/Controllers/Ajax/GroupAdminController.php index 9fd781b8f..cb471f40d 100644 --- a/app/Http/Controllers/Ajax/GroupAdminController.php +++ b/app/Http/Controllers/Ajax/GroupAdminController.php @@ -48,11 +48,11 @@ public function addProblemTag(Request $request) $groupModel=new GroupModel(); $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id); - if ($clearance < 2) { + if ($clearance<2) { return ResponseModel::err(7002); } - $tags = $groupModel->problemTags($all_data['gid'],$all_data['pid']); - if(in_array($all_data['tag'],$tags)){ + $tags=$groupModel->problemTags($all_data['gid'], $all_data['pid']); + if (in_array($all_data['tag'], $tags)) { return ResponseModel::err(7007); } @@ -84,9 +84,9 @@ public function refreshElo(Request $request) $request->validate([ 'gid' => 'required|string', ]); - $gid = $request->input('gid'); + $gid=$request->input('gid'); $groupModel=new GroupModel(); - if($groupModel->judgeClearance($gid,Auth::user()->id) < 2) { + if ($groupModel->judgeClearance($gid, Auth::user()->id)<2) { return ResponseModel::err(2001); } $groupModel->refreshElo($gid); diff --git a/app/Http/Controllers/Ajax/GroupController.php b/app/Http/Controllers/Ajax/GroupController.php index 9aa705e87..ed8332b02 100644 --- a/app/Http/Controllers/Ajax/GroupController.php +++ b/app/Http/Controllers/Ajax/GroupController.php @@ -42,8 +42,8 @@ public function joinGroup(Request $request) if (is_null($join_policy)) { return ResponseModel::err(7001); } - $group = Group::find($all_data['gid']); - $leader = $group->leader; + $group=Group::find($all_data['gid']); + $leader=$group->leader; $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id); if ($join_policy==1) { if ($clearance==-1) { @@ -57,17 +57,17 @@ public function joinGroup(Request $request) 'group' => [ 'gcode' => $group->gcode, 'name' => $group->name, - 'url' => route('group.detail',['gcode' => $group->gcode]) + 'url' => route('group.detail', ['gcode' => $group->gcode]) ], 'user' => [ [ 'name' => Auth::user()->name, - 'url' => route('user.view',['uid' => Auth::user()->id]) + 'url' => route('user.view', ['uid' => Auth::user()->id]) ] ] ] ]); - return ResponseModel::success(200,null,[ + return ResponseModel::success(200, null, [ 'uid' => Auth::user()->id, 'role_color_old' => $groupModel->role_color[-1], 'role_color' => $groupModel->role_color[1], @@ -88,12 +88,12 @@ public function joinGroup(Request $request) 'group' => [ 'gcode' => $group->gcode, 'name' => $group->name, - 'url' => route('group.detail',['gcode' => $group->gcode]) + 'url' => route('group.detail', ['gcode' => $group->gcode]) ], 'user' => [ [ 'name' => Auth::user()->name, - 'url' => route('user.view',['uid' => Auth::user()->id]) + 'url' => route('user.view', ['uid' => Auth::user()->id]) ] ] ] @@ -112,17 +112,17 @@ public function joinGroup(Request $request) 'group' => [ 'gcode' => $group->gcode, 'name' => $group->name, - 'url' => route('group.detail',['gcode' => $group->gcode]) + 'url' => route('group.detail', ['gcode' => $group->gcode]) ], 'user' => [ [ 'name' => Auth::user()->name, - 'url' => route('user.view',['uid' => Auth::user()->id]) + 'url' => route('user.view', ['uid' => Auth::user()->id]) ] ] ] ]); - return ResponseModel::success(200,null,[ + return ResponseModel::success(200, null, [ 'uid' => Auth::user()->id, 'role_color_old' => $groupModel->role_color[-1], 'role_color' => $groupModel->role_color[1], @@ -140,12 +140,12 @@ public function joinGroup(Request $request) 'group' => [ 'gcode' => $group->gcode, 'name' => $group->name, - 'url' => route('group.detail',['gcode' => $group->gcode]) + 'url' => route('group.detail', ['gcode' => $group->gcode]) ], 'user' => [ [ 'name' => Auth::user()->name, - 'url' => route('user.view',['uid' => Auth::user()->id]) + 'url' => route('user.view', ['uid' => Auth::user()->id]) ] ] ] @@ -160,14 +160,14 @@ public function exitGroup(Request $request) $request->validate([ 'gid' => 'required|integer', ]); - $uid = Auth::user()->id; - $gid = $request->input('gid'); - $groupModel = new OutdatedGroupModel(); - $clearance = $groupModel->judgeClearance($gid,$uid); - if($clearance == 3) { + $uid=Auth::user()->id; + $gid=$request->input('gid'); + $groupModel=new OutdatedGroupModel(); + $clearance=$groupModel->judgeClearance($gid, $uid); + if ($clearance==3) { return ResponseModel::err(7008); } - $groupModel->removeClearance($uid,$gid); + $groupModel->removeClearance($uid, $gid); return ResponseModel::success(200); } @@ -184,9 +184,13 @@ public function createGroup(Request $request) $all_data=$request->all(); $groupModel=new OutdatedGroupModel(); - if($all_data["gcode"]=="create") return ResponseModel::err(7005); + if ($all_data["gcode"]=="create") { + return ResponseModel::err(7005); + } $is_group=$groupModel->isGroup($all_data["gcode"]); - if($is_group) return ResponseModel::err(7006); + if ($is_group) { + return ResponseModel::err(7006); + } $allow_extension=['jpg', 'png', 'jpeg', 'gif', 'bmp']; if (!empty($request->file('img')) && $request->file('img')->isValid()) { @@ -215,20 +219,20 @@ public function getPracticeStat(Request $request) $groupModel=new OutdatedGroupModel(); $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id); - if ($clearance > 0) { - switch($all_data['mode']){ + if ($clearance>0) { + switch ($all_data['mode']) { case 'contest': - $ret = $groupModel->groupMemberPracticeContestStat($all_data["gid"]); + $ret=$groupModel->groupMemberPracticeContestStat($all_data["gid"]); break; case 'tag': - $ret = $groupModel->groupMemberPracticeTagStat($all_data["gid"]); + $ret=$groupModel->groupMemberPracticeTagStat($all_data["gid"]); break; default: return ResponseModel::err(1007); break; } - return ResponseModel::success(200,null,$ret); + return ResponseModel::success(200, null, $ret); } return ResponseModel::err(7002); } @@ -244,10 +248,10 @@ public function eloChangeLog(Request $request) $groupModel=new OutdatedGroupModel(); $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id); - if($clearance <= 0){ + if ($clearance<=0) { return ResponseModel::err(7002); } - $ret = $groupModel->getEloChangeLog($all_data['gid'],$all_data['uid']); - return ResponseModel::success(200,null,$ret); + $ret=$groupModel->getEloChangeLog($all_data['gid'], $all_data['uid']); + return ResponseModel::success(200, null, $ret); } } diff --git a/app/Http/Controllers/Ajax/GroupManageController.php b/app/Http/Controllers/Ajax/GroupManageController.php index 4f65a5c29..159a98ad4 100644 --- a/app/Http/Controllers/Ajax/GroupManageController.php +++ b/app/Http/Controllers/Ajax/GroupManageController.php @@ -5,7 +5,7 @@ use App\Models\ContestModel; use App\Models\GroupModel; use App\Models\ResponseModel; -use App\Models\UserModel; +use App\Models\Eloquent\User; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; @@ -36,7 +36,7 @@ public function arrangeContest(Request $request) $all_data=$request->all(); - if(($all_data['public'] ?? 0) && ($all_data['practice'] ?? 0)){ + if (($all_data['public'] ?? 0) && ($all_data['practice'] ?? 0)) { return ResponseModel::err(4007); } @@ -67,7 +67,7 @@ public function arrangeContest(Request $request) return ResponseModel::err(1003); } - $cid = $contestModel->arrangeContest($all_data["gid"], [ + $cid=$contestModel->arrangeContest($all_data["gid"], [ "assign_uid"=>Auth::user()->id, "name"=>$all_data["name"], "description"=>$all_data["description"], @@ -78,7 +78,7 @@ public function arrangeContest(Request $request) "public"=>$all_data["public"] ?? 0, ], $problemSet); - return ResponseModel::success(200,'Successful!',$cid); + return ResponseModel::success(200, 'Successful!', $cid); } public function changeGroupName(Request $request) @@ -92,7 +92,7 @@ public function changeGroupName(Request $request) $groupModel=new GroupModel(); $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id); - if ($clearance < 2){ + if ($clearance<2) { return ResponseModel::err(2001); } @@ -111,11 +111,11 @@ public function changeJoinPolicy(Request $request) $groupModel=new GroupModel(); $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id); - if ($clearance < 2){ + if ($clearance<2) { return ResponseModel::err(2001); } - if ($all_data["join_policy"] < 1 || $all_data["join_policy"] > 3){ + if ($all_data["join_policy"]<1 || $all_data["join_policy"]>3) { return ResponseModel::err(1007); } @@ -129,7 +129,7 @@ public function changeGroupImage(Request $request) 'gid' => 'required|integer', ]); - $all_data = $request->all(); + $all_data=$request->all(); if (!empty($request->file('img')) && $request->file('img')->isValid()) { $extension=$request->file('img')->extension(); @@ -141,7 +141,7 @@ public function changeGroupImage(Request $request) $groupModel=new GroupModel(); $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id); - if ($clearance < 2){ + if ($clearance<2) { return ResponseModel::err(2001); } @@ -179,18 +179,18 @@ public function changeMemberClearance(Request $request) $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id); $target_clearance=$groupModel->judgeClearance($all_data["gid"], $all_data['uid']); - if($target_clearance == -3){ + if ($target_clearance==-3) { return ResponseModel::err(7004); } - if($target_clearance >= $clearance || $clearance < 2 || $all_data['permission'] >= $clearance){ + if ($target_clearance>=$clearance || $clearance<2 || $all_data['permission']>=$clearance) { return ResponseModel::err(2001); } $groupModel->changeClearance($all_data['uid'], $all_data["gid"], $all_data['permission']); - $result_info = $groupModel->userProfile($all_data['uid'],$all_data["gid"]); - return ResponseModel::success(200,null,$result_info); + $result_info=$groupModel->userProfile($all_data['uid'], $all_data["gid"]); + return ResponseModel::success(200, null, $result_info); } public function approveMember(Request $request) @@ -206,7 +206,7 @@ public function approveMember(Request $request) $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id); $targetClearance=$groupModel->judgeClearance($all_data["gid"], $all_data["uid"]); if ($clearance>1) { - if($targetClearance!=0) { + if ($targetClearance!=0) { return ResponseModel::err(7003); } $groupModel->changeClearance($all_data["uid"], $all_data["gid"], 1); @@ -227,7 +227,7 @@ public function removeMember(Request $request) $groupModel=new GroupModel(); $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id); $targetClearance=$groupModel->judgeClearance($all_data["gid"], $all_data["uid"]); - if ($clearance <= 1 || $clearance <= $targetClearance){ + if ($clearance<=1 || $clearance<=$targetClearance) { return ResponseModel::err(7002); } @@ -247,16 +247,22 @@ public function inviteMember(Request $request) $groupModel=new GroupModel(); $is_user=$groupModel->isUser($all_data["email"]); - if(!$is_user) return ResponseModel::err(2006); + if (!$is_user) { + return ResponseModel::err(2006); + } $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id); - if($clearance<2) return ResponseModel::err(7002); + if ($clearance<2) { + return ResponseModel::err(7002); + } $targetClearance=$groupModel->judgeEmailClearance($all_data["gid"], $all_data["email"]); - if($targetClearance!=-3) return ResponseModel::err(7003); + if ($targetClearance!=-3) { + return ResponseModel::err(7003); + } $groupModel->inviteMember($all_data["gid"], $all_data["email"]); - $basic = $groupModel->basic($all_data['gid']); - $url = route('group.detail',['gcode' => $basic['gcode']]); - $receiverInfo = UserModel::where('email',$all_data['email'])->first(); - $sender_name = Auth::user()->name; + $basic=$groupModel->basic($all_data['gid']); + $url=route('group.detail', ['gcode' => $basic['gcode']]); + $receiverInfo=User::where('email', $all_data['email'])->first(); + $sender_name=Auth::user()->name; sendMessage([ 'receiver' => $receiverInfo["id"], 'sender' => Auth::user()->id, @@ -298,7 +304,7 @@ public function createNotice(Request $request) $groupModel=new GroupModel(); $clearance=$groupModel->judgeClearance($all_data["gid"], Auth::user()->id); - if ($clearance < 2){ + if ($clearance<2) { return ResponseModel::err(2001); } $groupModel->createNotice($all_data["gid"], Auth::user()->id, $all_data["title"], $all_data["content"]); diff --git a/app/Http/Controllers/Ajax/MessageController.php b/app/Http/Controllers/Ajax/MessageController.php index d289a4fba..ef70b7714 100644 --- a/app/Http/Controllers/Ajax/MessageController.php +++ b/app/Http/Controllers/Ajax/MessageController.php @@ -15,24 +15,24 @@ public function unread(Request $request) $request->validate([ 'uid' => 'required|integer' ]); - $uid = $request->input('uid'); - if(!Auth::check() || Auth::user()->id != $uid){ + $uid=$request->input('uid'); + if (!Auth::check() || Auth::user()->id!=$uid) { return ResponseModel::err(2001); } - $ret = Message::unread($uid); - return ResponseModel::success(200,null,$ret); + $ret=Message::unread($uid); + return ResponseModel::success(200, null, $ret); } public function allRead() { - $uid = Auth::user()->id; + $uid=Auth::user()->id; Message::allRead($uid); return ResponseModel::success(200); } public function deleteAll() { - $uid = Auth::user()->id; + $uid=Auth::user()->id; Message::removeAllRead($uid); return ResponseModel::success(200); } diff --git a/app/Http/Controllers/Ajax/ProblemController.php b/app/Http/Controllers/Ajax/ProblemController.php index c1355884e..2f2de081f 100644 --- a/app/Http/Controllers/Ajax/ProblemController.php +++ b/app/Http/Controllers/Ajax/ProblemController.php @@ -110,8 +110,8 @@ public function submitSolutionDiscussion(Request $request) if (empty($basic)) { return ResponseModel::err(3001); } - $ret=$problemModel->addSolution($pid,Auth::user()->id,$content); - return $ret?ResponseModel::success(200):ResponseModel::err(3003); + $ret=$problemModel->addSolution($pid, Auth::user()->id, $content); + return $ret ?ResponseModel::success(200) : ResponseModel::err(3003); } /** * The Ajax Problem Solution Discussion Update. @@ -126,8 +126,8 @@ public function updateSolutionDiscussion(Request $request) $problemModel=new ProblemModel(); $psoid=$all_data["psoid"]; $content=$all_data["content"]; - $ret=$problemModel->updateSolution($psoid,Auth::user()->id,$content); - return $ret?ResponseModel::success(200):ResponseModel::err(3004); + $ret=$problemModel->updateSolution($psoid, Auth::user()->id, $content); + return $ret ?ResponseModel::success(200) : ResponseModel::err(3004); } /** * The Ajax Problem Solution Discussion Delete. @@ -141,8 +141,8 @@ public function deleteSolutionDiscussion(Request $request) $all_data=$request->all(); $problemModel=new ProblemModel(); $psoid=$all_data["psoid"]; - $ret=$problemModel->removeSolution($psoid,Auth::user()->id); - return $ret?ResponseModel::success(200):ResponseModel::err(3004); + $ret=$problemModel->removeSolution($psoid, Auth::user()->id); + return $ret ?ResponseModel::success(200) : ResponseModel::err(3004); } /** * The Ajax Problem Solution Discussion Vote. @@ -157,8 +157,8 @@ public function voteSolutionDiscussion(Request $request) $problemModel=new ProblemModel(); $psoid=$all_data["psoid"]; $type=$all_data["type"]; - $ret=$problemModel->voteSolution($psoid,Auth::user()->id,$type); - return $ret["ret"]?ResponseModel::success(200,null,["votes"=>$ret["votes"],"select"=>$ret["select"]]):ResponseModel::err(3004); + $ret=$problemModel->voteSolution($psoid, Auth::user()->id, $type); + return $ret["ret"] ?ResponseModel::success(200, null, ["votes"=>$ret["votes"], "select"=>$ret["select"]]) : ResponseModel::err(3004); } /** * The Ajax Problem Solution Submit. @@ -252,8 +252,8 @@ public function postDiscussion(Request $request) if (empty($basic)) { return ResponseModel::err(3001); } - $ret=$problemModel->addDiscussion(Auth::user()->id,$pid,$title,$content); - return $ret?ResponseModel::success(200, null, $ret):ResponseModel::err(3003); + $ret=$problemModel->addDiscussion(Auth::user()->id, $pid, $title, $content); + return $ret ?ResponseModel::success(200, null, $ret) : ResponseModel::err(3003); } public function addComment(Request $request) @@ -272,8 +272,8 @@ public function addComment(Request $request) if (empty($basic)) { return ResponseModel::err(3001); } - $ret=$problemModel->addComment(Auth::user()->id,$pdid,$content,$reply_id); - return $ret?ResponseModel::success(200, null, $ret):ResponseModel::err(3003); + $ret=$problemModel->addComment(Auth::user()->id, $pdid, $content, $reply_id); + return $ret ?ResponseModel::success(200, null, $ret) : ResponseModel::err(3003); } /** @@ -292,15 +292,15 @@ public function resubmitSolution(Request $request) $submissionData=$submissionModel->basic($all_data["sid"]); - if($submissionData["uid"]!=Auth::user()->id){ + if ($submissionData["uid"]!=Auth::user()->id) { return ResponseModel::err(2001); } - if($submissionData["verdict"]!="Submission Error"){ + if ($submissionData["verdict"]!="Submission Error") { return ResponseModel::err(6003); } - $submissionModel->updateSubmission($all_data["sid"],[ + $submissionModel->updateSubmission($all_data["sid"], [ "verdict"=>"Pending", "time"=>0, "memory"=>0 diff --git a/app/Http/Controllers/Ajax/SearchController.php b/app/Http/Controllers/Ajax/SearchController.php index 15e594bef..780f84afa 100644 --- a/app/Http/Controllers/Ajax/SearchController.php +++ b/app/Http/Controllers/Ajax/SearchController.php @@ -23,34 +23,34 @@ public function __invoke(Request $request) if (!$request->has('search_key')) { return ResponseModel::err(1003); } - $key = $request->input('search_key'); - $all_result = []; - $search_from = [ + $key=$request->input('search_key'); + $all_result=[]; + $search_from=[ 'users' => \App\Models\Search\UserSearchModel::class, 'problems' => \App\Models\Search\ProblemSearchModel::class, 'contests' => \App\Models\Search\ContestSearchModel::class, 'groups' => \App\Models\Search\GroupSearchModel::class, ]; foreach ($search_from as $name => $model_class) { - if(class_exists($model_class)){ - $model = new $model_class(); - if(!method_exists($model,'search')){ - $all_result[$name] = [ + if (class_exists($model_class)) { + $model=new $model_class(); + if (!method_exists($model, 'search')) { + $all_result[$name]=[ 'code' => -1, 'msg' => 'cannot find search method in '.$model_class ]; continue; } - $result = $model->search($key); - $all_result[$name] = $result; - }else{ - $all_result[$name] = [ + $result=$model->search($key); + $all_result[$name]=$result; + } else { + $all_result[$name]=[ 'code' => -1, 'msg' => 'cannot find class named '.$model_class - ];; + ]; ; continue; } } - return ResponseModel::success(200,'Successful',$all_result); + return ResponseModel::success(200, 'Successful', $all_result); } } diff --git a/app/Http/Controllers/Ajax/SubmissionController.php b/app/Http/Controllers/Ajax/SubmissionController.php index 8b144ba3f..b74ad2455 100644 --- a/app/Http/Controllers/Ajax/SubmissionController.php +++ b/app/Http/Controllers/Ajax/SubmissionController.php @@ -51,14 +51,14 @@ public function share(Request $request) return ResponseModel::err(3002); } $submissionModel=new SubmissionModel(); - if($all_data["method"]==1){ + if ($all_data["method"]==1) { // NOJ Share $status=$submissionModel->share($all_data["sid"], Auth::check() ? Auth::user()->id : null); - return empty($status)?ResponseModel::err(1001):ResponseModel::success(200, null, $status); - } elseif($all_data["method"]==2){ + return empty($status) ?ResponseModel::err(1001) : ResponseModel::success(200, null, $status); + } elseif ($all_data["method"]==2) { // Pastebin $status=$submissionModel->sharePB($all_data["sid"], Auth::check() ? Auth::user()->id : null); - return empty($status)?ResponseModel::err(1001):ResponseModel::success(200, null, $status); + return empty($status) ?ResponseModel::err(1001) : ResponseModel::success(200, null, $status); } else { return ResponseModel::err(6002); } diff --git a/app/Http/Controllers/Api/AccountController.php b/app/Http/Controllers/Api/AccountController.php index f55836abe..665a41886 100644 --- a/app/Http/Controllers/Api/AccountController.php +++ b/app/Http/Controllers/Api/AccountController.php @@ -8,19 +8,19 @@ class AccountController extends Controller { public function login(Request $request) { - $credentials = [ + $credentials=[ 'email' => $request->email, 'password' => $request->password ]; - if(auth()->attempt($credentials)) { - $user = auth()->user(); - if(!empty($user->tokens)){ - foreach($user->tokens as $token){ + if (auth()->attempt($credentials)) { + $user=auth()->user(); + if (!empty($user->tokens)) { + foreach ($user->tokens as $token) { $token->delete(); } } - $token = $user->createToken('NOJ Password Grant Client')->accessToken; + $token=$user->createToken('NOJ Password Grant Client')->accessToken; return response()->json([ 'success' => true, 'message' => 'Successfully Login', diff --git a/app/Http/Controllers/Api/ContestController.php b/app/Http/Controllers/Api/ContestController.php index 0a85e68ab..13942d9c9 100644 --- a/app/Http/Controllers/Api/ContestController.php +++ b/app/Http/Controllers/Api/ContestController.php @@ -11,7 +11,7 @@ class ContestController extends Controller { public function info(Request $request) { - $contest = $request->contest; + $contest=$request->contest; return response()->json([ 'success' => true, 'message' => 'Succeed', @@ -39,80 +39,80 @@ public function info(Request $request) { } public function status(Request $request) { - $page = $request->page ?? 1; - $filter = $request->filter; - $contest = $request->contest; + $page=$request->page ?? 1; + $filter=$request->filter; + $contest=$request->contest; - $account = $filter['account'] ?? null; - $problem = $filter['problem'] ?? null; - $result = $filter['result'] ?? null; + $account=$filter['account'] ?? null; + $problem=$filter['problem'] ?? null; + $result=$filter['result'] ?? null; //filter - $builder = $contest->submissions()->orderBy('submission_date', 'desc')->with(['user', 'contest.group', 'problem']); - if($account !== null) { - $participants = $contest->participants(); - $user = null; - foreach($participants as $participant) { - if($participant->name == $account){ - $user = $participant; + $builder=$contest->submissions()->orderBy('submission_date', 'desc')->with(['user', 'contest.group', 'problem']); + if ($account!==null) { + $participants=$contest->participants(); + $user=null; + foreach ($participants as $participant) { + if ($participant->name==$account) { + $user=$participant; break; } } - $builder = $builder->where('uid', $user == null ? -1 : $user->id); + $builder=$builder->where('uid', $user==null ? -1 : $user->id); } - if($problem !== null){ - $problem = $contest->problems()->where('ncode', $problem)->first(); - $builder = $builder->where('pid', $problem->pid ?? null); + if ($problem!==null) { + $problem=$contest->problems()->where('ncode', $problem)->first(); + $builder=$builder->where('pid', $problem->pid ?? null); } - if($result !== null) { - $builder = $builder->where('verdict', $result); + if ($result!==null) { + $builder=$builder->where('verdict', $result); } //status_visibility - if($contest->status_visibility == 1){ - if(auth()->check()){ - $builder = $builder->where('uid', auth()->user()->id); - }else{ - $builder = $builder->where('uid', -1); + if ($contest->status_visibility==1) { + if (auth()->check()) { + $builder=$builder->where('uid', auth()->user()->id); + } else { + $builder=$builder->where('uid', -1); } } - if($contest->status_visibility == 0){ - $builder = $builder->where('uid', -1); + if ($contest->status_visibility==0) { + $builder=$builder->where('uid', -1); } - $submissions = $builder->paginate(50); + $submissions=$builder->paginate(50); - $regex = '/\?page=([\d+])$/'; - $matches = []; - $pagination = [ + $regex='/\?page=([\d+])$/'; + $matches=[]; + $pagination=[ 'current_page' => $submissions->currentPage(), - 'has_next_page' => $submissions->nextPageUrl() === null ? false : true, - 'has_previous_page' => $submissions->previousPageUrl() === null ? false : true, + 'has_next_page' => $submissions->nextPageUrl()===null ? false : true, + 'has_previous_page' => $submissions->previousPageUrl()===null ? false : true, 'next_page' => null, 'previous_page' => null, 'num_pages' => $submissions->lastPage(), 'num_items' => $submissions->count(), ]; - if($pagination['has_next_page']) { - $next_page = preg_match($regex, $submissions->nextPageUrl(), $matches); - $pagination['next_page'] = intval($matches[1]); + if ($pagination['has_next_page']) { + $next_page=preg_match($regex, $submissions->nextPageUrl(), $matches); + $pagination['next_page']=intval($matches[1]); } - if($pagination['has_previous_page']) { - $next_page = preg_match($regex, $submissions->previousPageUrl(), $matches); - $pagination['previous_page'] = intval($matches[1]); + if ($pagination['has_previous_page']) { + $next_page=preg_match($regex, $submissions->previousPageUrl(), $matches); + $pagination['previous_page']=intval($matches[1]); } - $data = []; - foreach($submissions->items() as $submission) { - $score_parse = 0; - if($contest->rule == 2){ - if($submission->verdict == 'Accepted') { - $score_parse = 100; - }else if($submission->verdict == 'Partially Accepted') { - $score_parse = round($submission->score / $submission->problem->tot_score * $contest->problems()->where('pid', $submission->problem->pid)->first()->points, 1); + $data=[]; + foreach ($submissions->items() as $submission) { + $score_parse=0; + if ($contest->rule==2) { + if ($submission->verdict=='Accepted') { + $score_parse=100; + } else if ($submission->verdict=='Partially Accepted') { + $score_parse=round($submission->score / $submission->problem->tot_score * $contest->problems()->where('pid', $submission->problem->pid)->first()->points, 1); } } - $data[] = [ + $data[]=[ 'sid' => $submission->sid, 'name' => $submission->user->name, 'nickname' => $submission->nick_name, @@ -139,26 +139,26 @@ public function status(Request $request) { } public function scoreboard(Request $request) { - $contest = $request->contest; - $contestModel = new OutdatedContestModel(); - $contestRank = $contestModel->contestRank($contest->cid, auth()->check() ? auth()->user()->id : 0); + $contest=$request->contest; + $contestModel=new OutdatedContestModel(); + $contestRank=$contestModel->contestRank($contest->cid, auth()->check() ? auth()->user()->id : 0); //frozen about - if($contest->forze_length != 0) { - $frozen = [ + if ($contest->forze_length!=0) { + $frozen=[ 'enable' => true, 'frozen_length' => $contest->forze_length ]; - }else{ - $frozen = [ + } else { + $frozen=[ 'enable' => false, 'frozen_length' => 0 ]; } //header - if($contest->rule == 1){ - $header = [ + if ($contest->rule==1) { + $header=[ 'rank' => 'Rank', 'normal' => [ 'Account', 'Score', 'Penalty' @@ -167,14 +167,14 @@ public function scoreboard(Request $request) { 'problems' => [], 'problemsSubHeader' => [] ]; - $problems = $contest->problems()->orderBy('ncode', 'asc')->get(); - foreach($problems as $problem) { - $header['problems'][] = $problem->ncode; - $header['problemsSubHeader'][] = $problem->submissions()->where('submission_date', '<=', $contest->frozen_time)->where('verdict', 'Accepted')->count() - . ' / ' . $problem->submissions()->where('submission_date', '<=', $contest->frozen_time)->count(); + $problems=$contest->problems()->orderBy('ncode', 'asc')->get(); + foreach ($problems as $problem) { + $header['problems'][]=$problem->ncode; + $header['problemsSubHeader'][]=$problem->submissions()->where('submission_date', '<=', $contest->frozen_time)->where('verdict', 'Accepted')->count() + . ' / '.$problem->submissions()->where('submission_date', '<=', $contest->frozen_time)->count(); } - }else if($contest->rule == 2){ - $header = [ + } else if ($contest->rule==2) { + $header=[ 'rank' => 'Rank', 'normal' => [ 'Account', 'Score', 'Solved' @@ -182,76 +182,76 @@ public function scoreboard(Request $request) { 'subHeader' => false, 'problems' => [] ]; - $problems = $contest->problems()->orderBy('ncode', 'asc')->get(); - foreach($problems as $problem) { - $header['problems'][] = $problem->ncode; + $problems=$contest->problems()->orderBy('ncode', 'asc')->get(); + foreach ($problems as $problem) { + $header['problems'][]=$problem->ncode; } } - $user = auth()->user(); + $user=auth()->user(); //body - if($contest->rule == 1){ - $body = []; - $lastRank = null; - $rank = 1; - foreach($contestRank as $userRank) { - if(!empty($lastRank)) { - if($lastRank['score'] != $userRank['score'] || $lastRank['penalty'] != $userRank['penalty']) { - $rank += 1; + if ($contest->rule==1) { + $body=[]; + $lastRank=null; + $rank=1; + foreach ($contestRank as $userRank) { + if (!empty($lastRank)) { + if ($lastRank['score']!=$userRank['score'] || $lastRank['penalty']!=$userRank['penalty']) { + $rank+=1; } } - $lastRank = $userRank; - $userBody = [ + $lastRank=$userRank; + $userBody=[ 'rank' => $rank, 'normal' => [ $userRank['name'], $userRank['score'], intval($userRank['penalty']) ], 'problems' => [] ]; - foreach($userRank['problem_detail'] as $problem) { - $userBody['problems'][] = [ - 'mainColor' => $problem['color'] === "" ? null : $problem['color'], - 'mainScore' => $problem['solved_time_parsed'] === "" ? null : $problem['solved_time_parsed'], + foreach ($userRank['problem_detail'] as $problem) { + $userBody['problems'][]=[ + 'mainColor' => $problem['color']==="" ? null : $problem['color'], + 'mainScore' => $problem['solved_time_parsed']==="" ? null : $problem['solved_time_parsed'], 'subColor' => null, - 'subScore' => $problem['wrong_doings'] == 0 ? null : '-'.$problem['wrong_doings'] + 'subScore' => $problem['wrong_doings']==0 ? null : '-'.$problem['wrong_doings'] ]; } - $userBody['extra'] = [ - 'owner' => isset($userBody['remote']) && $userBody['remote'] ? false : $user->id == $userRank['uid'], + $userBody['extra']=[ + 'owner' => isset($userBody['remote']) && $userBody['remote'] ? false : $user->id==$userRank['uid'], 'remote' => $userBody['remote'] ?? false ]; - $body[] = $userBody; + $body[]=$userBody; } - }else if($contest->rule == 2){ - $body = []; - $lastRank = null; - $rank = 1; - foreach($contestRank as $userRank) { - if(!empty($lastRank)) { - if($lastRank['score'] != $userRank['score'] || $lastRank['solved'] != $userRank['solved']) { - $rank += 1; + } else if ($contest->rule==2) { + $body=[]; + $lastRank=null; + $rank=1; + foreach ($contestRank as $userRank) { + if (!empty($lastRank)) { + if ($lastRank['score']!=$userRank['score'] || $lastRank['solved']!=$userRank['solved']) { + $rank+=1; } } - $lastRank = $userRank; - $userBody = [ + $lastRank=$userRank; + $userBody=[ 'rank' => $rank, 'normal' => [ $userRank['name'], $userRank['score'], intval($userRank['solved']) ], 'problems' => [] ]; - foreach($userRank['problem_detail'] as $problem) { - $userBody['problems'][] = [ - 'mainColor' => $problem['color'] === "" ? null : $problem['color'], - 'mainScore' => $problem['score'] === "" ? null : $problem['score_parsed'], + foreach ($userRank['problem_detail'] as $problem) { + $userBody['problems'][]=[ + 'mainColor' => $problem['color']==="" ? null : $problem['color'], + 'mainScore' => $problem['score']==="" ? null : $problem['score_parsed'], 'subColor' => null, 'subScore' => null ]; } - $userBody['extra'] = [ - 'owner' => isset($userBody['remote']) && $userBody['remote'] ? false : $user->id == $userRank['uid'], + $userBody['extra']=[ + 'owner' => isset($userBody['remote']) && $userBody['remote'] ? false : $user->id==$userRank['uid'], 'remote' => $userBody['remote'] ?? false ]; - $body[] = $userBody; + $body[]=$userBody; } } @@ -268,7 +268,7 @@ public function scoreboard(Request $request) { } public function clarification(Request $request) { - $contest = $request->contest; + $contest=$request->contest; return response()->json([ 'success' => true, 'message' => 'Succeed', @@ -280,7 +280,7 @@ public function clarification(Request $request) { } public function requestClarification(Request $request) { - if(empty($request->title) || empty($request->contest)) { + if (empty($request->title) || empty($request->contest)) { return response()->json([ 'success' => false, 'message' => 'Parameter Missing', @@ -292,8 +292,8 @@ public function requestClarification(Request $request) { ] ]); } - $contest = $request->contest; - $clarification = $contest->clarifications()->create([ + $contest=$request->contest; + $clarification=$contest->clarifications()->create([ 'cid' => $contest->cid, 'type' => 1, 'title' => $request->title, @@ -312,18 +312,18 @@ public function requestClarification(Request $request) { } public function problems(Request $request) { - $contest = $request->contest; - $contestProblems = $contest->problems()->with('problem')->orderBy('ncode', 'asc')->get(); - $problems = []; - foreach($contestProblems as $contestProblem) { + $contest=$request->contest; + $contestProblems=$contest->problems()->with('problem')->orderBy('ncode', 'asc')->get(); + $problems=[]; + foreach ($contestProblems as $contestProblem) { //get status - $ac_submission = $contestProblem->submissions()->where('uid', auth()->user()->id)->where('verdict', 'Accepted')->orderBy('submission_date', 'desc')->first(); - $last_submission = $contestProblem->submissions()->where('uid', auth()->user()->id)->orderBy('submission_date', 'desc')->first(); + $ac_submission=$contestProblem->submissions()->where('uid', auth()->user()->id)->where('verdict', 'Accepted')->orderBy('submission_date', 'desc')->first(); + $last_submission=$contestProblem->submissions()->where('uid', auth()->user()->id)->orderBy('submission_date', 'desc')->first(); //get compilers - $compilers_info = []; - $compilers = $contestProblem->compilers->get(); - foreach($compilers as $compiler) { - $compilers_info[] = [ + $compilers_info=[]; + $compilers=$contestProblem->compilers->get(); + foreach ($compilers as $compiler) { + $compilers_info[]=[ 'coid' => $compiler->coid, 'oid' => $compiler->oid, 'comp' => $compiler->comp, @@ -333,8 +333,8 @@ public function problems(Request $request) { 'display_name' => $compiler->display_name ]; } - $highest_submit = $contestProblem->submissions()->where('uid', auth()->user()->id)->orderBy('score', 'desc')->first(); - $problems[] = [ + $highest_submit=$contestProblem->submissions()->where('uid', auth()->user()->id)->orderBy('score', 'desc')->first(); + $problems[]=[ 'pid' => $contestProblem->pid, 'pcode' => $contestProblem->problem->pcode, 'ncode' => $contestProblem->ncode, @@ -343,7 +343,7 @@ public function problems(Request $request) { 'time_limit' => $contestProblem->problem->time_limit, 'memory_limit' => $contestProblem->problem->memory_limit, ], - 'statistics' => $contest->rule == 1 ? [ + 'statistics' => $contest->rule==1 ? [ 'accepted' => $contestProblem->submissions()->where('submission_date', '<=', $contest->frozen_time)->where('verdict', 'Accepted')->count(), 'attempted' => $contestProblem->submissions()->where('submission_date', '<=', $contest->frozen_time)->count(), 'score' => null, @@ -387,12 +387,12 @@ public function problems(Request $request) { } public function submitSolution(Request $request) { - $contest = $request->contest; - $contest_problem = $request->contest_problem; - $problem = $request->problem; - $compiler = $request->compiler; + $contest=$request->contest; + $contest_problem=$request->contest_problem; + $problem=$request->problem; + $compiler=$request->compiler; - if(empty($request->solution) || strlen($request->solution) > 65535) { + if (empty($request->solution) || strlen($request->solution)>65535) { return response()->json([ 'success' => false, 'message' => 'Parameter \'solution\' Invalid', @@ -404,7 +404,7 @@ public function submitSolution(Request $request) { ] ]); } - $submission = Submission::create([ + $submission=Submission::create([ 'time'=>'0', 'memory'=>'0', 'verdict'=>'Pending', @@ -420,7 +420,7 @@ public function submitSolution(Request $request) { 'jid'=>null, 'score'=>0 ]); - $all_data = [ + $all_data=[ 'lang' => $compiler->lcode, 'pid' => $problem->pid, 'pcode' => $problem->pcode, @@ -433,9 +433,9 @@ public function submitSolution(Request $request) { 'contest' => $contest->cid, 'sid' => $submission->sid ]; - try{ + try { dispatch(new ProcessSubmission($all_data))->onQueue($problem->oj); - }catch(\Throwable $e){ + } catch (\Throwable $e) { return response()->json([ 'success' => false, 'message' => $e->getMessage(), @@ -457,10 +457,10 @@ public function submitSolution(Request $request) { ]); } - public function fetchAnnouncement(Request $request){ - $contest = $request->contest; - $clarification = $contest->clarifications()->where(['type' => 0, 'public' => 1]) - ->whereBetween('created_at',[date("Y-m-d H:i:s", time()-59), date("Y-m-d H:i:s")]) + public function fetchAnnouncement(Request $request) { + $contest=$request->contest; + $clarification=$contest->clarifications()->where(['type' => 0, 'public' => 1]) + ->whereBetween('created_at', [date("Y-m-d H:i:s", time()-59), date("Y-m-d H:i:s")]) ->first(); return response()->json([ 'success' => true, diff --git a/app/Http/Controllers/Api/ProblemController.php b/app/Http/Controllers/Api/ProblemController.php index c8ffa4e5a..13119538a 100644 --- a/app/Http/Controllers/Api/ProblemController.php +++ b/app/Http/Controllers/Api/ProblemController.php @@ -8,10 +8,10 @@ class ProblemController extends Controller { public function fetchVerdict(Request $request) { - $submission = $request->submission; - $problem = $submission->problem; - $contest = $submission->contest; - $contest_problem = !empty($contest) ? $submission->contest->problems()->where('pid', $problem->pid)->first() : null; + $submission=$request->submission; + $problem=$submission->problem; + $contest=$submission->contest; + $contest_problem=!empty($contest) ? $submission->contest->problems()->where('pid', $problem->pid)->first() : null; return response()->json([ 'success' => true, 'message' => 'Succeed', @@ -28,11 +28,11 @@ public function fetchVerdict(Request $request) { "lang" => $submission->compiler->lang, "language" => $submission->language, "memory" => $submission->memory, - "owner" => $submission->user->id == auth()->user()->id, + "owner" => $submission->user->id==auth()->user()->id, "pid" => $problem->pid, "remote_id" => $submission->remote_id, "score" => $submission->score, - "score_parsed" => (!empty($contest) && $contest->rule == 2) ? $submission->score / $problem->tot_score * $contest_problem->points : 0, // if has ioi contest set to score parsed, else 0 + "score_parsed" => (!empty($contest) && $contest->rule==2) ? $submission->score / $problem->tot_score * $contest_problem->points : 0, // if has ioi contest set to score parsed, else 0 "share" => $submission->share, "sid" => $submission->sid, "solution" => $submission->solution, diff --git a/app/Http/Controllers/Api/SubmissionController.php b/app/Http/Controllers/Api/SubmissionController.php index 1526c2b99..a36f66246 100644 --- a/app/Http/Controllers/Api/SubmissionController.php +++ b/app/Http/Controllers/Api/SubmissionController.php @@ -12,8 +12,8 @@ public function info(Request $request) return response()->json([ 'success' => true, 'message' => 'Succeed', - 'ret' => array_merge($request->submission->toArray(),[ - 'owner' => $request->submission->user->id == auth()->user()->id, + 'ret' => array_merge($request->submission->toArray(), [ + 'owner' => $request->submission->user->id==auth()->user()->id, 'lang' => $request->submission->compiler->lang ]), 'err' => [] diff --git a/app/Http/Controllers/Api/SystemController.php b/app/Http/Controllers/Api/SystemController.php index 6e7f55b46..ecb1ac2ce 100644 --- a/app/Http/Controllers/Api/SystemController.php +++ b/app/Http/Controllers/Api/SystemController.php @@ -7,7 +7,7 @@ class SystemController extends Controller { - public function info(){ + public function info() { return response()->json([ 'success' => true, 'message' => 'To Boldly Go', diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php index 5b2b31c8d..ef0203682 100644 --- a/app/Http/Controllers/Auth/ForgotPasswordController.php +++ b/app/Http/Controllers/Auth/ForgotPasswordController.php @@ -37,7 +37,7 @@ public function __construct() */ public function showLinkRequestForm() { - return view('auth.passwords.email',[ + return view('auth.passwords.email', [ 'page_title'=>"Reset Password", 'site_title'=>config("app.name"), 'navigation' => "Account" diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 627ea6dfc..c8e5e8479 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -4,6 +4,7 @@ use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\AuthenticatesUsers; +use App\Models\Eloquent\Tool\Socialite; class LoginController extends Controller { @@ -42,7 +43,8 @@ public function showLoginForm() return view("auth.login", [ 'page_title'=>"Login", 'site_title'=>config("app.name"), - 'navigation' => "Account" + 'navigation' => "Account", + 'socialites' => Socialite::getAvailable(), ]); } } diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index eae7c54ce..16b2a1681 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -2,7 +2,7 @@ namespace App\Http\Controllers\Auth; -use App\User; +use App\Models\Eloquent\User; use App\Http\Controllers\Controller; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Validator; @@ -50,7 +50,7 @@ protected function validator(array $data) { return Validator::make($data, [ 'name' => ['required', 'string', 'max:16', 'unique:users'], - 'email' => ['required', 'string', 'email', 'max:255', 'unique:users'], + 'email' => ['required', 'string', 'email', 'max:255', 'unique:users', 'allowed_email_domain'], 'password' => ['required', 'string', 'min:8', 'confirmed'], 'agreement' => ['required'], ]); @@ -60,7 +60,7 @@ protected function validator(array $data) * Create a new user instance after a valid registration. * * @param array $data - * @return \App\User + * @return \App\Models\Eloquent\User */ protected function create(array $data) { diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php index 59b6c0649..ffe5c3349 100644 --- a/app/Http/Controllers/Auth/ResetPasswordController.php +++ b/app/Http/Controllers/Auth/ResetPasswordController.php @@ -52,9 +52,9 @@ public function __construct() * @param string|null $token * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ - public function showResetForm(Request $request, $token = null) + public function showResetForm(Request $request, $token=null) { - return view('auth.passwords.reset',[ + return view('auth.passwords.reset', [ 'token' => $token, 'email' => $request->email, 'page_title'=>"Reset Password", diff --git a/app/Http/Controllers/Auth/VerificationController.php b/app/Http/Controllers/Auth/VerificationController.php index 2b9cdc634..afd8fce17 100644 --- a/app/Http/Controllers/Auth/VerificationController.php +++ b/app/Http/Controllers/Auth/VerificationController.php @@ -44,7 +44,7 @@ public function show(Request $request) { return $request->user()->hasVerifiedEmail() ? redirect($this->redirectPath()) - : view('auth.verify',[ + : view('auth.verify', [ 'page_title'=>"Verify Email", 'site_title'=>config("app.name"), 'navigation' => "Account" diff --git a/app/Http/Controllers/Contest/AdminController.php b/app/Http/Controllers/Contest/AdminController.php index c8bbc5c74..8b379a6b5 100644 --- a/app/Http/Controllers/Contest/AdminController.php +++ b/app/Http/Controllers/Contest/AdminController.php @@ -27,8 +27,8 @@ public function admin($cid) $contestModel=new ContestModel(); $verified=$contestModel->isVerified($cid); $clearance=$contestModel->judgeClearance($cid, Auth::user()->id); - if ($clearance <= 2) { - return Redirect::route('contest_detail', ['cid' => $cid]); + if ($clearance<=2) { + return Redirect::route('contest.detail', ['cid' => $cid]); } $contest_name=$contestModel->contestName($cid); $customInfo=$contestModel->getCustomInfo($cid); @@ -36,20 +36,20 @@ public function admin($cid) $basicInfo=$contestModel->basic($cid); $contest_accounts=$accountModel->getContestAccount($cid); $gcode=$contestModel->gcode($cid); - $isEnd = $contestModel->remainingTime($cid) < 0; - $generatePDFStatus = JobStatus::find(Cache::tags(['contest', 'admin', 'PDFGenerate'])->get($cid, 0)); - $generatePDFStatus = is_null($generatePDFStatus)?'empty':$generatePDFStatus->status; - if(in_array($generatePDFStatus,['finished','failed'])){ + $isEnd=$contestModel->remainingTime($cid)<0; + $generatePDFStatus=JobStatus::find(Cache::tags(['contest', 'admin', 'PDFGenerate'])->get($cid, 0)); + $generatePDFStatus=is_null($generatePDFStatus) ? 'empty' : $generatePDFStatus->status; + if (in_array($generatePDFStatus, ['finished', 'failed'])) { Cache::tags(['contest', 'admin', 'PDFGenerate'])->forget($cid); } - $anticheatStatus = JobStatus::find(Cache::tags(['contest', 'admin', 'anticheat'])->get($cid, 0)); - $anticheatProgress = is_null($anticheatStatus)?0:$anticheatStatus->progress_percentage; - $anticheatStatus = is_null($anticheatStatus)?'empty':$anticheatStatus->status; - if(Storage::disk('local')->exists("contest/anticheat/$cid/report/report.zip")) { + $anticheatStatus=JobStatus::find(Cache::tags(['contest', 'admin', 'anticheat'])->get($cid, 0)); + $anticheatProgress=is_null($anticheatStatus) ? 0 : $anticheatStatus->progress_percentage; + $anticheatStatus=is_null($anticheatStatus) ? 'empty' : $anticheatStatus->status; + if (Storage::disk('local')->exists("contest/anticheat/$cid/report/report.zip")) { $anticheatStatus='finished'; $anticheatProgress=100; } - if(in_array($anticheatStatus, ['finished','failed'])){ + if (in_array($anticheatStatus, ['finished', 'failed'])) { Cache::tags(['contest', 'admin', 'anticheat'])->forget($cid); } return view('contest.board.admin', [ @@ -77,46 +77,52 @@ public function downloadContestAccountXlsx($cid) { $contestModel=new ContestModel(); $clearance=$contestModel->judgeClearance($cid, Auth::user()->id); - if ($clearance <= 2) { - return Redirect::route('contest_detail', ['cid' => $cid]); + if ($clearance<=2) { + return Redirect::route('contest.detail', ['cid' => $cid]); } $account=$contestModel->getContestAccount($cid); - if($account==null){ - return ; - }else{ + if ($account==null) { + return; + } else { $AccountExport=new AccountExport($account); $filename="ContestAccount$cid"; return Excel::download($AccountExport, $filename.'.xlsx'); } } - public function refreshContestRank($cid){ + public function refreshContestRank($cid) { $contestModel=new ContestModel(); $clearance=$contestModel->judgeClearance($cid, Auth::user()->id); - if ($clearance <= 2) { + if ($clearance<=2) { return Redirect::route('contest.detail', ['cid' => $cid]); } - $contest_eloquent = EloquentContestModel::find($cid); + $contest_eloquent=EloquentContestModel::find($cid); $contestRankRaw=$contest_eloquent->rankRefresh(); Cache::tags(['contest', 'rank'])->put($cid, $contestRankRaw); Cache::tags(['contest', 'rank'])->put("contestAdmin$cid", $contestRankRaw); $end_time=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]); - if(time() > strtotime($end_time)){ + if (time()>strtotime($end_time)) { $contestModel->storeContestRankInMySQL($cid, $contestRankRaw); } $contestModel->deleteZip("contestCodeZip/$cid/"); - return Redirect::route('contest.rank', ['cid' => $cid]); + return Redirect::route('contest.board.rank', ['cid' => $cid]); } - public function scrollBoard($cid){ + public function scrollBoard($cid) { $contestModel=new ContestModel(); $clearance=$contestModel->judgeClearance($cid, Auth::user()->id); - if ($clearance <= 2) { - return Redirect::route('contest_detail', ['cid' => $cid]); + if ($clearance<=2) { + return Redirect::route('contest.detail', ['cid' => $cid]); } $basicInfo=$contestModel->basic($cid); - if($basicInfo['froze_length'] == 0){ - return Redirect::route('contest.admin', ['cid' => $cid]); + if ($basicInfo['froze_length']==0) { + return Redirect::route('contest.board.admin', ['cid' => $cid]); + } + if ($basicInfo['registration']==0) { + return Redirect::route('contest.board.admin', ['cid' => $cid]); + } + if ($basicInfo['rule']!=1) { + return Redirect::route('contest.board.admin', ['cid' => $cid]); } return view('contest.board.scrollBoard', [ 'page_title'=>"ScrollBoard", diff --git a/app/Http/Controllers/Contest/BoardController.php b/app/Http/Controllers/Contest/BoardController.php index 799f57137..669b753a7 100644 --- a/app/Http/Controllers/Contest/BoardController.php +++ b/app/Http/Controllers/Contest/BoardController.php @@ -6,8 +6,8 @@ use App\Models\ProblemModel; use App\Models\CompilerModel; use App\Models\Submission\SubmissionModel; -use App\Models\AccountModel; use App\Http\Controllers\Controller; +use App\Models\Eloquent\Tool\MonacoTheme; use Illuminate\Http\Request; use Auth; use Redirect; @@ -21,7 +21,7 @@ class BoardController extends Controller */ public function board($cid) { - return Redirect::route('contest.challenge', ['cid' => $cid]); + return Redirect::route('contest.board.challenge', ['cid' => $cid]); } /** @@ -34,10 +34,10 @@ public function challenge($cid) $contestModel=new ContestModel(); $clearance=$contestModel->judgeClearance($cid, Auth::user()->id); $basicInfo=$contestModel->basic($cid); - if (!$clearance || time() < strtotime($basicInfo['begin_time'])) { - if($clearance == 3){ - return Redirect::route('contest.admin', ['cid' => $cid]); - }else{ + if (!$clearance || time() $cid]); + } else { return Redirect::route('contest.detail', ['cid' => $cid]); } } @@ -50,7 +50,7 @@ public function challenge($cid) if ($remainingTime<=0) { $remainingTime=0; } - if($basicInfo['public'] && !$basicInfo['audit_status']){ + if ($basicInfo['public'] && !$basicInfo['audit_status']) { return Redirect::route('contest.detail', ['cid' => $cid]); } return view('contest.board.challenge', [ @@ -80,18 +80,17 @@ public function editor($cid, $ncode) $problemModel=new ProblemModel(); $compilerModel=new CompilerModel(); $submissionModel=new SubmissionModel(); - $accountModel=new AccountModel(); $clearance=$contestModel->judgeClearance($cid, Auth::user()->id); $basicInfo=$contestModel->basic($cid); - if (!$clearance || time() < strtotime($basicInfo['begin_time'])) { - if($clearance == 3){ - return Redirect::route('contest.admin', ['cid' => $cid]); - }else{ + if (!$clearance || time() $cid]); + } else { return Redirect::route('contest.detail', ['cid' => $cid]); } } $basicInfo=$contestModel->basic($cid); - if($basicInfo['public'] && !$basicInfo['audit_status']){ + if ($basicInfo['public'] && !$basicInfo['audit_status']) { return Redirect::route('contest.detail', ['cid' => $cid]); } $contest_name=$contestModel->contestName($cid); @@ -99,7 +98,7 @@ public function editor($cid, $ncode) $contest_ended=$contestModel->isContestEnded($cid); $pid=$contestModel->getPid($cid, $ncode); if (empty($pid)) { - return Redirect::route('contest.board', ['cid' => $cid]); + return Redirect::route('contest.board.index', ['cid' => $cid]); } $pcode=$problemModel->pcode($pid); @@ -122,8 +121,10 @@ public function editor($cid, $ncode) ]; } - $editor_left_width = $accountModel->getExtra(Auth::user()->id, 'editor_left_width'); - if(empty($editor_left_width)) $editor_left_width='40'; + $accountExt=Auth::user()->getExtra(['editor_left_width', 'editor_theme']); + $editor_left_width=isset($accountExt['editor_left_width']) ? $accountExt['editor_left_width'] : '40'; + $editor_theme=isset($accountExt['editor_theme']) ? $accountExt['editor_theme'] : 'vs-dark'; + $themeConfig=MonacoTheme::getTheme($editor_theme); return view('contest.board.editor', [ 'page_title'=>"Problem Detail", @@ -144,6 +145,8 @@ public function editor($cid, $ncode) 'clearance' => $clearance, 'oj_detail' => $oj_detail, 'editor_left_width'=>$editor_left_width, + 'theme_config'=>$themeConfig, + 'editor_themes'=>MonacoTheme::getAll(), ]); } @@ -157,15 +160,15 @@ public function rank($cid) $contestModel=new ContestModel(); $clearance=$contestModel->judgeClearance($cid, Auth::user()->id); $basicInfo=$contestModel->basic($cid); - if (!$clearance || time() < strtotime($basicInfo['begin_time'])) { - if($clearance == 3){ - return Redirect::route('contest.admin', ['cid' => $cid]); - }else{ + if (!$clearance || time() $cid]); + } else { return Redirect::route('contest.detail', ['cid' => $cid]); } } $basicInfo=$contestModel->basic($cid); - if($basicInfo['public'] && !$basicInfo['audit_status']){ + if ($basicInfo['public'] && !$basicInfo['audit_status']) { return Redirect::route('contest.detail', ['cid' => $cid]); } $contest_name=$contestModel->contestName($cid); @@ -176,14 +179,14 @@ public function rank($cid) // To determine the ranking foreach ($contestRank as $i => &$r) { - if($i != 0) { - if($r['score'] == $contestRank[$i-1]['score'] && ($contest_rule == 1 ? ($r['penalty'] == $contestRank[$i-1]['penalty']) : 1) ){ - $r['rank'] = $contestRank[$i-1]['rank']; - }else{ - $r['rank'] = $i + 1; + if ($i!=0) { + if ($r['score']==$contestRank[$i-1]['score'] && ($contest_rule==1 ? ($r['penalty']==$contestRank[$i-1]['penalty']) : 1)) { + $r['rank']=$contestRank[$i-1]['rank']; + } else { + $r['rank']=$i+1; } - }else{ - $r['rank'] = 1; + } else { + $r['rank']=1; } } $rankFrozen=$contestModel->isFrozen($cid); @@ -220,15 +223,15 @@ public function status(Request $request) $contestModel=new ContestModel(); $clearance=$contestModel->judgeClearance($cid, Auth::user()->id); $basicInfo=$contestModel->basic($cid); - if (!$clearance || time() < strtotime($basicInfo['begin_time'])) { - if($clearance == 3){ - return Redirect::route('contest.admin', ['cid' => $cid]); - }else{ + if (!$clearance || time() $cid]); + } else { return Redirect::route('contest.detail', ['cid' => $cid]); } } $basicInfo=$contestModel->basic($cid); - if($basicInfo['public'] && !$basicInfo['audit_status']){ + if ($basicInfo['public'] && !$basicInfo['audit_status']) { return Redirect::route('contest.detail', ['cid' => $cid]); } $contest_name=$contestModel->contestName($cid); @@ -262,14 +265,14 @@ public function clarification($cid) $contestModel=new ContestModel(); $clearance=$contestModel->judgeClearance($cid, Auth::user()->id); $basicInfo=$contestModel->basic($cid); - if (!$clearance || time() < strtotime($basicInfo['begin_time'])) { - if($clearance == 3){ - return Redirect::route('contest.admin', ['cid' => $cid]); - }else{ + if (!$clearance || time() $cid]); + } else { return Redirect::route('contest.detail', ['cid' => $cid]); } } - if($basicInfo['public'] && !$basicInfo['audit_status']){ + if ($basicInfo['public'] && !$basicInfo['audit_status']) { return Redirect::route('contest.detail', ['cid' => $cid]); } $contest_name=$contestModel->contestName($cid); @@ -300,14 +303,14 @@ public function print($cid) $contestModel=new ContestModel(); $clearance=$contestModel->judgeClearance($cid, Auth::user()->id); $basicInfo=$contestModel->basic($cid); - if (!$clearance || time() < strtotime($basicInfo['begin_time'])) { - if($clearance == 3){ - return Redirect::route('contest.admin', ['cid' => $cid]); - }else{ + if (!$clearance || time() $cid]); + } else { return Redirect::route('contest.detail', ['cid' => $cid]); } } - if($basicInfo['public'] && !$basicInfo['audit_status']){ + if ($basicInfo['public'] && !$basicInfo['audit_status']) { return Redirect::route('contest.detail', ['cid' => $cid]); } $contest_name=$contestModel->contestName($cid); @@ -324,19 +327,19 @@ public function print($cid) ]); } - public function analysis($cid){ + public function analysis($cid) { $contestModel=new ContestModel(); $clearance=$contestModel->judgeClearance($cid, Auth::user()->id); $basicInfo=$contestModel->basic($cid); - if (!$clearance || time() < strtotime($basicInfo['begin_time'])) { - if($clearance == 3){ - return Redirect::route('contest.admin', ['cid' => $cid]); - }else{ + if (!$clearance || time() $cid]); + } else { return Redirect::route('contest.detail', ['cid' => $cid]); } } $basicInfo=$contestModel->basic($cid); - if($basicInfo['public'] && !$basicInfo['audit_status']){ + if ($basicInfo['public'] && !$basicInfo['audit_status']) { return Redirect::route('contest.detail', ['cid' => $cid]); } $contest_name=$contestModel->contestName($cid); diff --git a/app/Http/Controllers/Contest/IndexController.php b/app/Http/Controllers/Contest/IndexController.php index 419db74b8..37863f304 100644 --- a/app/Http/Controllers/Contest/IndexController.php +++ b/app/Http/Controllers/Contest/IndexController.php @@ -27,7 +27,7 @@ public function index(Request $request) $filter["rated"]=isset($all_data["rated"]) ? $all_data["rated"] : null; $filter["anticheated"]=isset($all_data["anticheated"]) ? $all_data["anticheated"] : null; $filter["practice"]=isset($all_data["practice"]) ? $all_data["practice"] : null; - $return_list=$contestModel->list($filter,Auth::check()?Auth::user()->id:0); + $return_list=$contestModel->list($filter, Auth::check() ?Auth::user()->id : 0); $featured=$contestModel->featured(); if (is_null($return_list)) { if (isset($all_data["page"]) && $all_data["page"]>1) { @@ -66,7 +66,7 @@ public function detail($cid) $contestModel=new ContestModel(); $groupModel=new GroupModel(); $clearance=Auth::check() ? $contestModel->judgeClearance($cid, Auth::user()->id) : 0; - $basic = $contestModel->basic($cid); + $basic=$contestModel->basic($cid); if (Auth::check()) { $contest_detail=$contestModel->detail($cid, Auth::user()->id); $registration=$contestModel->registration($cid, Auth::user()->id); diff --git a/app/Http/Controllers/Group/AdminController.php b/app/Http/Controllers/Group/AdminController.php index 11992fa8f..9da74d3b9 100644 --- a/app/Http/Controllers/Group/AdminController.php +++ b/app/Http/Controllers/Group/AdminController.php @@ -21,7 +21,7 @@ class AdminController extends Controller */ public function settings($gcode) { - return Redirect::route('group.settings.general', ['gcode' => $gcode]);; + return Redirect::route('group.settings.general', ['gcode' => $gcode]); ; } /** @@ -31,7 +31,7 @@ public function settings($gcode) */ public function settingsReturn($gcode) { - return Redirect::route('group.detail', ['gcode' => $gcode]);; + return Redirect::route('group.detail', ['gcode' => $gcode]); ; } /** @@ -60,10 +60,10 @@ public function settingsGeneral($gcode) * * @return Response */ - public function problems($gcode){ - $groupModel = new GroupModel(); - $group_info = $groupModel->details($gcode); - $problems = $groupModel->problems($group_info['gid']); + public function problems($gcode) { + $groupModel=new GroupModel(); + $group_info=$groupModel->details($gcode); + $problems=$groupModel->problems($group_info['gid']); $basic_info=$groupModel->details($gcode); return view('group.settings.problems', [ 'page_title'=>"Group Problems", @@ -104,6 +104,13 @@ public function settingsMember($gcode) $clearance=$groupModel->judgeClearance($basic_info["gid"], Auth::user()->id); $member_list=$groupModel->userList($basic_info["gid"]); $group_notice=$groupModel->detailNotice($gcode); + // PHP 7.4 Fix + if (is_null($group_notice)) { + $group_notice=[ + 'content'=>null, + 'title'=>null, + ]; + } return view('group.settings.member', [ 'page_title'=>"Group Setting Member", 'site_title'=>config("app.name"), diff --git a/app/Http/Controllers/Group/IndexController.php b/app/Http/Controllers/Group/IndexController.php index b0e154121..2cf435c17 100644 --- a/app/Http/Controllers/Group/IndexController.php +++ b/app/Http/Controllers/Group/IndexController.php @@ -47,8 +47,15 @@ public function detail($gcode) $clearance=$groupModel->judgeClearance($basic_info["gid"], Auth::user()->id); $member_list=$groupModel->userList($basic_info["gid"]); $group_notice=$groupModel->groupNotice($basic_info["gid"]); - $contest_list=$contestModel->listByGroup($basic_info["gid"])['contest_list']; - $paginator=$contestModel->listByGroup($basic_info["gid"])['paginator']; + // PHP 7.4 Fix + $groupContest=$contestModel->listByGroup($basic_info["gid"]); + if (is_null($groupContest)) { + $contest_list=null; + $paginator=null; + } else { + $contest_list=$contestModel->listByGroup($basic_info["gid"])['contest_list']; + $paginator=$contestModel->listByGroup($basic_info["gid"])['paginator']; + } return view('group.detail', [ 'page_title'=>"Group Detail", 'site_title'=>config("app.name"), @@ -85,12 +92,14 @@ public function create() * * @return Response */ - public function analysis($gcode){ - $groupModel = new GroupModel(); + public function analysis($gcode) { + $groupModel=new GroupModel(); $basic_info=$groupModel->details($gcode); $clearance=$groupModel->judgeClearance($basic_info["gid"], Auth::user()->id); - if($clearance < 1) return Redirect::route('group.detail',['gcode' => $gcode]); - $group_info = $groupModel->details($gcode); + if ($clearance<1) { + return Redirect::route('group.detail', ['gcode' => $gcode]); + } + $group_info=$groupModel->details($gcode); return view('group.settings.analysis', [ 'page_title'=>"Group Analysis", 'site_title'=>"NOJ", @@ -100,13 +109,13 @@ public function analysis($gcode){ ]); } - public function analysisDownload($gcode,Request $request){ - $all_data = $request->all(); - $groupModel = new GroupModel(); - $group_info = $groupModel->details($gcode); - $mode = $all_data['mode'] ?? 'contest'; - if($mode == 'contest'){ - $data = $groupModel->groupMemberPracticeContestStat($group_info['gid']); + public function analysisDownload($gcode, Request $request) { + $all_data=$request->all(); + $groupModel=new GroupModel(); + $group_info=$groupModel->details($gcode); + $mode=$all_data['mode'] ?? 'contest'; + if ($mode=='contest') { + $data=$groupModel->groupMemberPracticeContestStat($group_info['gid']); return Excel::download( new GroupAnalysisExport( [ @@ -119,10 +128,10 @@ public function analysisDownload($gcode,Request $request){ 'percent' => $all_data['percent'] ?? false, ] ), - $gcode . '_Group_Contest_Analysis.xlsx' + $gcode.'_Group_Contest_Analysis.xlsx' ); - }else{ - $data = $groupModel->groupMemberPracticeTagStat($group_info['gid']); + } else { + $data=$groupModel->groupMemberPracticeTagStat($group_info['gid']); return Excel::download( new GroupAnalysisExport( [ @@ -135,7 +144,7 @@ public function analysisDownload($gcode,Request $request){ 'percent' => $all_data['percent'] ?? false, ] ), - $gcode . '_Group_Tag_Analysis.xlsx' + $gcode.'_Group_Tag_Analysis.xlsx' ); } } diff --git a/app/Http/Controllers/LatexController.php b/app/Http/Controllers/LatexController.php index 48daca2a7..31e403229 100644 --- a/app/Http/Controllers/LatexController.php +++ b/app/Http/Controllers/LatexController.php @@ -12,7 +12,7 @@ class LatexController extends Controller { public function svg(Request $request) { - $ltxsource = $request->input('ltxsource'); + $ltxsource=$request->input('ltxsource'); if (is_null($ltxsource)) { return; } @@ -24,7 +24,7 @@ public function svg(Request $request) public function png(Request $request) { - $ltxsource = $request->input('ltxsource'); + $ltxsource=$request->input('ltxsource'); if (is_null($ltxsource)) { return; } @@ -39,17 +39,17 @@ private static function generatePNG($ltxsource) if (!Storage::exists('latex-svg/'.urlencode($ltxsource).'.svg')) { self::generateSVG($ltxsource); } - $image = new Imagick(); + $image=new Imagick(); $image->readImageBlob(Storage::get('latex-svg/'.urlencode($ltxsource).'.svg')); - $res = $image->getImageResolution(); - $x_ratio = $res['x'] / $image->getImageWidth(); - $y_ratio = $res['y'] / $image->getImageHeight(); + $res=$image->getImageResolution(); + $x_ratio=$res['x'] / $image->getImageWidth(); + $y_ratio=$res['y'] / $image->getImageHeight(); // $ratio=intval(200/$image->getImageHeight()); $ratio=10; - $width=$image->getImageWidth()*$ratio; - $height=$image->getImageHeight()*$ratio; + $width=$image->getImageWidth() * $ratio; + $height=$image->getImageHeight() * $ratio; $image->removeImage(); - $image->setResolution($width*$x_ratio, $height*$y_ratio); + $image->setResolution($width * $x_ratio, $height * $y_ratio); $image->setBackgroundColor(new \ImagickPixel('transparent')); $image->readImageBlob(Storage::get('latex-svg/'.urlencode($ltxsource).'.svg')); $image->setImageFormat("png32"); @@ -58,7 +58,7 @@ private static function generatePNG($ltxsource) private static function generateSVG($ltxsource) { - $contents=str_replace('fill:rgb(0%,0%,0%)', 'fill:rgb(0,0,0)', Requests::get('http://www.tlhiv.org/ltxpreview/ltxpreview.cgi?' . http_build_query([ + $contents=str_replace('fill:rgb(0%,0%,0%)', 'fill:rgb(0,0,0)', Requests::get('http://www.tlhiv.org/ltxpreview/ltxpreview.cgi?'.http_build_query([ 'width' => 10, 'height' => 10, 'ltx' => '', diff --git a/app/Http/Controllers/MainController.php b/app/Http/Controllers/MainController.php index f113baca2..f4549b56c 100644 --- a/app/Http/Controllers/MainController.php +++ b/app/Http/Controllers/MainController.php @@ -11,9 +11,9 @@ */ namespace App\Http\Controllers; -use App\Models\AnnouncementModel; +use App\Models\Eloquent\Announcement; use App\Models\ProblemModel; -use App\Models\CarouselModel; +use App\Models\Eloquent\Carousel; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Auth; @@ -40,8 +40,6 @@ class MainController extends Controller */ public function home(Request $request) { - $announcementModel=new AnnouncementModel(); - $announcements=$announcementModel->fetch(); $problem=new ProblemModel(); $ojs=$problem->ojs(); // Log::debug(["info"=>"User Viewed Home!"]); @@ -49,9 +47,9 @@ public function home(Request $request) 'page_title'=>"Home", 'site_title'=>config("app.name"), 'navigation' => "Home", - 'announcements' => $announcements, + 'announcements' => Announcement::orderBy('created_at', 'desc')->get(), 'ojs' => $ojs, - 'carousel' => CarouselModel::list() + 'carousel' => Carousel::where(["available"=>1])->get() ]); } @@ -59,11 +57,11 @@ public function home(Request $request) public function oldRedirect(Request $request) { $all_data=$request->all(); - $method=isset($all_data["method"])?$all_data["method"]:null; - $id=isset($all_data["id"])?$all_data["id"]:null; - if($method=="showdetail" && !is_null($id)){ + $method=isset($all_data["method"]) ? $all_data["method"] : null; + $id=isset($all_data["id"]) ? $all_data["id"] : null; + if ($method=="showdetail" && !is_null($id)) { $problemModel=new ProblemModel(); - return ($problemModel->existPCode("NOJ$id"))?Redirect::route('problem.detail', ['pcode' => "NOJ$id"]):Redirect::route('problem_index'); + return ($problemModel->existPCode("NOJ$id")) ?Redirect::route('problem.detail', ['pcode' => "NOJ$id"]) : Redirect::route('problem_index'); } return Redirect::route('home'); } diff --git a/app/Http/Controllers/MessageController.php b/app/Http/Controllers/MessageController.php index b6062e7dc..c64490c2c 100644 --- a/app/Http/Controllers/MessageController.php +++ b/app/Http/Controllers/MessageController.php @@ -10,8 +10,8 @@ class MessageController extends Controller { public function index() { - $uid = Auth::user()->id; - $messages = Message::list($uid); + $uid=Auth::user()->id; + $messages=Message::list($uid); return view('message.index', [ 'page_title'=>"Message", 'site_title'=>config("app.name"), @@ -22,8 +22,8 @@ public function index() public function detail($id) { - $message = Message::read($id); - if(empty($message) || $message->receiver != Auth::user()->id){ + $message=Message::read($id); + if (empty($message) || $message->receiver!=Auth::user()->id) { return Redirect::route('message.index'); } return view('message.detail', [ diff --git a/app/Http/Controllers/OAuth/AAuthController.php b/app/Http/Controllers/OAuth/AAuthController.php new file mode 100644 index 000000000..58c5da3ba --- /dev/null +++ b/app/Http/Controllers/OAuth/AAuthController.php @@ -0,0 +1,126 @@ +platformName="AAuth"; + $this->platformID="aauth"; + } + + public function redirectTo() + { + // 2 ways to access this page, you want to bind(logined), you want to login(not logined) + if (Auth::check()) { + // logined user, only users with non-temp email & pass access and binded can unbind + if (!Auth::user()->isIndependent()) { + return redirect()->route('account.settings'); + } + if (Auth::user()->getExtra('aauth_id')) { + return $this->generateOperationView(Auth::user()->getExtra('aauth_nickname')); + } + } + return new RedirectResponse('https://cn.aauth.link/#/launch/'.config('services.aauth.client_id')); + } + + private function user($code) + { + $response=Requests::post('https://cn.api.aauth.link/auth/', [], json_encode([ + 'code' => $code, + 'app' => config('services.aauth.client_id'), + 'secret' => config('services.aauth.client_secret') + ])); + if (!$response->success) { + throw new Exception('Requesting Error'); + } + $user=json_decode($response->body); + if (json_last_error()!==JSON_ERROR_NONE) { + throw new Exception('JSON Error'); + } + return $user; + } + + public function handleCallback() + { + try { + $aauth_user=$this->user(request()->code); + } catch (Throwable $e) { + return redirect()->route('home'); + } + + if (Auth::check()) { + $user_id=Auth::user()->id; + $ret=UserExtra::search('aauth_id', $aauth_user->id); + if (!empty($ret) && $ret[0]['uid']!=$user_id) { + $user=User::find($ret[0]['uid']); + return $this->generateDuplicateView($user->email); + } + Auth::user()->setExtra('aauth_id', $aauth_user->id); + Auth::user()->setExtra('aauth_nickname', $aauth_user->name); + return $this->generateSuccessView(Auth::user()->getExtra('aauth_nickname')); + } else { + $ret=UserExtra::search('aauth_id', $aauth_user->id); + if (!empty($ret)) { + Auth::loginUsingId($ret[0]['uid'], true); + Auth::user()->setExtra('aauth_nickname', $aauth_user->name); + return redirect()->route('account.dashboard'); + } else { + if (config('app.allow_oauth_temp_account')) { + try { + $createdUser=User::create([ + 'name' => Str::random(12), + 'email' => Str::random(16)."@temporary.email", + 'password' => '', + 'avatar' => '/static/img/avatar/default.png', + ]); + } catch (QueryException $exception) { + return $this->generateUnknownErrorView(); + } + Auth::loginUsingId($createdUser->id, true); + Auth::user()->setExtra('aauth_id', $aauth_user->id); + Auth::user()->setExtra('aauth_nickname', $aauth_user->name); + return redirect()->route('account.dashboard'); + } + return $this->generateAccountNotFoundView(); + } + } + } + + public function unbind() + { + if (!Auth::check()) { + return redirect()->route('home'); + } + if (Auth::user()->getExtra('aauth_id')) { + return $this->generateUnbindConfirmView(Auth::user()->email, Auth::user()->getExtra('aauth_nickname')); + } else { + return $this->generateAlreadyUnbindView(); + } + } + + public function confirmUnbind() + { + if (!Auth::check()) { + return redirect()->route('home'); + } + if (Auth::user()->getExtra('aauth_id')) { + Auth::user()->setExtra('aauth_id', null); + Auth::user()->setExtra('aauth_nickname', null); + return $this->generateUnbindSuccessView(); + } else { + return $this->generateAlreadyUnbindView(); + } + } +} diff --git a/app/Http/Controllers/OAuth/GithubController.php b/app/Http/Controllers/OAuth/GithubController.php index afff29662..3eb287e78 100644 --- a/app/Http/Controllers/OAuth/GithubController.php +++ b/app/Http/Controllers/OAuth/GithubController.php @@ -1,214 +1,128 @@ platform="Github"; + $this->platformID="github"; + } + public function redirectTo() { - $accountModel = new AccountModel(); - if(Auth::check()){ - $info=$accountModel->detail(Auth::user()->id); - if(Auth::check() && $info['contest_account']){ - return redirect('/account/settings'); + // 2 ways to access this page, you want to bind(logined), you want to login(not logined) + if (Auth::check()) { + // logined user, only users with non-temp email & pass access and binded can unbind + if (!Auth::user()->isIndependent()) { + return redirect()->route('account.settings'); + } + if (Auth::user()->getExtra('github_id')) { + return $this->generateOperationView(Auth::user()->getExtra('github_email')); } - } - if(Auth::check() && $accountModel->getExtra(Auth::user()->id ,'github_id')){ - return view('oauth.index',[ - 'page_title'=>"OAuth", - 'site_title'=>config("app.name"), - 'navigation'=>"OAuth", - 'platform' => 'Github', - 'display_html' => 'You\'re already tied to the github account : '.$accountModel->getExtra(Auth::user()->id ,'github_email').'
- You can choose to unbind or go back to the homepage', - 'buttons' => [ - [ - 'text' => 'unbind', - 'href' => route('oauth.github.unbind'), - 'style' => 'btn-danger' - ], - [ - 'text' => 'home', - 'href' => route('home'), - ], - ] - ]); } return Socialite::driver('github')->redirect(); } public function handleCallback() { - try{ - $github_user = Socialite::driver('github')->user(); - }catch(\Laravel\Socialite\Two\InvalidStateException $e){ - return redirect('/'); + try { + $github_user=Socialite::driver('github')->user(); + } catch (\Laravel\Socialite\Two\InvalidStateException $e) { + return redirect()->route('home'); } - $accountModel = new AccountModel(); - if(Auth::check()){ - $user_id = Auth::user()->id; - $ret = $accountModel->findExtra('github_id',$github_user->id); - if(!empty($ret) && $ret['uid'] != $user_id){ - $user = UserModel::find($ret['uid']); - return view('oauth.index',[ - 'page_title'=>"OAuth", - 'site_title'=>config("app.name"), - 'navigation'=>"OAuth", - 'platform' => 'Github', - 'display_html' => 'The github account is now tied to another '.config("app.name").' account : '.$user->email.'
- You can try logging in using github', - 'buttons' => [ - [ - 'text' => 'home', - 'href' => route('home'), - ], - ] - ]); + if (Auth::check()) { + $user_id=Auth::user()->id; + $ret=UserExtra::search('github_id', $github_user->id); + if (!empty($ret) && $ret[0]['uid']!=$user_id) { + $user=User::find($ret[0]['uid']); + return $this->generateDuplicateView($user->email); } - $accountModel->setExtra($user_id,'github_id',$github_user->id); - $accountModel->setExtra($user_id,'github_email',$github_user->email); - $accountModel->setExtra($user_id,'github_nickname',$github_user->nickname); - $accountModel->setExtra($user_id,'github_homepage',($github_user->user)['html_url']); - $accountModel->setExtra($user_id,'github_token',$github_user->token,101); - return view('oauth.index',[ - 'page_title'=>"OAuth", - 'site_title'=>config("app.name"), - 'navigation'=>"OAuth", - 'platform' => 'Github', - 'display_html' => 'You have successfully tied up the github account : '.$accountModel->getExtra(Auth::user()->id ,'github_email').'
- You can log in to '.config("app.name").' later using this account', - 'buttons' => [ - [ - 'text' => 'home', - 'href' => route('home'), - ], - ] - ]); - }else{ - $ret = $accountModel->findExtra('github_id',$github_user->id); - if(!empty($ret)){ - Auth::loginUsingId($ret['uid']); - $user_id = Auth::user()->id; - $accountModel->setExtra($user_id,'github_email',$github_user->email); - $accountModel->setExtra($user_id,'github_nickname',$github_user->nickname); - $accountModel->setExtra($user_id,'github_homepage',($github_user->user)['html_url']); - $accountModel->setExtra($user_id,'github_token',$github_user->token,101); - return redirect('/'); - }else{ - return view('oauth.index',[ - 'page_title'=>"OAuth", - 'site_title'=>config("app.name"), - 'navigation'=>"OAuth", - 'platform' => 'Github', - 'display_text' => 'This github account doesn\'t seem to have a '.config("app.name").' account, please register or log in first', - 'buttons' => [ - [ - 'text' => 'login', - 'href' => route('login'), - ], - [ - 'text' => 'register', - 'href' => route('register'), - ], - ] - ]); + Auth::user()->setExtra('github_id', $github_user->id); + Auth::user()->setExtra('github_email', $github_user->email); + Auth::user()->setExtra('github_nickname', $github_user->nickname); + Auth::user()->setExtra('github_homepage', ($github_user->user)['html_url']); + Auth::user()->setExtra('github_token', $github_user->token, 101); + return $this->generateSuccessView(Auth::user()->getExtra('github_email')); + } else { + $ret=UserExtra::search('github_id', $github_user->id); + if (!empty($ret)) { + Auth::loginUsingId($ret[0]['uid'], true); + Auth::user()->setExtra('github_email', $github_user->email); + Auth::user()->setExtra('github_nickname', $github_user->nickname); + Auth::user()->setExtra('github_homepage', ($github_user->user)['html_url']); + Auth::user()->setExtra('github_token', $github_user->token, 101); + return redirect()->route('account.dashboard'); + } else { + if (config('app.allow_oauth_temp_account')) { + try { + $createdUser=User::create([ + 'name' => Str::random(12), + 'email' => Str::random(16)."@temporary.email", + 'password' => '', + 'avatar' => '/static/img/avatar/default.png', + ]); + } catch (QueryException $exception) { + return $this->generateUnknownErrorView(); + } + Auth::loginUsingId($createdUser->id, true); + Auth::user()->setExtra('github_id', $github_user->id); + Auth::user()->setExtra('github_email', $github_user->email); + Auth::user()->setExtra('github_nickname', $github_user->nickname); + Auth::user()->setExtra('github_homepage', ($github_user->user)['html_url']); + Auth::user()->setExtra('github_token', $github_user->token, 101); + return redirect()->route('account.dashboard'); + } + $buttons=[[ + 'text' => 'login', + 'href' => route('login'), + ]]; + if (config('function.register')) { + $buttons[]=[ + 'text' => 'register', + 'href' => route('register'), + ]; + } + return $this->generateAccountNotFoundView(); } } } public function unbind() { - if(!Auth::check()){ - return redirect('/'); + if (!Auth::check()) { + return redirect()->route('home'); } - $accountModel = new AccountModel(); - if($accountModel->getExtra(Auth::user()->id ,'github_id')){ - return view('oauth.index',[ - 'page_title'=>"OAuth", - 'site_title'=>config("app.name"), - 'navigation'=>"OAuth", - 'platform' => 'Github', - 'display_html' => 'You are trying to unbind the following two :
- Your '.config("app.name").' account : '.Auth::user()->email.'
- This Github account : '.$accountModel->getExtra(Auth::user()->id ,'github_email').'
- Make your decision carefully, although you can later establish the binding again', - 'buttons' => [ - [ - 'text' => 'confirm', - 'href' => route('oauth.github.unbind.confirm'), - 'style' => 'btn-danger' - ], - [ - 'text' => 'home', - 'href' => route('home'), - ], - ] - ]); - }else{ - return view('oauth.index',[ - 'page_title'=>"OAuth", - 'site_title'=>config("app.name"), - 'navigation'=>"OAuth", - 'platform' => 'Github', - 'display_html' => 'You\'re not tied to github', - 'buttons' => [ - [ - 'text' => 'home', - 'href' => route('home'), - ], - ] - ]); + if (Auth::user()->getExtra('github_id')) { + return $this->generateUnbindConfirmView(Auth::user()->email, Auth::user()->getExtra('github_email')); + } else { + return $this->generateAlreadyUnbindView(); } } public function confirmUnbind() { - if(!Auth::check()){ - return redirect('/'); + if (!Auth::check()) { + return redirect()->route('home'); } - $accountModel = new AccountModel(); - $user_id = Auth::user()->id; - if($accountModel->getExtra($user_id ,'github_id')){ - $accountModel->setExtra($user_id,'github_id',null); - $accountModel->setExtra($user_id,'github_email',null); - $accountModel->setExtra($user_id,'github_nickname',null); - $accountModel->setExtra($user_id,'github_homepage',null); - $accountModel->setExtra($user_id,'github_token',null); - return view('oauth.index',[ - 'page_title'=>"OAuth", - 'site_title'=>config("app.name"), - 'navigation'=>"OAuth", - 'platform' => 'Github', - 'display_html' => 'You have successfully unbound your Github account from your '.config("app.name").' account', - 'buttons' => [ - [ - 'text' => 'home', - 'href' => route('home'), - ], - ] - ]); - }else{ - return view('oauth.index',[ - 'page_title'=>"OAuth", - 'site_title'=>config("app.name"), - 'navigation'=>"OAuth", - 'platform' => 'Github', - 'display_html' => 'You\'re not tied to github', - 'buttons' => [ - [ - 'text' => 'home', - 'href' => route('home'), - ], - ] - ]); + if (Auth::user()->getExtra('github_id')) { + Auth::user()->setExtra('github_id', null); + Auth::user()->setExtra('github_email', null); + Auth::user()->setExtra('github_nickname', null); + Auth::user()->setExtra('github_homepage', null); + Auth::user()->setExtra('github_token', null); + return $this->generateUnbindSuccessView(); + } else { + return $this->generateAlreadyUnbindView(); } - } } diff --git a/app/Http/Controllers/OAuth/OAuthController.php b/app/Http/Controllers/OAuth/OAuthController.php new file mode 100644 index 000000000..5150c7d04 --- /dev/null +++ b/app/Http/Controllers/OAuth/OAuthController.php @@ -0,0 +1,132 @@ + __("oauth.title.platform", ['platform' => $this->platformName]), + 'site_title' => config("app.name"), + 'navigation' => "OAuth", + 'platform' => $this->platformName, + ]; + return view('oauth.index', $config); + } + + protected function generateOperationView($OAuthAccount) { + return $this->generateView([ + 'display_html' => __("oauth.operation", ['platform' => $this->platformName, 'oauthaccount' => $OAuthAccount]), + 'buttons' => [ + [ + 'text' => __("oauth.action.unbind"), + 'href' => route("oauth.{$this->platformID}.unbind"), + 'style' => 'btn-danger' + ], + [ + 'text' => __("oauth.action.home"), + 'href' => route('home'), + ], + ] + ]); + } + + protected function generateDuplicateView($NOJAccount) { + return $this->generateView([ + 'display_html' => __("oauth.duplicate", ['platform' => $this->platformName, 'appname' => config("app.name"), 'nojaccount' => $NOJAccount]), + 'buttons' => [ + [ + 'text' => __("oauth.action.home"), + 'href' => route('home'), + ], + ] + ]); + } + + protected function generateSuccessView($OAuthAccount) { + return $this->generateView([ + 'display_html' => __("oauth.success", ['platform' => $this->platformName, 'appname' => config("app.name"), 'oauthaccount' => $OAuthAccount]), + 'buttons' => [ + [ + 'text' => __("oauth.action.home"), + 'href' => route('home'), + ], + ] + ]); + } + + protected function generateUnknownErrorView() { + return $this->generateView([ + 'display_text' => __("oauth.action.unknownerror"), + 'buttons' => [ + [ + 'text' => __("oauth.action.retry"), + 'href' => route('login'), + ] + ] + ]); + } + + protected function generateAccountNotFoundView() { + $buttons=[[ + 'text' => __("oauth.action.login"), + 'href' => route('login'), + ]]; + if (config('function.register')) { + $buttons[]=[ + 'text' => __("oauth.action.register"), + 'href' => route('register'), + ]; + } + return $this->generateView([ + 'display_text' => __("oauth.accountnotfound", ['platform' => $this->platformName, 'appname' => config("app.name")]), + 'buttons' => $buttons + ]); + } + + protected function generateUnbindConfirmView($NOJAccount, $OAuthAccount) { + return $this->generateView([ + 'display_html' => __("oauth.unbindconfirm", ['platform' => $this->platformName, 'appname' => config("app.name"), 'oauthaccount' => $OAuthAccount, 'nojaccount' => $NOJAccount]), + 'buttons' => [ + [ + 'text' => __("oauth.action.confirm"), + 'href' => route("oauth.{$this->platformID}.unbind.confirm"), + 'style' => 'btn-danger' + ], + [ + 'text' => __("oauth.action.home"), + 'href' => route('home'), + ], + ] + ]); + } + + protected function generateAlreadyUnbindView() { + return $this->generateView([ + 'display_html' => __("oauth.alreadyunbind", ['platform' => $this->platformName]), + 'buttons' => [ + [ + 'text' => __("oauth.action.home"), + 'href' => route('home'), + ], + ] + ]); + } + + protected function generateUnbindSuccessView() { + return $this->generateView([ + 'display_html' => __("oauth.unbindsuccess", ['platform' => $this->platformName, 'appname' => config("app.name")]), + 'buttons' => [ + [ + 'text' => __("oauth.action.home"), + 'href' => route('home'), + ], + ] + ]); + } +} diff --git a/app/Http/Controllers/ProblemController.php b/app/Http/Controllers/ProblemController.php index bd7721707..26e8d6a11 100644 --- a/app/Http/Controllers/ProblemController.php +++ b/app/Http/Controllers/ProblemController.php @@ -8,6 +8,7 @@ use App\Models\AccountModel; use App\Http\Controllers\Controller; use Illuminate\Http\Request; +use App\Models\Eloquent\Tool\MonacoTheme; use JavaScript; use Auth; @@ -131,8 +132,10 @@ public function editor($pcode) ]; } - $editor_left_width = $account->getExtra(Auth::user()->id, 'editor_left_width'); - if(empty($editor_left_width)) $editor_left_width='40'; + $accountExt=Auth::user()->getExtra(['editor_left_width', 'editor_theme']); + $editor_left_width=isset($accountExt['editor_left_width']) ? $accountExt['editor_left_width'] : '40'; + $editor_theme=isset($accountExt['editor_theme']) ? $accountExt['editor_theme'] : 'vs-dark'; + $themeConfig=MonacoTheme::getTheme($editor_theme); return is_null($prob_detail) ? redirect("/problem") : view('problem.editor', [ 'page_title'=>$prob_detail["title"], @@ -146,10 +149,12 @@ public function editor($pcode) 'contest_mode'=> false, 'oj_detail'=>$oj_detail, 'editor_left_width'=>$editor_left_width, + 'theme_config'=>$themeConfig, + 'editor_themes'=>MonacoTheme::getAll(), ]); } - /** + /** * Show the Problem Discussion Page. * * @return Response diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php index 20c30be16..e44d66ce6 100644 --- a/app/Http/Controllers/SearchController.php +++ b/app/Http/Controllers/SearchController.php @@ -19,8 +19,8 @@ public function __invoke(Request $request) 'site_title' => config("app.name"), 'navigation' => null, 'search_key' => $request->input('q'), - 'search_category' => $request->input('tab','problems'), - 'page' => $request->input('page',1) + 'search_category' => $request->input('tab', 'problems'), + 'page' => $request->input('page', 1) ]); } } diff --git a/app/Http/Controllers/SystemController.php b/app/Http/Controllers/SystemController.php index 5b9d23d1b..2b6bfe82d 100644 --- a/app/Http/Controllers/SystemController.php +++ b/app/Http/Controllers/SystemController.php @@ -17,7 +17,7 @@ class SystemController extends Controller public function info() { $judgerModel=new JudgerModel(); - $judgeServer=$judgerModel->fetchServer(1); + $judgeServer=$judgerModel->fetchServer(0); return view('system.info', [ 'page_title' => "System Info", 'site_title' => config("app.name"), diff --git a/app/Http/Controllers/TermController.php b/app/Http/Controllers/TermsController.php similarity index 51% rename from app/Http/Controllers/TermController.php rename to app/Http/Controllers/TermsController.php index f842c3af6..bb23c1d55 100644 --- a/app/Http/Controllers/TermController.php +++ b/app/Http/Controllers/TermsController.php @@ -2,23 +2,17 @@ namespace App\Http\Controllers; -use App\Models\ProblemModel; -use App\Models\Submission\SubmissionModel; -use App\Models\CompilerModel; -use App\Models\AccountModel; use App\Http\Controllers\Controller; use Illuminate\Http\Request; -use JavaScript; -use Auth; -class TermController extends Controller +class TermsController extends Controller { public function user(Request $request) { - return view('term.user', [ + return view('terms.user', [ 'page_title' => "Terms ans Conditions", 'site_title' => config("app.name"), - 'navigation' => "Term" + 'navigation' => "Terms" ]); } } diff --git a/app/Http/Controllers/Tool/Ajax/ImageHostingController.php b/app/Http/Controllers/Tool/Ajax/ImageHostingController.php new file mode 100644 index 000000000..4b59efd30 --- /dev/null +++ b/app/Http/Controllers/Tool/Ajax/ImageHostingController.php @@ -0,0 +1,52 @@ +hasPermission(26)) { + return ResponseModel::err(2001); + } + + $isValid=$request->file('image')->isValid(); + if ($isValid) { + $extension=$request->file('image')->extension(); + } else { + return ResponseModel::err(1005); + } + + $allow_extension=['jpg', 'png', 'jpeg', 'gif', 'bmp']; + if ($isValid && in_array($extension, $allow_extension)) { + $path=$request->file('image')->store('/static/img/upload', 'NOJPublic'); + $id=ImageHosting::create([ + 'user_id' => $user->id, + 'relative_path' => "/$path" + ])->id; + return ResponseModel::success(200, null, [ + 'relative_path' => "/$path", + 'path' => url($path), + 'id' => $id, + 'redirect_url' => route('tool.imagehosting.detail', ['id'=>$id]), + ]); + } else { + return ResponseModel::err(1005); + } + } +} diff --git a/app/Http/Controllers/Tool/Ajax/PastebinController.php b/app/Http/Controllers/Tool/Ajax/PastebinController.php index fecc6e978..c8a8f8518 100644 --- a/app/Http/Controllers/Tool/Ajax/PastebinController.php +++ b/app/Http/Controllers/Tool/Ajax/PastebinController.php @@ -19,7 +19,7 @@ class PastebinController extends Controller */ public function generate(Request $request) { - $aval_lang=["plaintext", "json", "bat", "coffeescript", "c", "cpp", "csharp", "csp", "css", "dockerfile", "fsharp", "go", "handlebars", "html", "ini", "java", "javascript", "less", "lua", "markdown", "msdax", "mysql", "objective-c", "pgsql", "php", "postiats", "powerquery", "powershell", "pug", "python", "r", "razor", "redis", "redshift", "ruby", "rust", "sb", "scss", "sol", "sql", "st", "swift", "typescript", "vb", "xml", "yaml", "scheme", "clojure", "shell", "perl", "azcli", "apex"]; + $aval_lang=["plaintext", "json", "bat", "coffeescript", "c", "cpp", "csharp", "csp", "css", "dockerfile", "fsharp", "go", "handlebars", "haskell", "html", "ini", "java", "javascript", "less", "lua", "markdown", "msdax", "mysql", "objective-c", "pgsql", "php", "postiats", "powerquery", "powershell", "pug", "python", "r", "razor", "redis", "redshift", "ruby", "rust", "sb", "scss", "sol", "sql", "st", "swift", "typescript", "vb", "xml", "yaml", "scheme", "clojure", "shell", "perl", "azcli", "apex"]; $request->validate([ 'syntax' => [ diff --git a/app/Http/Controllers/Tool/ImageHostingController.php b/app/Http/Controllers/Tool/ImageHostingController.php new file mode 100644 index 000000000..7510e477f --- /dev/null +++ b/app/Http/Controllers/Tool/ImageHostingController.php @@ -0,0 +1,64 @@ + "Create", + 'site_title' => "Image Hosting", + 'navigation' => "Image Hosting", + 'permission' => Auth::user()->hasPermission(26) + ]); + } + + /** + * Show the Image Hosting Detail Page. + * + * @return Response + */ + public function detail($id) + { + $image=ImageHosting::find($id); + if (is_null($image)) { + return abort('404'); + } + if (Auth::user()->id!=$image->user_id) { + return abort('403'); + } + return view('tool.imagehosting.detail', [ + 'page_title' => "Detail", + 'site_title' => "Image Hosting", + 'navigation' => "Image Hosting", + 'image' => $image, + ]); + } + + /** + * Show the Image Hosting List Page. + * + * @return Response + */ + public function list() + { + $images=Auth::user()->imagehostings()->orderBy('created_at', 'desc')->get(); + return view('tool.imagehosting.list', [ + 'page_title' => "List", + 'site_title' => "Image Hosting", + 'navigation' => "Image Hosting", + 'images' => $images, + ]); + } +} diff --git a/app/Http/Controllers/Tool/PastebinController.php b/app/Http/Controllers/Tool/PastebinController.php index d9388248d..58f9dab3f 100644 --- a/app/Http/Controllers/Tool/PastebinController.php +++ b/app/Http/Controllers/Tool/PastebinController.php @@ -16,10 +16,10 @@ class PastebinController extends Controller public function view($code) { $detail=Pastebin::where('code', $code)->first(); - if(is_null($detail)){ + if (is_null($detail)) { return abort('404'); } - if(!is_null($detail->expired_at) && strtotime($detail->expired_at) < strtotime(date("y-m-d h:i:s"))){ + if (!is_null($detail->expired_at) && strtotime($detail->expired_at)delete(); return abort('404'); } diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 70fd1ed09..7259915c6 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -4,6 +4,9 @@ use Illuminate\Http\Request; use App\Models\AccountModel; +use App\Models\Eloquent\User; +use App\Models\Eloquent\UserExtra; +use App\Models\Eloquent\Tool\Socialite; use Auth; class UserController extends Controller @@ -27,12 +30,12 @@ public function view($uid) { $accountModel=new AccountModel(); $info=$accountModel->detail($uid); - if($info == null) { + if ($info==null) { return redirect("/"); } $feed=$accountModel->feed($uid); - $extraInfo = $accountModel->getExtra($uid, ['gender', 'contanct', 'school', 'country', 'location'],0); - $socialiteInfo = $accountModel->getSocialiteInfo($uid,0); + $extraInfo=User::find($uid)->getExtra(['gender', 'contact', 'school', 'country', 'location'], 0); + $socialiteInfo=User::find($uid)->getSocialiteInfo(0); return view("account.dashboard", [ 'page_title'=>$info["name"], 'site_title'=>config("app.name"), @@ -42,7 +45,9 @@ public function view($uid) 'settingsView' => false, 'feed'=>$feed, 'extra_info' => $extraInfo, + 'extraDict' => UserExtra::$extraDict, 'socialite_info' => $socialiteInfo, + 'socialites' => Socialite::getAvailable(), ]); } } diff --git a/app/Http/Middleware/Api/Contest/Clearance.php b/app/Http/Middleware/Api/Contest/Clearance.php index 6668fd83e..92f70c2ac 100644 --- a/app/Http/Middleware/Api/Contest/Clearance.php +++ b/app/Http/Middleware/Api/Contest/Clearance.php @@ -17,22 +17,22 @@ class Clearance */ public function handle($request, Closure $next, $clearance) { - $clearance = [ + $clearance=[ 'visible' => 1, 'participated' => 2, 'admin' => 3, 'public_visible' => 4 ][$clearance]; - $user = auth()->user(); - $contest = new OutdatedContestModel(); - if($clearance == 4) { - if($contest->judgeOutsideClearance($request->cid,$user->id)){ - $contest = Contest::find($request->cid); + $user=auth()->user(); + $contest=new OutdatedContestModel(); + if ($clearance==4) { + if ($contest->judgeOutsideClearance($request->cid, $user->id)) { + $contest=Contest::find($request->cid); $request->merge([ 'contest' => $contest ]); return $next($request); - }else{ + } else { return response()->json([ 'success' => false, 'message' => 'Contest Not Found', @@ -44,13 +44,13 @@ public function handle($request, Closure $next, $clearance) ] ]); } - }else if($contest->judgeClearance($request->cid,$user->id) >= $clearance) { - $contest = Contest::find($request->cid); + } else if ($contest->judgeClearance($request->cid, $user->id)>=$clearance) { + $contest=Contest::find($request->cid); $request->merge([ 'contest' => $contest ]); return $next($request); - }else{ + } else { return response()->json([ 'success' => false, 'message' => 'Permission Denied', diff --git a/app/Http/Middleware/Api/Contest/HasCompiler.php b/app/Http/Middleware/Api/Contest/HasCompiler.php index 191132394..3a0a8d64a 100644 --- a/app/Http/Middleware/Api/Contest/HasCompiler.php +++ b/app/Http/Middleware/Api/Contest/HasCompiler.php @@ -15,9 +15,9 @@ class HasCompiler */ public function handle($request, Closure $next) { - $contest_problem = $request->contest_problem; - $compiler = $contest_problem->compilers->where('coid', $request->coid)->first(); - if(empty($compiler)) { + $contest_problem=$request->contest_problem; + $compiler=$contest_problem->compilers->where('coid', $request->coid)->first(); + if (empty($compiler)) { return response()->json([ 'success' => false, 'message' => 'Compiler Not Found', diff --git a/app/Http/Middleware/Api/Contest/HasProblem.php b/app/Http/Middleware/Api/Contest/HasProblem.php index 71e02f55d..08c045deb 100644 --- a/app/Http/Middleware/Api/Contest/HasProblem.php +++ b/app/Http/Middleware/Api/Contest/HasProblem.php @@ -15,9 +15,9 @@ class HasProblem */ public function handle($request, Closure $next) { - $contest = $request->contest; - $contest_problem = $contest->problems()->where('pid', $request->pid)->first(); - if(empty($contest_problem)) { + $contest=$request->contest; + $contest_problem=$contest->problems()->where('pid', $request->pid)->first(); + if (empty($contest_problem)) { return response()->json([ 'success' => false, 'message' => 'Problem Not Found', diff --git a/app/Http/Middleware/Api/Submission/Exist.php b/app/Http/Middleware/Api/Submission/Exist.php index 3bd160490..0e4dda429 100644 --- a/app/Http/Middleware/Api/Submission/Exist.php +++ b/app/Http/Middleware/Api/Submission/Exist.php @@ -16,8 +16,8 @@ class Exist */ public function handle($request, Closure $next) { - $submission = Submission::find($request->sid); - if(empty($submission)) { + $submission=Submission::find($request->sid); + if (empty($submission)) { return response()->json([ 'success' => false, 'message' => 'Submission Not Found', diff --git a/app/Http/Middleware/Contest/IsDesktop.php b/app/Http/Middleware/Contest/IsDesktop.php index ec577a0e3..a6bf07fef 100644 --- a/app/Http/Middleware/Contest/IsDesktop.php +++ b/app/Http/Middleware/Contest/IsDesktop.php @@ -17,18 +17,18 @@ class IsDesktop */ public function handle($request, Closure $next) { - $contest = Contest::find($request->cid); - if(!empty($contest) && $contest->desktop && !$contest->is_end) { - if(auth()->check()) { - $user = auth()->user(); - $contestModel = new OutdatedContestModel(); - if($contestModel->judgeClearance($contest->cid, $user->id) == 3){ + $contest=Contest::find($request->cid); + if (!empty($contest) && $contest->desktop && !$contest->is_end) { + if (auth()->check()) { + $user=auth()->user(); + $contestModel=new OutdatedContestModel(); + if ($contestModel->judgeClearance($contest->cid, $user->id)==3) { return $next($request); } } - if(strtolower($request->method()) == 'get'){ - return response()->redirectToRoute('contest.detail',['cid' => $contest->cid]); - }else{ + if (strtolower($request->method())=='get') { + return response()->redirectToRoute('contest.detail', ['cid' => $contest->cid]); + } else { return header("HTTP/1.1 403 Forbidden"); } } diff --git a/app/Http/Middleware/Group/Banned.php b/app/Http/Middleware/Group/Banned.php index 89ca20d24..fa9153160 100644 --- a/app/Http/Middleware/Group/Banned.php +++ b/app/Http/Middleware/Group/Banned.php @@ -17,12 +17,12 @@ class Banned */ public function handle($request, Closure $next) { - $gcode = $request->gcode; - $group = Group::where('gcode',$gcode)->first(); - $banneds = $group->banneds()->where('removed_at','>',date('Y-m-d H:i:s'))->first(); - $user = Auth::user(); - if(!empty($banneds) && $user->id != $group->leader->id) { - return response()->view('errors.451',[ + $gcode=$request->gcode; + $group=Group::where('gcode', $gcode)->first(); + $banneds=$group->banneds()->where('removed_at', '>', date('Y-m-d H:i:s'))->first(); + $user=Auth::user(); + if (!empty($banneds) && $user->id!=$group->leader->id) { + return response()->view('errors.451', [ 'description' => 'This group is currently banned. Please contact the group administrator.' ]); } diff --git a/app/Http/Middleware/Group/Exists.php b/app/Http/Middleware/Group/Exists.php index 552985512..279c660ee 100644 --- a/app/Http/Middleware/Group/Exists.php +++ b/app/Http/Middleware/Group/Exists.php @@ -16,11 +16,11 @@ class Exists */ public function handle($request, Closure $next) { - $gcode = $request->gcode; - $group = Group::where('gcode',$gcode)->first(); - if(!empty($group)){ + $gcode=$request->gcode; + $group=Group::where('gcode', $gcode)->first(); + if (!empty($group)) { return $next($request); - }else{ + } else { return redirect('/group'); } diff --git a/app/Http/Middleware/Privileged.php b/app/Http/Middleware/Privileged.php index 18fda99ac..7f92cf89d 100644 --- a/app/Http/Middleware/Privileged.php +++ b/app/Http/Middleware/Privileged.php @@ -18,16 +18,16 @@ class Privileged public function handle($request, Closure $next) { if (Auth::check()) { - if(isset($request->gcode)){ + if (isset($request->gcode)) { //group privilege $groupModel=new GroupModel(); - if($groupModel->judgeClearance($groupModel->gid($request->gcode), Auth::user()->id)>=2){ + if ($groupModel->judgeClearance($groupModel->gid($request->gcode), Auth::user()->id)>=2) { return $next($request); } - }elseif(isset($request->cid)) { + } elseif (isset($request->cid)) { //contest privilege $contestModel=new ContestModel(); - if($contestModel->judgeClearance($request->cid, Auth::user()->id)==3){ + if ($contestModel->judgeClearance($request->cid, Auth::user()->id)==3) { return $next($request); } } diff --git a/app/Http/Middleware/User/Banned.php b/app/Http/Middleware/User/Banned.php index 26d213584..d76e3d413 100644 --- a/app/Http/Middleware/User/Banned.php +++ b/app/Http/Middleware/User/Banned.php @@ -17,25 +17,25 @@ class Banned public function handle($request, Closure $next) { //check login - if(!Auth::check()){ + if (!Auth::check()) { return $next($request); } - $user = Auth::user(); - $banned = $user->banneds()->orderBy('removed_at', 'desc')->first(); + $user=Auth::user(); + $banned=$user->banneds()->orderBy('removed_at', 'desc')->first(); //check if there are any banned records - if(empty($banned)) { + if (empty($banned)) { return $next($request); } //check the time of the last record - if(strtotime($banned->removed_at) <= time()){ + if (strtotime($banned->removed_at)<=time()) { return $next($request); } //return error page - if($request->method() == 'GET'){ - return response()->view('errors.451',[ + if ($request->method()=='GET') { + return response()->view('errors.451', [ 'description' => "Your account is currently blocked and will remain so until {$banned->removed_at}. Here's why: {$banned->reason}", ]); - }else{ + } else { return response()->json([ 'ret' => 451, 'desc' => 'Unavailable For Legal Reasons', diff --git a/app/Jobs/AntiCheat.php b/app/Jobs/AntiCheat.php index 75a039ec9..d46fb7055 100644 --- a/app/Jobs/AntiCheat.php +++ b/app/Jobs/AntiCheat.php @@ -8,26 +8,29 @@ use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; +use Symfony\Component\Process\Exception\ProcessFailedException; use App\Models\Eloquent\Contest as EloquentContestModel; -use App\Models\Eloquent\UserModel as EloquentUserModel; +use App\Models\Eloquent\User; use Imtigger\LaravelJobStatus\Trackable; +use Symfony\Component\Process\Process; use KubAT\PhpSimple\HtmlDomParser; use PhpZip\ZipFile; -use MOSS\MOSS; use Storage; use Str; +use Log; class AntiCheat implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, Trackable; - public $tries = 1; + public $tries=1; public $progressVal=40; public $stepVal=0; protected $cid; + protected $retArr=[]; protected $supportLang=[ 'c'=>'c', - 'cpp'=>'cc', + 'cpp'=>'c++', 'java'=>'java' ]; @@ -54,7 +57,9 @@ public function handle() $cid=$this->cid; $contest=EloquentContestModel::find($cid); - if(!$contest->isJudgingComplete()) throw new Exception('Judging Incompleted'); + if (!$contest->isJudgingComplete()) { + throw new Exception('Judging Incompleted'); + } $acceptedSubmissions=$contest->submissions->whereIn('verdict', [ 'Accepted', @@ -65,120 +70,150 @@ public function handle() Storage::deleteDirectory("contest/anticheat/$cid/"); sleep(1); $this->setProgressNow(20); - $totMOSS=0; + $totProb=0; + $probLangs=[]; + - foreach($acceptedSubmissions as $submission){ + foreach ($acceptedSubmissions as $submission) { $lang=$submission->compiler->lang; - if(Arr::has($this->supportLang, $lang)){ + if (Arr::has($this->supportLang, $lang)) { $prob=$probIndex[$submission->pid]; $lang=$this->supportLang[$lang]; $ext=$lang; Storage::put("contest/anticheat/$cid/raw/$prob/$lang/[$submission->uid][$submission->sid].$ext", $submission->solution); - $probLangs[$prob][$lang]=true; - $totMOSS++; + if (!isset($probLangs[$prob][$lang])) { + $probLangs[$prob][$lang]=1; + } else { + $probLangs[$prob][$lang]++; + } + $totProb++; } } $this->setProgressNow(40); - $this->stepVal=50/$totMOSS*3; + $this->stepVal=50 / ($totProb * 2); $this->progressVal=40; - foreach($probLangs as $prob=>$langs){ - foreach($langs as $lang=>$availableVal){ + foreach ($probLangs as $prob=>$langs) { + foreach ($langs as $lang=>$submissionCount) { $this->detectPlagiarism([ 'lang'=>$lang, 'cid'=>$cid, 'prob'=>$prob, + 'count'=>$submissionCount, 'comment'=>"Contest #$cid Problem $prob Language $lang Code Plagiarism Check", ]); } } $this->setProgressNow(90); - $this->finalizeReport($probLangs); + $this->finalizeReport(); $this->setProgressNow(100); } - private function incProgress(){ - $this->progressVal+=$this->stepVal; + private function incProgress($factor=1) { + $this->progressVal+=($this->stepVal) * $factor; $this->setProgressNow(intval($this->progressVal)); } private function detectPlagiarism($config) { - $userid = config('moss.userid'); $lang=$config['lang']; $cid=$config['cid']; $prob=$config['prob']; - $comment=$config['comment']; - $moss = new MOSS($userid); - $moss->setLanguage($lang); - $moss->addByWildcard(storage_path("app/contest/anticheat/$cid/raw/$prob/$lang/*")); - $moss->setCommentString($comment); - $id=$moss->send(); - $this->incProgress(); - $moss->saveTo(storage_path("app/contest/anticheat/$cid/report/$prob/$lang"), $id); - $this->incProgress(); - $this->afterWork($cid,$prob,$lang); - $this->incProgress(); + $count=$config['count']; + if (strtoupper(substr(php_uname('s'), 0, 3))==='WIN') { + // Windows + $exe=base_path('binary'.DIRECTORY_SEPARATOR.'win'.DIRECTORY_SEPARATOR.'sim_'.$lang.'.exe'); + } else { + // Linux or else + $process=new Process(['chmod', '+x', base_path('binary'.DIRECTORY_SEPARATOR.'linux'.DIRECTORY_SEPARATOR.'sim*')]); + $process->run(); + $exe=base_path('binary'.DIRECTORY_SEPARATOR.'linux'.DIRECTORY_SEPARATOR.'sim_'.$lang); + } + + $exec=escapeshellarg($exe).' -p '; + + // wildcardly add all files + $exec.='*.'.$lang; + + $process=new Process($exec); + $process->setWorkingDirectory(Storage::path('contest'.DIRECTORY_SEPARATOR.'anticheat'.DIRECTORY_SEPARATOR.$cid.DIRECTORY_SEPARATOR.'raw'.DIRECTORY_SEPARATOR.$prob.DIRECTORY_SEPARATOR.$lang)); + $process->run(); + if (!$process->isSuccessful()) { + Log::error("Cannot Compare Problem $prob of Contest $cid, Languages $lang"); + throw new ProcessFailedException($process); + } + Log::info($process->getOutput()); + $this->incProgress($count); + //afterWork + $this->afterWork($cid, $prob, $lang, $process->getOutput()); + $this->incProgress($count); } - private function afterWork($cid,$prob,$lang) + private function afterWork($cid, $prob, $lang, $rawContent) { - $rawPath="contest/anticheat/$cid/raw/$prob/$lang"; - $reportPath="contest/anticheat/$cid/report/$prob/$lang"; - $generalPage=HtmlDomParser::str_get_html(Storage::disk('local')->get("$reportPath/index.html"), true, true, DEFAULT_TARGET_CHARSET, false); - $table=$generalPage->find('table', 0); - if(is_null($table)) return; - foreach($table->find('tr') as $tr){ - if(Str::contains($tr->outertext, '')) continue; - $firstUID=null; - foreach($tr->find('a') as $a){ - $a->innertext=explode("$rawPath/",$a->plaintext)[1]; - $a->innertext=str_replace(".$lang (",' (',$a->plaintext); - [$uid,$sid,$percent]=sscanf($a->innertext,"[%d][%d] (%d"); - if($firstUID==$uid){ - $tr->outertext=''; - break; - } - $firstUID=$uid; - $username=EloquentUserModel::find($uid)->name; - $a->innertext="$sid. [$prob][$username][$percent%]"; + foreach (preg_split('~[\r\n]+~', $rawContent) as $line) { + if (blank($line) or ctype_space($line)) { + continue; + } + // [3057][64659].c++ consists for 100 % of [3057][64679].c++ material + $line=explode('%', $line); + if (!isset($line[1])) { + continue; } + [$uid1, $sid1, $percentage]=sscanf($line[0], "[%d][%d].$lang consists for %d "); + [$uid2, $sid2]=sscanf($line[1], " of [%d][%d].$lang material"); + if ($uid1==$uid2) { + continue; + } + $username1=User::find($uid1)->name; + $username2=User::find($uid2)->name; + $this->retArr[]=[ + "sub1"=>"$sid1. [$prob][$username1]", + "sub2"=>"$sid2. [$prob][$username2]", + "similarity"=>$percentage, + "code1"=>Storage::disk('local')->get("contest/anticheat/$cid/raw/$prob/$lang/[$uid1][$sid1].$lang"), + "code2"=>Storage::disk('local')->get("contest/anticheat/$cid/raw/$prob/$lang/[$uid2][$sid2].$lang"), + 'cid'=>$cid, + 'prob'=>$prob, + 'lang'=>$lang, + ]; + Log::info($line); } - Storage::disk('local')->put("$reportPath/index.html",$table->outertext); } - private function finalizeReport($probLangs) + private function finalizeReport() { + $retArr=$this->retArr; + usort($retArr, function($a, $b) { + return $b['similarity']<=>$a['similarity']; + }); + Log::debug($retArr); $cid=$this->cid; - $generalPage=""; $index=0; - foreach($probLangs as $prob=>$langs){ - foreach($langs as $lang=>$availableVal){ - $probPage=HtmlDomParser::str_get_html(Storage::disk('local')->get("contest/anticheat/$cid/report/$prob/$lang/index.html"), true, true, DEFAULT_TARGET_CHARSET, false); - $table=$probPage->find('table', 0); - if(is_null($table)) continue; - foreach($table->find('tr') as $tr){ - if(Str::contains($tr->outertext, ' - - - - - "; - $index++; - } - } + $generalPage="
File 1File 2Lines Matched
')) continue; - $submissionA=$tr->children(0)->children(0); - $submissionB=$tr->children(1)->children(0); - $linesMatch=$tr->children(2); - [$subIndex]=sscanf($submissionA->href, "match%d.html"); - Storage::disk('local')->put("contest/anticheat/$cid/report/final/match$index.html", ' - - '); - Storage::disk('local')->copy("contest/anticheat/$cid/report/$prob/$lang/match$subIndex-0.html", "contest/anticheat/$cid/report/final/match$index-0.html"); - Storage::disk('local')->copy("contest/anticheat/$cid/report/$prob/$lang/match$subIndex-1.html", "contest/anticheat/$cid/report/final/match$index-1.html"); - $generalPage.=" -
$submissionA->plaintext$submissionB->plaintext$linesMatch->plaintext
"; + foreach ($retArr as $ret) { + $lang=strtoupper($ret['lang']); + $sub1=$ret['sub1']; + $sub2=$ret['sub2']; + $similarity=$ret['similarity']; + $generalPage.=" + + + + + + + "; + //write match$index.html + $matchIndexPage=''; + Storage::disk('local')->put("contest/anticheat/$cid/report/final/match$index.html", $matchIndexPage); + //write two code html + $match0Page='
'.PHP_EOL.htmlspecialchars($ret['code1']).PHP_EOL.'
'; + Storage::disk('local')->put("contest/anticheat/$cid/report/final/match$index-0.html", $match0Page); + $match1Page='
'.PHP_EOL.htmlspecialchars($ret['code2']).PHP_EOL.'
'; + Storage::disk('local')->put("contest/anticheat/$cid/report/final/match$index-1.html", $match1Page); + $index++; } $generalPage.="
LanguageSubmission 1Submission 2Sub 1 Consists for x% of Sub 2
$lang$sub1$sub2$similarity%
"; Storage::disk('local')->put("contest/anticheat/$cid/report/final/index.html", $generalPage); diff --git a/app/Jobs/GeneratePDF.php b/app/Jobs/GeneratePDF.php index ed832e127..6c65e1347 100644 --- a/app/Jobs/GeneratePDF.php +++ b/app/Jobs/GeneratePDF.php @@ -15,7 +15,7 @@ class GeneratePDF implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, Trackable; - public $tries = 5; + public $tries=5; protected $cid; protected $config; @@ -33,7 +33,7 @@ public function __construct($cid, $config) 'cover'=>false, 'advice'=>false, ]; - $this->config=array_merge($default,$config); + $this->config=array_merge($default, $config); } /** @@ -46,7 +46,7 @@ public function handle() $cid=$this->cid; $config=$this->config; - if (!is_dir(storage_path("app/contest/pdf/"))){ + if (!is_dir(storage_path("app/contest/pdf/"))) { mkdir(storage_path("app/contest/pdf/"), 0777, true); } diff --git a/app/Jobs/ProcessSubmission.php b/app/Jobs/ProcessSubmission.php index 746fc56a1..0c7751057 100644 --- a/app/Jobs/ProcessSubmission.php +++ b/app/Jobs/ProcessSubmission.php @@ -14,7 +14,7 @@ class ProcessSubmission implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - public $tries = 5; + public $tries=5; protected $all_data=[]; /** @@ -41,7 +41,7 @@ public function handle() public function failed() { - $submissionModel = new SubmissionModel(); + $submissionModel=new SubmissionModel(); $submissionModel->updateSubmission($this->all_data["sid"], ["verdict"=>"Submission Error"]); } } diff --git a/app/Models/AccountModel.php b/app/Models/AccountModel.php index 3d01a56d4..d4b33ee5d 100644 --- a/app/Models/AccountModel.php +++ b/app/Models/AccountModel.php @@ -5,35 +5,13 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; +use App\Models\Eloquent\User; use grubersjoe\BingPhoto; use Cache; use Storage; class AccountModel extends Model { - private $user_extra = [ - 0 => 'gender', - 1 => 'contact', - 2 => 'school', - 3 => 'country', - 4 => 'location', - 5 => 'editor_left_width', - - 1000 => 'github_id', - 1001 => 'github_email', - 1002 => 'github_nickname', - 1003 => 'github_homepage', - 1004 => 'github_token', - ]; - - private $socialite_support = [ - //use the form "platform_id" for unique authentication - //such as github_id - 'github' => [ - 'email','nickname','homepage','token' - ], - ]; - public function generatePassword($length=8) { $chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ23456789'; @@ -48,8 +26,8 @@ public function generatePassword($length=8) public function feed($uid=null) { $ret=[]; - $solution=DB::table("problem_solution")->join("problem","problem.pid","=","problem_solution.pid")->where(["uid"=>$uid,"audit"=>1])->select("problem.pid as pid","pcode","title","problem_solution.created_at as created_at")->orderBy("problem_solution.created_at","DESC")->get()->all(); - foreach($solution as &$s){ + $solution=DB::table("problem_solution")->join("problem", "problem.pid", "=", "problem_solution.pid")->where(["uid"=>$uid, "audit"=>1])->select("problem.pid as pid", "pcode", "title", "problem_solution.created_at as created_at")->orderBy("problem_solution.created_at", "DESC")->get()->all(); + foreach ($solution as &$s) { $s["type"]="event"; $s["color"]="wemd-orange"; $s["icon"]="comment-check-outline"; @@ -61,7 +39,7 @@ public function feed($uid=null) public function generateContestAccount($cid, $ccode, $num) { $ret=[]; - $starting=DB::table("users")->where('prefix','=',$ccode)->count(); + $starting=DB::table("users")->where('prefix', '=', $ccode)->count(); $contestModel=new ContestModel(); for ($i=1; $i<=$num; $i++) { $pass=$this->generatePassword(); @@ -109,7 +87,7 @@ public function add($data) public function detail($uid) { - if (filter_var($uid, FILTER_VALIDATE_INT) === false) { + if (filter_var($uid, FILTER_VALIDATE_INT)===false) { return null; } $ret=DB::table("users")->where(["id"=>$uid])->first(); @@ -129,14 +107,14 @@ public function detail($uid) ])->join("problem", "problem.pid", "=", "submission.pid")->select('pcode')->distinct()->get()->all(); $ret["solvedCount"]=count($ret["solved"]); // Casual - $ret["rank"]=Cache::tags(['rank',$ret["id"]])->get("rank", "N/A"); - $ret["rankTitle"]=Cache::tags(['rank',$ret["id"]])->get("title", "Recruit"); + $ret["rank"]=Cache::tags(['rank', $ret["id"]])->get("rank", "N/A"); + $ret["rankTitle"]=Cache::tags(['rank', $ret["id"]])->get("title", "Recruit"); $ret["rankTitleColor"]=RankModel::getColor($ret["rankTitle"]); // Professional $ret["professionalTitle"]=RankModel::getProfessionalTitle($ret["professional_rate"]); $ret["professionalTitleColor"]=RankModel::getProfessionalColor($ret["professionalTitle"]); // Administration Group - $ret["admin"]=$uid==1?1:0; + $ret["admin"]=User::find($uid)->hasPermission(1); if (Cache::tags(['bing', 'pic'])->get(date("Y-m-d"))==null) { $bing=new BingPhoto([ 'locale' => 'zh-CN', @@ -147,119 +125,4 @@ public function detail($uid) $ret["image"]=Cache::tags(['bing', 'pic'])->get(date("Y-m-d")); return $ret; } - - /** - * To get some extra info of a user. - * - * @param int $uid id of the user - * @param string|array $need An array is returned when an array is passed in,Only one value is returned when a string is passed in. - * @return string|array $result - */ - public function getExtra($uid,$need, $secret_level = 0){ - $ret = DB::table('users_extra')->where('uid',$uid)->orderBy('key')->get()->all(); - $result = []; - if(!empty($ret)){ - if(is_string($need)){ - foreach ($ret as $value) { - if(empty($value['secret_level']) || $value['secret_level'] <= $secret_level){ - $key_name = $this->user_extra[$value['key']] ?? 'unknown'; - if($key_name == $need){ - return $value['value']; - } - } - } - return null; - }else{ - foreach ($ret as $value) { - if(empty($value['secret_level']) || $value['secret_level'] <= $secret_level){ - $key_name = $this->user_extra[$value['key']] ?? 'unknown'; - if(in_array($key_name,$need)){ - $result[$key_name] = $value['value']; - } - } - } - } - } - return $result; - } - - /** - * To set some extra info of a user. - * - * @param int $uid id of the user - * @param string $key_name insert when key not found or update when key exists. Only values declared in the AccountModel are accepted - * @param string|null $value the extra info will be delete when value is null - * @return mixed $result - */ - public function setExtra($uid,$key_name,$value = null,$secret_level = -1){ - $key = array_search($key_name,$this->user_extra); - if($key === false){ - return false; - } - $ret = DB::table('users_extra')->where('uid',$uid)->where('key',$key)->first(); - if(!empty($ret)){ - unset($ret['id']); - if(!is_null($value)){ - $ret['value'] = $value; - }else{ - DB::table('users_extra')->where('uid',$uid)->where('key',$key)->delete(); - return true; - } - if($secret_level != -1){ - $ret['secret_level'] = $secret_level; - } - return DB::table('users_extra')->where('uid',$uid)->where('key',$key)->update($ret); - }else{ - if($value === null){ - return true; - } - return DB::table('users_extra')->insertGetId( - [ - 'uid' => $uid, - 'key' => $key, - 'value' => $value, - 'secret_level' => $secret_level == -1 ? 0 : $secret_level, - ] - ); - } - } - - /** - * find a extra info key-value pair - * @param string $key_name the key - * @param string $value the value - * @return string $result - */ - public function findExtra($key,$value) - { - $key = array_search($key,$this->user_extra); - if($key){ - return DB::table('users_extra')->where('key',$key)->where('value',$value)->first(); - }else{ - return null; - } - } - - public function getSocialiteInfo($uid,$secret_level = -1) - { - $socialites = []; - foreach ($this->socialite_support as $key => $value) { - $id_keyname = $key.'_id'; - $id = $this->getExtra($uid,$id_keyname); - if(!empty($id)){ - $info = [ - 'id' => $id, - ]; - foreach ($value as $info_name) { - $info_temp = $this->getExtra($uid,$key.'_'.$info_name); - if($info_temp !== null){ - $info[$info_name] = $info_temp; - } - } - $socialites[$key] = $info; - } - } - - return $socialites; - } } diff --git a/app/Models/AnnouncementModel.php b/app/Models/AnnouncementModel.php deleted file mode 100644 index cc6717535..000000000 --- a/app/Models/AnnouncementModel.php +++ /dev/null @@ -1,33 +0,0 @@ -table)->orderBy('created_at','desc')->get()->all(); - if (empty($list)) { - return []; - } - foreach ($list as &$item) { - $notice_author=DB::table("users")->where(["id"=>$item["uid"]])->first(); - $item["name"]=$notice_author["name"]; - $item["avatar"]=$notice_author["avatar"]; - $item["post_date_parsed"]=formatHumanReadableTime($item["created_at"]); - $item["content_parsed"]=clean(convertMarkdownToHtml($item["content"])); - } - return $list; - } -} diff --git a/app/Models/Babel/ExtensionModel.php b/app/Models/Babel/ExtensionModel.php index f50799480..3e2884a85 100644 --- a/app/Models/Babel/ExtensionModel.php +++ b/app/Models/Babel/ExtensionModel.php @@ -22,13 +22,13 @@ public static function localList() $ret=[]; $marketspaceRaw=self::getRemote(); $marketspace=[]; - foreach($marketspaceRaw["packages"] as $extension){ + foreach ($marketspaceRaw["packages"] as $extension) { $marketspace[$extension["name"]]=$extension; } $localList=self::getLocal(); - foreach($localList as $extension){ + foreach ($localList as $extension) { $temp=[ "details"=>$extension, "status"=>0, @@ -37,30 +37,30 @@ public static function localList() "settings"=>null, "available"=>null ]; - $temp["details"]["typeParsed"]=$temp["details"]["type"]=="virtual-judge"?"VirtualJudge":"OnlineJudge"; + $temp["details"]["typeParsed"]=$temp["details"]["type"]=="virtual-judge" ? "VirtualJudge" : "OnlineJudge"; try { if ($extension["version"]=='__cur__') { $extension["version"]=explode("-", version())[0]; } $downloadedVersion=new Version($extension["version"]); - if(isset($marketspace[$extension["name"]])){ + if (isset($marketspace[$extension["name"]])) { //remote extension, else is local extension $remoteVersion=new Version($marketspace[$extension["name"]]["version"]); $temp["updatable"]=$remoteVersion->isGreaterThan($downloadedVersion); $temp["details"]["official"]=$marketspace[$extension["name"]]["official"]; - } else{ + } else { $temp["updatable"]=false; $temp["details"]["official"]=0; } $installedConfig=OJ::where(["ocode"=>$extension["code"]])->first(); - if (is_null($installedConfig)){ + if (is_null($installedConfig)) { $temp["status"]=1; } else { $temp["version"]=$installedConfig->version; // local installed version $installedVersion=new Version($temp["version"]); - if ($downloadedVersion->isGreaterThan($installedVersion)){ + if ($downloadedVersion->isGreaterThan($installedVersion)) { $temp["status"]=1; } else { $temp["status"]=2; @@ -68,7 +68,7 @@ public static function localList() $temp["settings"]=false; $temp["available"]=$installedConfig->status; } - }catch (Throwable $e){ + } catch (Throwable $e) { continue; } $ret[]=$temp; @@ -80,8 +80,10 @@ public static function list() { $ret=[]; $marketspaceRaw=self::getRemote(); - if(empty($marketspaceRaw)) return []; - foreach($marketspaceRaw["packages"] as $extension){ + if (empty($marketspaceRaw)) { + return []; + } + foreach ($marketspaceRaw["packages"] as $extension) { $temp=[ "details"=>$extension, "status"=>0, @@ -90,11 +92,11 @@ public static function list() "settings"=>null, "available"=>null ]; - $temp["details"]["typeParsed"]=$temp["details"]["type"]=="virtual-judge"?"VirtualJudge":"OnlineJudge"; + $temp["details"]["typeParsed"]=$temp["details"]["type"]=="virtual-judge" ? "VirtualJudge" : "OnlineJudge"; try { try { $BabelConfig=json_decode(file_get_contents(babel_path("Extension/{$extension['code']}/babel.json")), true); - }catch (Throwable $e){ + } catch (Throwable $e) { $BabelConfig=[]; } if (!empty($BabelConfig)) { @@ -106,12 +108,12 @@ public static function list() $temp["updatable"]=$remoteVersion->isGreaterThan($downloadedVersion); $installedConfig=OJ::where(["ocode"=>$extension["code"]])->first(); - if (is_null($installedConfig)){ + if (is_null($installedConfig)) { $temp["status"]=1; } else { $temp["version"]=$installedConfig->version; // local installed version $installedVersion=new Version($temp["version"]); - if ($downloadedVersion->isGreaterThan($installedVersion)){ + if ($downloadedVersion->isGreaterThan($installedVersion)) { $temp["status"]=1; } else { $temp["status"]=2; @@ -120,7 +122,7 @@ public static function list() $temp["available"]=$installedConfig->status; } } - }catch (Throwable $e){ + } catch (Throwable $e) { continue; } $ret[]=$temp; @@ -132,11 +134,13 @@ public static function list() public static function getLocal() { $ret=[]; - $dirs = array_filter(glob(babel_path("Extension/*")), 'is_dir'); - foreach($dirs as $d){ + $dirs=array_filter(glob(babel_path("Extension/*")), 'is_dir'); + foreach ($dirs as $d) { $extension=basename($d); $BabelConfig=json_decode(file_get_contents(babel_path("Extension/$extension/babel.json")), true); - if($extension==$BabelConfig["code"]) $ret[]=$BabelConfig; + if ($extension==$BabelConfig["code"]) { + $ret[]=$BabelConfig; + } } return $ret; } @@ -145,7 +149,7 @@ public static function getRemote() { try { return json_decode(file_get_contents(config('babel.mirror')."/babel.json"), true); - }catch(Throwable $e){ + } catch (Throwable $e) { return []; } } @@ -153,10 +157,14 @@ public static function getRemote() public static function remoteDetail($code) { $babelConfig=self::getRemote(); - if(empty($babelConfig)) return []; + if (empty($babelConfig)) { + return []; + } $babelConfigPackages=$babelConfig["packages"]; - foreach($babelConfigPackages as $package) { - if($package["code"]==$code) return $package; + foreach ($babelConfigPackages as $package) { + if ($package["code"]==$code) { + return $package; + } } return []; } diff --git a/app/Models/CarouselModel.php b/app/Models/CarouselModel.php deleted file mode 100644 index 072d2ec66..000000000 --- a/app/Models/CarouselModel.php +++ /dev/null @@ -1,14 +0,0 @@ -where(["available"=>1])->get()->all(); - } -} diff --git a/app/Models/CompilerModel.php b/app/Models/CompilerModel.php index 3f1fc8767..1edf4f1de 100644 --- a/app/Models/CompilerModel.php +++ b/app/Models/CompilerModel.php @@ -21,7 +21,7 @@ public function list($oid=1, $pid=null) if ($special && $special['special_compiler']) { $t=$t->whereIn('coid', explode(',', $special['special_compiler'])); } - $compiler_list=$t->get()->all(); + $compiler_list=$t->orderBy('display_name')->get()->all(); return $compiler_list; } @@ -100,11 +100,11 @@ public function detail($coid) public static function add($row) { - if(self::checkExist([ + if (self::checkExist([ "oid"=>$row["oid"], "lcode"=>$row["lcode"], "deleted"=>0 - ])){ + ])) { throw new Exception("Duplicate Language Code"); } return DB::table('compiler')->insert($row); diff --git a/app/Models/ContestModel.php b/app/Models/ContestModel.php index 5ba63f957..6b28032b0 100644 --- a/app/Models/ContestModel.php +++ b/app/Models/ContestModel.php @@ -5,7 +5,7 @@ use App\Models\Eloquent\Contest as EloquentContestModel; use GrahamCampbell\Markdown\Facades\Markdown; use App\Models\Submission\SubmissionModel; -use App\Models\Eloquent\UserModel as User; +use App\Models\Eloquent\User; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\DB; use App\Models\Rating\RatingCalculator; @@ -115,8 +115,8 @@ public function gid($cid) public function gcode($cid) { - $gid = $this->gid($cid); - return DB::table('group')->where('gid','=',$gid)->first()["gcode"]; + $gid=$this->gid($cid); + return DB::table('group')->where('gid', '=', $gid)->first()["gcode"]; } public function runningContest() @@ -141,19 +141,19 @@ public function grantAccess($uid, $cid, $audit=0) public function listForSetting($gid) { - $uid = Auth::user()->id; - $group_contests = DB::table('contest') - ->where('gid',$gid) - ->orderBy('begin_time','desc') + $uid=Auth::user()->id; + $group_contests=DB::table('contest') + ->where('gid', $gid) + ->orderBy('begin_time', 'desc') ->get()->all(); - $groupModel = new GroupModel(); - $group_clearance = $groupModel->judgeClearance($gid,$uid); + $groupModel=new GroupModel(); + $group_clearance=$groupModel->judgeClearance($gid, $uid); foreach ($group_contests as &$contest) { - $contest['is_admin'] = ($contest['assign_uid'] == $uid || $group_clearance == 3); - $contest['begin_stamps'] = strtotime($contest['begin_time']); - $contest['end_stamps'] = strtotime($contest['end_time']); - $contest['status'] = time() >= $contest['end_stamps'] ? 1 - : (time() <= $contest['begin_stamps'] ? -1 : 0); + $contest['is_admin']=($contest['assign_uid']==$uid || $group_clearance==3); + $contest['begin_stamps']=strtotime($contest['begin_time']); + $contest['end_stamps']=strtotime($contest['end_time']); + $contest['status']=time()>=$contest['end_stamps'] ? 1 + : (time()<=$contest['begin_stamps'] ? -1 : 0); $contest["rule_parsed"]=$this->rule[$contest["rule"]]; $contest["date_parsed"]=[ "date"=>date_format(date_create($contest["begin_time"]), 'j'), @@ -161,11 +161,11 @@ public function listForSetting($gid) ]; $contest["length"]=$this->calcLength($contest["begin_time"], $contest["end_time"]); } - usort($group_contests,function($a,$b){ - if($a['is_admin'] == $b['is_admin']){ - return $b['begin_stamps'] - $a['begin_stamps']; + usort($group_contests, function($a, $b) { + if ($a['is_admin']==$b['is_admin']) { + return $b['begin_stamps']-$a['begin_stamps']; } - return $b['is_admin'] - $a['is_admin']; + return $b['is_admin']-$a['is_admin']; }); return $group_contests; } @@ -176,9 +176,9 @@ public function listByGroup($gid) // "gid"=>$gid // ])->orderBy('begin_time', 'desc')->get()->all(); $preQuery=DB::table($this->tableName); - $paginator=$preQuery->where('gid','=',$gid)->orderBy('begin_time', 'desc')->paginate(10); + $paginator=$preQuery->where('gid', '=', $gid)->orderBy('begin_time', 'desc')->paginate(10); $contest_list=$paginator->all(); - if(empty($contest_list)){ + if (empty($contest_list)) { return null; } @@ -203,7 +203,7 @@ public function rule($cid) ])->first()["rule"]; } - public function list($filter,$uid) + public function list($filter, $uid) { if ($uid) { //$paginator=DB::select('SELECT DISTINCT contest.* FROM group_member inner join contest on group_member.gid=contest.gid left join contest_participant on contest.cid=contest_participant.cid where (public=1 and audit=1) or (group_member.uid=:uid and group_member.role>0 and (contest_participant.uid=:uidd or ISNULL(contest_participant.uid)) and (registration=0 or (registration=1 and not ISNULL(contest_participant.uid))))',["uid"=>$uid,"uidd"=>$uid])->paginate(10); @@ -227,15 +227,15 @@ public function list($filter,$uid) if ($filter['practice']) { $paginator=$paginator->where(["practice"=>$filter['practice']]); } - $paginator = $paginator ->paginate(10); - }elseif($filter['public']=='0'){ + $paginator=$paginator ->paginate(10); + } elseif ($filter['public']=='0') { $paginator=DB::table('group_member') ->groupBy('contest.cid') ->select('contest.*') ->join('contest', 'group_member.gid', '=', 'contest.gid') ->leftJoin('contest_participant', 'contest.cid', '=', 'contest_participant.cid') ->where( - function ($query) use ($filter,$uid) { + function($query) use ($filter, $uid) { if ($filter['rule']) { $query=$query->where(["rule"=>$filter['rule']]); } @@ -258,14 +258,14 @@ function ($query) use ($filter,$uid) { ) ->orderBy('contest.begin_time', 'desc') ->paginate(10); - }else{ + } else { $paginator=DB::table('group_member') ->groupBy('contest.cid') ->select('contest.*') ->join('contest', 'group_member.gid', '=', 'contest.gid') ->leftJoin('contest_participant', 'contest.cid', '=', 'contest_participant.cid') ->where( - function ($query) use ($filter) { + function($query) use ($filter) { if ($filter['rule']) { $query=$query->where(["rule"=>$filter['rule']]); } @@ -281,12 +281,14 @@ function ($query) use ($filter) { if ($filter['practice']) { $query=$query->where(["practice"=>$filter['practice']]); } - $query->where('public', 1) - ->where('audit_status', 1); + $query->where([ + 'public'=>1, + 'audit_status'=>1 + ]); } ) ->orWhere( - function ($query) use ($filter,$uid) { + function($query) use ($filter, $uid) { if ($filter['rule']) { $query=$query->where(["rule"=>$filter['rule']]); } @@ -332,7 +334,7 @@ function ($query) use ($filter,$uid) { if ($filter['practice']) { $paginator=$paginator->where(["practice"=>$filter['practice']]); } - $paginator = $paginator ->paginate(10); + $paginator=$paginator ->paginate(10); } $contest_list=$paginator->all(); foreach ($contest_list as &$c) { @@ -370,14 +372,14 @@ public function featured() } } - public function registContest($cid,$uid) + public function registContest($cid, $uid) { $registered=DB::table("contest_participant")->where([ "cid"=>$cid, "uid"=>$uid ])->first(); - if(empty($registered)){ + if (empty($registered)) { DB::table("contest_participant")->insert([ "cid"=>$cid, "uid"=>$uid, @@ -385,7 +387,7 @@ public function registContest($cid,$uid) ]); $name=User::find($uid)->name; $contest=$this->basic($cid); - $url=route('contest.detail',['cid' => $cid]); + $url=route('contest.detail', ['cid' => $cid]); sendMessage([ 'receiver' => $uid, 'sender' => 1, // potential bugs @@ -419,9 +421,9 @@ public function intToChr($index, $start=65) public function problems($cid) { return DB::table('contest_problem') - ->join('problem','contest_problem.pid','=','problem.pid') - ->where('cid',$cid) - ->select('problem.pid as pid','pcode','number') + ->join('problem', 'contest_problem.pid', '=', 'problem.pid') + ->where('cid', $cid) + ->select('problem.pid as pid', 'pcode', 'number') ->orderBy('number') ->get()->all(); } @@ -443,18 +445,18 @@ public function contestProblems($cid, $uid) $end_time=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]); foreach ($problemSet as &$p) { - if($p['practice']){ - $tags = DB::table("group_problem_tag") - ->where('gid',$p['gid']) - ->where('pid',$p['pid']) + if ($p['practice']) { + $tags=DB::table("group_problem_tag") + ->where('gid', $p['gid']) + ->where('pid', $p['pid']) ->get()->all(); - $tags_arr = []; - if(!empty($tags)){ + $tags_arr=[]; + if (!empty($tags)) { foreach ($tags as $value) { - array_push($tags_arr,$value['tag']); + array_push($tags_arr, $value['tag']); } } - $p['tags'] = $tags_arr; + $p['tags']=$tags_arr; } if ($contest_rule==1) { $prob_stat=DB::table("submission")->select( @@ -701,21 +703,25 @@ public function contestRankCache($cid) $totScore+=$prob_stat["solved"]; } } + + $nickName=DB::table("group_member")->where([ + "uid" => $s["uid"], + "gid" => $contest_info["gid"] + ])->where("role", ">", 0)->first(); + + $nickName=is_null($nickName) ?null:$nickName["nick_name"]; $ret[]=[ "uid" => $s["uid"], "name" => DB::table("users")->where([ "id"=>$s["uid"] ])->first()["name"], - "nick_name" => DB::table("group_member")->where([ - "uid" => $s["uid"], - "gid" => $contest_info["gid"] - ])->where("role", ">", 0)->first()["nick_name"], + "nick_name" => $nickName, "score" => $totScore, "penalty" => $totPen, "problem_detail" => $prob_detail ]; } - usort($ret, function ($a, $b) { + usort($ret, function($a, $b) { if ($a["score"]==$b["score"]) { if ($a["penalty"]==$b["penalty"]) { return 0; @@ -748,21 +754,25 @@ public function contestRankCache($cid) $totSolved+=$prob_stat["solved"]; $totScore+=intval($prob_stat["score_parsed"]); } + + $nickName=DB::table("group_member")->where([ + "uid" => $s["uid"], + "gid" => $contest_info["gid"] + ])->where("role", ">", 0)->first(); + + $nickName=is_null($nickName) ?null:$nickName["nick_name"]; $ret[]=[ "uid" => $s["uid"], "name" => DB::table("users")->where([ "id"=>$s["uid"] ])->first()["name"], - "nick_name" => DB::table("group_member")->where([ - "uid" => $s["uid"], - "gid" => $contest_info["gid"] - ])->where("role", ">", 0)->first()["nick_name"], + "nick_name" => $nickName, "score" => $totScore, "solved" => $totSolved, "problem_detail" => $prob_detail ]; } - usort($ret, function ($a, $b) { + usort($ret, function($a, $b) { if ($a["score"]==$b["score"]) { if ($a["solved"]==$b["solved"]) { return 0; @@ -784,7 +794,7 @@ public function contestRankCache($cid) return $ret; } - public function contestRank($cid, $uid = 0) + public function contestRank($cid, $uid=0) { // [ToDo] If the current user's in the organizer group show nick name // [ToDo] The participants determination @@ -801,36 +811,36 @@ public function contestRank($cid, $uid = 0) "gid" => $contest_info["gid"] ])->where("role", ">", 0)->first()); - $clearance = $this -> judgeClearance($cid, $uid); + $clearance=$this -> judgeClearance($cid, $uid); /** New Version With MySQL */ $end_time=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]); - $contest_eloquent = EloquentContestModel::find($cid); + $contest_eloquent=EloquentContestModel::find($cid); - if(time() < $end_time){ - if($clearance == 3){ + if (time()<$end_time) { + if ($clearance==3) { $contestRankRaw=Cache::tags(['contest', 'rank'])->get("contestAdmin$cid"); - }else{ + } else { $contestRankRaw=Cache::tags(['contest', 'rank'])->get($cid); } - if(!isset($contestRankRaw)){ + if (!isset($contestRankRaw)) { $contestRankRaw=$contest_eloquent->rankRefresh(); } - }else{ - if($clearance == 3){ + } else { + if ($clearance==3) { $contestRankRaw=Cache::tags(['contest', 'rank'])->get("contestAdmin$cid"); if (!isset($contestRankRaw)) { $contestRankRaw=$this->getContestRankFromMySQL($cid); - if(!isset($contestRankRaw)){ + if (!isset($contestRankRaw)) { $contestRankRaw=$contest_eloquent->rankRefresh(); $this->storeContestRankInMySQL($cid, $contestRankRaw); } } - }else{ + } else { $contestRankRaw=$this->getContestRankFromMySQL($cid); - if(!isset($contestRankRaw)){ + if (!isset($contestRankRaw)) { $contestRankRaw=Cache::tags(['contest', 'rank'])->get($cid); - if(!isset($contestRankRaw)){ + if (!isset($contestRankRaw)) { $contestRankRaw=$contest_eloquent->rankRefresh(); } $this->storeContestRankInMySQL($cid, $contestRankRaw); @@ -848,15 +858,15 @@ public function contestRank($cid, $uid = 0) // $contestRankRaw=$this->contestRankCache($cid); // } // } - if($contest_info["rule"]==1){ + if ($contest_info["rule"]==1) { foreach ($contestRankRaw as &$cr) { - $solved = 0; - foreach($cr['problem_detail'] as $pd){ - if(!empty($pd['solved_time_parsed'])){ - $solved ++; + $solved=0; + foreach ($cr['problem_detail'] as $pd) { + if (!empty($pd['solved_time_parsed'])) { + $solved++; } } - $cr['solved'] = $solved; + $cr['solved']=$solved; } } @@ -905,16 +915,16 @@ public function getRejudgeQueue($cid) public function getClarificationList($cid) { - $uid = Auth::user()->id; - $clearance = $this -> judgeClearance($cid, $uid); - if($clearance == 3){ + $uid=Auth::user()->id; + $clearance=$this -> judgeClearance($cid, $uid); + if ($clearance==3) { return DB::table("contest_clarification")->where([ "cid"=>$cid ])->orderBy('created_at', 'desc')->get()->all(); - }else{ + } else { return DB::table("contest_clarification")->where([ "cid"=>$cid - ])->where(function ($query) { + ])->where(function($query) { $query->where([ "public"=>1 ])->orWhere([ @@ -1027,7 +1037,7 @@ public function frozenTime($cid) public function getContestRecord($filter, $cid) { $basicInfo=$this->basic($cid); - $userInfo=DB::table('group_member')->where('gid',$basicInfo["gid"])->where('uid',Auth::user()->id)->get()->first(); + $userInfo=DB::table('group_member')->where('gid', $basicInfo["gid"])->where('uid', Auth::user()->id)->get()->first(); $problemSet_temp=DB::table("contest_problem")->join("problem", "contest_problem.pid", "=", "problem.pid")->where([ "cid"=>$cid ])->orderBy('ncode', 'asc')->select("ncode", "alias", "contest_problem.pid as pid", "title", "points", "tot_score")->get()->all(); @@ -1040,14 +1050,14 @@ public function getContestRecord($filter, $cid) $end_time=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]); $contestEnd=time()>$end_time; - $filter['pid'] = array_search($filter['ncode'], array_column($problemSet_temp, 'ncode')); - if($filter['pid']==false){ - $filter['pid'] = null; - }else{ - $filter['pid'] = $problemSet_temp[$filter['pid']]['pid']; + $filter['pid']=array_search($filter['ncode'], array_column($problemSet_temp, 'ncode')); + if ($filter['pid']===false) { + $filter['pid']=is_null($filter['ncode']) ?null:-1; + } else { + $filter['pid']=$problemSet_temp[$filter['pid']]['pid']; } - if($userInfo==null || $userInfo["role"]!=3){ + if ($userInfo==null || $userInfo["role"]!=3) { if ($basicInfo["status_visibility"]==2) { // View all $paginator=DB::table("submission")->where([ @@ -1061,7 +1071,7 @@ public function getContestRecord($filter, $cid) "users.id", "=", "submission.uid" - )->where(function ($query) use ($frozen_time) { + )->where(function($query) use ($frozen_time) { $query->where( "submission_date", "<", @@ -1088,15 +1098,15 @@ public function getContestRecord($filter, $cid) 'desc' ); - if($filter["pid"]){ + if ($filter["pid"]) { $paginator=$paginator->where(["pid"=>$filter["pid"]]); } - if($filter["result"]){ + if ($filter["result"]) { $paginator=$paginator->where(["verdict"=>$filter["result"]]); } - if($filter["account"]){ + if ($filter["account"]) { $paginator=$paginator->where(["name"=>$filter["account"]]); } @@ -1132,15 +1142,15 @@ public function getContestRecord($filter, $cid) 'desc' ); - if($filter["pid"]){ + if ($filter["pid"]) { $paginator=$paginator->where(["pid"=>$filter["pid"]]); } - if($filter["result"]){ + if ($filter["result"]) { $paginator=$paginator->where(["verdict"=>$filter["result"]]); } - if($filter["account"]){ + if ($filter["account"]) { $paginator=$paginator->where(["name"=>$filter["account"]]); } @@ -1151,7 +1161,7 @@ public function getContestRecord($filter, $cid) "records"=>[] ]; } - }else{ + } else { if ($basicInfo["status_visibility"]==2) { // View all $paginator=DB::table("submission")->where([ @@ -1183,15 +1193,15 @@ public function getContestRecord($filter, $cid) 'desc' ); - if($filter["pid"]){ + if ($filter["pid"]) { $paginator=$paginator->where(["pid"=>$filter["pid"]]); } - if($filter["result"]){ + if ($filter["result"]) { $paginator=$paginator->where(["verdict"=>$filter["result"]]); } - if($filter["account"]){ + if ($filter["account"]) { $paginator=$paginator->where(["name"=>$filter["account"]]); } @@ -1227,15 +1237,15 @@ public function getContestRecord($filter, $cid) 'desc' ); - if($filter["pid"]){ + if ($filter["pid"]) { $paginator=$paginator->where(["pid"=>$filter["pid"]]); } - if($filter["result"]){ + if ($filter["result"]) { $paginator=$paginator->where(["verdict"=>$filter["result"]]); } - if($filter["account"]){ + if ($filter["account"]) { $paginator=$paginator->where(["name"=>$filter["account"]]); } @@ -1288,30 +1298,30 @@ public function judgeClearance($cid, $uid=0) * 2 stands for participant* * 3 stands for admin * ***************************/ - if ($uid==0 || filter_var($cid, FILTER_VALIDATE_INT) === false) { + if ($uid==0 || filter_var($cid, FILTER_VALIDATE_INT)===false) { return 0; } - $groupModel = new GroupModel(); + $groupModel=new GroupModel(); $contest_info=DB::table("contest")->where("cid", $cid)->first(); - $userInfo=DB::table('group_member')->where('gid',$contest_info["gid"])->where('uid',$uid)->get()->first(); + $userInfo=DB::table('group_member')->where('gid', $contest_info["gid"])->where('uid', $uid)->get()->first(); - if(empty($contest_info)){ + if (empty($contest_info)) { // contest not exist return 0; } - if($uid == $contest_info['assign_uid'] || $groupModel->judgeClearance($contest_info['gid'],$uid) == 3){ + if ($uid==$contest_info['assign_uid'] || $groupModel->judgeClearance($contest_info['gid'], $uid)==3) { return 3; } - $contest_started = strtotime($contest_info['begin_time']) < time(); - $contest_ended = strtotime($contest_info['end_time']) < time(); + $contest_started=strtotime($contest_info['begin_time'])where("cid", $cid)->first(); @@ -1399,12 +1409,12 @@ public function contestRule($cid) public function updateProfessionalRate($cid) { $basic=$this->basic($cid); - if($basic["rated"]&&!$basic["is_rated"]){ + if ($basic["rated"] && !$basic["is_rated"]) { $ratingCalculator=new RatingCalculator($cid); - if($ratingCalculator->calculate()){ + if ($ratingCalculator->calculate()) { $ratingCalculator->storage(); return true; - }else{ + } else { return false; } } else { @@ -1412,26 +1422,26 @@ public function updateProfessionalRate($cid) } } - public function contestUpdate($cid,$data,$problems) + public function contestUpdate($cid, $data, $problems) { - if($problems !== false){ - $old_problmes = array_column( + if ($problems!==false) { + $old_problmes=array_column( DB::table('contest_problem') - ->where('cid',$cid) + ->where('cid', $cid) ->get()->all(), 'pid' ); - DB::transaction(function () use ($cid, $data, $problems,$old_problmes) { + DB::transaction(function() use ($cid, $data, $problems, $old_problmes) { DB::table($this->tableName) - ->where('cid',$cid) + ->where('cid', $cid) ->update($data); DB::table('contest_problem') - ->where('cid',$cid) + ->where('cid', $cid) ->delete(); - $new_problems = []; + $new_problems=[]; foreach ($problems as $p) { $pid=DB::table("problem")->where(["pcode"=>$p["pcode"]])->select("pid")->first()["pid"]; - array_push($new_problems,$pid); + array_push($new_problems, $pid); DB::table("contest_problem")->insert([ "cid"=>$cid, "number"=>$p["number"], @@ -1441,29 +1451,29 @@ public function contestUpdate($cid,$data,$problems) "points"=>$p["points"] ]); } - foreach($old_problmes as $op) { - if(!in_array($op,$new_problems)){ + foreach ($old_problmes as $op) { + if (!in_array($op, $new_problems)) { DB::table('submission') - ->where('cid',$cid) - ->where('pid',$op) + ->where('cid', $cid) + ->where('pid', $op) ->delete(); } } }, 5); - $contestRankRaw = $this->contestRankCache($cid); + $contestRankRaw=$this->contestRankCache($cid); Cache::tags(['contest', 'rank'])->put($cid, $contestRankRaw); Cache::tags(['contest', 'rank'])->put("contestAdmin$cid", $contestRankRaw); - }else{ + } else { DB::table($this->tableName) - ->where('cid',$cid) + ->where('cid', $cid) ->update($data); } } - public function contestUpdateProblem($cid,$problems) + public function contestUpdateProblem($cid, $problems) { DB::table('contest_problem') - ->where('cid',$cid) + ->where('cid', $cid) ->delete(); foreach ($problems as $p) { DB::table("contest_problem")->insertGetId([ @@ -1479,8 +1489,8 @@ public function contestUpdateProblem($cid,$problems) public function arrangeContest($gid, $config, $problems) { - $cid = -1; - DB::transaction(function () use ($gid, $config, $problems,&$cid) { + $cid=-1; + DB::transaction(function() use ($gid, $config, $problems, &$cid) { $cid=DB::table($this->tableName)->insertGetId([ "gid"=>$gid, "name"=>$config["name"], @@ -1494,7 +1504,7 @@ public function arrangeContest($gid, $config, $problems) "rule"=>1, //todo "begin_time"=>$config["begin_time"], "end_time"=>$config["end_time"], - "vcid"=>isset($config["vcid"])?$config["vcid"]:null, + "vcid"=>isset($config["vcid"]) ? $config["vcid"] : null, "public"=>$config["public"], "registration"=>0, //todo "registration_due"=>null, //todo @@ -1502,7 +1512,7 @@ public function arrangeContest($gid, $config, $problems) "froze_length"=>0, //todo "status_visibility"=>$config["status_visibility"], "created_at"=>date("Y-m-d H:i:s"), - "crawled" => isset($config['vcid'])?$config['crawled'] : null, + "crawled" => isset($config['vcid']) ? $config['crawled'] : null, "audit_status"=>$config["public"] ? 0 : 1 ]); @@ -1521,13 +1531,13 @@ public function arrangeContest($gid, $config, $problems) return $cid; } - public function updateContestRankTable($cid,$sub) + public function updateContestRankTable($cid, $sub) { - $lock = Cache::lock("contestrank$cid",10); - try{ - if($lock->get()){ - if(Cache::tags(['contest','rank'])->get($cid) != null){ - $ret = Cache::tags(['contest','rank'])->get($cid); + $lock=Cache::lock("contestrank$cid", 10); + try { + if ($lock->get()) { + if (Cache::tags(['contest', 'rank'])->get($cid)!=null) { + $ret=Cache::tags(['contest', 'rank'])->get($cid); $chache=[]; $chache['contest_info']=DB::table("contest")->where("cid", $cid)->first(); $chache['problemSet']=DB::table("contest_problem")->join("problem", "contest_problem.pid", "=", "problem.pid")->where([ @@ -1536,27 +1546,26 @@ public function updateContestRankTable($cid,$sub) $chache['frozen_time']=DB::table("contest")->where(["cid"=>$cid])->select(DB::raw("UNIX_TIMESTAMP(end_time)-froze_length as frozen_time"))->first()["frozen_time"]; $chache['end_time']=strtotime(DB::table("contest")->where(["cid"=>$cid])->select("end_time")->first()["end_time"]); - $id = 0; + $id=0; - foreach($chache['problemSet'] as $key => $p){ - if ($p['pid'] == $sub['pid']){ - $chache['problemSet'][$key]['cpid'] = $key; - $id = $key; + foreach ($chache['problemSet'] as $key => $p) { + if ($p['pid']==$sub['pid']) { + $chache['problemSet'][$key]['cpid']=$key; + $id=$key; } } - $ret = $this->updateContestRankDetail($chache['contest_info'],$chache['problemSet'][$id],$cid,$sub['uid'],$ret); - $ret = $this->sortContestRankTable($chache['contest_info'],$cid,$ret); + $ret=$this->updateContestRankDetail($chache['contest_info'], $chache['problemSet'][$id], $cid, $sub['uid'], $ret); + $ret=$this->sortContestRankTable($chache['contest_info'], $cid, $ret); - if (time() < $chache['frozen_time']){ + if (time()<$chache['frozen_time']) { Cache::tags(['contest', 'rank'])->put($cid, $ret); } Cache::tags(['contest', 'rank'])->put("contestAdmin$cid", $ret); - if(time() > $chache['end_time']){ + if (time()>$chache['end_time']) { $this->storeContestRankInMySQL($cid, $ret); } - } - else{ + } else { $ret=[]; $chache=[]; $chache['contest_info']=DB::table("contest")->where("cid", $cid)->first(); @@ -1571,7 +1580,7 @@ public function updateContestRankTable($cid,$sub) "cid"=>$cid, "audit"=>1 ])->select('uid')->get()->all(); - }else{ + } else { $submissionUsers=DB::table("submission")->where([ "cid"=>$cid ])->where( @@ -1584,39 +1593,39 @@ public function updateContestRankTable($cid,$sub) ])->select('uid')->groupBy('uid')->get()->all(); } - $chacheAdmin = $chache; + $chacheAdmin=$chache; foreach ($submissionUsers as $s) { foreach ($chache['problemSet'] as $key => $p) { - $p['cpid'] = $key; - $ret = $this->updateContestRankDetail($chache['contest_info'],$p,$cid,$s['uid'],$ret); + $p['cpid']=$key; + $ret=$this->updateContestRankDetail($chache['contest_info'], $p, $cid, $s['uid'], $ret); } } - $ret = $this->sortContestRankTable($chache['contest_info'],$cid,$ret); + $ret=$this->sortContestRankTable($chache['contest_info'], $cid, $ret); Cache::tags(['contest', 'rank'])->put($cid, $ret); $retAdmin=[]; foreach ($submissionUsersAdmin as $s) { foreach ($chacheAdmin['problemSet'] as $key => $p) { - $p['cpid'] = $key; - $retAdmin = $this->updateContestRankDetail($chacheAdmin['contest_info'],$p,$cid,$s['uid'],$retAdmin); + $p['cpid']=$key; + $retAdmin=$this->updateContestRankDetail($chacheAdmin['contest_info'], $p, $cid, $s['uid'], $retAdmin); } } - $retAdmin = $this->sortContestRankTable($chacheAdmin['contest_info'],$cid,$retAdmin); + $retAdmin=$this->sortContestRankTable($chacheAdmin['contest_info'], $cid, $retAdmin); Cache::tags(['contest', 'rank'])->put("contestAdmin$cid", $retAdmin); } } - }catch(LockTimeoutException $e){ + } catch (LockTimeoutException $e) { Log::warning("Contest Rank Lock Timed Out"); - }finally{ + } finally { optional($lock)->release(); } } - public function sortContestRankTable($contest_info,$cid,$ret) + public function sortContestRankTable($contest_info, $cid, $ret) { - if ($contest_info["rule"]==1){ - usort($ret, function ($a, $b) { + if ($contest_info["rule"]==1) { + usort($ret, function($a, $b) { if ($a["score"]==$b["score"]) { if ($a["penalty"]==$b["penalty"]) { return 0; @@ -1631,8 +1640,8 @@ public function sortContestRankTable($contest_info,$cid,$ret) return 1; } }); - }else if ($contest_info["rule"]==2){ - usort($ret, function ($a, $b) { + } else if ($contest_info["rule"]==2) { + usort($ret, function($a, $b) { if ($a["score"]==$b["score"]) { if ($a["solved"]==$b["solved"]) { return 0; @@ -1651,21 +1660,22 @@ public function sortContestRankTable($contest_info,$cid,$ret) return $ret; } - public function updateContestRankDetail($contest_info,$problem,$cid,$uid,$ret) + public function updateContestRankDetail($contest_info, $problem, $cid, $uid, $ret) { - $id = count($ret); - foreach($ret as $key => $r){ - if($r['uid'] == $uid) - $id = $key; + $id=count($ret); + foreach ($ret as $key => $r) { + if ($r['uid']==$uid) { + $id=$key; + } } if ($contest_info["rule"]==1) { // ACM/ICPC Mode - if($id == count($ret)){ - $prob_detail = []; - $totPen = 0; - $totScore = 0; - }else{ - $prob_detail = $ret[$id]['problem_detail']; + if ($id==count($ret)) { + $prob_detail=[]; + $totPen=0; + $totScore=0; + } else { + $prob_detail=$ret[$id]['problem_detail']; $totPen=$ret[$id]['penalty']; $totScore=$ret[$id]['score']; }; @@ -1683,7 +1693,7 @@ public function updateContestRankDetail($contest_info,$problem,$cid,$uid,$ret) "uid"=>$uid, ])->orderBy('submission_date', 'desc')->first(); - if ($ac_times<=1 && isset($last_record) && $last_record['verdict']!="Waiting" && $last_record['verdict']!="Submission Error" && $last_record['verdict']!="System Error"){ + if ($ac_times<=1 && isset($last_record) && $last_record['verdict']!="Waiting" && $last_record['verdict']!="Submission Error" && $last_record['verdict']!="System Error") { $prob_stat=$this->contestProblemInfoACM($cid, $problem["pid"], $uid); $prob_detail[$problem['cpid']]=[ @@ -1699,15 +1709,18 @@ public function updateContestRankDetail($contest_info,$problem,$cid,$uid,$ret) $totScore+=$prob_stat["solved"]; } + $nickName=DB::table("group_member")->where([ + "uid" => $uid, + "gid" => $contest_info["gid"] + ])->where("role", ">", 0)->first(); + $nickName=is_null($nickName) ?null:$nickName["nick_name"]; + $ret[$id]=[ "uid" => $uid, "name" => DB::table("users")->where([ "id"=>$uid ])->first()["name"], - "nick_name" => DB::table("group_member")->where([ - "uid" => $uid, - "gid" => $contest_info["gid"] - ])->where("role", ">", 0)->first()["nick_name"], + "nick_name" => $nickName, "score" => $totScore, "penalty" => $totPen, "problem_detail" => $prob_detail @@ -1715,12 +1728,12 @@ public function updateContestRankDetail($contest_info,$problem,$cid,$uid,$ret) } } elseif ($contest_info["rule"]==2) { // IOI Mode - if($id == count($ret)){ - $prob_detail = []; - $totSolved = 0; - $totScore = 0; - }else{ - $prob_detail = $ret[$id]['problem_detail']; + if ($id==count($ret)) { + $prob_detail=[]; + $totSolved=0; + $totScore=0; + } else { + $prob_detail=$ret[$id]['problem_detail']; $totSolved=$ret[$id]['solved']; $totScore=$ret[$id]['score']; }; @@ -1736,15 +1749,18 @@ public function updateContestRankDetail($contest_info,$problem,$cid,$uid,$ret) $totSolved+=$prob_stat["solved"]; $totScore+=intval($prob_stat["score_parsed"]); + $nickName=DB::table("group_member")->where([ + "uid" => $uid, + "gid" => $contest_info["gid"] + ])->where("role", ">", 0)->first(); + $nickName=is_null($nickName) ?null:$nickName["nick_name"]; + $ret[$id]=[ "uid" => $uid, "name" => DB::table("users")->where([ "id"=> $uid ])->first()["name"], - "nick_name" => DB::table("group_member")->where([ - "uid" => $uid, - "gid" => $contest_info["gid"] - ])->where("role", ">", 0)->first()["nick_name"], + "nick_name" => $nickName, "score" => $totScore, "solved" => $totSolved, "problem_detail" => $prob_detail @@ -1753,47 +1769,47 @@ public function updateContestRankDetail($contest_info,$problem,$cid,$uid,$ret) return $ret; } - public function assignMember($cid,$uid){ + public function assignMember($cid, $uid) { return DB::table("contest")->where(["cid"=>$cid])->update([ "assign_uid"=>$uid ]); } - public function canUpdateContestTime($cid,$time = []) + public function canUpdateContestTime($cid, $time=[]) { - $begin_time_new = $time['begin'] ?? null; - $end_time_new = $time['end'] ?? null; + $begin_time_new=$time['begin'] ?? null; + $end_time_new=$time['end'] ?? null; - $hold_time = DB::table('contest') - ->where('cid',$cid) - ->select('begin_time','end_time') + $hold_time=DB::table('contest') + ->where('cid', $cid) + ->select('begin_time', 'end_time') ->first(); - $begin_stamps = strtotime($hold_time['begin_time']); - $end_stamps = strtotime($hold_time['end_time']); + $begin_stamps=strtotime($hold_time['begin_time']); + $end_stamps=strtotime($hold_time['end_time']); /* -1 : have not begun 0 : ing 1 : end */ - $status = time() >= $end_stamps ? 1 - : (time() <= $begin_stamps ? -1 : 0); - if($status === -1){ - if(time() > $begin_time_new){ + $status=time()>=$end_stamps ? 1 + : (time()<=$begin_stamps ? -1 : 0); + if ($status===-1) { + if (time()>$begin_time_new) { return false; } return true; - }else if($status === 0){ - if($begin_time_new !== null){ + } else if ($status===0) { + if ($begin_time_new!==null) { return false; } - if($end_time_new !== null){ - if(strtotime($end_time_new) <= time()){ + if ($end_time_new!==null) { + if (strtotime($end_time_new)<=time()) { return false; - }else{ + } else { return true; } } - }else{ + } else { return false; } @@ -1802,22 +1818,21 @@ public function canUpdateContestTime($cid,$time = []) public function replyClarification($ccid, $content) { - return DB::table("contest_clarification")->where('ccid','=',$ccid)->update([ + return DB::table("contest_clarification")->where('ccid', '=', $ccid)->update([ "reply"=>$content ]); } public function setClarificationPublic($ccid, $public) { - if($public) + if ($public) { - return DB::table("contest_clarification")->where('ccid','=',$ccid)->update([ + return DB::table("contest_clarification")->where('ccid', '=', $ccid)->update([ "public"=>1 ]); - } - else + } else { - return DB::table("contest_clarification")->where('ccid','=',$ccid)->update([ + return DB::table("contest_clarification")->where('ccid', '=', $ccid)->update([ "public"=>0 ]); } @@ -1830,90 +1845,88 @@ public function getContestAccount($cid) public function praticeAnalysis($cid) { - $gid = DB::table('contest') - ->where('cid',$cid) + $gid=DB::table('contest') + ->where('cid', $cid) ->first()['gid']; - $contestRank = $this->contestRank($cid,Auth::user()->id); - if(!empty($contestRank)){ - $all_problems = DB::table('problem') - ->whereIn('pid',array_column($contestRank[0]['problem_detail'],'pid')) - ->select('pid','title') + $contestRank=$this->contestRank($cid, Auth::user()->id); + if (!empty($contestRank)) { + $all_problems=DB::table('problem') + ->whereIn('pid', array_column($contestRank[0]['problem_detail'], 'pid')) + ->select('pid', 'title') ->get()->all(); - }else{ - $all_problems = []; + } else { + $all_problems=[]; } - $tags = DB::table('group_problem_tag') + $tags=DB::table('group_problem_tag') ->where('gid', $gid) - ->whereIn('pid', array_column($all_problems,'pid')) + ->whereIn('pid', array_column($all_problems, 'pid')) ->get()->all(); - $all_tags = array_unique(array_column($tags,'tag')); - $memberData = []; - foreach($contestRank as $member){ - $m = [ + $all_tags=array_unique(array_column($tags, 'tag')); + $memberData=[]; + foreach ($contestRank as $member) { + $m=[ 'uid' => $member['uid'], 'name' => $member['name'], 'nick_name' => $member['nick_name'], ]; - $completion = []; - foreach ($all_tags as $tag){ - $completion[$tag] = []; + $completion=[]; + foreach ($all_tags as $tag) { + $completion[$tag]=[]; foreach ($tags as $t) { - if($t['tag'] == $tag){ + if ($t['tag']==$tag) { foreach ($member['problem_detail'] as $pd) { - if($pd['pid'] == $t['pid']){ - $completion[$tag][$t['pid']] = $pd['solved_time_parsed'] == "" ? 0 : 1; + if ($pd['pid']==$t['pid']) { + $completion[$tag][$t['pid']]=$pd['solved_time_parsed']=="" ? 0 : 1; } } } } } - $m['completion'] = $completion; - $memberData[] = $m; + $m['completion']=$completion; + $memberData[]=$m; } return $memberData; } public function storeContestRankInMySQL($cid, $data) { - $contestRankJson = json_encode($data); - return DB::table('contest')->where('cid','=',$cid)->update([ + $contestRankJson=json_encode($data); + return DB::table('contest')->where('cid', '=', $cid)->update([ 'rank' => $contestRankJson ]); } public function getContestRankFromMySQL($cid) { - $contestRankJson = DB::table('contest')->where('cid','=',$cid)->pluck('rank')->first(); - $data = json_decode($contestRankJson, true); + $contestRankJson=DB::table('contest')->where('cid', '=', $cid)->pluck('rank')->first(); + $data=json_decode($contestRankJson, true); return $data; } public function isVerified($cid) { - return DB::table('contest')->where('cid','=',$cid)->pluck('verified')->first(); + return DB::table('contest')->where('cid', '=', $cid)->pluck('verified')->first(); } public function getScrollBoardData($cid) { - $members = DB::table("submission") - ->join('users','users.id','=','submission.uid') - ->join('contest', 'contest.cid', '=', 'submission.cid') - ->join('group_member', 'users.id', '=', 'group_member.uid') - ->where('submission.cid', $cid)->select('users.id as uid','users.name as name','group_member.nick_name as nick_name') - ->groupBy('uid')->get()->all(); - $submissions = DB::table("submission") + $members=DB::table("contest_participant")->where([ + "cid"=>$cid, + "audit"=>1 + ])->leftjoin('users', 'users.id', '=', 'contest_participant.uid')->select('users.id as uid', 'users.name as name', DB::raw('NULL AS nick_name'))->get()->all(); + $submissions=DB::table("submission") ->where('cid', $cid) ->select('sid', 'verdict', 'submission_date', 'pid', 'uid') ->orderBy('submission_date') ->get()->all(); - $problems = DB::table('contest_problem') + $problems=DB::table('contest_problem') ->where('cid', $cid) - ->select('ncode','pid') + ->select('ncode', 'pid') ->orderBy('ncode') ->get()->all(); - $contest = DB::table('contest') - ->where('cid',$cid) - ->select('begin_time','end_time','froze_length') + $contest=DB::table('contest') + ->where('cid', $cid) + ->select('begin_time', 'end_time', 'froze_length') ->first(); return [ 'members' => $members, @@ -1923,7 +1936,7 @@ public function getScrollBoardData($cid) ]; } - public function storageCode($path,$cid) + public function storageCode($path, $cid) { Storage::disk("private")->makeDirectory($path); @@ -1934,7 +1947,7 @@ public function storageCode($path,$cid) "cid"=>$cid ])->get(); $problem_info=array(); - foreach($contest_problems as $contest_problem) { + foreach ($contest_problems as $contest_problem) { $problem_info[$contest_problem["pid"]]=DB::table("problem")->where([ "pid"=>$contest_problem["pid"] ])->first(); @@ -1945,7 +1958,7 @@ public function storageCode($path,$cid) $compilers=DB::table("compiler")->get(); $language=array(); - foreach($compilers as $compiler) { + foreach ($compilers as $compiler) { $language[$compiler["coid"]]=$compiler["lang"]; } @@ -1954,14 +1967,14 @@ public function storageCode($path,$cid) $submissions=DB::table("submission")->where([ "cid"=>$cid, ])->get(); - foreach($submissions as $submission) { + foreach ($submissions as $submission) { $user_name=DB::table("users")->where([ "id"=>$submission["uid"] ])->first(); $SubmissionModel=new SubmissionModel(); $suffix_name=isset($SubmissionModel->langConfig[$language[$submission["coid"]]]) ? $SubmissionModel->langConfig[$language[$submission["coid"]]]["extensions"][0] : $SubmissionModel->langConfig["plaintext"]["extensions"][0]; //die($submission["sid"]); - $file_name=(string)($submission["sid"])."-".$user_name["name"]."-".$problem_info[$submission["pid"]]["ncode"]."-".$submission["verdict"].$suffix_name; + $file_name=(string) ($submission["sid"])."-".$user_name["name"]."-".$problem_info[$submission["pid"]]["ncode"]."-".$submission["verdict"].$suffix_name; Storage::disk("private")->put($path."/".urlencode($problem_info[$submission["pid"]]["path"])."/".$file_name, $submission["solution"]); } } @@ -1971,33 +1984,31 @@ public function deleteZip($path) Storage::disk("private")->deleteDirectory($path); } - public function GenerateZip($path,$cid,$code_path,$outputFilename) + public function GenerateZip($path, $cid, $code_path, $outputFilename) { Storage::disk("private")->deleteDirectory($code_path); - $this->storageCode($code_path,$cid); + $this->storageCode($code_path, $cid); Storage::disk("private")->makeDirectory($path); // create new archive - $zipFile = new \PhpZip\ZipFile(); - $directories = Storage::disk("private")->allDirectories($code_path); - try{ - foreach($directories as $directorie) + $zipFile=new \PhpZip\ZipFile(); + $directories=Storage::disk("private")->allDirectories($code_path); + try { + foreach ($directories as $directorie) { - preg_match("/contestCode\/\d+(.*)/",$directorie,$problem_name); - $zipFile->addDir(base_path('storage/app/private/'.$directorie),urldecode($problem_name[1]));// add files from the directory + preg_match("/contestCode\/\d+(.*)/", $directorie, $problem_name); + $zipFile->addDir(base_path('storage/app/private/'.$directorie), urldecode($problem_name[1])); // add files from the directory } $zipFile ->saveAsFile(base_path('storage/app/private/'.$path.$cid.".zip")); // save the archive to a file //->extractTo(base_path('storage/app/private/'.$path)); // extract files to the specified directory - } - catch(\PhpZip\Exception\ZipException $e){ + } catch (\PhpZip\Exception\ZipException $e) { // handle exception Log::debug($e); - } - finally{ + } finally { $zipFile->close(); } } @@ -2009,21 +2020,21 @@ public function zipName($cid) $contest=DB::table("contest")->where([ "cid"=>$cid ])->first(); - return $outputFilename=(string)($contest["cid"])."-".$contest["name"].".zip"; + return $outputFilename=(string) ($contest["cid"])."-".$contest["name"].".zip"; } public function judgeOver($cid) { - $submissions = DB::table('submission') + $submissions=DB::table('submission') ->where(['cid' => $cid]) - ->whereIn('verdict',['Waiting','Pending']) + ->whereIn('verdict', ['Waiting', 'Pending']) ->select('sid') ->get()->all(); - if(empty($submissions)){ + if (empty($submissions)) { return [ 'result' => true ]; - }else{ + } else { return [ 'result' => false, 'sid' => $submissions diff --git a/app/Models/Eloquent/Abuse.php b/app/Models/Eloquent/Abuse.php index e23aec1a7..b7631d613 100644 --- a/app/Models/Eloquent/Abuse.php +++ b/app/Models/Eloquent/Abuse.php @@ -20,6 +20,6 @@ class Abuse extends Model public function user() { - return $this->belongsTo('App\Models\Eloquent\UserModel', 'user_id'); + return $this->belongsTo('App\Models\Eloquent\User', 'user_id'); } } diff --git a/app/Models/Eloquent/Announcement.php b/app/Models/Eloquent/Announcement.php new file mode 100644 index 000000000..fed4dc0fc --- /dev/null +++ b/app/Models/Eloquent/Announcement.php @@ -0,0 +1,30 @@ +belongsTo('App\Models\Eloquent\User', 'uid'); + } + + public function getPostDateParsedAttribute() + { + return formatHumanReadableTime($this->created_at); + } + + public function getContentParsedAttribute() + { + return clean(convertMarkdownToHtml($this->content)); + } +} diff --git a/app/Models/Eloquent/Carousel.php b/app/Models/Eloquent/Carousel.php new file mode 100644 index 000000000..51b329996 --- /dev/null +++ b/app/Models/Eloquent/Carousel.php @@ -0,0 +1,15 @@ +display_name.' @ '.$this->oj->name; + } + + public function oj() { + return $this->belongsTo('App\Models\Eloquent\OJ', 'oid', 'oid'); + } } diff --git a/app/Models/Eloquent/Contest.php b/app/Models/Eloquent/Contest.php index 8ecef2845..a494446a7 100644 --- a/app/Models/Eloquent/Contest.php +++ b/app/Models/Eloquent/Contest.php @@ -2,7 +2,6 @@ namespace App\Models\Eloquent; -use Illuminate\Database\Eloquent\Collection as EloquentCollection; use Illuminate\Database\Eloquent\Model; use App\Models\ProblemModel as OutdatedProblemModel; use Illuminate\Support\Facades\DB; @@ -13,33 +12,49 @@ class Contest extends Model { protected $table='contest'; protected $primaryKey='cid'; - const DELETED_AT=null; - const UPDATED_AT=null; - const CREATED_AT=null; + + public function getParsedRuleAttribute() + { + $rule=["Unknown", "ICPC", "IOI", "Custom ICPC", "Custom IOI", "HASAAOSE Compulter Exam"]; + return $rule[$this->rule]; + } + + public static function boot() + { + parent::boot(); + static::saving(function($model) { + if ($model->custom_icon!="" && $model->custom_icon!=null && $model->custom_icon[0]!="/") { + $model->custom_icon="/$model->custom_icon"; + } + if ($model->img!="" && $model->img!=null && $model->img[0]!="/") { + $model->img="/$model->img"; + } + }); + } //Repository function - public function participants($ignore_frozen = true) + public function participants($ignore_frozen=true) { - if($this->registration){ - $participants = ContestParticipant::where('cid',$this->cid)->get(); + if ($this->registration) { + $participants=ContestParticipant::where('cid', $this->cid)->get(); $participants->load('user'); - $users = new EloquentCollection; + $users=collect(); foreach ($participants as $participant) { - $user = $participant->user; + $user=$participant->user; $users->add($user); } return $users->unique(); - }else{ + } else { $this->load('submissions.user'); - if($ignore_frozen){ - $frozen_time = $this->frozen_time; - $submissions = $this->submissions()->where('submission_date','<',$frozen_time)->get(); - }else{ - $submissions = $this->submissions; + if ($ignore_frozen) { + $frozen_time=$this->frozen_time; + $submissions=$this->submissions()->where('submission_date', '<', $frozen_time)->get(); + } else { + $submissions=$this->submissions; } - $users = new EloquentCollection; + $users=collect(); foreach ($submissions as $submission) { - $user = $submission->user; + $user=$submission->user; $users->add($user); } return $users->unique(); @@ -49,18 +64,18 @@ public function participants($ignore_frozen = true) // Repository/Service? function public function rankRefresh() { - $ret = []; - $participants = $this->participants(); - $contest_problems = $this->problems; + $ret=[]; + $participants=$this->participants(); + $contest_problems=$this->problems; $contest_problems->load('problem'); - if($this->rule == 1){ + if ($this->rule==1) { // ACM/ICPC Mode foreach ($participants as $participant) { $prob_detail=[]; $totPen=0; $totScore=0; foreach ($contest_problems as $contest_problem) { - $prob_stat = $contest_problem->userStatus($participant); + $prob_stat=$contest_problem->userStatus($participant); $prob_detail[]=[ 'ncode'=>$contest_problem->ncode, 'pid'=>$contest_problem->pid, @@ -86,7 +101,7 @@ public function rankRefresh() "problem_detail" => $prob_detail ]; } - usort($ret, function ($a, $b) { + usort($ret, function($a, $b) { if ($a["score"]==$b["score"]) { if ($a["penalty"]==$b["penalty"]) { return 0; @@ -103,53 +118,53 @@ public function rankRefresh() }); Cache::tags(['contest', 'rank'])->put($this->cid, $ret, 60); return $ret; - }else{ + } else { // IO Mode - $c = new OutdatedContestModel(); + $c=new OutdatedContestModel(); return $c->contestRankCache($this->cid); } } public function clarifications() { - return $this->hasMany('App\Models\Eloquent\ContestClarification','cid','cid'); + return $this->hasMany('App\Models\Eloquent\ContestClarification', 'cid', 'cid'); } public function problems() { - return $this->hasMany('App\Models\Eloquent\ContestProblem','cid','cid'); + return $this->hasMany('App\Models\Eloquent\ContestProblem', 'cid', 'cid'); } public function submissions() { - return $this->hasMany('App\Models\Eloquent\Submission','cid','cid'); + return $this->hasMany('App\Models\Eloquent\Submission', 'cid', 'cid'); } public function group() { - return $this->hasOne('App\Models\Eloquent\Group','gid','gid'); + return $this->hasOne('App\Models\Eloquent\Group', 'gid', 'gid'); } public function getFrozenTimeAttribute() { - $end_time = strtotime($this->end_time); - return $end_time - $this->froze_length; + $end_time=strtotime($this->end_time); + return $end_time-$this->froze_length; } public function getIsEndAttribute() { - return strtotime($this->end_time) < time(); + return strtotime($this->end_time)orderBy('number','asc')->get(); - foreach($problemset as $problem){ + $problemset=ContestProblem::where('cid', $cid)->orderBy('number', 'asc')->get(); + foreach ($problemset as $problem) { $problemDetail=ProblemModel::find($problem->pid); $problemRet=(new OutdatedProblemModel())->detail($problemDetail->pcode); - if ($renderLatex){ - foreach (['description','input','output','note'] as $section){ + if ($renderLatex) { + foreach (['description', 'input', 'output', 'note'] as $section) { $problemRet['parsed'][$section]=latex2Image($problemRet['parsed'][$section]); } } @@ -163,6 +178,6 @@ public static function getProblemSet($cid, $renderLatex=false) public function isJudgingComplete() { - return $this->submissions->whereIn('verdict',['Waiting','Pending'])->count()==0; + return $this->submissions->whereIn('verdict', ['Waiting', 'Pending'])->count()==0; } } diff --git a/app/Models/Eloquent/ContestClarification.php b/app/Models/Eloquent/ContestClarification.php index 73686dcc2..26b4bd7ea 100644 --- a/app/Models/Eloquent/ContestClarification.php +++ b/app/Models/Eloquent/ContestClarification.php @@ -20,7 +20,7 @@ public function contest() public function user() { - return $this->belongsTo('App\Models\Eloquent\UserModel', 'uid'); + return $this->belongsTo('App\Models\Eloquent\User', 'uid'); } public function getPublicAttribute($value) @@ -29,6 +29,6 @@ public function getPublicAttribute($value) } protected $fillable=[ - 'cid', 'type', 'title', 'content', 'public', 'uid' + 'cid', 'type', 'title', 'content', 'reply', 'public', 'uid', 'remote_code' ]; } diff --git a/app/Models/Eloquent/ContestParticipant.php b/app/Models/Eloquent/ContestParticipant.php index 24b9d0fc3..f628be017 100644 --- a/app/Models/Eloquent/ContestParticipant.php +++ b/app/Models/Eloquent/ContestParticipant.php @@ -8,17 +8,14 @@ class ContestParticipant extends Model { protected $table='contest_participant'; protected $primaryKey='cpid'; - const DELETED_AT=null; - const UPDATED_AT=null; - const CREATED_AT=null; public function user() { - return $this->belongsTo('App\Models\Eloquent\UserModel', 'uid'); + return $this->belongsTo('App\Models\Eloquent\User', 'uid'); } public function contest() { - return $this->belongsTo('App\Models\Eloquent\Contest','cid','cid'); + return $this->belongsTo('App\Models\Eloquent\Contest', 'cid', 'cid'); } } diff --git a/app/Models/Eloquent/ContestProblem.php b/app/Models/Eloquent/ContestProblem.php index e71a4f7d7..1e2c9c313 100644 --- a/app/Models/Eloquent/ContestProblem.php +++ b/app/Models/Eloquent/ContestProblem.php @@ -9,36 +9,37 @@ class ContestProblem extends Model { protected $table='contest_problem'; protected $primaryKey='cpid'; - public $timestamps = null; - const DELETED_AT=null; - const UPDATED_AT=null; - const CREATED_AT=null; + public $timestamps=null; + + protected $fillable=[ + 'number', 'ncode', 'pid', 'alias', 'points' + ]; public function contest() { - return $this->belongsTo('App\Models\Eloquent\Contest','cid','cid'); + return $this->belongsTo('App\Models\Eloquent\Contest', 'cid', 'cid'); } public function problem() { - return $this->belongsTo('App\Models\Eloquent\Problem','pid','pid'); + return $this->belongsTo('App\Models\Eloquent\Problem', 'pid', 'pid'); } public function submissions() { - return $this->problem->submissions()->where('cid',$this->contest->cid); + return $this->problem->submissions()->where('cid', $this->contest->cid); } public function getCompilersAttribute() { - $special = $this->problem->special_compiler; - $compilers = Compiler::where([ + $special=$this->problem->special_compiler; + $compilers=Compiler::where([ 'oid' => $this->problem->OJ, 'available' => 1, 'deleted' => 0 ]); - if(!empty($special)) { - $compilers = $compilers->whereIn('coid', explode(',', $special)); + if (!empty($special)) { + $compilers=$compilers->whereIn('coid', explode(',', $special)); } return $compilers; } @@ -53,34 +54,35 @@ public function userStatus($user) 'wrong_doings' => 0, 'color' => '', ]; - $ac_record = $this->ac_record($user); - if(!empty($ac_record[0])){ - $ret['solved'] = 1; - $ret['solved_time'] = $ac_record[0]->submission_date - strtotime($this->contest->begin_time); - $ret['solved_time_parsed'] = formatProblemSolvedTime($ret['solved_time']); - $ret['wrong_doings'] = $ac_record[2]; - $ret['color'] = $ac_record[1] ? 'wemd-green-text' : 'wemd-teal-text'; - }else{ - $ret['wrong_doings'] = $ac_record[2]; + $ac_record=$this->ac_record($user); + if (!empty($ac_record[0])) { + $ret['solved']=1; + $ret['solved_time']=$ac_record[0]->submission_date-strtotime($this->contest->begin_time); + $ret['solved_time_parsed']=formatProblemSolvedTime($ret['solved_time']); + $ret['wrong_doings']=$ac_record[2]; + $ret['color']=$ac_record[1] ? 'wemd-green-text' : 'wemd-teal-text'; + } else { + $ret['wrong_doings']=$ac_record[2]; } return $ret; } public function ac_record($user) { - $user_ac = $this->submissions()->where([ + $frozen_time=$this->contest->frozen_time; + $user_ac=$this->submissions()->where([ 'uid' => $user->id, 'verdict' => 'Accepted' - ])->first(); + ])->where("submission_date", "<", $frozen_time)->orderBy('submission_date', 'asc')->first(); - $other_ac = 1; - $wrong_trys = 0; - if(!empty($user_ac)){ - $other_ac = $this->submissions() - ->where('verdict','Accepted') + $other_ac=1; + $wrong_trys=0; + if (!empty($user_ac)) { + $other_ac=$this->submissions() + ->where('verdict', 'Accepted') ->where('submission_date', '<', $user_ac->submission_date) ->count(); - $wrong_trys = $this->submissions()->where([ + $wrong_trys=$this->submissions()->where([ 'uid' => $user->id, ])->whereIn('verdict', [ 'Runtime Error', @@ -91,8 +93,8 @@ public function ac_record($user) 'Presentation Error', 'Output Limit Exceeded' ])->where('submission_date', '<', $user_ac->submission_date)->count(); - }else{ - $wrong_trys = $this->submissions()->where([ + } else { + $wrong_trys=$this->submissions()->where([ 'uid' => $user->id, ])->whereIn('verdict', [ 'Runtime Error', diff --git a/app/Models/Eloquent/ContestProblemModel.php b/app/Models/Eloquent/ContestProblemModel.php deleted file mode 100644 index f8f91dca6..000000000 --- a/app/Models/Eloquent/ContestProblemModel.php +++ /dev/null @@ -1,20 +0,0 @@ -belongsTo('App\Models\Eloquent\Problem', 'pid'); - } -} diff --git a/app/Models/Eloquent/Dojo/Dojo.php b/app/Models/Eloquent/Dojo/Dojo.php index bfbafd571..4379e6031 100644 --- a/app/Models/Eloquent/Dojo/Dojo.php +++ b/app/Models/Eloquent/Dojo/Dojo.php @@ -9,6 +9,10 @@ class Dojo extends Model { use SoftDeletes; + protected $fillable=[ + 'name', 'description', 'dojo_phase_id', 'passline', 'precondition', 'order' + ]; + public function phase() { return $this->belongsTo('App\Models\Eloquent\Dojo\DojoPhase', 'dojo_phase_id'); @@ -27,13 +31,37 @@ public function passes() public function canPass() { $tot=0; - foreach($this->problems->sortBy('order') as $problem){ + foreach ($this->problems->sortBy('order') as $problem) { $problem=$problem->problem; $tot+=$problem->problem_status['color']=='wemd-green-text'; } return $tot>=$this->passline; } + public function getPreconditionAttribute($value) + { + $precondition=[]; + foreach (explode(',', $value) as $dojo_id) { + if (blank($dojo_id)) { + continue; + } + if (!is_null(Dojo::find($dojo_id))) { + $precondition[]=$dojo_id; + } + } + return $precondition; + } + + public function getTotProblemAttribute() + { + return count($this->problems); + } + + public function setPreconditionAttribute($value) + { + $this->attributes['precondition']=implode(',', $value); + } + public function getPassedAttribute() { return DojoPass::isPassed($this->id); @@ -41,11 +69,12 @@ public function getPassedAttribute() public function getAvailabilityAttribute() { - foreach(explode(',', $this->precondition) as $dojo_id){ - if(blank($dojo_id)) continue; - if(!DojoPass::isPassed($dojo_id)) return 'locked'; + foreach ($this->precondition as $dojo_id) { + if (!DojoPass::isPassed($dojo_id)) { + return 'locked'; + } } - return $this->passed?'passed':'available'; + return $this->passed ? 'passed' : 'available'; } } diff --git a/app/Models/Eloquent/Dojo/DojoPass.php b/app/Models/Eloquent/Dojo/DojoPass.php index 3ad5eec1f..bbf220c09 100644 --- a/app/Models/Eloquent/Dojo/DojoPass.php +++ b/app/Models/Eloquent/Dojo/DojoPass.php @@ -21,14 +21,14 @@ public function dojo() public function user() { - return $this->belongsTo('App\Models\Eloquent\UserModel', 'user_id'); + return $this->belongsTo('App\Models\Eloquent\User', 'user_id'); } public static function isPassed($dojo_id) { - return Auth::check()?self::where([ + return Auth::check() ?self::where([ "dojo_id"=>$dojo_id, "user_id"=>Auth::user()->id, - ])->count()>0:false; + ])->count()>0 : false; } } diff --git a/app/Models/Eloquent/Dojo/DojoPhase.php b/app/Models/Eloquent/Dojo/DojoPhase.php index 687508495..e48ad043c 100644 --- a/app/Models/Eloquent/Dojo/DojoPhase.php +++ b/app/Models/Eloquent/Dojo/DojoPhase.php @@ -9,6 +9,10 @@ class DojoPhase extends Model { use SoftDeletes; + protected $fillable=[ + 'name', 'description', 'passline', 'order' + ]; + public function dojos() { return $this->hasMany('App\Models\Eloquent\Dojo\Dojo', 'dojo_phase_id'); diff --git a/app/Models/Eloquent/Dojo/DojoProblem.php b/app/Models/Eloquent/Dojo/DojoProblem.php index 002302f8c..9261f8e74 100644 --- a/app/Models/Eloquent/Dojo/DojoProblem.php +++ b/app/Models/Eloquent/Dojo/DojoProblem.php @@ -9,6 +9,10 @@ class DojoProblem extends Model { use SoftDeletes; + protected $fillable=[ + 'dojo_id', 'problem_id', 'order' + ]; + public function dojo() { return $this->belongsTo('App\Models\Eloquent\Dojo\Dojo', 'dojo_id'); diff --git a/app/Models/Eloquent/Group.php b/app/Models/Eloquent/Group.php index c5c79083e..7f8ab9ad8 100644 --- a/app/Models/Eloquent/Group.php +++ b/app/Models/Eloquent/Group.php @@ -10,7 +10,7 @@ class Group extends Model public function members() { - return $this->hasMany('App\Models\Eloquent\GroupMember', 'gid','gid'); + return $this->hasMany('App\Models\Eloquent\GroupMember', 'gid', 'gid'); } public function banneds() @@ -18,13 +18,23 @@ public function banneds() return $this->hasMany('App\Models\Eloquent\GroupBanned', 'group_id', 'gid'); } + public static function boot() + { + parent::boot(); + static::saving(function($model) { + if ($model->img!="" && $model->img!=null && $model->img[0]!="/") { + $model->img="/$model->img"; + } + }); + } + public function getLeaderAttribute() { - return $this->members()->where('role',3)->first()->user; + return $this->members()->where('role', 3)->first()->user; } public function getLinkAttribute() { - return route('group.detail',['gcode' => $this->gcode]); + return route('group.detail', ['gcode' => $this->gcode]); } } diff --git a/app/Models/Eloquent/GroupBanned.php b/app/Models/Eloquent/GroupBanned.php index b01776356..543eef54e 100644 --- a/app/Models/Eloquent/GroupBanned.php +++ b/app/Models/Eloquent/GroupBanned.php @@ -9,13 +9,13 @@ class GroupBanned extends Model { use SoftDeletes; - protected $fillable = ['group_id', 'abuse_id', 'reason', 'removed_at']; + protected $fillable=['group_id', 'abuse_id', 'reason', 'removed_at']; public function abuse() { - return $this->belongsTo('\App\Models\Eloquent\Abuse'); + return $this->belongsTo('App\Models\Eloquent\Abuse'); } public function group() { - return $this->belongsTo('\App\Models\Eloquent\Group',null,'gid'); + return $this->belongsTo('App\Models\Eloquent\Group', null, 'gid'); } } diff --git a/app/Models/Eloquent/GroupMember.php b/app/Models/Eloquent/GroupMember.php index dcb6e2632..0e5ba5b73 100644 --- a/app/Models/Eloquent/GroupMember.php +++ b/app/Models/Eloquent/GroupMember.php @@ -12,11 +12,13 @@ class GroupMember extends Model protected $table='group_member'; protected $primaryKey='gmid'; + protected $fillable=['gid', 'uid', 'role', 'nick_name', 'sub_group', 'ranking']; + public function user() { - return $this->belongsTo('App\Models\Eloquent\UserModel','uid','id'); + return $this->belongsTo('App\Models\Eloquent\User', 'uid', 'id'); } public function group() { - return $this->belongsTo('App\Models\Eloquent\Group','gid','gid'); + return $this->belongsTo('App\Models\Eloquent\Group', 'gid', 'gid'); } } diff --git a/app/Models/Eloquent/JudgeServer.php b/app/Models/Eloquent/JudgeServer.php new file mode 100644 index 000000000..991f96a43 --- /dev/null +++ b/app/Models/Eloquent/JudgeServer.php @@ -0,0 +1,39 @@ +whereNotNull($key)->pluck($key)->toArray(); + } + + public function oj() { + return $this->belongsTo('App\Models\Eloquent\OJ', 'oid', 'oid'); + } + + public static function boot() + { + parent::boot(); + static::saving(function($model) { + $columns=$model->getDirty(); + foreach ($columns as $column => $newValue) { + if ($column=="status") { + $model->status_update_at=now(); + break; + } + } + }); + } +} diff --git a/app/Models/Eloquent/JudgeServerModel.php b/app/Models/Eloquent/JudgeServerModel.php deleted file mode 100644 index 079a28911..000000000 --- a/app/Models/Eloquent/JudgeServerModel.php +++ /dev/null @@ -1,20 +0,0 @@ -whereNotNull($key)->pluck($key)->toArray(); - } -} diff --git a/app/Models/Eloquent/Judger.php b/app/Models/Eloquent/Judger.php new file mode 100644 index 000000000..8814e16ce --- /dev/null +++ b/app/Models/Eloquent/Judger.php @@ -0,0 +1,30 @@ +handle.' @ '.$this->oj->name; + } + + public static function column($key) + { + return Self::groupBy($key)->whereNotNull($key)->pluck($key)->toArray(); + } + + public function oj() { + return $this->belongsTo('App\Models\Eloquent\OJ', 'oid', 'oid'); + } +} diff --git a/app/Models/Eloquent/Message.php b/app/Models/Eloquent/Message.php index 9ba28d31c..f7ffb6875 100644 --- a/app/Models/Eloquent/Message.php +++ b/app/Models/Eloquent/Message.php @@ -17,78 +17,78 @@ class Message extends Model */ public static function send($config) { - if(!empty($config['type'])){ - if($config['type'] == 1) { //to a leader that member apply to join the group - $messages = Message::where([ + if (!empty($config['type'])) { + if ($config['type']==1) { //to a leader that member apply to join the group + $messages=Message::where([ 'receiver' => $config['receiver'], 'type' => $config['type'], 'unread' => 1 ])->get(); - if(!empty($messages)) { - foreach($messages as $message) { - $data = json_decode($message->data,true); - if($data['group']['gcode'] == $config['data']['group']['gcode']) { - array_push($data['user'],$config['data']['user'][0]); - $message->data = json_encode($data); + if (!empty($messages)) { + foreach ($messages as $message) { + $data=json_decode($message->data, true); + if ($data['group']['gcode']==$config['data']['group']['gcode']) { + array_push($data['user'], $config['data']['user'][0]); + $message->data=json_encode($data); $message->save(); return true; } } } - }elseif ($config['type'] == 2) { //to a leader that member agree to join the group - $messages = Message::where([ + } elseif ($config['type']==2) { //to a leader that member agree to join the group + $messages=Message::where([ 'receiver' => $config['receiver'], 'type' => $config['type'], 'unread' => 1 ])->get(); - if(!empty($messages)) { - foreach($messages as $message) { - $data = json_decode($message->data,true); - if($data['group'] == $config['data']['group']) { - array_push($data['user'],$config['data']['user'][0]); - $message->data = json_encode($data); + if (!empty($messages)) { + foreach ($messages as $message) { + $data=json_decode($message->data, true); + if ($data['group']==$config['data']['group']) { + array_push($data['user'], $config['data']['user'][0]); + $message->data=json_encode($data); $message->save(); return true; } } } - }elseif ($config['type'] == 3) { //to a person that solution was passed - $message = Message::where([ + } elseif ($config['type']==3) { //to a person that solution was passed + $message=Message::where([ 'receiver' => $config['receiver'], 'type' => $config['type'], 'unread' => 1 ])->first(); - if(!empty($message)) { - $data = json_decode($message->data,true); - array_push($data,$config['data']); - $message->data = json_encode($data); + if (!empty($message)) { + $data=json_decode($message->data, true); + array_push($data, $config['data']); + $message->data=json_encode($data); $message->save(); return true; } - }elseif ($config['type'] == 4) { //to a person that solution was blocked - $message = Message::where([ + } elseif ($config['type']==4) { //to a person that solution was blocked + $message=Message::where([ 'receiver' => $config['receiver'], 'type' => $config['type'], 'unread' => 1 ])->first(); - if(!empty($message)) { - $data = json_decode($message->data,true); - array_push($data,$config['data']); - $message->data = json_encode($data); + if (!empty($message)) { + $data=json_decode($message->data, true); + array_push($data, $config['data']); + $message->data=json_encode($data); $message->save(); return true; } } } - $message = new Message; - $message->sender = $config['sender']; - $message->receiver = $config['receiver']; - $message->title = $config['title']; - if(isset($config['data']) && isset($config['type'])){ - $message->type = $config['type'] ?? null; - $message->data = json_encode($config['data']); - }else{ - $message->content = $config['content']; + $message=new Message; + $message->sender=$config['sender']; + $message->receiver=$config['receiver']; + $message->title=$config['title']; + if (isset($config['data']) && isset($config['type'])) { + $message->type=$config['type'] ?? null; + $message->data=json_encode($config['data']); + } else { + $message->content=$config['content']; } /* if(isset($config['reply'])){ @@ -98,7 +98,7 @@ public static function send($config) $message->reply = $config['allow_reply']; } */ - $message->official = 1; + $message->official=1; $message->save(); return true; } @@ -132,9 +132,9 @@ public static function list($uid) { return static::with('sender_user') - ->where('receiver',$uid) - ->orderBy('unread','desc') - ->orderBy('updated_at','desc') + ->where('receiver', $uid) + ->orderBy('unread', 'desc') + ->orderBy('updated_at', 'desc') ->paginate(15); } @@ -147,9 +147,9 @@ public static function list($uid) */ public static function read($mid) { - $message = static::with('sender_user')->find($mid); - if(!empty($message)){ - $message->unread = 0; + $message=static::with('sender_user')->find($mid); + if (!empty($message)) { + $message->unread=0; $message->save(); } return $message; @@ -164,7 +164,7 @@ public static function read($mid) */ public static function allRead($uid) { - return static::where('receiver',$uid) + return static::where('receiver', $uid) ->update(['unread' => 0]); } @@ -192,20 +192,20 @@ public static function removeAllRead($uid) */ public static function remove($messages) { - $del_count = 0; - if(is_array($messages)){ + $del_count=0; + if (is_array($messages)) { foreach ($messages as $mid) { - $message = static::find($mid); - if(!empty($message)){ + $message=static::find($mid); + if (!empty($message)) { $message->delete(); - $del_count ++; + $del_count++; } } - }else{ - $message = static::find($messages); - if(!empty($message)){ + } else { + $message=static::find($messages); + if (!empty($message)) { $message->delete(); - $del_count ++; + $del_count++; } } return $del_count; @@ -213,36 +213,36 @@ public static function remove($messages) public function getContentAttribute($value) { - if(!empty($this->type)){ - $data = json_decode($this->data,true); - $content = ''; - if($this->type == 1) { - foreach($data['user'] as $user) { - $content .= "[{$user['name']}]({$user['url']}), "; + if (!empty($this->type)) { + $data=json_decode($this->data, true); + $content=''; + if ($this->type==1) { + foreach ($data['user'] as $user) { + $content.="[{$user['name']}]({$user['url']}), "; } - $content = substr($content,0,strlen($content)-2); - $content .= " want to join your group [{$data['group']['name']}]({$data['group']['url']})"; + $content=substr($content, 0, strlen($content)-2); + $content.=" want to join your group [{$data['group']['name']}]({$data['group']['url']})"; return $content; - }elseif($this->type == 2) { - foreach($data['user'] as $user) { - $content .= "[{$user['name']}]({$user['url']}), "; + } elseif ($this->type==2) { + foreach ($data['user'] as $user) { + $content.="[{$user['name']}]({$user['url']}), "; } - $content = substr($content,0,strlen($content)-2); - $content .= " have agreed to join your group [{$data['group']['name']}]({$data['group']['url']})"; + $content=substr($content, 0, strlen($content)-2); + $content.=" have agreed to join your group [{$data['group']['name']}]({$data['group']['url']})"; return $content; } //todo - }else{ + } else { return $value; } } public function sender_user() { - return $this->belongsTo('App\Models\Eloquent\UserModel','sender','id'); + return $this->belongsTo('App\Models\Eloquent\User', 'sender', 'id'); } public function receiver_user() { - return $this->belongsTo('App\Models\Eloquent\UserModel','receiver','id'); + return $this->belongsTo('App\Models\Eloquent\User', 'receiver', 'id'); } } diff --git a/app/Models/Eloquent/OJ.php b/app/Models/Eloquent/OJ.php index a14f6355e..c242eb009 100644 --- a/app/Models/Eloquent/OJ.php +++ b/app/Models/Eloquent/OJ.php @@ -9,7 +9,19 @@ class OJ extends Model { protected $table='oj'; protected $primaryKey='oid'; - const DELETED_AT=null; - const UPDATED_AT=null; - const CREATED_AT=null; + + public function judge_servers() + { + return $this->hasMany('App\Models\Eloquent\JudgeServer', 'oid', 'oid'); + } + + public function compilers() + { + return $this->hasMany('App\Models\Eloquent\Compiler', 'oid', 'oid'); + } + + public function judgers() + { + return $this->hasMany('App\Models\Eloquent\Judger', 'oid', 'oid'); + } } diff --git a/app/Models/Eloquent/Problem.php b/app/Models/Eloquent/Problem.php index 7067bd217..ec1dfeb8a 100644 --- a/app/Models/Eloquent/Problem.php +++ b/app/Models/Eloquent/Problem.php @@ -11,23 +11,26 @@ class Problem extends Model { protected $table='problem'; protected $primaryKey='pid'; - const DELETED_AT=null; const UPDATED_AT="update_date"; - const CREATED_AT=null; + + public function getReadableNameAttribute() + { + return $this->pcode.'. '.$this->title; + } public function submissions() { - return $this->hasMany('App\Models\Eloquent\Submission','pid','pid'); + return $this->hasMany('App\Models\Eloquent\Submission', 'pid', 'pid'); } public function problemSamples() { - return $this->hasMany('App\Models\Eloquent\ProblemSample','pid','pid'); + return $this->hasMany('App\Models\Eloquent\ProblemSample', 'pid', 'pid'); } public function getProblemStatusAttribute() { - if(Auth::check()){ + if (Auth::check()) { $prob_status=(new OutdatedSubmissionModel())->getProblemStatus($this->pid, Auth::user()->id); if (empty($prob_status)) { return [ diff --git a/app/Models/Eloquent/ProblemSample.php b/app/Models/Eloquent/ProblemSample.php index 9494a5884..b5fd9cad4 100644 --- a/app/Models/Eloquent/ProblemSample.php +++ b/app/Models/Eloquent/ProblemSample.php @@ -8,9 +8,9 @@ class ProblemSample extends Model { protected $table='problem_sample'; protected $primaryKey='psid'; - protected $fillable = ['sample_input', 'sample_output']; + protected $fillable=['sample_input', 'sample_output']; public function problem() { - return $this->belongTo('App\Models\Eloquent\Problem','pid','pid'); + return $this->belongTo('App\Models\Eloquent\Problem', 'pid', 'pid'); } } diff --git a/app/Models/Eloquent/ProblemSolutionModel.php b/app/Models/Eloquent/ProblemSolution.php similarity index 84% rename from app/Models/Eloquent/ProblemSolutionModel.php rename to app/Models/Eloquent/ProblemSolution.php index de95d40fc..d265fa07d 100644 --- a/app/Models/Eloquent/ProblemSolutionModel.php +++ b/app/Models/Eloquent/ProblemSolution.php @@ -5,7 +5,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\DB; -class ProblemSolutionModel extends Model +class ProblemSolution extends Model { protected $table='problem_solution'; protected $primaryKey='psoid'; diff --git a/app/Models/Eloquent/Setting.php b/app/Models/Eloquent/Setting.php new file mode 100644 index 000000000..c60e6f077 --- /dev/null +++ b/app/Models/Eloquent/Setting.php @@ -0,0 +1,12 @@ +belongsTo('App\Models\Eloquent\UserModel', 'uid'); + return $this->belongsTo('App\Models\Eloquent\User', 'uid'); } public function contest() @@ -35,16 +35,29 @@ public function problem() return $this->belongsTo('App\Models\Eloquent\Problem', 'pid'); } + public function judger() + { + return $this->belongsTo('App\Models\Eloquent\Judger', 'jid'); + } + + public function getJudgerNameAttribute() + { + if (!is_null($this->judger)) { + return $this->judger->readable_name; + } + return '-'; + } + public function getNcodeAttribute() { - $contest = $this->contest; + $contest=$this->contest; return $contest->problems->where('pid', $this->pid)->first()->ncode; } public function getNickNameAttribute() { - $member = $this->contest->group->members()->where('uid', $this->user->id)->first(); - if(!empty($member)) { + $member=$this->contest->group->members()->where('uid', $this->user->id)->first(); + if (!empty($member)) { return $member->nickname; } return null; @@ -79,9 +92,19 @@ public function getLangAttribute() return $this->compiler->lang; } + public function getParsedScoreAttribute() + { + if (is_null($this->contest)) { + $tot_score=100; + } else { + $tot_score=$this->contest->problems->where('pid', $this->pid)->first()->points; + } + return round($this->score / max($this->problem->tot_score, 1) * $tot_score, 1); + } + public function getSubmissionDateParsedAttribute() { - $submission_date = date('Y-m-d H:i:s', $this->submission_date); + $submission_date=date('Y-m-d H:i:s', $this->submission_date); return formatHumanReadableTime($submission_date); } diff --git a/app/Models/Eloquent/Tool/AppSettings.php b/app/Models/Eloquent/Tool/AppSettings.php new file mode 100644 index 000000000..2240df4a7 --- /dev/null +++ b/app/Models/Eloquent/Tool/AppSettings.php @@ -0,0 +1,31 @@ + $key])->first(); + if (blank($ret) || blank($ret->content)) { + return $default; + } + return $ret->is_json ? json_decode($ret->content) : $ret->content; + } + + public static function set($key, $content) { + $ret=Setting::where(['key' => $key])->first(); + if (blank($ret)) { + return Setting::create([ + 'key' => $key, + 'content' => $content, + 'is_json' => false, + ]); + } + return Setting::find($ret->id)->update([ + 'content' => $content, + 'is_json' => false, + ]); + } +} diff --git a/app/Models/Eloquent/Tool/ImageHosting.php b/app/Models/Eloquent/Tool/ImageHosting.php new file mode 100644 index 000000000..1f8366e11 --- /dev/null +++ b/app/Models/Eloquent/Tool/ImageHosting.php @@ -0,0 +1,26 @@ +belongsTo('App\Models\Eloquent\User'); + } + + public function getAbsolutePathAttribute() + { + return url($this->relative_path); + } +} diff --git a/app/Models/Eloquent/Tool/MonacoTheme.php b/app/Models/Eloquent/Tool/MonacoTheme.php new file mode 100644 index 000000000..d33b617c7 --- /dev/null +++ b/app/Models/Eloquent/Tool/MonacoTheme.php @@ -0,0 +1,275 @@ +[ + "id" => "vs-dark", + "name" => "Default", + "background" => "rgb(30,30,30)" + ], + "vs"=>[ + "id" => "vs", + "name" => "Default (White)", + "background" => "rgb(255,255,254)" + ], + "hc-black"=>[ + "id" => "hc-black", + "name" => "High Contrast (Dark)", + "background" => "rgb(0,0,0)" + ], + "active4d" => [ + "id" => "active4d", + "name" => "Active4D", + "background" => "#FFFFFF" + ], + "all-hallows-eve" => [ + "id" => "all-hallows-eve", + "name" => "All Hallows Eve", + "background" => "#000000" + ], + "amy" => [ + "id" => "amy", + "name" => "Amy", + "background" => "#200020" + ], + "birds-of-paradise" => [ + "id" => "birds-of-paradise", + "name" => "Birds of Paradise", + "background" => "#372725" + ], + "blackboard" => [ + "id" => "blackboard", + "name" => "Blackboard", + "background" => "#0C1021" + ], + "brilliance-black" => [ + "id" => "brilliance-black", + "name" => "Brilliance Black", + "background" => "#0D0D0DFA" + ], + "brilliance-dull" => [ + "id" => "brilliance-dull", + "name" => "Brilliance Dull", + "background" => "#050505FA" + ], + "chrome-devtools" => [ + "id" => "chrome-devtools", + "name" => "Chrome DevTools", + "background" => "#FFFFFF" + ], + "clouds-midnight" => [ + "id" => "clouds-midnight", + "name" => "Clouds Midnight", + "background" => "#191919" + ], + "clouds" => [ + "id" => "clouds", + "name" => "Clouds", + "background" => "#FFFFFF" + ], + "cobalt" => [ + "id" => "cobalt", + "name" => "Cobalt", + "background" => "#002240" + ], + "dawn" => [ + "id" => "dawn", + "name" => "Dawn", + "background" => "#F9F9F9" + ], + "dreamweaver" => [ + "id" => "dreamweaver", + "name" => "Dreamweaver", + "background" => "#FFFFFF" + ], + "eiffel" => [ + "id" => "eiffel", + "name" => "Eiffel", + "background" => "#FFFFFF" + ], + "espresso-libre" => [ + "id" => "espresso-libre", + "name" => "Espresso Libre", + "background" => "#2A211C" + ], + "github" => [ + "id" => "github", + "name" => "GitHub", + "background" => "#F8F8FF" + ], + "idle" => [ + "id" => "idle", + "name" => "IDLE", + "background" => "#FFFFFF" + ], + "katzenmilch" => [ + "id" => "katzenmilch", + "name" => "Katzenmilch", + "background" => "#E8E9E8" + ], + "kuroir-theme" => [ + "id" => "kuroir-theme", + "name" => "Kuroir Theme", + "background" => "#E8E9E8" + ], + "lazy" => [ + "id" => "lazy", + "name" => "LAZY", + "background" => "#FFFFFF" + ], + "magicwb--amiga-" => [ + "id" => "magicwb--amiga-", + "name" => "MagicWB (Amiga)", + "background" => "#969696" + ], + "merbivore-soft" => [ + "id" => "merbivore-soft", + "name" => "Merbivore Soft", + "background" => "#161616" + ], + "merbivore" => [ + "id" => "merbivore", + "name" => "Merbivore", + "background" => "#161616" + ], + "monokai-bright" => [ + "id" => "monokai-bright", + "name" => "Monokai Bright", + "background" => "#272822" + ], + "monokai" => [ + "id" => "monokai", + "name" => "Monokai", + "background" => "#272822" + ], + "night-owl" => [ + "id" => "night-owl", + "name" => "Night Owl", + "background" => "#011627" + ], + "oceanic-next" => [ + "id" => "oceanic-next", + "name" => "Oceanic Next", + "background" => "#1B2B34" + ], + "pastels-on-dark" => [ + "id" => "pastels-on-dark", + "name" => "Pastels on Dark", + "background" => "#211E1E" + ], + "slush-and-poppies" => [ + "id" => "slush-and-poppies", + "name" => "Slush and Poppies", + "background" => "#F1F1F1" + ], + "solarized-dark" => [ + "id" => "solarized-dark", + "name" => "Solarized-dark", + "background" => "#002B36" + ], + "solarized-light" => [ + "id" => "solarized-light", + "name" => "Solarized-light", + "background" => "#FDF6E3" + ], + "spacecadet" => [ + "id" => "spacecadet", + "name" => "SpaceCadet", + "background" => "#0D0D0D" + ], + "sunburst" => [ + "id" => "sunburst", + "name" => "Sunburst", + "background" => "#000000" + ], + "textmate--mac-classic-" => [ + "id" => "textmate--mac-classic-", + "name" => "Textmate (Mac Classic)", + "background" => "#FFFFFF" + ], + "tomorrow-night-blue" => [ + "id" => "tomorrow-night-blue", + "name" => "Tomorrow-Night-Blue", + "background" => "#002451" + ], + "tomorrow-night-bright" => [ + "id" => "tomorrow-night-bright", + "name" => "Tomorrow-Night-Bright", + "background" => "#000000" + ], + "tomorrow-night-eighties" => [ + "id" => "tomorrow-night-eighties", + "name" => "Tomorrow-Night-Eighties", + "background" => "#2D2D2D" + ], + "tomorrow-night" => [ + "id" => "tomorrow-night", + "name" => "Tomorrow-Night", + "background" => "#1D1F21" + ], + "tomorrow" => [ + "id" => "tomorrow", + "name" => "Tomorrow", + "background" => "#FFFFFF" + ], + "twilight" => [ + "id" => "twilight", + "name" => "Twilight", + "background" => "#141414" + ], + "upstream-sunburst" => [ + "id" => "upstream-sunburst", + "name" => "Upstream Sunburst", + "background" => "#000000F7" + ], + "vibrant-ink" => [ + "id" => "vibrant-ink", + "name" => "Vibrant Ink", + "background" => "#000000" + ], + "xcode-default" => [ + "id" => "xcode-default", + "name" => "Xcode_default", + "background" => "#FFFFFF" + ], + "zenburnesque" => [ + "id" => "zenburnesque", + "name" => "Zenburnesque", + "background" => "#404040" + ], + "iplastic" => [ + "id" => "iplastic", + "name" => "iPlastic", + "background" => "#EEEEEEEB" + ], + "idlefingers" => [ + "id" => "idlefingers", + "name" => "idleFingers", + "background" => "#323232" + ], + "krtheme" => [ + "id" => "krtheme", + "name" => "krTheme", + "background" => "#0B0A09" + ], + "monoindustrial" => [ + "id" => "monoindustrial", + "name" => "monoindustrial", + "background" => "#222C28" + ] + ]; + + public static function getTheme($id) { + if (!isset(self::$theme[$id])) { + return self::$theme['vs-dark']; + } + return self::$theme[$id]; + } + + public static function getAll() { + return self::$theme; + } +} diff --git a/app/Models/Eloquent/Tool/Pastebin.php b/app/Models/Eloquent/Tool/Pastebin.php index eb5267a36..ce5b472cd 100644 --- a/app/Models/Eloquent/Tool/Pastebin.php +++ b/app/Models/Eloquent/Tool/Pastebin.php @@ -7,8 +7,8 @@ class Pastebin extends Model { - protected $table = 'pastebin'; - protected $primaryKey = 'pbid'; + protected $table='pastebin'; + protected $primaryKey='pbid'; protected $fillable=[ 'lang', 'title', 'user_id', 'expired_at', 'content', 'code' @@ -16,7 +16,7 @@ class Pastebin extends Model public function user() { - return $this->belongsTo('App\Models\Eloquent\UserModel', 'user_id'); + return $this->belongsTo('App\Models\Eloquent\User', 'user_id'); } public static function generatePbCode($length=6) diff --git a/app/Models/Eloquent/Tool/Socialite.php b/app/Models/Eloquent/Tool/Socialite.php new file mode 100644 index 000000000..a9f72a306 --- /dev/null +++ b/app/Models/Eloquent/Tool/Socialite.php @@ -0,0 +1,18 @@ +[ + 'name'=>'Default', + 'primaryColor'=>'#3E4551', + ], + "classic"=>[ + 'name'=>'Classic', + 'primaryColor'=>'#424242', + ], + "cranberry"=>[ + 'name'=>'Cranberry', + 'primaryColor'=>'#C62828', + ], + "byzantium"=>[ + 'name'=>'Byzantium', + 'primaryColor'=>'#ad1457', + ], + "orchids"=>[ + 'name'=>'Orchids', + 'primaryColor'=>'#6a1b9a', + ], + "blueberry"=>[ + 'name'=>'Blueberry', + 'primaryColor'=>'#4527a0', + ], + "starrynights"=>[ + 'name'=>'Starrynights', + 'primaryColor'=>'#283593', + ], + "electric"=>[ + 'name'=>'Electric', + 'primaryColor'=>'#1565C0', + ], + "oceanic"=>[ + 'name'=>'Oceanic', + 'primaryColor'=>'#0277bd', + ], + "emerald"=>[ + 'name'=>'Emerald', + 'primaryColor'=>'#00695c', + ], + "aventurine"=>[ + 'name'=>'Aventurine', + 'primaryColor'=>'#2E7D32', + ], + "tropical"=>[ + 'name'=>'Tropical', + 'primaryColor'=>'#ef6c00', + ], + "ginger"=>[ + 'name'=>'Ginger', + 'primaryColor'=>'#d84315', + ], + "espresso"=>[ + 'name'=>'Espresso', + 'primaryColor'=>'#4e342e', + ], + "enigma"=>[ + 'name'=>'Enigma', + 'primaryColor'=>'#37474f', + ], + ]; + + public static function getTheme($id) { + if (!isset(self::$theme[$id])) { + return self::$theme['default']; + } + return self::$theme[$id]; + } + + public static function getAll() { + return self::$theme; + } +} diff --git a/app/Models/Eloquent/User.php b/app/Models/Eloquent/User.php new file mode 100644 index 000000000..36cad6293 --- /dev/null +++ b/app/Models/Eloquent/User.php @@ -0,0 +1,168 @@ +hasMany('App\Models\Eloquent\UserBanned'); + } + + public function announcements() { + return $this->hasMany('App\Models\Eloquent\Announcement'); + } + + public function permissions() { + return $this->hasMany('App\Models\Eloquent\UserPermission'); + } + + public function imagehostings() { + return $this->hasMany('App\Models\Eloquent\Tool\ImageHosting'); + } + + public function extras() { + return $this->hasMany('App\Models\Eloquent\UserExtra', 'uid'); + } + + public function hasPermission($permissionID) { + return ($this->permissions()->where(['permission_id'=>$permissionID])->count())>0; + } + + public function hasIndependentPassword() { + return filled($this->password); + } + + public function hasIndependentEmail() { + return !in_array(explode('@', $this->email)[1], ['temporary.email']) && !$this->contest_account; + } + + public function isIndependent() { + return $this->hasIndependentPassword() && $this->hasIndependentEmail(); + } + + /** + * To get some extra info of a user. + * + * @param string|array $need An array is returned when an array is passed in, Only one value is returned when a string is passed in. + * @param int|null $secretLevel the secret level this query currently running on + * @return string|array $result + */ + public function getExtra($need, $secretLevel=0) { + $ret=$this->extras()->orderBy('key')->get()->toArray(); + $result=[]; + if (!empty($ret)) { + if (is_string($need)) { + foreach ($ret as $value) { + if (empty($value['secret_level']) || $value['secret_level']<=$secretLevel) { + $keyName=UserExtra::$extraMapping[$value['key']] ?? 'unknown'; + if ($keyName==$need) { + return $value['value']; + } + } + } + return null; + } else { + foreach ($ret as $value) { + if (empty($value['secret_level']) || $value['secret_level']<=$secretLevel) { + $keyName=UserExtra::$extraMapping[$value['key']] ?? 'unknown'; + if (in_array($keyName, $need)) { + $result[$keyName]=$value['value']; + } + } + } + } + } + return $result; + } + + /** + * To set some extra info of a user. + * + * @param string $keyName insert when key not found or update when key exists. Only values declared in UserExtra Model are accepted + * @param string|null $value the extra info will be delete when value is null + * @param int|null $secretLevel the secret level this query currently running on + * @return mixed $result + */ + public function setExtra($keyName, $value=null, $secretLevel=-1) { + $key=array_search($keyName, UserExtra::$extraMapping); + if ($key===false) { + return false; + } + $ret=$this->extras()->where('key', $key)->limit(1)->get()->toArray(); + if (!empty($ret)) { + $ret=$ret[0]; + unset($ret['id']); + if (!is_null($value)) { + $ret['value']=$value; + } else { + $this->extras()->where('key', $key)->delete(); + return true; + } + if ($secretLevel!=-1) { + $ret['secret_level']=$secretLevel; + } + return $this->extras()->where('key', $key)->update($ret); + } else { + if ($value===null) { + return true; + } + return $this->extras()->create([ + 'key' => $key, + 'value' => $value, + 'secret_level' => $secretLevel==-1 ? 0 : $secretLevel, + ])->id; + } + } + + public function getSocialiteInfo($secretLevel=-1) + { + $socialites=[]; + foreach (UserExtra::$socialite_support as $key => $value) { + $id_keyname=$key.'_id'; + $id=$this->getExtra($id_keyname); + if (!empty($id)) { + $info=[ + 'id' => $id, + ]; + foreach ($value as $info_name) { + $info_temp=$this->getExtra($key.'_'.$info_name); + if ($info_temp!==null) { + $info[$info_name]=$info_temp; + } + } + $socialites[$key]=$info; + } + } + + return $socialites; + } +} diff --git a/app/Models/Eloquent/UserBanned.php b/app/Models/Eloquent/UserBanned.php index e4d5a362d..beaf23000 100644 --- a/app/Models/Eloquent/UserBanned.php +++ b/app/Models/Eloquent/UserBanned.php @@ -9,13 +9,13 @@ class UserBanned extends Model { use SoftDeletes; - protected $fillable = ['user_id', 'abuse_id', 'reason', 'removed_at']; + protected $fillable=['user_id', 'abuse_id', 'reason', 'removed_at']; public function abuse() { - return $this->belongsTo('\App\Models\Eloquent\Abuse'); + return $this->belongsTo('App\Models\Eloquent\Abuse'); } public function user() { - return $this->belongsTo('\App\User'); + return $this->belongsTo('App\Models\Eloquent\User'); } } diff --git a/app/Models/Eloquent/UserExtra.php b/app/Models/Eloquent/UserExtra.php new file mode 100644 index 000000000..c529eb924 --- /dev/null +++ b/app/Models/Eloquent/UserExtra.php @@ -0,0 +1,89 @@ + 'gender', + 1 => 'contact', + 2 => 'school', + 3 => 'country', + 4 => 'location', + 5 => 'editor_left_width', + 6 => 'editor_theme', + + 1000 => 'github_id', + 1001 => 'github_email', + 1002 => 'github_nickname', + 1003 => 'github_homepage', + 1004 => 'github_token', + 1010 => 'aauth_id', + 1011 => 'aauth_nickname', + ]; + + public static $extraDict=[ + 'gender' => [ + 'icon' => 'MDI gender-transgender', + 'locale' => 'dashboard.setting.gender', + ], + 'contact' => [ + 'icon' => 'MDI contacts', + 'locale' => 'dashboard.setting.contact', + ], + 'school' => [ + 'icon' => 'MDI school', + 'locale' => 'dashboard.setting.school', + ], + 'country' => [ + 'icon' => 'MDI earth', + 'locale' => 'dashboard.setting.countryAndRegion', + ], + 'location' => [ + 'icon' => 'MDI map-marker', + 'locale' => 'dashboard.setting.detailedLocation', + ], + ]; + + public static $socialite_support=[ + //use the form "platform_id" for unique authentication + //such as github_id + 'github' => [ + 'email', 'nickname', 'homepage', 'token' + ], + 'aauth' => [ + 'nickname' + ], + ]; + + public function user() { + return $this->belongsTo('App\Models\Eloquent\User', 'id', 'uid'); + } + + /** + * find a extra info key-value pair + * @param string $key_name the key + * @param string $value the value + * @return string $result + */ + public static function search($key, $value) + { + $key=array_search($key, UserExtra::$extraMapping); + if ($key) { + return self::where([ + 'key' => $key, + 'value' => $value + ])->limit(1)->get()->toArray(); + } else { + return null; + } + } + +} diff --git a/app/Models/Eloquent/UserModel.php b/app/Models/Eloquent/UserModel.php deleted file mode 100644 index 5d09d44c0..000000000 --- a/app/Models/Eloquent/UserModel.php +++ /dev/null @@ -1,32 +0,0 @@ -hasMany('App\Models\Eloquent\UserBanned'); - } -} diff --git a/app/Models/Eloquent/UserPermission.php b/app/Models/Eloquent/UserPermission.php new file mode 100644 index 000000000..012a8b60c --- /dev/null +++ b/app/Models/Eloquent/UserPermission.php @@ -0,0 +1,22 @@ + 'Show site admin badge and allow frontend access to admin portal', + // Why 26 you may ask? Praise be the all-mighty samsung AC that keeps my room at 26 celsius. + '26' => 'Allow access to image hosting services', + ]; + + public function user() { + return $this->belongsTo('App\Models\Eloquent\User'); + } +} diff --git a/app/Models/GroupModel.php b/app/Models/GroupModel.php index 7824eba9d..5a96a7f43 100644 --- a/app/Models/GroupModel.php +++ b/app/Models/GroupModel.php @@ -58,10 +58,10 @@ public function cacheTrendingGroups() foreach ($trending_groups as &$t) { $t["members"]=$this->countGroupMembers($t["gid"]); } - usort($trending_groups, function ($a, $b) { + usort($trending_groups, function($a, $b) { return $b["members"]<=>$a["members"]; }); - Cache::tags(['group'])->put('trending', array_slice($trending_groups,0,12), 3600*24); + Cache::tags(['group'])->put('trending', array_slice($trending_groups, 0, 12), 3600 * 24); } public function userGroups($uid) @@ -101,13 +101,13 @@ public function changeNickName($gid, $uid, $nickName) public function changeGroupName($gid, $GroupName) { - return DB::table("group")->where('gid',$gid)->update([ + return DB::table("group")->where('gid', $gid)->update([ "name"=>$GroupName ]); } - public function changeJoinPolicy($gid, $JoinPolicy){ - return DB::table("group")->where('gid',$gid)->update([ + public function changeJoinPolicy($gid, $JoinPolicy) { + return DB::table("group")->where('gid', $gid)->update([ "join_policy"=>$JoinPolicy ]); } @@ -121,7 +121,9 @@ public function basic($gid) public function details($gcode) { $basic_info=DB::table($this->tableName)->where(["gcode"=>$gcode])->first(); - if(empty($basic_info)) return []; + if (empty($basic_info)) { + return []; + } $basic_info["members"]=$this->countGroupMembers($basic_info["gid"]); $basic_info["tags"]=$this->getGroupTags($basic_info["gid"]); $basic_info["create_time_foramt"]=date_format(date_create($basic_info["created_at"]), 'M jS, Y'); @@ -138,10 +140,10 @@ public function joinPolicy($gid) public function userProfile($uid, $gid) { $info=DB::table("group_member") - ->join('users','users.id','=','group_member.uid') + ->join('users', 'users.id', '=', 'group_member.uid') ->where(["gid"=>$gid, "uid"=>$uid]) ->where("role", ">", 0) - ->select('avatar','describes','email','gid','uid','name','nick_name','professional_rate','role','sub_group') + ->select('avatar', 'describes', 'email', 'gid', 'uid', 'name', 'nick_name', 'professional_rate', 'role', 'sub_group') ->first(); if (!empty($info)) { $info["role_parsed"]=$this->role[$info["role"]]; @@ -169,7 +171,9 @@ public function userList($gid) foreach ($user_list as &$u) { $u["role_parsed"]=$this->role[$u["role"]]; $u["role_color"]=$this->role_color[$u["role"]]; - if(is_null($u["sub_group"])) $u["sub_group"]="None"; + if (is_null($u["sub_group"])) { + $u["sub_group"]="None"; + } } return $user_list; } @@ -230,16 +234,16 @@ public function isMember($gid, $uid) ])->where("role", ">", 0)->count(); } - public function problemTags($gid,$pid = -1) + public function problemTags($gid, $pid=-1) { - if($pid == -1){ - $tags = DB::table('group_problem_tag') + if ($pid==-1) { + $tags=DB::table('group_problem_tag') ->select('tag') - ->where('gid',$gid) + ->where('gid', $gid) ->distinct() ->get()->all(); - }else{ - $tags = DB::table('group_problem_tag') + } else { + $tags=DB::table('group_problem_tag') ->select('tag') ->where('gid', $gid) ->where('pid', $pid) @@ -247,10 +251,10 @@ public function problemTags($gid,$pid = -1) ->get()->all(); } - $tags_arr = []; - if(!empty($tags)){ + $tags_arr=[]; + if (!empty($tags)) { foreach ($tags as $value) { - array_push($tags_arr,$value['tag']); + array_push($tags_arr, $value['tag']); } } return $tags_arr; @@ -258,28 +262,28 @@ public function problemTags($gid,$pid = -1) public function problems($gid) { - $contestModel = new ContestModel(); - $problems = DB::table('contest_problem') - ->join('contest','contest_problem.cid', '=', 'contest.cid') - ->join('problem','contest_problem.pid', '=', 'problem.pid' ) + $contestModel=new ContestModel(); + $problems=DB::table('contest_problem') + ->join('contest', 'contest_problem.cid', '=', 'contest.cid') + ->join('problem', 'contest_problem.pid', '=', 'problem.pid') ->select('contest_problem.cid as cid', 'problem.pid as pid', 'pcode', 'title') - ->where('contest.gid',$gid) - ->where('contest.practice',1) - ->orderBy('contest.created_at','desc') + ->where('contest.gid', $gid) + ->where('contest.practice', 1) + ->orderBy('contest.created_at', 'desc') ->distinct() ->get()->all(); - $user_id = Auth::user()->id; - foreach($problems as $key => $value){ - if($contestModel->judgeClearance($value['cid'],$user_id) != 3){ + $user_id=Auth::user()->id; + foreach ($problems as $key => $value) { + if ($contestModel->judgeClearance($value['cid'], $user_id)!=3) { unset($problems[$key]); - }else{ - $problems[$key]['tags'] = $this->problemTags($gid,$value['pid']); + } else { + $problems[$key]['tags']=$this->problemTags($gid, $value['pid']); } } return $problems; } - public function problemAddTag($gid,$pid,$tag) + public function problemAddTag($gid, $pid, $tag) { return DB::table("group_problem_tag")->insert([ "gid"=>$gid, @@ -288,7 +292,7 @@ public function problemAddTag($gid,$pid,$tag) ]); } - public function problemRemoveTag($gid,$pid,$tag) + public function problemRemoveTag($gid, $pid, $tag) { return DB::table("group_problem_tag")->where([ "gid"=>$gid, @@ -300,7 +304,9 @@ public function problemRemoveTag($gid,$pid,$tag) public function judgeEmailClearance($gid, $email) { $user=DB::table("users")->where(["email"=>$email])->first(); - if(empty($user)) return -4; + if (empty($user)) { + return -4; + } $ret=DB::table("group_member")->where([ "gid"=>$gid, "uid"=>$user["id"], @@ -391,20 +397,20 @@ public function createNotice($gid, $uid, $title, $content) public function groupMemberPracticeContestStat($gid) { - $contestModel = new ContestModel(); + $contestModel=new ContestModel(); - $allPracticeContest = DB::table('contest') + $allPracticeContest=DB::table('contest') ->where([ 'gid' => $gid, 'practice' => 1, ]) - ->select('cid','name') + ->select('cid', 'name') ->get()->all(); - $user_list = $this->userList($gid); + $user_list=$this->userList($gid); - $memberData = []; + $memberData=[]; foreach ($user_list as $u) { - $memberData[$u['uid']] = [ + $memberData[$u['uid']]=[ 'name' => $u['name'], 'nick_name' => $u['nick_name'], 'elo' => $u['ranking'], @@ -415,61 +421,61 @@ public function groupMemberPracticeContestStat($gid) ]; } foreach ($allPracticeContest as $c) { - $contestRankRaw = $contestModel->contestRank($c['cid']); - foreach($contestRankRaw as $key => $contestRank){ - if(isset($contestRank['remote']) && $contestRank['remote']){ + $contestRankRaw=$contestModel->contestRank($c['cid']); + foreach ($contestRankRaw as $key => $contestRank) { + if (isset($contestRank['remote']) && $contestRank['remote']) { unset($contestRankRaw[$key]); } } - $contestRank = array_values($contestRankRaw); - $problemsCount = DB::table('contest_problem') - ->where('cid',$c['cid']) + $contestRank=array_values($contestRankRaw); + $problemsCount=DB::table('contest_problem') + ->where('cid', $c['cid']) ->count(); - $index = 1; - $rank = 1; - $last_cr = []; - $last_rank = 1; + $index=1; + $rank=1; + $last_cr=[]; + $last_rank=1; foreach ($contestRank as $cr) { - $last_rank = $index; - if(!empty($last_cr)){ - if($cr['solved'] == $last_cr['solved'] && $cr['penalty'] == $last_cr['penalty'] ){ - $rank = $last_rank; - }else{ - $rank = $index; - $last_rank = $rank; + $last_rank=$index; + if (!empty($last_cr)) { + if ($cr['solved']==$last_cr['solved'] && $cr['penalty']==$last_cr['penalty']) { + $rank=$last_rank; + } else { + $rank=$index; + $last_rank=$rank; } } - if(in_array($cr['uid'],array_keys($memberData))) { - $memberData[$cr['uid']]['solved_all'] += $cr['solved']; - $memberData[$cr['uid']]['problem_all'] += $problemsCount; - $memberData[$cr['uid']]['penalty'] += $cr['penalty']; - $memberData[$cr['uid']]['contest_detial'][$c['cid']] = [ + if (in_array($cr['uid'], array_keys($memberData))) { + $memberData[$cr['uid']]['solved_all']+=$cr['solved']; + $memberData[$cr['uid']]['problem_all']+=$problemsCount; + $memberData[$cr['uid']]['penalty']+=$cr['penalty']; + $memberData[$cr['uid']]['contest_detial'][$c['cid']]=[ 'rank' => $rank, 'solved' => $cr['solved'], 'problems' => $problemsCount, 'penalty' => $cr['penalty'] ]; } - $last_cr = $cr; + $last_cr=$cr; $index++; } } - $new_memberData = []; + $new_memberData=[]; foreach ($memberData as $uid => $data) { - $contest_count = 0; - $rank_sum = 0; + $contest_count=0; + $rank_sum=0; foreach ($data['contest_detial'] as $cid => $c) { - $rank_sum += $c['rank']; - $contest_count += 1; + $rank_sum+=$c['rank']; + $contest_count+=1; } - $temp = $data; - $temp['uid'] = $uid; - if($contest_count != 0){ - $temp['rank_ave'] = $rank_sum/$contest_count; + $temp=$data; + $temp['uid']=$uid; + if ($contest_count!=0) { + $temp['rank_ave']=$rank_sum / $contest_count; } - array_push($new_memberData,$temp); + array_push($new_memberData, $temp); } - $ret = [ + $ret=[ 'contest_list' => $allPracticeContest, 'member_data' => $new_memberData ]; @@ -478,58 +484,58 @@ public function groupMemberPracticeContestStat($gid) public function groupMemberPracticeTagStat($gid) { - $tags = $this->problemTags($gid); - $tag_problems = []; + $tags=$this->problemTags($gid); + $tag_problems=[]; - $user_list = $this->userList($gid); + $user_list=$this->userList($gid); foreach ($tags as $tag) { - $tag_problems[$tag] = DB::table('problem') - ->join('group_problem_tag','problem.pid','=','group_problem_tag.pid') + $tag_problems[$tag]=DB::table('problem') + ->join('group_problem_tag', 'problem.pid', '=', 'group_problem_tag.pid') ->where([ 'group_problem_tag.gid' => $gid, 'tag' => $tag ]) - ->select('group_problem_tag.pid as pid','pcode','title') + ->select('group_problem_tag.pid as pid', 'pcode', 'title') ->get()->all(); } - $all_problems = []; + $all_problems=[]; foreach ($tag_problems as &$tag_problem_set) { foreach ($tag_problem_set as $problem) { - $all_problems[$problem['pid']] = $problem; + $all_problems[$problem['pid']]=$problem; } - $tag_problem_set = array_column($tag_problem_set,'pid'); + $tag_problem_set=array_column($tag_problem_set, 'pid'); } - $submission_data = DB::table('submission') - ->whereIn('pid',array_keys($all_problems)) - ->whereIn('uid',array_column($user_list,'uid')) - ->where('verdict','Accepted') - ->select('pid','uid') + $submission_data=DB::table('submission') + ->whereIn('pid', array_keys($all_problems)) + ->whereIn('uid', array_column($user_list, 'uid')) + ->where('verdict', 'Accepted') + ->select('pid', 'uid') ->get()->all(); - $memberData = []; + $memberData=[]; foreach ($user_list as $member) { - $completion = []; - foreach($tag_problems as $tag => $problems) { - $completion[$tag] = []; + $completion=[]; + foreach ($tag_problems as $tag => $problems) { + $completion[$tag]=[]; foreach ($problems as $problem) { - $is_accepted = 0; + $is_accepted=0; foreach ($submission_data as $sd) { - if($sd['pid'] == $problem && $sd['uid'] == $member['uid']){ - $is_accepted = 1; + if ($sd['pid']==$problem && $sd['uid']==$member['uid']) { + $is_accepted=1; break; } } - $completion[$tag][$problem] = $is_accepted; + $completion[$tag][$problem]=$is_accepted; } } - array_push($memberData,[ + array_push($memberData, [ 'uid' => $member['uid'], 'name' => $member['name'], 'nick_name' => $member['nick_name'], 'completion' => $completion, ]); } - $ret = [ + $ret=[ 'all_problems' => $all_problems, 'tag_problems' => $tag_problems, 'member_data' => $memberData @@ -539,10 +545,10 @@ public function groupMemberPracticeTagStat($gid) public function refreshAllElo() { - $result = []; - $gids = DB::table('group')->select('gid','name')->get()->all(); + $result=[]; + $gids=DB::table('group')->select('gid', 'name')->get()->all(); foreach ($gids as $gid) { - $result[$gid['gid']] = [ + $result[$gid['gid']]=[ 'name' => $gid['name'], 'result' => $this->refreshElo($gid['gid']), ]; @@ -553,41 +559,41 @@ public function refreshAllElo() public function refreshElo($gid) { DB::table('group_rated_change_log') - ->where('gid',$gid) + ->where('gid', $gid) ->delete(); DB::table('group_member') - ->where('gid',$gid) + ->where('gid', $gid) ->update([ 'ranking' => 1500 ]); - $contests = DB::table('contest') + $contests=DB::table('contest') ->where([ 'gid' => $gid, 'practice' => 1 ]) - ->where('end_time','<',date("Y-m-d H:i:s")) - ->select('cid','name') + ->where('end_time', '<', date("Y-m-d H:i:s")) + ->select('cid', 'name') ->orderBy('end_time') ->get()->all(); - if(empty($contests)) { + if (empty($contests)) { return []; } - $result = []; - $contestModel = new ContestModel(); + $result=[]; + $contestModel=new ContestModel(); foreach ($contests as $contest) { - $judge_status = $contestModel->judgeOver($contest['cid']); - if($judge_status['result'] == true){ - $calc = new GroupRatingCalculator($contest['cid']); + $judge_status=$contestModel->judgeOver($contest['cid']); + if ($judge_status['result']==true) { + $calc=new GroupRatingCalculator($contest['cid']); $calc->calculate(); $calc->storage(); - $result[] = [ + $result[]=[ 'ret' => 'success', 'cid' => $contest['cid'], 'name' => $contest['name'] ]; - }else{ - $result[] = [ + } else { + $result[]=[ 'ret' => 'judging', 'cid' => $contest['cid'], 'name' => $contest['name'], @@ -599,21 +605,21 @@ public function refreshElo($gid) return $result; } - public function getEloChangeLog($gid,$uid) + public function getEloChangeLog($gid, $uid) { - $ret = DB::table('group_rated_change_log') - ->join('contest','group_rated_change_log.cid','=','contest.cid') + $ret=DB::table('group_rated_change_log') + ->join('contest', 'group_rated_change_log.cid', '=', 'contest.cid') ->where([ 'group_rated_change_log.gid' => $gid, 'group_rated_change_log.uid' => $uid ])->select('group_rated_change_log.cid as cid', 'contest.name as name', 'ranking', 'end_time') ->orderBy('contest.end_time') ->get()->all(); - $begin = [ + $begin=[ 'cid' => -1, 'name' => '', 'ranking' => '1500', - 'end_time' => date("Y-m-d H:i:s",(strtotime($ret[0]['end_time'] ?? time()) - 3600*24)), + 'end_time' => date("Y-m-d H:i:s", (strtotime($ret[0]['end_time'] ?? time())-3600 * 24)), ]; array_unshift($ret, $begin); return $ret; diff --git a/app/Models/JudgerModel.php b/app/Models/JudgerModel.php index ed06568b5..693f69082 100644 --- a/app/Models/JudgerModel.php +++ b/app/Models/JudgerModel.php @@ -59,16 +59,20 @@ public function server($oid=1) "oid"=>$oid, "available"=>1, "status"=>0 - ])->orderBy('usage','desc')->get()->first(); + ])->orderBy('usage', 'asc')->get()->first(); return $serverList; } - public function fetchServer($oid=1) + public function fetchServer($oid=0) { - $serverList=DB::table("judge_server")->where(["oid"=>$oid])->get()->all(); + $serverList=DB::table("judge_server"); + if ($oid) { + $serverList=$serverList->where(["oid"=>$oid]); + } + $serverList=$serverList->get()->all(); foreach ($serverList as &$server) { - $server["status_parsed"]=is_null($server["status"])?self::$status["-1"]:self::$status[$server["status"]]; + $server["status_parsed"]=is_null($server["status"]) ?self::$status["-1"] : self::$status[$server["status"]]; } return $serverList; } diff --git a/app/Models/Latex/LatexModel.php b/app/Models/Latex/LatexModel.php index bbacff2b2..ff4103fa5 100644 --- a/app/Models/Latex/LatexModel.php +++ b/app/Models/Latex/LatexModel.php @@ -9,12 +9,14 @@ class LatexModel extends Model { public static function info($ltxsource, $type="png") { - if(!in_array($type,['png','svg'])) return []; + if (!in_array($type, ['png', 'svg'])) { + return []; + } $url=route("latex.$type", ['ltxsource' => $ltxsource]); - $image = new Imagick(); + $image=new Imagick(); $image->readImageBlob(Storage::get('latex-svg/'.urlencode($ltxsource).'.svg')); - $width = $image->getImageWidth(); - $height = $image->getImageHeight(); - return [$url,$width/5,$height/5]; + $width=$image->getImageWidth(); + $height=$image->getImageHeight(); + return [$url, $width / 5, $height / 5]; } } diff --git a/app/Models/OJModel.php b/app/Models/OJModel.php index a7a682e70..0d7f46761 100644 --- a/app/Models/OJModel.php +++ b/app/Models/OJModel.php @@ -13,7 +13,8 @@ class OJModel extends Model public static function oid($ocode) { - return DB::table('oj')->where(["ocode"=>$ocode])->first()["oid"]; + $ret=DB::table('oj')->where(["ocode"=>$ocode])->first(); + return is_null($ret) ?null:$ret["oid"]; } public static function ocode($oid) diff --git a/app/Models/ProblemModel.php b/app/Models/ProblemModel.php index 81cdecb78..acfc4a382 100644 --- a/app/Models/ProblemModel.php +++ b/app/Models/ProblemModel.php @@ -48,11 +48,11 @@ public function detail($pcode, $cid=null) $prob_detail["pdf"]=false; $prob_detail["viewerShow"]=false; $prob_detail["file_ext"]=null; - if($prob_detail['file'] && !blank($prob_detail['file_url'])){ - $prob_detail["file_ext"]=explode('.',basename($prob_detail['file_url'])); + if ($prob_detail['file'] && !blank($prob_detail['file_url'])) { + $prob_detail["file_ext"]=explode('.', basename($prob_detail['file_url'])); $prob_detail["file_ext"]=end($prob_detail["file_ext"]); $prob_detail["pdf"]=Str::is("*.pdf", basename($prob_detail['file_url'])); - $prob_detail["viewerShow"]= blank($prob_detail["parsed"]["description"]) && + $prob_detail["viewerShow"]=blank($prob_detail["parsed"]["description"]) && blank($prob_detail["parsed"]["input"]) && blank($prob_detail["parsed"]["output"]) && blank($prob_detail["parsed"]["note"]); @@ -107,7 +107,7 @@ public function tags() public function ojs() { - return DB::table("oj")->orderBy('oid', 'asc')->limit(12)->get()->all(); + return DB::table("oj")->orderBy('oid', 'asc')->get()->all(); } public function ojdetail($oid) @@ -194,9 +194,9 @@ public function addSolution($pid, $uid, $content) private function inteliAudit($uid, $content) { - if (strpos($content, '```')!==false){ + if (strpos($content, '```')!==false) { $userSolutionHistory=DB::table("problem_solution")->where(['uid'=>$uid])->orderByDesc('updated_at')->first(); - if (!empty($userSolutionHistory) && $userSolutionHistory["audit"]==1){ + if (!empty($userSolutionHistory) && $userSolutionHistory["audit"]==1) { return 1; } } @@ -292,7 +292,7 @@ public function list($filter, $uid=null) { // $prob_list = DB::table($this->table)->select("pid","pcode","title")->get()->all(); // return a array $submissionModel=new SubmissionModel(); - $preQuery=DB::table($this->table)->where('hide','=',0); + $preQuery=DB::table($this->table)->where('hide', '=', 0); if ($filter['oj']) { $preQuery=$preQuery->where(["OJ"=>$filter['oj']]); } @@ -454,7 +454,9 @@ public function insertProblem($data) if (!empty($data["sample"])) { foreach ($data["sample"] as $d) { - if(!isset($d['sample_note'])) $d['sample_note']=null; + if (!isset($d['sample_note'])) { + $d['sample_note']=null; + } DB::table("problem_sample")->insert([ 'pid'=>$pid, 'sample_input'=>$d['sample_input'], @@ -503,7 +505,9 @@ public function updateProblem($data) if (!empty($data["sample"])) { foreach ($data["sample"] as $d) { - if(!isset($d['sample_note'])) $d['sample_note']=null; + if (!isset($d['sample_note'])) { + $d['sample_note']=null; + } DB::table("problem_sample")->insert([ 'pid'=>$pid, 'sample_input'=>$d['sample_input'], @@ -518,7 +522,7 @@ public function updateProblem($data) public function discussionList($pid) { - $paginator = DB::table('problem_discussion')->join( + $paginator=DB::table('problem_discussion')->join( "users", "id", "=", @@ -537,10 +541,10 @@ public function discussionList($pid) 'users.name', 'users.id as uid' ])->paginate(15); - $list = $paginator->all(); - foreach($list as &$l){ - $l['updated_at'] = formatHumanReadableTime($l['updated_at']); - $l['comment_count'] = DB::table('problem_discussion_comment')->where('pdid','=',$l['pdid'])->count(); + $list=$paginator->all(); + foreach ($list as &$l) { + $l['updated_at']=formatHumanReadableTime($l['updated_at']); + $l['comment_count']=DB::table('problem_discussion_comment')->where('pdid', '=', $l['pdid'])->count(); } return [ 'paginator' => $paginator, @@ -550,7 +554,7 @@ public function discussionList($pid) public function discussionDetail($pdid) { - $main = DB::table('problem_discussion')->join( + $main=DB::table('problem_discussion')->join( "users", "id", "=", @@ -569,12 +573,12 @@ public function discussionDetail($pdid) 'users.name', 'users.id as uid' ])->get()->first(); - $main['created_at'] = formatHumanReadableTime($main['created_at']); + $main['created_at']=formatHumanReadableTime($main['created_at']); $main['content']=clean(Markdown::convertToHtml($main["content"])); - $comment_count = DB::table('problem_discussion_comment')->where('pdid','=',$pdid)->count(); + $comment_count=DB::table('problem_discussion_comment')->where('pdid', '=', $pdid)->count(); - $paginator = DB::table('problem_discussion_comment')->join( + $paginator=DB::table('problem_discussion_comment')->join( "users", "id", "=", @@ -593,11 +597,11 @@ public function discussionDetail($pdid) 'users.name', 'users.id as uid' ])->paginate(10); - $comment = $paginator->all(); - foreach($comment as &$c){ + $comment=$paginator->all(); + foreach ($comment as &$c) { $c['content']=clean(Markdown::convertToHtml($c["content"])); - $c['created_at'] = formatHumanReadableTime($c['created_at']); - $c['reply'] = DB::table('problem_discussion_comment')->join( + $c['created_at']=formatHumanReadableTime($c['created_at']); + $c['reply']=DB::table('problem_discussion_comment')->join( "users", "id", "=", @@ -625,20 +629,20 @@ public function discussionDetail($pdid) 'users.name', 'users.id as uid' ])->get()->all(); - foreach($c['reply'] as $k=>&$cr){ + foreach ($c['reply'] as $k=>&$cr) { $cr['content']=clean(Markdown::convertToHtml($cr["content"])); - $cr['reply_uid'] = DB::table('problem_discussion_comment')->where( + $cr['reply_uid']=DB::table('problem_discussion_comment')->where( 'pdcid', '=', $cr['reply_id'] )->get()->first()['uid']; - $cr['reply_name'] = DB::table('users')->where( + $cr['reply_name']=DB::table('users')->where( 'id', '=', $cr['reply_uid'] )->get()->first()['name']; - $cr['created_at'] = formatHumanReadableTime($cr['created_at']); - if($this->replyParent($cr['pdcid'])!=$c['pdcid']){ + $cr['created_at']=formatHumanReadableTime($cr['created_at']); + if ($this->replyParent($cr['pdcid'])!=$c['pdcid']) { unset($c['reply'][$k]); } } @@ -653,19 +657,19 @@ public function discussionDetail($pdid) public function replyParent($pdcid) { - $reply_id=DB::table('problem_discussion_comment')->where('pdcid','=',$pdcid)->get()->first()['reply_id']; - $top=DB::table('problem_discussion_comment')->where('pdcid','=',$reply_id)->get()->first()['reply_id']; - if(isset($top)){ + $reply_id=DB::table('problem_discussion_comment')->where('pdcid', '=', $pdcid)->get()->first()['reply_id']; + $top=DB::table('problem_discussion_comment')->where('pdcid', '=', $reply_id)->get()->first()['reply_id']; + if (isset($top)) { return $this->replyParent($reply_id); - }else{ + } else { return $reply_id; } } public function pcodeByPdid($dcode) { - $pid = DB::table('problem_discussion')->where('pdid','=',$dcode)->get()->first()['pid']; - $pcode = $this->pcode($pid); + $pid=DB::table('problem_discussion')->where('pdid', '=', $dcode)->get()->first()['pid']; + $pcode=$this->pcode($pid); return $pcode; } @@ -686,11 +690,11 @@ public function addDiscussion($uid, $pid, $title, $content) public function pidByPdid($pdid) { - $pid = DB::table('problem_discussion')->where('pdid','=',$pdid)->get()->first()['pid']; + $pid=DB::table('problem_discussion')->where('pdid', '=', $pdid)->get()->first()['pid']; return $pid; } - public function addComment($uid,$pdid,$content,$reply_id) + public function addComment($uid, $pdid, $content, $reply_id) { $pid=$this->pidByPdid($pdid); $pdcid=DB::table('problem_discussion_comment')->insertGetId([ @@ -709,6 +713,6 @@ public function addComment($uid,$pdid,$content,$reply_id) public function isHidden($pid) { - return DB::table('problem')->where('pid','=',$pid)->get()->first()['hide']; + return DB::table('problem')->where('pid', '=', $pid)->get()->first()['hide']; } } diff --git a/app/Models/RankModel.php b/app/Models/RankModel.php index 9616d0c25..04bf1af66 100644 --- a/app/Models/RankModel.php +++ b/app/Models/RankModel.php @@ -7,7 +7,7 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Arr; use App\Models\Rating\RatingCalculator; -use Cache,Redis; +use Cache, Redis; class RankModel extends Model { @@ -65,28 +65,34 @@ class RankModel extends Model public static function getColor($rankTitle) { - if(is_null($rankTitle)) return ""; + if (is_null($rankTitle)) { + return ""; + } return self::$casualRanking[$rankTitle]; } public static function getProfessionalColor($rankTitle) { - if(is_null($rankTitle)) return self::$professionalRanking["None"]; + if (is_null($rankTitle)) { + return self::$professionalRanking["None"]; + } return self::$professionalRanking[$rankTitle]; } public function list($num) { $rankList=Cache::tags(['rank'])->get('general'); - if($rankList==null) $rankList=[]; - $rankList=array_slice($rankList,0,$num); - $userInfoRaw=DB::table("users")->select("id as uid","avatar","name")->get()->all(); + if ($rankList==null) { + $rankList=[]; + } + $rankList=array_slice($rankList, 0, $num); + $userInfoRaw=DB::table("users")->select("id as uid", "avatar", "name")->get()->all(); $userInfo=[]; - foreach($userInfoRaw as $u){ + foreach ($userInfoRaw as $u) { $userInfo[$u["uid"]]=$u; } - foreach($rankList as &$r){ - $r["details"]=isset($userInfo[$r["uid"]])?$userInfo[$r["uid"]]:[]; + foreach ($rankList as &$r) { + $r["details"]=isset($userInfo[$r["uid"]]) ? $userInfo[$r["uid"]] : []; } // var_dump($rankList); exit(); return $rankList; @@ -109,8 +115,8 @@ public function rankList() $rankSolved=$rankItem["totValue"]; } $rankTitle=$this->getRankTitle($rankValue); - Cache::tags(['rank',$rankItem["uid"]])->put("rank", $rankValue, 86400); - Cache::tags(['rank',$rankItem["uid"]])->put("title", $rankTitle, 86400); + Cache::tags(['rank', $rankItem["uid"]])->put("rank", $rankValue, 86400); + Cache::tags(['rank', $rankItem["uid"]])->put("title", $rankTitle, 86400); $rankListCached[]=[ "uid"=>$rankItem["uid"], "rank"=>$rankValue, @@ -127,14 +133,14 @@ public function rankList() public function getProfessionalRanking() { - $professionalRankList = []; - $verifiedUsers = DB::table("users")->select("professional_rate","id as uid","avatar","name")->get()->all(); - $rankIter = 0; - foreach($verifiedUsers as $user) { - $rankVal = $user['professional_rate']; - $rankTitle = self::getProfessionalTitle($rankVal); - $titleColor = self::getProfessionalColor($rankTitle); - $professionalRankList[$rankIter++] = [ + $professionalRankList=[]; + $verifiedUsers=DB::table("users")->select("professional_rate", "id as uid", "avatar", "name")->get()->all(); + $rankIter=0; + foreach ($verifiedUsers as $user) { + $rankVal=$user['professional_rate']; + $rankTitle=self::getProfessionalTitle($rankVal); + $titleColor=self::getProfessionalColor($rankTitle); + $professionalRankList[$rankIter++]=[ "name"=>$user["name"], "uid"=>$user["uid"], "avatar"=>$user["avatar"], @@ -156,7 +162,7 @@ private function procRankingPer() $tot+=$c; } foreach ($this->casualRankingPer as &$c) { - $c=round($c*$totUsers/$tot); + $c=round($c * $totUsers / $tot); $cur+=$c; $c=$cur; } @@ -167,16 +173,20 @@ private function procRankingPer() public function getRankTitle($rankVal) { - foreach($this->casualRankingPer as $title=>$c){ - if($rankVal<=$c) return $title; + foreach ($this->casualRankingPer as $title=>$c) { + if ($rankVal<=$c) { + return $title; + } } return Arr::last($this->casualRankingPer); } public static function getProfessionalTitle($rankVal) { - foreach(self::$professionalRankingPer as $title=>$point) { - if($rankVal >= $point) return $title; + foreach (self::$professionalRankingPer as $title=>$point) { + if ($rankVal>=$point) { + return $title; + } } return Arr::last(self::$professionalRankingPer); } diff --git a/app/Models/Rating/GroupRatingCalculator.php b/app/Models/Rating/GroupRatingCalculator.php index fade31f09..1c168387d 100644 --- a/app/Models/Rating/GroupRatingCalculator.php +++ b/app/Models/Rating/GroupRatingCalculator.php @@ -14,36 +14,36 @@ class GroupRatingCalculator extends Model public $totParticipants=0; public $INITIAL_RATING=1500; - public function __construct($cid){ - $contestModel = new ContestModel(); - $this->cid = $cid; - $this->gid = $contestModel->gid($cid); + public function __construct($cid) { + $contestModel=new ContestModel(); + $this->cid=$cid; + $this->gid=$contestModel->gid($cid); // get rank $this->getRecord(); } - private function getRecord(){ - $contestModel = new ContestModel(); - $contestRankRaw = $contestModel->contestRank($this->cid); - foreach($contestRankRaw as $key => $contestRank){ - if(isset($contestRank['remote']) && $contestRank['remote']){ + private function getRecord() { + $contestModel=new ContestModel(); + $contestRankRaw=$contestModel->contestRank($this->cid); + foreach ($contestRankRaw as $key => $contestRank) { + if (isset($contestRank['remote']) && $contestRank['remote']) { unset($contestRankRaw[$key]); } } - $contestRankRaw = array_values($contestRankRaw); - $members = array_column($contestRankRaw,'uid'); - $ratings_temp = DB::table('group_member') + $contestRankRaw=array_values($contestRankRaw); + $members=array_column($contestRankRaw, 'uid'); + $ratings_temp=DB::table('group_member') ->where([ 'gid' => $this->gid, - ])->whereIn('uid',$members) - ->select('uid','ranking') + ])->whereIn('uid', $members) + ->select('uid', 'ranking') ->get()->all(); - $ratings = []; + $ratings=[]; foreach ($ratings_temp as $rating) { - $ratings[$rating['uid']] = $rating['ranking']; + $ratings[$rating['uid']]=$rating['ranking']; } - foreach($contestRankRaw as $c){ - if(!isset($ratings[$c['uid']])){ + foreach ($contestRankRaw as $c) { + if (!isset($ratings[$c['uid']])) { continue; } $this->contestants[]=[ @@ -52,87 +52,87 @@ private function getRecord(){ "rating"=>$ratings[$c['uid']], ]; } - $this->totParticipants = count($this->contestants); + $this->totParticipants=count($this->contestants); } - private function reassignRank(){ + private function reassignRank() { $this->sort("points"); - $idx = 0; - $points = $this->contestants[0]["points"]; - $i = 1; - while($i < $this->totParticipants){ - if($this->contestants[$i]["points"] < $points){ - $j = $idx; - while($j < $i){ - $this->contestants[$j]["rank"] = $i; - $j += 1; + $idx=0; + $points=$this->contestants[0]["points"]; + $i=1; + while ($i<$this->totParticipants) { + if ($this->contestants[$i]["points"]<$points) { + $j=$idx; + while ($j<$i) { + $this->contestants[$j]["rank"]=$i; + $j+=1; } - $idx = $i; - $points = $this->contestants[$i]["points"]; + $idx=$i; + $points=$this->contestants[$i]["points"]; } - $i += 1; + $i+=1; } - $j = $idx; - while($j < $this->totParticipants){ - $this->contestants[$j]["rank"] = $this->totParticipants; - $j += 1; + $j=$idx; + while ($j<$this->totParticipants) { + $this->contestants[$j]["rank"]=$this->totParticipants; + $j+=1; } } - private function getEloWinProbability($Ra, $Rb){ - return 1.0 / (1 + pow(10, ($Rb-$Ra)/400.0)); + private function getEloWinProbability($Ra, $Rb) { + return 1.0 / (1+pow(10, ($Rb-$Ra) / 400.0)); } - private function getSeed($rating){ - $result = 1.0; - foreach($this->contestants as $other){ - $result += $this->getEloWinProbability($other["rating"], $rating); + private function getSeed($rating) { + $result=1.0; + foreach ($this->contestants as $other) { + $result+=$this->getEloWinProbability($other["rating"], $rating); } return $result; } - private function getRatingToRank($rank){ + private function getRatingToRank($rank) { $left=1; $right=8000; - while($right - $left > 1){ - $mid = floor(($right + $left)/2); - if($this->getSeed($mid) < $rank){ - $right = $mid; - }else{ - $left = $mid; + while ($right-$left>1) { + $mid=floor(($right+$left) / 2); + if ($this->getSeed($mid)<$rank) { + $right=$mid; + } else { + $left=$mid; } } return $left; } - private function sort($key){ - usort($this->contestants, function ($a, $b) use ($key) { + private function sort($key) { + usort($this->contestants, function($a, $b) use ($key) { return $b[$key] <=> $a[$key]; }); } - public function calculate(){ - if(empty($this->contestants)){ + public function calculate() { + if (empty($this->contestants)) { return; } // recalc rank $this->reassignRank(); - foreach($this->contestants as &$member){ - $member["seed"] = 1.0; - foreach($this->contestants as $other){ - if($member["uid"] != $other["uid"]){ - $member["seed"] += $this->getEloWinProbability($other["rating"], $member["rating"]); + foreach ($this->contestants as &$member) { + $member["seed"]=1.0; + foreach ($this->contestants as $other) { + if ($member["uid"]!=$other["uid"]) { + $member["seed"]+=$this->getEloWinProbability($other["rating"], $member["rating"]); } } } unset($member); - foreach($this->contestants as &$contestant){ - $midRank = sqrt($contestant["rank"] * $contestant["seed"]); - $contestant["needRating"] = $this->getRatingToRank($midRank); - $contestant["delta"] = floor(($contestant["needRating"] - $contestant["rating"])/2); + foreach ($this->contestants as &$contestant) { + $midRank=sqrt($contestant["rank"] * $contestant["seed"]); + $contestant["needRating"]=$this->getRatingToRank($midRank); + $contestant["delta"]=floor(($contestant["needRating"]-$contestant["rating"]) / 2); } unset($contestant); @@ -140,39 +140,39 @@ public function calculate(){ // DO some adjuct // Total sum should not be more than ZERO. - $sum = 0; + $sum=0; - foreach($this->contestants as $contestant){ - $sum += $contestant["delta"]; + foreach ($this->contestants as $contestant) { + $sum+=$contestant["delta"]; } - $inc = -floor($sum / $this->totParticipants) - 1; - foreach($this->contestants as &$contestant){ - $contestant["delta"] += $inc; + $inc=-floor($sum / $this->totParticipants)-1; + foreach ($this->contestants as &$contestant) { + $contestant["delta"]+=$inc; } unset($contestant); // Sum of top-4*sqrt should be adjusted to ZERO. - $sum = 0; - $zeroSumCount = min(intval(4*round(sqrt($this->totParticipants))), $this->totParticipants); + $sum=0; + $zeroSumCount=min(intval(4 * round(sqrt($this->totParticipants))), $this->totParticipants); - for($i=0;$i<$zeroSumCount;$i++){ - $sum += $this->contestants[$i]["delta"]; + for ($i=0; $i<$zeroSumCount; $i++) { + $sum+=$this->contestants[$i]["delta"]; } - $inc = min(max(-floor($sum / $zeroSumCount), -10), 0); + $inc=min(max(-floor($sum / $zeroSumCount), -10), 0); - for($i=0;$i<$zeroSumCount;$i++){ - $this->contestants[$i]["delta"] += $inc; + for ($i=0; $i<$zeroSumCount; $i++) { + $this->contestants[$i]["delta"]+=$inc; } return $this->validateDeltas(); } - public function storage(){ + public function storage() { $contestants=$this->contestants; - DB::transaction(function () use ($contestants) { - foreach($contestants as $contestant){ + DB::transaction(function() use ($contestants) { + foreach ($contestants as $contestant) { $newRating=$contestant["rating"]+$contestant["delta"]; DB::table("group_member")->where([ 'gid' => $this->gid, @@ -190,20 +190,20 @@ public function storage(){ }, 5); } - private function validateDeltas(){ + private function validateDeltas() { $this->sort("points"); - for($i=0;$i<$this->totParticipants;$i++){ - for($j=$i+1;$j<$this->totParticipants;$j++){ - if($this->contestants[$i]["rating"] > $this->contestants[$j]["rating"]){ - if($this->contestants[$i]["rating"] + $this->contestants[$i]["delta"] < $this->contestants[$j]["rating"] + $this->contestants[$j]["delta"]){ + for ($i=0; $i<$this->totParticipants; $i++) { + for ($j=$i+1; $j<$this->totParticipants; $j++) { + if ($this->contestants[$i]["rating"]>$this->contestants[$j]["rating"]) { + if ($this->contestants[$i]["rating"]+$this->contestants[$i]["delta"]<$this->contestants[$j]["rating"]+$this->contestants[$j]["delta"]) { Log::warning("First rating invariant failed: {$this->contestants[$i]["uid"]} vs. {$this->contestants[$j]["uid"]}."); return false; } } - if($this->contestants[$i]["rating"] < $this->contestants[$j]["rating"]){ - if($this->contestants[$i]["delta"] < $this->contestants[$j]["delta"]){ + if ($this->contestants[$i]["rating"]<$this->contestants[$j]["rating"]) { + if ($this->contestants[$i]["delta"]<$this->contestants[$j]["delta"]) { Log::warning("Second rating invariant failed: {$this->contestants[$i]["uid"]} vs. {$this->contestants[$j]["uid"]}."); return false; } diff --git a/app/Models/Rating/RatingCalculator.php b/app/Models/Rating/RatingCalculator.php index 064f506c7..aa6fdd18a 100644 --- a/app/Models/Rating/RatingCalculator.php +++ b/app/Models/Rating/RatingCalculator.php @@ -17,14 +17,14 @@ class RatingCalculator extends Model public $totParticipants=0; public $INITIAL_RATING=1500; - public function __construct($cid){ + public function __construct($cid) { $this->cid=$cid; // get rank $this->getRecord(); } - private function getRecord(){ + private function getRecord() { $contestRankRaw=Cache::tags(['contest', 'rank'])->get($this->cid); if ($contestRankRaw==null) { @@ -32,8 +32,8 @@ private function getRecord(){ $contestRankRaw=$contestModel->contestRankCache($this->cid); } - $this->totParticipants = count($contestRankRaw); - foreach($contestRankRaw as $c){ + $this->totParticipants=count($contestRankRaw); + foreach ($contestRankRaw as $c) { $this->contestants[]=[ "uid"=>$c["uid"], "points"=>$c["score"], @@ -42,84 +42,84 @@ private function getRecord(){ } } - private function reassignRank(){ + private function reassignRank() { $this->sort("points"); - $idx = 0; - $points = $this->contestants[0]["points"]; - $i = 1; - while($i < $this->totParticipants){ - if($this->contestants[$i]["points"] < $points){ - $j = $idx; - while($j < $i){ - $this->contestants[$j]["rank"] = $i; - $j += 1; + $idx=0; + $points=$this->contestants[0]["points"]; + $i=1; + while ($i<$this->totParticipants) { + if ($this->contestants[$i]["points"]<$points) { + $j=$idx; + while ($j<$i) { + $this->contestants[$j]["rank"]=$i; + $j+=1; } - $idx = $i; - $points = $this->contestants[$i]["points"]; + $idx=$i; + $points=$this->contestants[$i]["points"]; } - $i += 1; + $i+=1; } - $j = $idx; - while($j < $this->totParticipants){ - $this->contestants[$j]["rank"] = $this->totParticipants; - $j += 1; + $j=$idx; + while ($j<$this->totParticipants) { + $this->contestants[$j]["rank"]=$this->totParticipants; + $j+=1; } } - private function getEloWinProbability($Ra, $Rb){ - return 1.0 / (1 + pow(10, ($Rb-$Ra)/400.0)); + private function getEloWinProbability($Ra, $Rb) { + return 1.0 / (1+pow(10, ($Rb-$Ra) / 400.0)); } - private function getSeed($rating){ - $result = 1.0; - foreach($this->contestants as $other){ - $result += $this->getEloWinProbability($other["rating"], $rating); + private function getSeed($rating) { + $result=1.0; + foreach ($this->contestants as $other) { + $result+=$this->getEloWinProbability($other["rating"], $rating); } return $result; } - private function getRatingToRank($rank){ + private function getRatingToRank($rank) { $left=1; $right=8000; - while($right - $left > 1){ - $mid = floor(($right + $left)/2); - if($this->getSeed($mid) < $rank){ - $right = $mid; - }else{ - $left = $mid; + while ($right-$left>1) { + $mid=floor(($right+$left) / 2); + if ($this->getSeed($mid)<$rank) { + $right=$mid; + } else { + $left=$mid; } } return $left; } - private function sort($key){ - usort($this->contestants, function ($a, $b) use ($key) { + private function sort($key) { + usort($this->contestants, function($a, $b) use ($key) { return $b[$key] <=> $a[$key]; }); } - public function calculate(){ - if(empty($this->contestants)){ + public function calculate() { + if (empty($this->contestants)) { return; } // recalc rank $this->reassignRank(); - foreach($this->contestants as &$member){ - $member["seed"] = 1.0; - foreach($this->contestants as $other){ - if($member["uid"] != $other["uid"]){ - $member["seed"] += $this->getEloWinProbability($other["rating"], $member["rating"]); + foreach ($this->contestants as &$member) { + $member["seed"]=1.0; + foreach ($this->contestants as $other) { + if ($member["uid"]!=$other["uid"]) { + $member["seed"]+=$this->getEloWinProbability($other["rating"], $member["rating"]); } } } unset($member); - foreach($this->contestants as &$contestant){ - $midRank = sqrt($contestant["rank"] * $contestant["seed"]); - $contestant["needRating"] = $this->getRatingToRank($midRank); - $contestant["delta"] = floor(($contestant["needRating"] - $contestant["rating"])/2); + foreach ($this->contestants as &$contestant) { + $midRank=sqrt($contestant["rank"] * $contestant["seed"]); + $contestant["needRating"]=$this->getRatingToRank($midRank); + $contestant["delta"]=floor(($contestant["needRating"]-$contestant["rating"]) / 2); } unset($contestant); @@ -127,39 +127,39 @@ public function calculate(){ // DO some adjuct // Total sum should not be more than ZERO. - $sum = 0; + $sum=0; - foreach($this->contestants as $contestant){ - $sum += $contestant["delta"]; + foreach ($this->contestants as $contestant) { + $sum+=$contestant["delta"]; } - $inc = -floor($sum / $this->totParticipants) - 1; - foreach($this->contestants as &$contestant){ - $contestant["delta"] += $inc; + $inc=-floor($sum / $this->totParticipants)-1; + foreach ($this->contestants as &$contestant) { + $contestant["delta"]+=$inc; } unset($contestant); // Sum of top-4*sqrt should be adjusted to ZERO. - $sum = 0; - $zeroSumCount = min(intval(4*round(sqrt($this->totParticipants))), $this->totParticipants); + $sum=0; + $zeroSumCount=min(intval(4 * round(sqrt($this->totParticipants))), $this->totParticipants); - for($i=0;$i<$zeroSumCount;$i++){ - $sum += $this->contestants[$i]["delta"]; + for ($i=0; $i<$zeroSumCount; $i++) { + $sum+=$this->contestants[$i]["delta"]; } - $inc = min(max(-floor($sum / $zeroSumCount), -10), 0); + $inc=min(max(-floor($sum / $zeroSumCount), -10), 0); - for($i=0;$i<$zeroSumCount;$i++){ - $this->contestants[$i]["delta"] += $inc; + for ($i=0; $i<$zeroSumCount; $i++) { + $this->contestants[$i]["delta"]+=$inc; } return $this->validateDeltas(); } - public function storage(){ + public function storage() { $contestants=$this->contestants; - DB::transaction(function () use ($contestants) { - foreach($contestants as $contestant){ + DB::transaction(function() use ($contestants) { + foreach ($contestants as $contestant) { $newRating=$contestant["rating"]+$contestant["delta"]; DB::table("users")->where([ "id"=>$contestant["uid"] @@ -181,20 +181,20 @@ public function storage(){ }, 5); } - private function validateDeltas(){ + private function validateDeltas() { $this->sort("points"); - for($i=0;$i<$this->totParticipants;$i++){ - for($j=$i+1;$j<$this->totParticipants;$j++){ - if($this->contestants[$i]["rating"] > $this->contestants[$j]["rating"]){ - if($this->contestants[$i]["rating"] + $this->contestants[$i]["delta"] < $this->contestants[$j]["rating"] + $this->contestants[$j]["delta"]){ + for ($i=0; $i<$this->totParticipants; $i++) { + for ($j=$i+1; $j<$this->totParticipants; $j++) { + if ($this->contestants[$i]["rating"]>$this->contestants[$j]["rating"]) { + if ($this->contestants[$i]["rating"]+$this->contestants[$i]["delta"]<$this->contestants[$j]["rating"]+$this->contestants[$j]["delta"]) { Log::warning("First rating invariant failed: {$this->contestants[$i]["uid"]} vs. {$this->contestants[$j]["uid"]}."); return false; } } - if($this->contestants[$i]["rating"] < $this->contestants[$j]["rating"]){ - if($this->contestants[$i]["delta"] < $this->contestants[$j]["delta"]){ + if ($this->contestants[$i]["rating"]<$this->contestants[$j]["rating"]) { + if ($this->contestants[$i]["delta"]<$this->contestants[$j]["delta"]) { Log::warning("Second rating invariant failed: {$this->contestants[$i]["uid"]} vs. {$this->contestants[$j]["uid"]}."); return false; } diff --git a/app/Models/ResponseModel.php b/app/Models/ResponseModel.php index 6afb1dd8d..26841bb1c 100644 --- a/app/Models/ResponseModel.php +++ b/app/Models/ResponseModel.php @@ -96,7 +96,7 @@ private static function desc($errCode) '7002' => "Insufficient Clearance", '7003' => "No Need to Approve", '7004' => "Group Member Not Found", - '7005' => "Don't play just for fun",//gcode=="create" + '7005' => "Don't play just for fun", //gcode=="create" '7006' => "A group with the same gcode already exists", '7007' => "Group Problem Tag Exist", '7008' => "The group leader cannot leave the group", diff --git a/app/Models/Search/ContestSearchModel.php b/app/Models/Search/ContestSearchModel.php index a19765b30..045a6fb4c 100644 --- a/app/Models/Search/ContestSearchModel.php +++ b/app/Models/Search/ContestSearchModel.php @@ -15,26 +15,26 @@ class ContestSearchModel extends Model public function search($key) { - $result = []; + $result=[]; //contest name find - if(strlen($key) >= 2){ - $ret = self::whereRaw('MATCH(`name`) AGAINST (? IN BOOLEAN MODE)',[$key]) + if (strlen($key)>=2) { + $ret=self::whereRaw('MATCH(`name`) AGAINST (? IN BOOLEAN MODE)', [$key]) ->select('cid', 'gid', 'name', 'rule', 'public', 'verified', 'practice', 'rated', 'anticheated', 'begin_time', 'end_time') - ->orderBy('end_time','DESC') + ->orderBy('end_time', 'DESC') ->limit(120) ->get()->all(); - $user_id = Auth::user()->id; - $contestModel = new ContestModel(); - foreach($ret as $c_index => $c){ - if(!$contestModel->judgeClearance($c['cid'],$user_id)){ + $user_id=Auth::user()->id; + $contestModel=new ContestModel(); + foreach ($ret as $c_index => $c) { + if (!$contestModel->judgeClearance($c['cid'], $user_id)) { unset($ret[$c_index]); } } - if(!empty($ret)){ - $result += $ret; + if (!empty($ret)) { + $result+=$ret; } } - if(!empty($result)) { + if (!empty($result)) { foreach ($result as &$contest) { $contest["rule_parsed"]=$this->rule[$contest["rule"]]; $contest["date_parsed"]=[ diff --git a/app/Models/Search/GroupSearchModel.php b/app/Models/Search/GroupSearchModel.php index 52f73fdd4..a4708b739 100644 --- a/app/Models/Search/GroupSearchModel.php +++ b/app/Models/Search/GroupSearchModel.php @@ -12,19 +12,19 @@ class GroupSearchModel extends Model public function search($key) { - $result = []; + $result=[]; //group name or gcode find - if(strlen($key) >= 2){ - $ret = self::where(function($query) use ($key){ - $query->whereRaw('MATCH(`name`) AGAINST (? IN BOOLEAN MODE)',[$key]) + if (strlen($key)>=2) { + $ret=self::where(function($query) use ($key){ + $query->whereRaw('MATCH(`name`) AGAINST (? IN BOOLEAN MODE)', [$key]) ->orWhere('gcode', $key); }) - ->where('public',1) - ->select('gid','gcode', 'img', 'name', 'description') + ->where('public', 1) + ->select('gid', 'gcode', 'img', 'name', 'description') ->limit(120) ->get()->all(); - if(!empty($ret)){ - $result += $ret; + if (!empty($ret)) { + $result+=$ret; } } diff --git a/app/Models/Search/ProblemSearchModel.php b/app/Models/Search/ProblemSearchModel.php index 10c73d7fa..d96db9bef 100644 --- a/app/Models/Search/ProblemSearchModel.php +++ b/app/Models/Search/ProblemSearchModel.php @@ -13,20 +13,20 @@ class ProblemSearchModel extends Model public function search($key) { - $result = []; - if(strlen($key) >= 2){ - $ret = self::where('pcode', $key) - ->orWhereRaw('MATCH(`title`) AGAINST (? IN BOOLEAN MODE)',[$key]) - ->select('pcode', 'title') + $result=[]; + if (strlen($key)>=2) { + $ret=self::where('pcode', $key) + ->orWhereRaw('MATCH(`title`) AGAINST (? IN BOOLEAN MODE)', [$key]) + ->select('pid', 'pcode', 'title') ->limit(120) ->get()->all(); - if(!empty($ret)){ - $result += $ret; + if (!empty($ret)) { + $result+=$ret; } } - $problemModel = new ProblemModel(); + $problemModel=new ProblemModel(); foreach ($result as $p_index => $p) { - if($problemModel->isBlocked($p['pid']) || $problemModel->isHidden($p["pid"])){ + if ($problemModel->isBlocked($p['pid']) || $problemModel->isHidden($p["pid"])) { unset($result[$p_index]); } } diff --git a/app/Models/Search/UserSearchModel.php b/app/Models/Search/UserSearchModel.php index a7f7dd13e..e644d7304 100644 --- a/app/Models/Search/UserSearchModel.php +++ b/app/Models/Search/UserSearchModel.php @@ -10,16 +10,16 @@ class UserSearchModel extends Model public function search($key) { - $result = []; - if(strlen($key) >= 2){ - $ret = self::where('email',$key) - ->orWhereRaw('MATCH(`name`) AGAINST (? IN BOOLEAN MODE)',[$key]) - ->select('id','avatar', 'name', 'describes', 'professional_rate') - ->orderBy('professional_rate','DESC') + $result=[]; + if (strlen($key)>=2) { + $ret=self::where('email', $key) + ->orWhereRaw('MATCH(`name`) AGAINST (? IN BOOLEAN MODE)', [$key]) + ->select('id', 'avatar', 'name', 'describes', 'professional_rate') + ->orderBy('professional_rate', 'DESC') ->limit(120) ->get()->all(); - if(!empty($ret)){ - $result += $ret; + if (!empty($ret)) { + $result+=$ret; } } return $result; diff --git a/app/Models/Submission/StatusModel.php b/app/Models/Submission/StatusModel.php index a8b2aad57..9798f1143 100644 --- a/app/Models/Submission/StatusModel.php +++ b/app/Models/Submission/StatusModel.php @@ -28,10 +28,12 @@ public function getJudgeStatus($sid, $uid) $end_time=strtotime(DB::table("contest")->where(["cid"=>$status["cid"]])->select("end_time")->first()["end_time"]); if (time()<$end_time) { $status["solution"]=null; + $status['compile_info']="You don't have the permission to view this compile info."; } } if ($status["share"]==0 && $status["uid"]!=$uid) { $status["solution"]=null; + $status['compile_info']="You don't have the permission to view this compile info."; } $compilerModel=new CompilerModel(); $status["lang"]=$compilerModel->detail($status["coid"])["lang"]; diff --git a/app/Models/Submission/SubmissionModel.php b/app/Models/Submission/SubmissionModel.php index b407f6a58..750be163b 100644 --- a/app/Models/Submission/SubmissionModel.php +++ b/app/Models/Submission/SubmissionModel.php @@ -104,6 +104,10 @@ public function __construct() "extensions" => [".handlebars", ".hbs"], "aliases" => ["Handlebars", "handlebars"], "mimetypes" => ["text/x-handlebars-template"] + ], [ + "id" => "haskell", + "extensions" => [".hs"], + "aliases" => ["Haskell", "haskell"] ], [ "id" => "html", "extensions" => [".html", ".htm", ".shtml", ".xhtml", ".mdoc", ".jsp", ".asp", ".aspx", ".jshtm"], @@ -371,7 +375,7 @@ public function getWaitingSubmission() ->where(['verdict'=>'Waiting']) ->get() ->all(); - foreach($ret as &$r){ + foreach ($ret as &$r) { $r["ocode"]=DB::table("oj")->where(["oid"=>$r["oid"]])->first()["ocode"]; } return $ret; @@ -389,14 +393,14 @@ public function updateSubmission($sid, $sub) if (isset($sub['verdict'])) { $sub["color"]=$this->colorScheme[$sub['verdict']]; } - $result = DB::table($this->tableName)->where(['sid'=>$sid])->update($sub); - $contestModel = new ContestModel(); - $submission_info = DB::table($this->tableName) -> where(['sid'=>$sid]) -> get() -> first(); - if ($result==1 && $submission_info['cid'] && $contestModel->isContestRunning($submission_info['cid'])){ - $sub['pid'] = $submission_info['pid']; - $sub['uid'] = $submission_info['uid']; - $sub['cid'] = $submission_info['cid']; - $sub['sid'] = $sid; + $result=DB::table($this->tableName)->where(['sid'=>$sid])->update($sub); + $contestModel=new ContestModel(); + $submission_info=DB::table($this->tableName) -> where(['sid'=>$sid]) -> get() -> first(); + if ($result==1 && $submission_info['cid'] && $contestModel->isContestRunning($submission_info['cid'])) { + $sub['pid']=$submission_info['pid']; + $sub['uid']=$submission_info['uid']; + $sub['cid']=$submission_info['cid']; + $sub['sid']=$sid; // $contestModel->updateContestRankTable($submission_info['cid'],$sub); } return $result; @@ -435,15 +439,15 @@ public function getRecord($filter) 'desc' ); - if($filter["pcode"]){ + if ($filter["pcode"]) { $paginator=$paginator->where(["pcode"=>$filter["pcode"]]); } - if($filter["result"]){ + if ($filter["result"]) { $paginator=$paginator->where(["verdict"=>$filter["result"]]); } - if($filter["account"]){ + if ($filter["account"]) { $paginator=$paginator->where(["name"=>$filter["account"]]); } diff --git a/app/Models/Update/UpdateModel.php b/app/Models/Update/UpdateModel.php index f5f3c2946..0e38c4705 100644 --- a/app/Models/Update/UpdateModel.php +++ b/app/Models/Update/UpdateModel.php @@ -24,7 +24,7 @@ public static function checkUpdate() "name"=>$versionInfo[0]["name"], "updatable"=>$updatable ]; - }catch(Throwable $e){ + } catch (Throwable $e) { return null; } } diff --git a/app/Models/UserModel.php b/app/Models/UserModel.php deleted file mode 100644 index 1dab14f90..000000000 --- a/app/Models/UserModel.php +++ /dev/null @@ -1,29 +0,0 @@ - request()->root()]); + config(['filesystems.disks.public.url' => request()->root().'/storage']); + config(['filesystems.disks.NOJPublic.url' => request()->root()]); + } } /** diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 9ba9067b2..b80689288 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -5,6 +5,7 @@ use Illuminate\Support\Facades\Gate; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; use Laravel\Passport\Passport; +use Illuminate\Support\Facades\Validator; class AuthServiceProvider extends ServiceProvider { @@ -15,6 +16,13 @@ class AuthServiceProvider extends ServiceProvider */ protected $policies=[]; + /** + * The forbidden doamins that cannot register NOJ. + * + * @var array + */ + protected $forbiddenDomains=['temporary.email']; + /** * Register any authentication / authorization services. * @@ -24,5 +32,9 @@ public function boot() { $this->registerPolicies(); Passport::routes(); + + Validator::extend('allowed_email_domain', function($attribute, $value, $parameters, $validator) { + return !in_array(explode('@', $value)[1], $this->forbiddenDomains); + }, 'Domain not valid for registration.'); } } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index e4945d629..046244496 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -7,6 +7,7 @@ use Illuminate\Auth\Listeners\SendEmailVerificationNotification; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; use Illuminate\Database\Events\StatementPrepared; +use SocialiteProviders\Manager\SocialiteWasCalled; class EventServiceProvider extends ServiceProvider { @@ -19,6 +20,9 @@ class EventServiceProvider extends ServiceProvider Registered::class => [ SendEmailVerificationNotification::class, ], + SocialiteWasCalled::class => [ + 'SocialiteProviders\\GitHub\\GitHubExtendSocialite@handle', + ], ]; /** diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 4a8fe1574..d276c8377 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -52,8 +52,8 @@ public function map() protected function mapWebRoutes() { Route::middleware('web') - ->namespace($this->namespace) - ->group(base_path('routes/web.php')); + ->namespace($this->namespace) + ->group(base_path('routes/web.php')); } /** @@ -66,8 +66,8 @@ protected function mapWebRoutes() protected function mapApiRoutes() { Route::prefix('api') - ->middleware('api') - ->namespace($this->namespace) - ->group(base_path('routes/api.php')); + ->middleware('api') + ->namespace($this->namespace) + ->group(base_path('routes/api.php')); } } diff --git a/app/User.php b/app/User.php deleted file mode 100644 index c7b860a0d..000000000 --- a/app/User.php +++ /dev/null @@ -1,35 +0,0 @@ -hasMany('App\Models\Eloquent\UserBanned'); - } -} diff --git a/binary/linux/sim_c b/binary/linux/sim_c new file mode 100755 index 000000000..3946a7f78 Binary files /dev/null and b/binary/linux/sim_c differ diff --git a/binary/linux/sim_c++ b/binary/linux/sim_c++ new file mode 100755 index 000000000..9f80685e1 Binary files /dev/null and b/binary/linux/sim_c++ differ diff --git a/binary/linux/sim_java b/binary/linux/sim_java new file mode 100755 index 000000000..4e42741d1 Binary files /dev/null and b/binary/linux/sim_java differ diff --git a/binary/linux/sim_text b/binary/linux/sim_text new file mode 100755 index 000000000..371fe6fe2 Binary files /dev/null and b/binary/linux/sim_text differ diff --git a/binary/win/sim_c++.exe b/binary/win/sim_c++.exe new file mode 100644 index 000000000..9c657ebee Binary files /dev/null and b/binary/win/sim_c++.exe differ diff --git a/binary/win/sim_c.exe b/binary/win/sim_c.exe new file mode 100644 index 000000000..3a20a4546 Binary files /dev/null and b/binary/win/sim_c.exe differ diff --git a/binary/win/sim_java.exe b/binary/win/sim_java.exe new file mode 100644 index 000000000..e88ffd43e Binary files /dev/null and b/binary/win/sim_java.exe differ diff --git a/binary/win/sim_text.exe b/binary/win/sim_text.exe new file mode 100644 index 000000000..10db97850 Binary files /dev/null and b/binary/win/sim_text.exe differ diff --git a/composer.json b/composer.json index 627615e60..5714ab8ee 100644 --- a/composer.json +++ b/composer.json @@ -13,11 +13,13 @@ "encore/laravel-admin": "^1.7", "fideloper/proxy": "^4.0", "fonts-asset/devicon": "^1.0", + "fonts-asset/langicon": "^1.0", "fonts-asset/mdi-wxss": "^1.0", "fonts-asset/montserrat": "^1.0", "fonts-asset/raleway": "^1.0", "fonts-asset/roboto": "^1.0", "fonts-asset/roboto-slab": "^1.0", + "fonts-asset/socialicon": "^1.0", "graham-campbell/markdown": "^11.0", "grubersjoe/bing-daily-photo": "^2.0", "illuminate/support": "^6.0", @@ -56,7 +58,9 @@ "npm-asset/lodash": "^4.17", "npm-asset/marked": "^0.6.2", "npm-asset/mathjax": "^2.7", - "npm-asset/monaco-editor": "0.17.1", + "npm-asset/monaco-ace-tokenizer": "^0.2.1", + "npm-asset/monaco-editor": "0.23.0", + "npm-asset/monaco-themes": "^0.3.3", "npm-asset/pdfobject": "^2.1", "npm-asset/perfect-scrollbar": "^1.4", "npm-asset/popper.js": "^1.5", @@ -67,6 +71,7 @@ "predis/predis": "^1.1", "rmccue/requests": "^1.7", "sebastian/version": "^2.0", + "socialiteproviders/github": "^4.1", "x3zvawq/noj_simplemde": "dev-main", "zsgsdesign/noj-admin-clike-editor": "dev-main" }, diff --git a/composer.lock b/composer.lock index bb1743de5..b64ef534f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0a02231367106fd28d2c056e19b39194", + "content-hash": "e10770d1b77f8c21372cb5b79ecaf7d7", "packages": [ { "name": "barryvdh/laravel-dompdf", @@ -60,6 +60,10 @@ "laravel", "pdf" ], + "support": { + "issues": "https://github.com/barryvdh/laravel-dompdf/issues", + "source": "https://github.com/barryvdh/laravel-dompdf/tree/master" + }, "funding": [ { "url": "https://github.com/barryvdh", @@ -70,16 +74,16 @@ }, { "name": "composer/installers", - "version": "v1.9.0", + "version": "v1.11.0", "source": { "type": "git", "url": "https://github.com/composer/installers.git", - "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca" + "reference": "ae03311f45dfe194412081526be2e003960df74b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/b93bcf0fa1fccb0b7d176b0967d969691cd74cca", - "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca", + "url": "https://api.github.com/repos/composer/installers/zipball/ae03311f45dfe194412081526be2e003960df74b", + "reference": "ae03311f45dfe194412081526be2e003960df74b", "shasum": "" }, "require": { @@ -90,17 +94,18 @@ "shama/baton": "*" }, "require-dev": { - "composer/composer": "1.6.* || 2.0.*@dev", - "composer/semver": "1.0.* || 2.0.*@dev", - "phpunit/phpunit": "^4.8.36", - "sebastian/comparator": "^1.2.4", + "composer/composer": "1.6.* || ^2.0", + "composer/semver": "^1 || ^3", + "phpstan/phpstan": "^0.12.55", + "phpstan/phpstan-phpunit": "^0.12.16", + "symfony/phpunit-bridge": "^4.2 || ^5", "symfony/process": "^2.3" }, "type": "composer-plugin", "extra": { "class": "Composer\\Installers\\Plugin", "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "1.x-dev" } }, "autoload": { @@ -138,6 +143,7 @@ "Porto", "RadPHP", "SMF", + "Starbug", "Thelia", "Whmcs", "WolfCMS", @@ -171,6 +177,7 @@ "majima", "mako", "mediawiki", + "miaoxing", "modulework", "modx", "moodle", @@ -178,6 +185,7 @@ "phpbb", "piwik", "ppi", + "processwire", "puppet", "pxcms", "reindex", @@ -187,46 +195,54 @@ "sydes", "sylius", "symfony", + "tastyigniter", "typo3", "wordpress", "yawik", "zend", "zikula" ], + "support": { + "issues": "https://github.com/composer/installers/issues", + "source": "https://github.com/composer/installers/tree/v1.11.0" + }, "funding": [ { "url": "https://packagist.com", "type": "custom" }, + { + "url": "https://github.com/composer", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/composer/composer", "type": "tidelift" } ], - "time": "2020-04-07T06:57:05+00:00" + "time": "2021-04-28T06:42:17+00:00" }, { "name": "defuse/php-encryption", - "version": "v2.2.1", + "version": "v2.3.1", "source": { "type": "git", "url": "https://github.com/defuse/php-encryption.git", - "reference": "0f407c43b953d571421e0020ba92082ed5fb7620" + "reference": "77880488b9954b7884c25555c2a0ea9e7053f9d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/defuse/php-encryption/zipball/0f407c43b953d571421e0020ba92082ed5fb7620", - "reference": "0f407c43b953d571421e0020ba92082ed5fb7620", + "url": "https://api.github.com/repos/defuse/php-encryption/zipball/77880488b9954b7884c25555c2a0ea9e7053f9d2", + "reference": "77880488b9954b7884c25555c2a0ea9e7053f9d2", "shasum": "" }, "require": { "ext-openssl": "*", "paragonie/random_compat": ">= 2", - "php": ">=5.4.0" + "php": ">=5.6.0" }, "require-dev": { - "nikic/php-parser": "^2.0|^3.0|^4.0", - "phpunit/phpunit": "^4|^5" + "phpunit/phpunit": "^4|^5|^6|^7|^8|^9" }, "bin": [ "bin/generate-defuse-key" @@ -266,7 +282,11 @@ "security", "symmetric key cryptography" ], - "time": "2018-07-24T23:27:56+00:00" + "support": { + "issues": "https://github.com/defuse/php-encryption/issues", + "source": "https://github.com/defuse/php-encryption/tree/v2.3.1" + }, + "time": "2021-04-09T23:57:26+00:00" }, { "name": "dnoegel/php-xdg-base-dir", @@ -299,20 +319,24 @@ "MIT" ], "description": "implementation of xdg base directory specification for php", + "support": { + "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", + "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" + }, "time": "2019-12-04T15:06:13+00:00" }, { "name": "doctrine/cache", - "version": "1.10.2", + "version": "2.1.1", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "13e3381b25847283a91948d04640543941309727" + "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/13e3381b25847283a91948d04640543941309727", - "reference": "13e3381b25847283a91948d04640543941309727", + "url": "https://api.github.com/repos/doctrine/cache/zipball/331b4d5dbaeab3827976273e9356b3b453c300ce", + "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce", "shasum": "" }, "require": { @@ -323,20 +347,19 @@ }, "require-dev": { "alcaeus/mongo-php-adapter": "^1.1", - "doctrine/coding-standard": "^6.0", + "cache/integration-tests": "dev-master", + "doctrine/coding-standard": "^8.0", "mongodb/mongodb": "^1.1", - "phpunit/phpunit": "^7.0", - "predis/predis": "~1.0" + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "predis/predis": "~1.0", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "symfony/cache": "^4.4 || ^5.2 || ^6.0@dev", + "symfony/var-exporter": "^4.4 || ^5.2 || ^6.0@dev" }, "suggest": { "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.9.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" @@ -381,6 +404,10 @@ "redis", "xcache" ], + "support": { + "issues": "https://github.com/doctrine/cache/issues", + "source": "https://github.com/doctrine/cache/tree/2.1.1" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -395,36 +422,38 @@ "type": "tidelift" } ], - "time": "2020-07-07T18:54:01+00:00" + "time": "2021-07-17T14:49:29+00:00" }, { "name": "doctrine/dbal", - "version": "2.12.1", + "version": "2.13.2", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "adce7a954a1c2f14f85e94aed90c8489af204086" + "reference": "8dd39d2ead4409ce652fd4f02621060f009ea5e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/adce7a954a1c2f14f85e94aed90c8489af204086", - "reference": "adce7a954a1c2f14f85e94aed90c8489af204086", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/8dd39d2ead4409ce652fd4f02621060f009ea5e4", + "reference": "8dd39d2ead4409ce652fd4f02621060f009ea5e4", "shasum": "" }, "require": { - "doctrine/cache": "^1.0", + "doctrine/cache": "^1.0|^2.0", + "doctrine/deprecations": "^0.5.3", "doctrine/event-manager": "^1.0", "ext-pdo": "*", - "php": "^7.3 || ^8" + "php": "^7.1 || ^8" }, "require-dev": { - "doctrine/coding-standard": "^8.1", - "jetbrains/phpstorm-stubs": "^2019.1", - "phpstan/phpstan": "^0.12.40", - "phpunit/phpunit": "^9.4", - "psalm/plugin-phpunit": "^0.10.0", + "doctrine/coding-standard": "9.0.0", + "jetbrains/phpstorm-stubs": "2020.2", + "phpstan/phpstan": "0.12.81", + "phpunit/phpunit": "^7.5.20|^8.5|9.5.5", + "squizlabs/php_codesniffer": "3.6.0", + "symfony/cache": "^4.4", "symfony/console": "^2.0.5|^3.0|^4.0|^5.0", - "vimeo/psalm": "^3.17.2" + "vimeo/psalm": "4.6.4" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -433,11 +462,6 @@ "bin/doctrine-dbal" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\DBAL\\": "lib/Doctrine/DBAL" @@ -488,6 +512,10 @@ "sqlserver", "sqlsrv" ], + "support": { + "issues": "https://github.com/doctrine/dbal/issues", + "source": "https://github.com/doctrine/dbal/tree/2.13.2" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -502,7 +530,50 @@ "type": "tidelift" } ], - "time": "2020-11-14T20:26:58+00:00" + "time": "2021-06-18T21:48:39+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "v0.5.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "9504165960a1f83cc1480e2be1dd0a0478561314" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/9504165960a1f83cc1480e2be1dd0a0478561314", + "reference": "9504165960a1f83cc1480e2be1dd0a0478561314", + "shasum": "" + }, + "require": { + "php": "^7.1|^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0|^7.0|^8.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0", + "psr/log": "^1.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/v0.5.3" + }, + "time": "2021-03-21T12:59:47+00:00" }, { "name": "doctrine/event-manager", @@ -578,6 +649,10 @@ "event system", "events" ], + "support": { + "issues": "https://github.com/doctrine/event-manager/issues", + "source": "https://github.com/doctrine/event-manager/tree/1.1.x" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -669,6 +744,10 @@ "uppercase", "words" ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.x" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -745,6 +824,10 @@ "parser", "php" ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/1.2.1" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -827,6 +910,10 @@ ], "description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter", "homepage": "https://github.com/dompdf/dompdf", + "support": { + "issues": "https://github.com/dompdf/dompdf/issues", + "source": "https://github.com/dompdf/dompdf/tree/master" + }, "time": "2020-08-30T22:54:22+00:00" }, { @@ -881,6 +968,10 @@ "cron", "schedule" ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v2.3.1" + }, "funding": [ { "url": "https://github.com/dragonmantank", @@ -891,16 +982,16 @@ }, { "name": "egulias/email-validator", - "version": "2.1.24", + "version": "2.1.25", "source": { "type": "git", "url": "https://github.com/egulias/EmailValidator.git", - "reference": "ca90a3291eee1538cd48ff25163240695bd95448" + "reference": "0dbf5d78455d4d6a41d186da50adc1122ec066f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ca90a3291eee1538cd48ff25163240695bd95448", - "reference": "ca90a3291eee1538cd48ff25163240695bd95448", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/0dbf5d78455d4d6a41d186da50adc1122ec066f4", + "reference": "0dbf5d78455d4d6a41d186da50adc1122ec066f4", "shasum": "" }, "require": { @@ -945,26 +1036,30 @@ "validation", "validator" ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/2.1.25" + }, "funding": [ { "url": "https://github.com/egulias", "type": "github" } ], - "time": "2020-11-14T15:56:27+00:00" + "time": "2020-12-29T14:50:06+00:00" }, { "name": "encore/laravel-admin", - "version": "v1.8.11", + "version": "v1.8.13", "source": { "type": "git", "url": "https://github.com/z-song/laravel-admin.git", - "reference": "6ddd381a9f4928b6c2175dea297e6a8b385d8d28" + "reference": "52c51ee3b7d7111e74a0f2f64a27539871126ac8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/z-song/laravel-admin/zipball/6ddd381a9f4928b6c2175dea297e6a8b385d8d28", - "reference": "6ddd381a9f4928b6c2175dea297e6a8b385d8d28", + "url": "https://api.github.com/repos/z-song/laravel-admin/zipball/52c51ee3b7d7111e74a0f2f64a27539871126ac8", + "reference": "52c51ee3b7d7111e74a0f2f64a27539871126ac8", "shasum": "" }, "require": { @@ -1021,7 +1116,11 @@ "grid", "laravel" ], - "time": "2020-11-15T02:55:51+00:00" + "support": { + "issues": "https://github.com/z-song/laravel-admin/issues", + "source": "https://github.com/z-song/laravel-admin/tree/v1.8.13" + }, + "time": "2021-07-15T03:43:30+00:00" }, { "name": "ezyang/htmlpurifier", @@ -1071,6 +1170,10 @@ "keywords": [ "html" ], + "support": { + "issues": "https://github.com/ezyang/htmlpurifier/issues", + "source": "https://github.com/ezyang/htmlpurifier/tree/master" + }, "time": "2020-06-29T00:56:53+00:00" }, { @@ -1125,20 +1228,24 @@ "proxy", "trusted proxy" ], + "support": { + "issues": "https://github.com/fideloper/TrustedProxy/issues", + "source": "https://github.com/fideloper/TrustedProxy/tree/4.4.1" + }, "time": "2020-10-22T13:48:01+00:00" }, { "name": "firebase/php-jwt", - "version": "v5.2.0", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "feb0e820b8436873675fd3aca04f3728eb2185cb" + "reference": "d2113d9b2e0e349796e72d2a63cf9319100382d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/feb0e820b8436873675fd3aca04f3728eb2185cb", - "reference": "feb0e820b8436873675fd3aca04f3728eb2185cb", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/d2113d9b2e0e349796e72d2a63cf9319100382d2", + "reference": "d2113d9b2e0e349796e72d2a63cf9319100382d2", "shasum": "" }, "require": { @@ -1147,6 +1254,9 @@ "require-dev": { "phpunit/phpunit": ">=4.8 <=9" }, + "suggest": { + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + }, "type": "library", "autoload": { "psr-4": { @@ -1175,20 +1285,24 @@ "jwt", "php" ], - "time": "2020-03-25T18:49:23+00:00" + "support": { + "issues": "https://github.com/firebase/php-jwt/issues", + "source": "https://github.com/firebase/php-jwt/tree/v5.4.0" + }, + "time": "2021-06-23T19:00:23+00:00" }, { "name": "fonts-asset/devicon", - "version": "1.0.0", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/ZsgsDesign/fonts-asset-Devicon.git", - "reference": "14381087a09512236b8471b3aea144f03a61914e" + "reference": "60b758649dac34cb7498fc450e8f4eec120e78df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ZsgsDesign/fonts-asset-Devicon/zipball/14381087a09512236b8471b3aea144f03a61914e", - "reference": "14381087a09512236b8471b3aea144f03a61914e", + "url": "https://api.github.com/repos/ZsgsDesign/fonts-asset-Devicon/zipball/60b758649dac34cb7498fc450e8f4eec120e78df", + "reference": "60b758649dac34cb7498fc450e8f4eec120e78df", "shasum": "" }, "type": "fonts-asset", @@ -1203,7 +1317,43 @@ } ], "description": "Devicon for composer.", - "time": "2020-12-10T16:02:19+00:00" + "support": { + "issues": "https://github.com/ZsgsDesign/fonts-asset-Devicon/issues", + "source": "https://github.com/ZsgsDesign/fonts-asset-Devicon/tree/1.0.3" + }, + "time": "2021-03-21T12:24:52+00:00" + }, + { + "name": "fonts-asset/langicon", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/ZsgsDesign/fonts-asset-Langicon.git", + "reference": "4d2929fb9ffc0fc7b0c974247a21621260004c76" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ZsgsDesign/fonts-asset-Langicon/zipball/4d2929fb9ffc0fc7b0c974247a21621260004c76", + "reference": "4d2929fb9ffc0fc7b0c974247a21621260004c76", + "shasum": "" + }, + "type": "fonts-asset", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "zsgsdesign", + "email": "zsgsdesign@gmail.com" + } + ], + "description": "Langicon for composer.", + "support": { + "issues": "https://github.com/ZsgsDesign/fonts-asset-Langicon/issues", + "source": "https://github.com/ZsgsDesign/fonts-asset-Langicon/tree/1.0.2" + }, + "time": "2021-08-11T15:50:43+00:00" }, { "name": "fonts-asset/mdi-wxss", @@ -1231,6 +1381,10 @@ } ], "description": "MDI-WXSS for composer.", + "support": { + "issues": "https://github.com/ZsgsDesign/fonts-asset-MDI-WXSS/issues", + "source": "https://github.com/ZsgsDesign/fonts-asset-MDI-WXSS/tree/1.0.0" + }, "time": "2020-12-10T16:05:48+00:00" }, { @@ -1259,6 +1413,10 @@ } ], "description": "Montserrat for composer.", + "support": { + "issues": "https://github.com/ZsgsDesign/fonts-asset-Montserrat/issues", + "source": "https://github.com/ZsgsDesign/fonts-asset-Montserrat/tree/1.0.0" + }, "time": "2020-12-10T16:05:47+00:00" }, { @@ -1287,6 +1445,10 @@ } ], "description": "Raleway for composer.", + "support": { + "issues": "https://github.com/ZsgsDesign/fonts-asset-Raleway/issues", + "source": "https://github.com/ZsgsDesign/fonts-asset-Raleway/tree/1.0.0" + }, "time": "2020-12-10T16:05:47+00:00" }, { @@ -1315,6 +1477,10 @@ } ], "description": "Roboto for composer.", + "support": { + "issues": "https://github.com/ZsgsDesign/fonts-asset-Roboto/issues", + "source": "https://github.com/ZsgsDesign/fonts-asset-Roboto/tree/1.0.0" + }, "time": "2020-12-10T16:05:46+00:00" }, { @@ -1343,8 +1509,44 @@ } ], "description": "Roboto-Slab for composer.", + "support": { + "issues": "https://github.com/ZsgsDesign/fonts-asset-Roboto-Slab/issues", + "source": "https://github.com/ZsgsDesign/fonts-asset-Roboto-Slab/tree/1.0.0" + }, "time": "2020-12-10T16:05:45+00:00" }, + { + "name": "fonts-asset/socialicon", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/ZsgsDesign/fonts-asset-Socialicon.git", + "reference": "c86238a19ccf804594e8713681f1aa214ee80346" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ZsgsDesign/fonts-asset-Socialicon/zipball/c86238a19ccf804594e8713681f1aa214ee80346", + "reference": "c86238a19ccf804594e8713681f1aa214ee80346", + "shasum": "" + }, + "type": "fonts-asset", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "zsgsdesign", + "email": "zsgsdesign@gmail.com" + } + ], + "description": "Socialicon for composer.", + "support": { + "issues": "https://github.com/ZsgsDesign/fonts-asset-Socialicon/issues", + "source": "https://github.com/ZsgsDesign/fonts-asset-Socialicon/tree/1.0.1" + }, + "time": "2021-08-11T15:50:45+00:00" + }, { "name": "graham-campbell/markdown", "version": "v11.2.1", @@ -1410,6 +1612,10 @@ "laravel", "markdown" ], + "support": { + "issues": "https://github.com/GrahamCampbell/Laravel-Markdown/issues", + "source": "https://github.com/GrahamCampbell/Laravel-Markdown/tree/11.2" + }, "funding": [ { "url": "https://github.com/GrahamCampbell", @@ -1471,26 +1677,30 @@ "daily", "photo" ], + "support": { + "issues": "https://github.com/grubersjoe/bing-daily-photo/issues", + "source": "https://github.com/grubersjoe/bing-daily-photo/tree/v2.0.0" + }, "time": "2019-03-06T14:39:30+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "7.2.0", + "version": "7.3.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79" + "reference": "7008573787b430c1c1f650e3722d9bba59967628" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/0aa74dfb41ae110835923ef10a9d803a22d50e79", - "reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7008573787b430c1c1f650e3722d9bba59967628", + "reference": "7008573787b430c1c1f650e3722d9bba59967628", "shasum": "" }, "require": { "ext-json": "*", "guzzlehttp/promises": "^1.4", - "guzzlehttp/psr7": "^1.7", + "guzzlehttp/psr7": "^1.7 || ^2.0", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0" }, @@ -1498,6 +1708,7 @@ "psr/http-client-implementation": "1.0" }, "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", "ext-curl": "*", "php-http/client-integration-tests": "^3.0", "phpunit/phpunit": "^8.5.5 || ^9.3.5", @@ -1511,7 +1722,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "7.1-dev" + "dev-master": "7.3-dev" } }, "autoload": { @@ -1551,6 +1762,10 @@ "rest", "web service" ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.3.0" + }, "funding": [ { "url": "https://github.com/GrahamCampbell", @@ -1569,20 +1784,20 @@ "type": "github" } ], - "time": "2020-10-10T11:47:56+00:00" + "time": "2021-03-23T11:33:13+00:00" }, { "name": "guzzlehttp/promises", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "60d379c243457e073cff02bc323a2a86cb355631" + "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/60d379c243457e073cff02bc323a2a86cb355631", - "reference": "60d379c243457e073cff02bc323a2a86cb355631", + "url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d", + "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d", "shasum": "" }, "require": { @@ -1620,33 +1835,40 @@ "keywords": [ "promise" ], - "time": "2020-09-30T07:37:28+00:00" + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.4.1" + }, + "time": "2021-03-07T09:25:29+00:00" }, { "name": "guzzlehttp/psr7", - "version": "1.7.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3" + "reference": "1dc8d9cba3897165e16d12bb13d813afb1eb3fe7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/53330f47520498c0ae1f61f7e2c90f55690c06a3", - "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/1dc8d9cba3897165e16d12bb13d813afb1eb3fe7", + "reference": "1dc8d9cba3897165e16d12bb13d813afb1eb3fe7", "shasum": "" }, "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0", - "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0", + "ralouphie/getallheaders": "^3.0" }, "provide": { + "psr/http-factory-implementation": "1.0", "psr/http-message-implementation": "1.0" }, "require-dev": { - "ext-zlib": "*", - "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" + "bamarni/composer-bin-plugin": "^1.4.1", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.8 || ^9.3.10" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" @@ -1654,16 +1876,13 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7-dev" + "dev-master": "2.0-dev" } }, "autoload": { "psr-4": { "GuzzleHttp\\Psr7\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1678,6 +1897,11 @@ { "name": "Tobias Schultze", "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" } ], "description": "PSR-7 message implementation that also provides common utility methods", @@ -1691,7 +1915,11 @@ "uri", "url" ], - "time": "2020-09-30T07:37:11+00:00" + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.0.0" + }, + "time": "2021-06-30T20:03:07+00:00" }, { "name": "imtigger/laravel-job-status", @@ -1748,30 +1976,34 @@ "laravel", "queue" ], + "support": { + "issues": "https://github.com/imTigger/laravel-job-status/issues", + "source": "https://github.com/imTigger/laravel-job-status/tree/master" + }, "time": "2019-02-12T18:33:24+00:00" }, { "name": "intervention/image", - "version": "2.5.1", + "version": "2.6.1", "source": { "type": "git", "url": "https://github.com/Intervention/image.git", - "reference": "abbf18d5ab8367f96b3205ca3c89fb2fa598c69e" + "reference": "0925f10b259679b5d8ca58f3a2add9255ffcda45" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Intervention/image/zipball/abbf18d5ab8367f96b3205ca3c89fb2fa598c69e", - "reference": "abbf18d5ab8367f96b3205ca3c89fb2fa598c69e", + "url": "https://api.github.com/repos/Intervention/image/zipball/0925f10b259679b5d8ca58f3a2add9255ffcda45", + "reference": "0925f10b259679b5d8ca58f3a2add9255ffcda45", "shasum": "" }, "require": { "ext-fileinfo": "*", - "guzzlehttp/psr7": "~1.1", + "guzzlehttp/psr7": "~1.1 || ^2.0", "php": ">=5.4.0" }, "require-dev": { "mockery/mockery": "~0.9.2", - "phpunit/phpunit": "^4.8 || ^5.7" + "phpunit/phpunit": "^4.8 || ^5.7 || ^7.5.15" }, "suggest": { "ext-gd": "to use GD library based image processing.", @@ -1818,7 +2050,21 @@ "thumbnail", "watermark" ], - "time": "2019-11-02T09:15:47+00:00" + "support": { + "issues": "https://github.com/Intervention/image/issues", + "source": "https://github.com/Intervention/image/tree/2.6.1" + }, + "funding": [ + { + "url": "https://www.paypal.me/interventionphp", + "type": "custom" + }, + { + "url": "https://github.com/Intervention", + "type": "github" + } + ], + "time": "2021-07-22T14:31:53+00:00" }, { "name": "jakub-onderka/php-console-color", @@ -1860,6 +2106,10 @@ "email": "jakub.onderka@gmail.com" } ], + "support": { + "issues": "https://github.com/JakubOnderka/PHP-Console-Color/issues", + "source": "https://github.com/JakubOnderka/PHP-Console-Color/tree/master" + }, "abandoned": "php-parallel-lint/php-console-color", "time": "2018-09-29T17:23:10+00:00" }, @@ -1907,6 +2157,10 @@ } ], "description": "Highlight PHP code in terminal", + "support": { + "issues": "https://github.com/JakubOnderka/PHP-Console-Highlighter/issues", + "source": "https://github.com/JakubOnderka/PHP-Console-Highlighter/tree/master" + }, "abandoned": "php-parallel-lint/php-console-highlighter", "time": "2018-09-29T18:48:56+00:00" }, @@ -1954,20 +2208,24 @@ "dom", "html" ], + "support": { + "issues": "https://github.com/Kub-AT/php-simple-html-dom-parser/issues", + "source": "https://github.com/Kub-AT/php-simple-html-dom-parser/tree/master" + }, "time": "2019-01-02T14:33:28+00:00" }, { "name": "laminas/laminas-diactoros", - "version": "2.5.0", + "version": "2.6.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-diactoros.git", - "reference": "4ff7400c1c12e404144992ef43c8b733fd9ad516" + "reference": "7d2034110ae18afe05050b796a3ee4b3fe177876" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/4ff7400c1c12e404144992ef43c8b733fd9ad516", - "reference": "4ff7400c1c12e404144992ef43c8b733fd9ad516", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/7d2034110ae18afe05050b796a3ee4b3fe177876", + "reference": "7d2034110ae18afe05050b796a3ee4b3fe177876", "shasum": "" }, "require": { @@ -1995,7 +2253,9 @@ "laminas/laminas-coding-standard": "~1.0.0", "php-http/psr7-integration-tests": "^1.1", "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.1" + "phpunit/phpunit": "^9.1", + "psalm/plugin-phpunit": "^0.14.0", + "vimeo/psalm": "^4.3" }, "type": "library", "extra": { @@ -2040,34 +2300,44 @@ "psr-17", "psr-7" ], + "support": { + "chat": "https://laminas.dev/chat", + "docs": "https://docs.laminas.dev/laminas-diactoros/", + "forum": "https://discourse.laminas.dev", + "issues": "https://github.com/laminas/laminas-diactoros/issues", + "rss": "https://github.com/laminas/laminas-diactoros/releases.atom", + "source": "https://github.com/laminas/laminas-diactoros" + }, "funding": [ { "url": "https://funding.communitybridge.org/projects/laminas-project", "type": "community_bridge" } ], - "time": "2020-11-18T18:39:28+00:00" + "time": "2021-05-18T14:41:54+00:00" }, { "name": "laminas/laminas-zendframework-bridge", - "version": "1.1.1", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-zendframework-bridge.git", - "reference": "6ede70583e101030bcace4dcddd648f760ddf642" + "reference": "13af2502d9bb6f7d33be2de4b51fb68c6cdb476e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/6ede70583e101030bcace4dcddd648f760ddf642", - "reference": "6ede70583e101030bcace4dcddd648f760ddf642", + "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/13af2502d9bb6f7d33be2de4b51fb68c6cdb476e", + "reference": "13af2502d9bb6f7d33be2de4b51fb68c6cdb476e", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0 || ^8.0" + "php": "^7.3 || ^8.0" }, "require-dev": { "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1 || ^9.3", - "squizlabs/php_codesniffer": "^3.5" + "psalm/plugin-phpunit": "^0.15.1", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.6" }, "type": "library", "extra": { @@ -2094,13 +2364,19 @@ "laminas", "zf" ], + "support": { + "forum": "https://discourse.laminas.dev/", + "issues": "https://github.com/laminas/laminas-zendframework-bridge/issues", + "rss": "https://github.com/laminas/laminas-zendframework-bridge/releases.atom", + "source": "https://github.com/laminas/laminas-zendframework-bridge" + }, "funding": [ { "url": "https://funding.communitybridge.org/projects/laminas-project", "type": "community_bridge" } ], - "time": "2020-09-14T14:23:00+00:00" + "time": "2021-06-24T12:49:22+00:00" }, { "name": "laracasts/utilities", @@ -2157,6 +2433,10 @@ "javascript", "laravel" ], + "support": { + "issues": "https://github.com/laracasts/PHP-Vars-To-Js-Transformer/issues", + "source": "https://github.com/laracasts/PHP-Vars-To-Js-Transformer/tree/3.2" + }, "time": "2020-09-07T13:29:37+00:00" }, { @@ -2211,6 +2491,10 @@ "backup", "laravel-admin" ], + "support": { + "issues": "https://github.com/laravel-admin-extensions/backup/issues", + "source": "https://github.com/laravel-admin-extensions/backup/tree/v1.1.1" + }, "time": "2020-09-11T04:42:29+00:00" }, { @@ -2263,6 +2547,10 @@ "helpers", "laravel-admin" ], + "support": { + "issues": "https://github.com/laravel-admin-extensions/helpers/issues", + "source": "https://github.com/laravel-admin-extensions/helpers/tree/master" + }, "time": "2019-12-11T02:59:06+00:00" }, { @@ -2316,6 +2604,10 @@ "laravel-admin", "log" ], + "support": { + "issues": "https://github.com/laravel-admin-extensions/log-viewer/issues", + "source": "https://github.com/laravel-admin-extensions/log-viewer/tree/master" + }, "time": "2018-11-13T17:17:36+00:00" }, { @@ -2369,6 +2661,10 @@ "manager", "media" ], + "support": { + "issues": "https://github.com/laravel-admin-extensions/media-manager/issues", + "source": "https://github.com/laravel-admin-extensions/media-manager/tree/master" + }, "time": "2019-10-14T09:05:25+00:00" }, { @@ -2424,6 +2720,10 @@ "manager", "redis" ], + "support": { + "issues": "https://github.com/laravel-admin-extensions/redis-manager/issues", + "source": "https://github.com/laravel-admin-extensions/redis-manager/tree/v1.3" + }, "time": "2019-12-11T02:38:49+00:00" }, { @@ -2478,20 +2778,24 @@ "scheduling", "task" ], + "support": { + "issues": "https://github.com/laravel-admin-extensions/scheduling/issues", + "source": "https://github.com/laravel-admin-extensions/scheduling/tree/v1.1" + }, "time": "2019-12-11T02:46:10+00:00" }, { "name": "laravel/framework", - "version": "v6.20.7", + "version": "v6.20.32", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "bdc79701b567c5f8ed44d212dd4a261b8300b9c3" + "reference": "04d4fa31d10ed344c9d1cf30a761b0c4e468aaf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/bdc79701b567c5f8ed44d212dd4a261b8300b9c3", - "reference": "bdc79701b567c5f8ed44d212dd4a261b8300b9c3", + "url": "https://api.github.com/repos/laravel/framework/zipball/04d4fa31d10ed344c9d1cf30a761b0c4e468aaf2", + "reference": "04d4fa31d10ed344c9d1cf30a761b0c4e468aaf2", "shasum": "" }, "require": { @@ -2627,7 +2931,11 @@ "framework", "laravel" ], - "time": "2020-12-08T15:31:27+00:00" + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2021-08-10T14:25:21+00:00" }, { "name": "laravel/passport", @@ -2700,6 +3008,10 @@ "oauth", "passport" ], + "support": { + "issues": "https://github.com/laravel/passport/issues", + "source": "https://github.com/laravel/passport" + }, "time": "2020-12-04T09:37:12+00:00" }, { @@ -2765,6 +3077,10 @@ "laravel", "oauth" ], + "support": { + "issues": "https://github.com/laravel/socialite/issues", + "source": "https://github.com/laravel/socialite" + }, "time": "2020-06-03T13:30:03+00:00" }, { @@ -2828,6 +3144,10 @@ "laravel", "psysh" ], + "support": { + "issues": "https://github.com/laravel/tinker/issues", + "source": "https://github.com/laravel/tinker/tree/v1.0.10" + }, "time": "2019-08-07T15:10:45+00:00" }, { @@ -2891,52 +3211,117 @@ "php", "xml" ], + "support": { + "issues": "https://gitlab.com/Laravelium/Sitemap/issues", + "source": "https://gitlab.com/Laravelium/Sitemap", + "wiki": "https://gitlab.com/Laravelium/Sitemap/wikis/home" + }, "time": "2019-09-03T19:16:19+00:00" }, + { + "name": "lcobucci/clock", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/clock.git", + "reference": "353d83fe2e6ae95745b16b3d911813df6a05bfb3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/clock/zipball/353d83fe2e6ae95745b16b3d911813df6a05bfb3", + "reference": "353d83fe2e6ae95745b16b3d911813df6a05bfb3", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "infection/infection": "^0.17", + "lcobucci/coding-standard": "^6.0", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-deprecation-rules": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/php-code-coverage": "9.1.4", + "phpunit/phpunit": "9.3.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lcobucci\\Clock\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Luís Cobucci", + "email": "lcobucci@gmail.com" + } + ], + "description": "Yet another clock abstraction", + "support": { + "issues": "https://github.com/lcobucci/clock/issues", + "source": "https://github.com/lcobucci/clock/tree/2.0.x" + }, + "funding": [ + { + "url": "https://github.com/lcobucci", + "type": "github" + }, + { + "url": "https://www.patreon.com/lcobucci", + "type": "patreon" + } + ], + "time": "2020-08-27T18:56:02+00:00" + }, { "name": "lcobucci/jwt", - "version": "3.4.1", + "version": "4.0.3", "source": { "type": "git", "url": "https://github.com/lcobucci/jwt.git", - "reference": "958a9873a63b0244a72f6e354ccc86019ee674a5" + "reference": "ae4165a76848e070fdac691e773243d10cd06ce1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lcobucci/jwt/zipball/958a9873a63b0244a72f6e354ccc86019ee674a5", - "reference": "958a9873a63b0244a72f6e354ccc86019ee674a5", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/ae4165a76848e070fdac691e773243d10cd06ce1", + "reference": "ae4165a76848e070fdac691e773243d10cd06ce1", "shasum": "" }, "require": { "ext-mbstring": "*", "ext-openssl": "*", - "php": "^5.6 || ^7.0" + "lcobucci/clock": "^2.0", + "php": "^7.4 || ^8.0" }, "require-dev": { - "mikey179/vfsstream": "~1.5", - "phpmd/phpmd": "~2.2", - "phpunit/php-invoker": "~1.1", - "phpunit/phpunit": "^5.7 || ^7.3", - "squizlabs/php_codesniffer": "~2.3" - }, - "suggest": { - "lcobucci/clock": "*" + "infection/infection": "^0.20", + "lcobucci/coding-standard": "^6.0", + "mikey179/vfsstream": "^1.6", + "phpbench/phpbench": "^0.17", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-deprecation-rules": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/php-invoker": "^3.1", + "phpunit/phpunit": "^9.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "4.0-dev" } }, "autoload": { "psr-4": { "Lcobucci\\JWT\\": "src" - }, - "files": [ - "compat/class-aliases.php", - "compat/json-exception-polyfill.php", - "compat/lcobucci-clock-polyfill.php" - ] + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2944,7 +3329,7 @@ ], "authors": [ { - "name": "Luís Otávio Cobucci Oblonczyk", + "name": "Luís Cobucci", "email": "lcobucci@gmail.com", "role": "Developer" } @@ -2954,6 +3339,10 @@ "JWS", "jwt" ], + "support": { + "issues": "https://github.com/lcobucci/jwt/issues", + "source": "https://github.com/lcobucci/jwt/tree/4.0.3" + }, "funding": [ { "url": "https://github.com/lcobucci", @@ -2964,20 +3353,20 @@ "type": "patreon" } ], - "time": "2020-11-27T01:17:14+00:00" + "time": "2021-03-23T23:47:22+00:00" }, { "name": "league/commonmark", - "version": "1.5.7", + "version": "1.6.6", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "11df9b36fd4f1d2b727a73bf14931d81373b9a54" + "reference": "c4228d11e30d7493c6836d20872f9582d8ba6dcf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/11df9b36fd4f1d2b727a73bf14931d81373b9a54", - "reference": "11df9b36fd4f1d2b727a73bf14931d81373b9a54", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/c4228d11e30d7493c6836d20872f9582d8ba6dcf", + "reference": "c4228d11e30d7493c6836d20872f9582d8ba6dcf", "shasum": "" }, "require": { @@ -2995,7 +3384,7 @@ "github/gfm": "0.29.0", "michelf/php-markdown": "~1.4", "mikehaertl/php-shellcommand": "^1.4", - "phpstan/phpstan": "^0.12", + "phpstan/phpstan": "^0.12.90", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.2", "scrutinizer/ocular": "^1.5", "symfony/finder": "^4.2" @@ -3033,6 +3422,12 @@ "md", "parser" ], + "support": { + "docs": "https://commonmark.thephpleague.com/", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" + }, "funding": [ { "url": "https://enjoy.gitstore.app/repositories/thephpleague/commonmark", @@ -3059,7 +3454,7 @@ "type": "tidelift" } ], - "time": "2020-10-31T13:49:32+00:00" + "time": "2021-07-17T17:13:23+00:00" }, { "name": "league/commonmark-ext-strikethrough", @@ -3120,6 +3515,10 @@ "strikeout", "strikethrough" ], + "support": { + "issues": "https://github.com/thephpleague/commonmark-ext-strikethrough/issues", + "source": "https://github.com/thephpleague/commonmark-ext-strikethrough/tree/master" + }, "funding": [ { "url": "https://www.patreon.com/colinodell", @@ -3177,20 +3576,24 @@ "event", "listener" ], + "support": { + "issues": "https://github.com/thephpleague/event/issues", + "source": "https://github.com/thephpleague/event/tree/master" + }, "time": "2018-11-26T11:52:41+00:00" }, { "name": "league/flysystem", - "version": "1.1.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "9be3b16c877d477357c015cec057548cf9b2a14a" + "reference": "f3ad69181b8afed2c9edf7be5a2918144ff4ea32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/9be3b16c877d477357c015cec057548cf9b2a14a", - "reference": "9be3b16c877d477357c015cec057548cf9b2a14a", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/f3ad69181b8afed2c9edf7be5a2918144ff4ea32", + "reference": "f3ad69181b8afed2c9edf7be5a2918144ff4ea32", "shasum": "" }, "require": { @@ -3206,7 +3609,6 @@ "phpunit/phpunit": "^8.5.8" }, "suggest": { - "ext-fileinfo": "Required for MimeType", "ext-ftp": "Allows you to use FTP server storage", "ext-openssl": "Allows you to use FTPS server storage", "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", @@ -3262,26 +3664,30 @@ "sftp", "storage" ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/1.1.4" + }, "funding": [ { "url": "https://offset.earth/frankdejonge", "type": "other" } ], - "time": "2020-08-23T07:39:11+00:00" + "time": "2021-06-23T21:56:05+00:00" }, { "name": "league/mime-type-detection", - "version": "1.5.1", + "version": "1.7.0", "source": { "type": "git", "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "353f66d7555d8a90781f6f5e7091932f9a4250aa" + "reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/353f66d7555d8a90781f6f5e7091932f9a4250aa", - "reference": "353f66d7555d8a90781f6f5e7091932f9a4250aa", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3", + "reference": "3b9dff8aaf7323590c1d2e443db701eb1f9aa0d3", "shasum": "" }, "require": { @@ -3289,8 +3695,9 @@ "php": "^7.2 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.36", - "phpunit/phpunit": "^8.5.8" + "friendsofphp/php-cs-fixer": "^2.18", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3" }, "type": "library", "autoload": { @@ -3309,6 +3716,10 @@ } ], "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.7.0" + }, "funding": [ { "url": "https://github.com/frankdejonge", @@ -3319,34 +3730,35 @@ "type": "tidelift" } ], - "time": "2020-10-18T11:50:25+00:00" + "time": "2021-01-18T20:58:21+00:00" }, { "name": "league/oauth1-client", - "version": "v1.8.2", + "version": "1.9.2", "source": { "type": "git", "url": "https://github.com/thephpleague/oauth1-client.git", - "reference": "159c3d2bf27568f9af87d6c3f4bb616a251eb12b" + "reference": "6247ffbf6b74fcc7f21313315b79e9b2560e68b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/159c3d2bf27568f9af87d6c3f4bb616a251eb12b", - "reference": "159c3d2bf27568f9af87d6c3f4bb616a251eb12b", + "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/6247ffbf6b74fcc7f21313315b79e9b2560e68b0", + "reference": "6247ffbf6b74fcc7f21313315b79e9b2560e68b0", "shasum": "" }, "require": { "ext-json": "*", "ext-openssl": "*", "guzzlehttp/guzzle": "^6.0|^7.0", - "php": ">=7.1" + "guzzlehttp/psr7": "^1.7|^2.0", + "php": ">=7.1||>=8.0" }, "require-dev": { "ext-simplexml": "*", - "friendsofphp/php-cs-fixer": "^2.16.1", - "mockery/mockery": "^1.3", + "friendsofphp/php-cs-fixer": "^2.17", + "mockery/mockery": "^1.3.3", "phpstan/phpstan": "^0.12.42", - "phpunit/phpunit": "^7.5" + "phpunit/phpunit": "^7.5||9.5" }, "suggest": { "ext-simplexml": "For decoding XML-based responses." @@ -3390,20 +3802,24 @@ "tumblr", "twitter" ], - "time": "2020-09-28T09:39:08+00:00" + "support": { + "issues": "https://github.com/thephpleague/oauth1-client/issues", + "source": "https://github.com/thephpleague/oauth1-client/tree/1.9.2" + }, + "time": "2021-08-03T23:29:01+00:00" }, { "name": "league/oauth2-server", - "version": "8.2.3", + "version": "8.3.2", "source": { "type": "git", "url": "https://github.com/thephpleague/oauth2-server.git", - "reference": "70bb329bc79b7965a56f46e293da946c5a976ef1" + "reference": "0809487d33dd8a2c8c8c04e4a599ba4aadba1ae6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/70bb329bc79b7965a56f46e293da946c5a976ef1", - "reference": "70bb329bc79b7965a56f46e293da946c5a976ef1", + "url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/0809487d33dd8a2c8c8c04e4a599ba4aadba1ae6", + "reference": "0809487d33dd8a2c8c8c04e4a599ba4aadba1ae6", "shasum": "" }, "require": { @@ -3467,33 +3883,37 @@ "secure", "server" ], + "support": { + "issues": "https://github.com/thephpleague/oauth2-server/issues", + "source": "https://github.com/thephpleague/oauth2-server/tree/8.3.2" + }, "funding": [ { "url": "https://github.com/sephster", "type": "github" } ], - "time": "2020-12-03T21:32:29+00:00" + "time": "2021-07-27T08:17:08+00:00" }, { "name": "maatwebsite/excel", - "version": "3.1.26", + "version": "3.1.33", "source": { "type": "git", "url": "https://github.com/Maatwebsite/Laravel-Excel.git", - "reference": "66f7c9584304ad0b6a267a5d8ffbfa2ff4272e85" + "reference": "b2de5ba92c5c1ad9415f0eb7c72838fb3eaaa5b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Maatwebsite/Laravel-Excel/zipball/66f7c9584304ad0b6a267a5d8ffbfa2ff4272e85", - "reference": "66f7c9584304ad0b6a267a5d8ffbfa2ff4272e85", + "url": "https://api.github.com/repos/Maatwebsite/Laravel-Excel/zipball/b2de5ba92c5c1ad9415f0eb7c72838fb3eaaa5b8", + "reference": "b2de5ba92c5c1ad9415f0eb7c72838fb3eaaa5b8", "shasum": "" }, "require": { "ext-json": "*", "illuminate/support": "5.8.*|^6.0|^7.0|^8.0", "php": "^7.0|^8.0", - "phpoffice/phpspreadsheet": "^1.15" + "phpoffice/phpspreadsheet": "^1.18" }, "require-dev": { "orchestra/testbench": "^6.0", @@ -3537,6 +3957,10 @@ "php", "phpspreadsheet" ], + "support": { + "issues": "https://github.com/Maatwebsite/Laravel-Excel/issues", + "source": "https://github.com/Maatwebsite/Laravel-Excel/tree/3.1.33" + }, "funding": [ { "url": "https://laravel-excel.com/commercial-support", @@ -3547,7 +3971,7 @@ "type": "github" } ], - "time": "2020-11-27T16:17:38+00:00" + "time": "2021-08-12T15:52:25+00:00" }, { "name": "maennchen/zipstream-php", @@ -3608,6 +4032,10 @@ "stream", "zip" ], + "support": { + "issues": "https://github.com/maennchen/ZipStream-PHP/issues", + "source": "https://github.com/maennchen/ZipStream-PHP/tree/master" + }, "funding": [ { "url": "https://opencollective.com/zipstream", @@ -3618,16 +4046,16 @@ }, { "name": "markbaker/complex", - "version": "2.0.0", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/MarkBaker/PHPComplex.git", - "reference": "9999f1432fae467bc93c53f357105b4c31bb994c" + "reference": "6f724d7e04606fd8adaa4e3bb381c3e9db09c946" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/9999f1432fae467bc93c53f357105b4c31bb994c", - "reference": "9999f1432fae467bc93c53f357105b4c31bb994c", + "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/6f724d7e04606fd8adaa4e3bb381c3e9db09c946", + "reference": "6f724d7e04606fd8adaa4e3bb381c3e9db09c946", "shasum": "" }, "require": { @@ -3636,11 +4064,7 @@ "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "phpcompatibility/php-compatibility": "^9.0", - "phpdocumentor/phpdocumentor": "2.*", - "phploc/phploc": "^4.0", - "phpmd/phpmd": "2.*", "phpunit/phpunit": "^7.0 || ^8.0 || ^9.3", - "sebastian/phpcpd": "^4.0", "squizlabs/php_codesniffer": "^3.4" }, "type": "library", @@ -3709,24 +4133,28 @@ "complex", "mathematics" ], - "time": "2020-08-26T10:42:07+00:00" + "support": { + "issues": "https://github.com/MarkBaker/PHPComplex/issues", + "source": "https://github.com/MarkBaker/PHPComplex/tree/2.0.3" + }, + "time": "2021-06-02T09:44:11+00:00" }, { "name": "markbaker/matrix", - "version": "2.0.0", + "version": "2.1.3", "source": { "type": "git", "url": "https://github.com/MarkBaker/PHPMatrix.git", - "reference": "9567d9c4c519fbe40de01dbd1e4469dbbb66f46a" + "reference": "174395a901b5ba0925f1d790fa91bab531074b61" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/9567d9c4c519fbe40de01dbd1e4469dbbb66f46a", - "reference": "9567d9c4c519fbe40de01dbd1e4469dbbb66f46a", + "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/174395a901b5ba0925f1d790fa91bab531074b61", + "reference": "174395a901b5ba0925f1d790fa91bab531074b61", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "php": "^7.1 || ^8.0" }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", @@ -3744,22 +4172,22 @@ "Matrix\\": "classes/src/" }, "files": [ - "classes/src/functions/adjoint.php", - "classes/src/functions/antidiagonal.php", - "classes/src/functions/cofactors.php", - "classes/src/functions/determinant.php", - "classes/src/functions/diagonal.php", - "classes/src/functions/identity.php", - "classes/src/functions/inverse.php", - "classes/src/functions/minors.php", - "classes/src/functions/trace.php", - "classes/src/functions/transpose.php", - "classes/src/operations/add.php", - "classes/src/operations/directsum.php", - "classes/src/operations/subtract.php", - "classes/src/operations/multiply.php", - "classes/src/operations/divideby.php", - "classes/src/operations/divideinto.php" + "classes/src/Functions/adjoint.php", + "classes/src/Functions/antidiagonal.php", + "classes/src/Functions/cofactors.php", + "classes/src/Functions/determinant.php", + "classes/src/Functions/diagonal.php", + "classes/src/Functions/identity.php", + "classes/src/Functions/inverse.php", + "classes/src/Functions/minors.php", + "classes/src/Functions/trace.php", + "classes/src/Functions/transpose.php", + "classes/src/Operations/add.php", + "classes/src/Operations/directsum.php", + "classes/src/Operations/subtract.php", + "classes/src/Operations/multiply.php", + "classes/src/Operations/divideby.php", + "classes/src/Operations/divideinto.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -3779,20 +4207,24 @@ "matrix", "vector" ], - "time": "2020-08-28T17:11:00+00:00" + "support": { + "issues": "https://github.com/MarkBaker/PHPMatrix/issues", + "source": "https://github.com/MarkBaker/PHPMatrix/tree/2.1.3" + }, + "time": "2021-05-25T15:42:17+00:00" }, { "name": "mews/purifier", - "version": "3.3.3", + "version": "3.3.5", "source": { "type": "git", "url": "https://github.com/mewebstudio/Purifier.git", - "reference": "8e0b3d87c79b38b8d88aeb3c0ba8b000a393a74c" + "reference": "53f2be3b94cf8940d23970f0aeb907ce8c9760f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mewebstudio/Purifier/zipball/8e0b3d87c79b38b8d88aeb3c0ba8b000a393a74c", - "reference": "8e0b3d87c79b38b8d88aeb3c0ba8b000a393a74c", + "url": "https://api.github.com/repos/mewebstudio/Purifier/zipball/53f2be3b94cf8940d23970f0aeb907ce8c9760f7", + "reference": "53f2be3b94cf8940d23970f0aeb907ce8c9760f7", "shasum": "" }, "require": { @@ -3856,20 +4288,24 @@ "security", "xss" ], - "time": "2020-11-03T19:46:27+00:00" + "support": { + "issues": "https://github.com/mewebstudio/Purifier/issues", + "source": "https://github.com/mewebstudio/Purifier/tree/3.3.5" + }, + "time": "2021-05-17T00:17:01+00:00" }, { "name": "monolog/monolog", - "version": "2.1.1", + "version": "2.3.2", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "f9eee5cec93dfb313a38b6b288741e84e53f02d5" + "reference": "71312564759a7db5b789296369c1a264efc43aad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f9eee5cec93dfb313a38b6b288741e84e53f02d5", - "reference": "f9eee5cec93dfb313a38b6b288741e84e53f02d5", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/71312564759a7db5b789296369c1a264efc43aad", + "reference": "71312564759a7db5b789296369c1a264efc43aad", "shasum": "" }, "require": { @@ -3882,16 +4318,17 @@ "require-dev": { "aws/aws-sdk-php": "^2.4.9 || ^3.0", "doctrine/couchdb": "~1.0@dev", - "elasticsearch/elasticsearch": "^6.0", + "elasticsearch/elasticsearch": "^7", "graylog2/gelf-php": "^1.4.2", + "mongodb/mongodb": "^1.8", "php-amqplib/php-amqplib": "~2.4", "php-console/php-console": "^3.1.3", - "php-parallel-lint/php-parallel-lint": "^1.0", "phpspec/prophecy": "^1.6.1", + "phpstan/phpstan": "^0.12.91", "phpunit/phpunit": "^8.5", "predis/predis": "^1.1", "rollbar/rollbar": "^1.3", - "ruflin/elastica": ">=0.90 <3.0", + "ruflin/elastica": ">=0.90 <7.0.1", "swiftmailer/swiftmailer": "^5.3|^6.0" }, "suggest": { @@ -3911,7 +4348,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-main": "2.x-dev" } }, "autoload": { @@ -3927,16 +4364,20 @@ { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" + "homepage": "https://seld.be" } ], "description": "Sends your logs to files, sockets, inboxes, databases and various web services", - "homepage": "http://github.com/Seldaek/monolog", + "homepage": "https://github.com/Seldaek/monolog", "keywords": [ "log", "logging", "psr-3" ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/2.3.2" + }, "funding": [ { "url": "https://github.com/Seldaek", @@ -3947,30 +4388,30 @@ "type": "tidelift" } ], - "time": "2020-07-23T08:41:23+00:00" + "time": "2021-07-23T07:42:52+00:00" }, { "name": "myclabs/php-enum", - "version": "1.7.7", + "version": "1.8.3", "source": { "type": "git", "url": "https://github.com/myclabs/php-enum.git", - "reference": "d178027d1e679832db9f38248fcc7200647dc2b7" + "reference": "b942d263c641ddb5190929ff840c68f78713e937" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/php-enum/zipball/d178027d1e679832db9f38248fcc7200647dc2b7", - "reference": "d178027d1e679832db9f38248fcc7200647dc2b7", + "url": "https://api.github.com/repos/myclabs/php-enum/zipball/b942d263c641ddb5190929ff840c68f78713e937", + "reference": "b942d263c641ddb5190929ff840c68f78713e937", "shasum": "" }, "require": { "ext-json": "*", - "php": ">=7.1" + "php": "^7.3 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^7", + "phpunit/phpunit": "^9.5", "squizlabs/php_codesniffer": "1.*", - "vimeo/psalm": "^3.8" + "vimeo/psalm": "^4.6.2" }, "type": "library", "autoload": { @@ -3993,6 +4434,10 @@ "keywords": [ "enum" ], + "support": { + "issues": "https://github.com/myclabs/php-enum/issues", + "source": "https://github.com/myclabs/php-enum/tree/1.8.3" + }, "funding": [ { "url": "https://github.com/mnapoli", @@ -4003,7 +4448,7 @@ "type": "tidelift" } ], - "time": "2020-11-14T18:14:52+00:00" + "time": "2021-07-05T08:18:36+00:00" }, { "name": "nelexa/zip", @@ -4069,26 +4514,31 @@ "zipalign", "ziparchive" ], + "support": { + "issues": "https://github.com/Ne-Lexa/php-zip/issues", + "source": "https://github.com/Ne-Lexa/php-zip/tree/3.3.3" + }, "time": "2020-07-11T21:01:42+00:00" }, { "name": "nesbot/carbon", - "version": "2.42.0", + "version": "2.51.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "d0463779663437392fe42ff339ebc0213bd55498" + "reference": "8619c299d1e0d4b344e1f98ca07a1ce2cfbf1922" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/d0463779663437392fe42ff339ebc0213bd55498", - "reference": "d0463779663437392fe42ff339ebc0213bd55498", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/8619c299d1e0d4b344e1f98ca07a1ce2cfbf1922", + "reference": "8619c299d1e0d4b344e1f98ca07a1ce2cfbf1922", "shasum": "" }, "require": { "ext-json": "*", "php": "^7.1.8 || ^8.0", "symfony/polyfill-mbstring": "^1.0", + "symfony/polyfill-php80": "^1.16", "symfony/translation": "^3.4 || ^4.0 || ^5.0" }, "require-dev": { @@ -4098,7 +4548,7 @@ "phpmd/phpmd": "^2.9", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^0.12.54", - "phpunit/phpunit": "^7.5 || ^8.0", + "phpunit/phpunit": "^7.5.20 || ^8.5.14", "squizlabs/php_codesniffer": "^3.4" }, "bin": [ @@ -4107,8 +4557,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev", - "dev-3.x": "3.x-dev" + "dev-3.x": "3.x-dev", + "dev-master": "2.x-dev" }, "laravel": { "providers": [ @@ -4134,20 +4584,24 @@ { "name": "Brian Nesbitt", "email": "brian@nesbot.com", - "homepage": "http://nesbot.com" + "homepage": "https://markido.com" }, { "name": "kylekatarnls", - "homepage": "http://github.com/kylekatarnls" + "homepage": "https://github.com/kylekatarnls" } ], "description": "An API extension for DateTime that supports 281 different languages.", - "homepage": "http://carbon.nesbot.com", + "homepage": "https://carbon.nesbot.com", "keywords": [ "date", "datetime", "time" ], + "support": { + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" + }, "funding": [ { "url": "https://opencollective.com/Carbon", @@ -4158,20 +4612,20 @@ "type": "tidelift" } ], - "time": "2020-11-28T14:25:28+00:00" + "time": "2021-07-28T13:16:28+00:00" }, { "name": "nikic/php-parser", - "version": "v4.10.3", + "version": "v4.12.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "dbe56d23de8fcb157bbc0cfb3ad7c7de0cfb0984" + "reference": "6608f01670c3cc5079e18c1dab1104e002579143" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dbe56d23de8fcb157bbc0cfb3ad7c7de0cfb0984", - "reference": "dbe56d23de8fcb157bbc0cfb3ad7c7de0cfb0984", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6608f01670c3cc5079e18c1dab1104e002579143", + "reference": "6608f01670c3cc5079e18c1dab1104e002579143", "shasum": "" }, "require": { @@ -4210,20 +4664,24 @@ "parser", "php" ], - "time": "2020-12-03T17:45:45+00:00" + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.12.0" + }, + "time": "2021-07-21T10:44:31+00:00" }, { "name": "njuptaaa/moss", - "version": "1.2.0", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/NJUPTAAA/MOSS.git", - "reference": "68048251a739a05506b6d817ddb0a09ff0e3ec76" + "reference": "e0114d71c9dfb45999eeee3ec004f9356dd552a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/NJUPTAAA/MOSS/zipball/68048251a739a05506b6d817ddb0a09ff0e3ec76", - "reference": "68048251a739a05506b6d817ddb0a09ff0e3ec76", + "url": "https://api.github.com/repos/NJUPTAAA/MOSS/zipball/e0114d71c9dfb45999eeee3ec004f9356dd552a3", + "reference": "e0114d71c9dfb45999eeee3ec004f9356dd552a3", "shasum": "" }, "require": { @@ -4246,7 +4704,11 @@ } ], "description": "Stanford MOSS Interface, for a Measure Of Software Similarity.", - "time": "2019-09-08T08:26:04+00:00" + "support": { + "issues": "https://github.com/NJUPTAAA/MOSS/issues", + "source": "https://github.com/NJUPTAAA/MOSS/tree/1.4.2" + }, + "time": "2021-04-03T06:27:21+00:00" }, { "name": "njuptaaa/poem", @@ -4282,6 +4744,10 @@ } ], "description": "parser for Problem-Oriented Exchangeable Mechanism.", + "support": { + "issues": "https://github.com/NJUPTAAA/POEM_Composer/issues", + "source": "https://github.com/NJUPTAAA/POEM_Composer/tree/master" + }, "time": "2019-10-10T12:19:21+00:00" }, { @@ -4357,10 +4823,10 @@ }, { "name": "npm-asset/clipboard", - "version": "2.0.6", + "version": "2.0.8", "dist": { "type": "tar", - "url": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz" + "url": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz" }, "require": { "npm-asset/good-listener": ">=1.2.2,<2.0.0", @@ -4374,10 +4840,10 @@ }, { "name": "npm-asset/codemirror", - "version": "5.58.3", + "version": "5.62.2", "dist": { "type": "tar", - "url": "https://registry.npmjs.org/codemirror/-/codemirror-5.58.3.tgz" + "url": "https://registry.npmjs.org/codemirror/-/codemirror-5.62.2.tgz" }, "type": "npm-asset", "license": [ @@ -4450,6 +4916,18 @@ "MPL-2.0 OR Apache-2.0" ] }, + { + "name": "npm-asset/fast-plist", + "version": "0.1.2", + "dist": { + "type": "tar", + "url": "https://registry.npmjs.org/fast-plist/-/fast-plist-0.1.2.tgz" + }, + "type": "npm-asset", + "license": [ + "MIT" + ] + }, { "name": "npm-asset/fileicon-svg", "version": "1.0.0", @@ -4491,10 +4969,10 @@ }, { "name": "npm-asset/jquery", - "version": "3.5.1", + "version": "3.6.0", "dist": { "type": "tar", - "url": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz" + "url": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz" }, "type": "npm-asset", "license": [ @@ -4541,16 +5019,16 @@ }, { "name": "npm-asset/lodash", - "version": "4.17.20-patch1", + "version": "4.17.21-patch1", "source": { "type": "git", "url": "https://github.com/lodash/lodash.git", - "reference": "f2e7063ee409ff40a60b14370c58dceee1a2efd4" + "reference": "c6e281b878b315c7a10d90f9c2af4cdb112d9625" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lodash/lodash/zipball/f2e7063ee409ff40a60b14370c58dceee1a2efd4", - "reference": "f2e7063ee409ff40a60b14370c58dceee1a2efd4" + "url": "https://api.github.com/repos/lodash/lodash/zipball/c6e281b878b315c7a10d90f9c2af4cdb112d9625", + "reference": "c6e281b878b315c7a10d90f9c2af4cdb112d9625" }, "type": "npm-asset", "license": [ @@ -4593,12 +5071,39 @@ "MIT" ] }, + { + "name": "npm-asset/monaco-ace-tokenizer", + "version": "0.2.1", + "dist": { + "type": "tar", + "url": "https://registry.npmjs.org/monaco-ace-tokenizer/-/monaco-ace-tokenizer-0.2.1.tgz" + }, + "type": "npm-asset", + "license": [ + "MIT" + ] + }, { "name": "npm-asset/monaco-editor", - "version": "0.17.1", + "version": "0.23.0", "dist": { "type": "tar", - "url": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.17.1.tgz" + "url": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.23.0.tgz" + }, + "type": "npm-asset", + "license": [ + "MIT" + ] + }, + { + "name": "npm-asset/monaco-themes", + "version": "0.3.3", + "dist": { + "type": "tar", + "url": "https://registry.npmjs.org/monaco-themes/-/monaco-themes-0.3.3.tgz" + }, + "require": { + "npm-asset/fast-plist": ">=0.1.2,<0.2.0" }, "type": "npm-asset", "license": [ @@ -4607,10 +5112,10 @@ }, { "name": "npm-asset/pdfobject", - "version": "2.2.3", + "version": "2.2.6", "dist": { "type": "tar", - "url": "https://registry.npmjs.org/pdfobject/-/pdfobject-2.2.3.tgz" + "url": "https://registry.npmjs.org/pdfobject/-/pdfobject-2.2.6.tgz" }, "type": "npm-asset", "license": [ @@ -4619,10 +5124,10 @@ }, { "name": "npm-asset/perfect-scrollbar", - "version": "1.5.0", + "version": "1.5.2", "dist": { "type": "tar", - "url": "https://registry.npmjs.org/perfect-scrollbar/-/perfect-scrollbar-1.5.0.tgz" + "url": "https://registry.npmjs.org/perfect-scrollbar/-/perfect-scrollbar-1.5.2.tgz" }, "type": "npm-asset", "license": [ @@ -4708,16 +5213,16 @@ }, { "name": "nyholm/psr7", - "version": "1.3.2", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/Nyholm/psr7.git", - "reference": "a272953743c454ac4af9626634daaf5ab3ce1173" + "reference": "2212385b47153ea71b1c1b1374f8cb5e4f7892ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Nyholm/psr7/zipball/a272953743c454ac4af9626634daaf5ab3ce1173", - "reference": "a272953743c454ac4af9626634daaf5ab3ce1173", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/2212385b47153ea71b1c1b1374f8cb5e4f7892ec", + "reference": "2212385b47153ea71b1c1b1374f8cb5e4f7892ec", "shasum": "" }, "require": { @@ -4731,7 +5236,7 @@ "psr/http-message-implementation": "1.0" }, "require-dev": { - "http-interop/http-factory-tests": "^0.8", + "http-interop/http-factory-tests": "^0.9", "php-http/psr7-integration-tests": "^1.0", "phpunit/phpunit": "^7.5 || 8.5 || 9.4", "symfony/error-handler": "^4.4" @@ -4739,7 +5244,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -4767,6 +5272,10 @@ "psr-17", "psr-7" ], + "support": { + "issues": "https://github.com/Nyholm/psr7/issues", + "source": "https://github.com/Nyholm/psr7/tree/1.4.1" + }, "funding": [ { "url": "https://github.com/Zegnat", @@ -4777,7 +5286,7 @@ "type": "github" } ], - "time": "2020-11-14T17:35:34+00:00" + "time": "2021-07-02T08:32:20+00:00" }, { "name": "oomphinc/composer-installers-extender", @@ -4830,20 +5339,24 @@ ], "description": "Extend the composer/installers plugin to accept any arbitrary package type.", "homepage": "http://www.oomphinc.com/", + "support": { + "issues": "https://github.com/oomphinc/composer-installers-extender/issues", + "source": "https://github.com/oomphinc/composer-installers-extender/tree/2.0.0" + }, "time": "2020-08-11T21:06:11+00:00" }, { "name": "opis/closure", - "version": "3.6.1", + "version": "3.6.2", "source": { "type": "git", "url": "https://github.com/opis/closure.git", - "reference": "943b5d70cc5ae7483f6aff6ff43d7e34592ca0f5" + "reference": "06e2ebd25f2869e54a306dda991f7db58066f7f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opis/closure/zipball/943b5d70cc5ae7483f6aff6ff43d7e34592ca0f5", - "reference": "943b5d70cc5ae7483f6aff6ff43d7e34592ca0f5", + "url": "https://api.github.com/repos/opis/closure/zipball/06e2ebd25f2869e54a306dda991f7db58066f7f6", + "reference": "06e2ebd25f2869e54a306dda991f7db58066f7f6", "shasum": "" }, "require": { @@ -4891,7 +5404,11 @@ "serialization", "serialize" ], - "time": "2020-11-07T02:01:34+00:00" + "support": { + "issues": "https://github.com/opis/closure/issues", + "source": "https://github.com/opis/closure/tree/3.6.2" + }, + "time": "2021-04-09T13:42:10+00:00" }, { "name": "orangehill/iseed", @@ -4950,24 +5467,28 @@ "laravel", "seed" ], + "support": { + "issues": "https://github.com/orangehill/iseed/issues", + "source": "https://github.com/orangehill/iseed/tree/v2.6.4" + }, "time": "2020-09-10T06:25:21+00:00" }, { "name": "paragonie/random_compat", - "version": "v9.99.99", + "version": "v9.99.100", "source": { "type": "git", "url": "https://github.com/paragonie/random_compat.git", - "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", - "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", "shasum": "" }, "require": { - "php": "^7" + "php": ">= 7" }, "require-dev": { "phpunit/phpunit": "4.*|5.*", @@ -4995,7 +5516,12 @@ "pseudorandom", "random" ], - "time": "2018-07-02T15:55:56+00:00" + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" }, { "name": "phar-io/version", @@ -5042,6 +5568,10 @@ } ], "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/master" + }, "time": "2018-07-08T19:19:57+00:00" }, { @@ -5079,6 +5609,10 @@ ], "description": "A library to read, parse, export and make subsets of different types of font files.", "homepage": "https://github.com/PhenX/php-font-lib", + "support": { + "issues": "https://github.com/PhenX/php-font-lib/issues", + "source": "https://github.com/PhenX/php-font-lib/tree/0.5.2" + }, "time": "2020-03-08T15:31:32+00:00" }, { @@ -5119,6 +5653,10 @@ ], "description": "A library to read, parse and export to PDF SVG files.", "homepage": "https://github.com/PhenX/php-svg-lib", + "support": { + "issues": "https://github.com/PhenX/php-svg-lib/issues", + "source": "https://github.com/PhenX/php-svg-lib/tree/master" + }, "time": "2019-09-11T20:02:13+00:00" }, { @@ -5169,20 +5707,24 @@ "stream", "uri" ], + "support": { + "issues": "https://github.com/php-http/message-factory/issues", + "source": "https://github.com/php-http/message-factory/tree/master" + }, "time": "2015-12-19T14:08:53+00:00" }, { "name": "phpoffice/phpspreadsheet", - "version": "1.15.0", + "version": "1.18.0", "source": { "type": "git", "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "a8e8068b31b8119e1daa5b1eb5715a3a8ea8305f" + "reference": "418cd304e8e6b417ea79c3b29126a25dc4b1170c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/a8e8068b31b8119e1daa5b1eb5715a3a8ea8305f", - "reference": "a8e8068b31b8119e1daa5b1eb5715a3a8ea8305f", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/418cd304e8e6b417ea79c3b29126a25dc4b1170c", + "reference": "418cd304e8e6b417ea79c3b29126a25dc4b1170c", "shasum": "" }, "require": { @@ -5199,21 +5741,25 @@ "ext-xmlwriter": "*", "ext-zip": "*", "ext-zlib": "*", + "ezyang/htmlpurifier": "^4.13", "maennchen/zipstream-php": "^2.1", - "markbaker/complex": "^1.5|^2.0", - "markbaker/matrix": "^1.2|^2.0", - "php": "^7.2|^8.0", + "markbaker/complex": "^2.0", + "markbaker/matrix": "^2.0", + "php": "^7.2 || ^8.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", "psr/simple-cache": "^1.0" }, "require-dev": { - "dompdf/dompdf": "^0.8.5", - "friendsofphp/php-cs-fixer": "^2.16", + "dealerdirect/phpcodesniffer-composer-installer": "dev-master", + "dompdf/dompdf": "^1.0", + "friendsofphp/php-cs-fixer": "^2.18", "jpgraph/jpgraph": "^4.0", "mpdf/mpdf": "^8.0", "phpcompatibility/php-compatibility": "^9.3", - "phpunit/phpunit": "^8.5|^9.3", + "phpstan/phpstan": "^0.12.82", + "phpstan/phpstan-phpunit": "^0.12.18", + "phpunit/phpunit": "^8.5", "squizlabs/php_codesniffer": "^3.5", "tecnickcom/tcpdf": "^6.3" }, @@ -5265,7 +5811,11 @@ "xls", "xlsx" ], - "time": "2020-10-11T13:20:59+00:00" + "support": { + "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.18.0" + }, + "time": "2021-05-31T18:21:15+00:00" }, { "name": "phpoption/phpoption", @@ -5320,6 +5870,10 @@ "php", "type" ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.7.5" + }, "funding": [ { "url": "https://github.com/GrahamCampbell", @@ -5334,16 +5888,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.29", + "version": "2.0.32", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "497856a8d997f640b4a516062f84228a772a48a8" + "reference": "f5c4c19880d45d0be3e7d24ae8ac434844a898cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/497856a8d997f640b4a516062f84228a772a48a8", - "reference": "497856a8d997f640b4a516062f84228a772a48a8", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/f5c4c19880d45d0be3e7d24ae8ac434844a898cd", + "reference": "f5c4c19880d45d0be3e7d24ae8ac434844a898cd", "shasum": "" }, "require": { @@ -5351,7 +5905,7 @@ }, "require-dev": { "phing/phing": "~2.7", - "phpunit/phpunit": "^4.8.35|^5.7|^6.0", + "phpunit/phpunit": "^4.8.35|^5.7|^6.0|^9.4", "squizlabs/php_codesniffer": "~2.0" }, "suggest": { @@ -5421,6 +5975,10 @@ "x.509", "x509" ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/2.0.32" + }, "funding": [ { "url": "https://github.com/terrafrost", @@ -5435,27 +5993,26 @@ "type": "tidelift" } ], - "time": "2020-09-08T04:24:43+00:00" + "time": "2021-06-12T12:12:59+00:00" }, { "name": "predis/predis", - "version": "v1.1.6", + "version": "v1.1.7", "source": { "type": "git", "url": "https://github.com/predis/predis.git", - "reference": "9930e933c67446962997b05201c69c2319bf26de" + "reference": "b240daa106d4e02f0c5b7079b41e31ddf66fddf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/predis/predis/zipball/9930e933c67446962997b05201c69c2319bf26de", - "reference": "9930e933c67446962997b05201c69c2319bf26de", + "url": "https://api.github.com/repos/predis/predis/zipball/b240daa106d4e02f0c5b7079b41e31ddf66fddf8", + "reference": "b240daa106d4e02f0c5b7079b41e31ddf66fddf8", "shasum": "" }, "require": { "php": ">=5.3.9" }, "require-dev": { - "cweagans/composer-patches": "^1.6", "phpunit/phpunit": "~4.8" }, "suggest": { @@ -5463,18 +6020,6 @@ "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol" }, "type": "library", - "extra": { - "composer-exit-on-patch-failure": true, - "patches": { - "phpunit/phpunit-mock-objects": { - "Fix PHP 7 and 8 compatibility": "./tests/phpunit_mock_objects.patch" - }, - "phpunit/phpunit": { - "Fix PHP 7 compatibility": "./tests/phpunit_php7.patch", - "Fix PHP 8 compatibility": "./tests/phpunit_php8.patch" - } - } - }, "autoload": { "psr-4": { "Predis\\": "src/" @@ -5504,37 +6049,36 @@ "predis", "redis" ], + "support": { + "issues": "https://github.com/predis/predis/issues", + "source": "https://github.com/predis/predis/tree/v1.1.7" + }, "funding": [ { "url": "https://github.com/sponsors/tillkruss", "type": "github" } ], - "time": "2020-09-11T19:18:05+00:00" + "time": "2021-04-04T19:34:46+00:00" }, { "name": "psr/container", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.2.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -5547,7 +6091,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", @@ -5559,7 +6103,11 @@ "container-interop", "psr" ], - "time": "2017-02-14T16:28:37+00:00" + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.1" + }, + "time": "2021-03-05T17:36:06+00:00" }, { "name": "psr/http-client", @@ -5608,6 +6156,9 @@ "psr", "psr-18" ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/master" + }, "time": "2020-06-29T06:28:15+00:00" }, { @@ -5660,6 +6211,9 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/master" + }, "time": "2019-04-30T12:38:16+00:00" }, { @@ -5710,20 +6264,23 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, "time": "2016-08-06T14:39:51+00:00" }, { "name": "psr/log", - "version": "1.1.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", - "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", "shasum": "" }, "require": { @@ -5747,7 +6304,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for logging libraries", @@ -5757,7 +6314,10 @@ "psr", "psr-3" ], - "time": "2020-03-23T09:12:05+00:00" + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" }, { "name": "psr/simple-cache", @@ -5805,6 +6365,9 @@ "psr-16", "simple-cache" ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/master" + }, "time": "2017-10-23T01:57:42+00:00" }, { @@ -5879,6 +6442,10 @@ "interactive", "shell" ], + "support": { + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.9.12" + }, "time": "2019-12-06T14:19:43+00:00" }, { @@ -5919,25 +6486,29 @@ } ], "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, "time": "2019-03-08T08:55:37+00:00" }, { "name": "ramsey/uuid", - "version": "3.9.3", + "version": "3.9.4", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "7e1633a6964b48589b142d60542f9ed31bd37a92" + "reference": "be2451bef8147b7352a28fb4cddb08adc497ada3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/7e1633a6964b48589b142d60542f9ed31bd37a92", - "reference": "7e1633a6964b48589b142d60542f9ed31bd37a92", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/be2451bef8147b7352a28fb4cddb08adc497ada3", + "reference": "be2451bef8147b7352a28fb4cddb08adc497ada3", "shasum": "" }, "require": { "ext-json": "*", - "paragonie/random_compat": "^1 | ^2 | 9.99.99", + "paragonie/random_compat": "^1 | ^2 | ^9.99.99", "php": "^5.4 | ^7 | ^8", "symfony/polyfill-ctype": "^1.8" }, @@ -6006,27 +6577,50 @@ "identifier", "uuid" ], - "time": "2020-02-21T04:36:14+00:00" + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "rss": "https://github.com/ramsey/uuid/releases.atom", + "source": "https://github.com/ramsey/uuid", + "wiki": "https://github.com/ramsey/uuid/wiki" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" + } + ], + "time": "2021-08-06T20:32:15+00:00" }, { "name": "rmccue/requests", - "version": "v1.7.0", + "version": "v1.8.1", "source": { "type": "git", - "url": "https://github.com/rmccue/Requests.git", - "reference": "87932f52ffad70504d93f04f15690cf16a089546" + "url": "https://github.com/WordPress/Requests.git", + "reference": "82e6936366eac3af4d836c18b9d8c31028fe4cd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rmccue/Requests/zipball/87932f52ffad70504d93f04f15690cf16a089546", - "reference": "87932f52ffad70504d93f04f15690cf16a089546", + "url": "https://api.github.com/repos/WordPress/Requests/zipball/82e6936366eac3af4d836c18b9d8c31028fe4cd5", + "reference": "82e6936366eac3af4d836c18b9d8c31028fe4cd5", "shasum": "" }, "require": { "php": ">=5.2" }, "require-dev": { - "requests/test-server": "dev-master" + "dealerdirect/phpcodesniffer-composer-installer": "^0.7", + "php-parallel-lint/php-console-highlighter": "^0.5.0", + "php-parallel-lint/php-parallel-lint": "^1.3", + "phpcompatibility/php-compatibility": "^9.0", + "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5", + "requests/test-server": "dev-master", + "squizlabs/php_codesniffer": "^3.5", + "wp-coding-standards/wpcs": "^2.0" }, "type": "library", "autoload": { @@ -6045,7 +6639,7 @@ } ], "description": "A HTTP library written in PHP, for human beings.", - "homepage": "http://github.com/rmccue/Requests", + "homepage": "http://github.com/WordPress/Requests", "keywords": [ "curl", "fsockopen", @@ -6055,7 +6649,11 @@ "iri", "sockets" ], - "time": "2016-10-13T00:11:37+00:00" + "support": { + "issues": "https://github.com/WordPress/Requests/issues", + "source": "https://github.com/WordPress/Requests/tree/v1.8.1" + }, + "time": "2021-06-04T09:56:25+00:00" }, { "name": "sabberworm/php-css-parser", @@ -6100,6 +6698,10 @@ "parser", "stylesheet" ], + "support": { + "issues": "https://github.com/sabberworm/PHP-CSS-Parser/issues", + "source": "https://github.com/sabberworm/PHP-CSS-Parser/tree/8.3.1" + }, "time": "2020-06-01T09:10:00+00:00" }, { @@ -6143,20 +6745,132 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/master" + }, "time": "2016-10-03T07:35:21+00:00" }, + { + "name": "socialiteproviders/github", + "version": "4.1.0", + "source": { + "type": "git", + "url": "https://github.com/SocialiteProviders/GitHub.git", + "reference": "25fc481721d74b829b43bff3519e7103d5339e19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SocialiteProviders/GitHub/zipball/25fc481721d74b829b43bff3519e7103d5339e19", + "reference": "25fc481721d74b829b43bff3519e7103d5339e19", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.2 || ^8.0", + "socialiteproviders/manager": "~4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "SocialiteProviders\\GitHub\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anton Komarev", + "email": "ell@cybercog.su" + } + ], + "description": "GitHub OAuth2 Provider for Laravel Socialite", + "support": { + "source": "https://github.com/SocialiteProviders/GitHub/tree/4.1.0" + }, + "time": "2020-12-01T23:10:59+00:00" + }, + { + "name": "socialiteproviders/manager", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/SocialiteProviders/Manager.git", + "reference": "0f5e82af0404df0080bdc5c105cef936c1711524" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SocialiteProviders/Manager/zipball/0f5e82af0404df0080bdc5c105cef936c1711524", + "reference": "0f5e82af0404df0080bdc5c105cef936c1711524", + "shasum": "" + }, + "require": { + "illuminate/support": "^6.0|^7.0|^8.0", + "laravel/socialite": "~4.0|~5.0", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.2", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "SocialiteProviders\\Manager\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "SocialiteProviders\\Manager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andy Wendt", + "email": "andy@awendt.com" + }, + { + "name": "Anton Komarev", + "email": "a.komarev@cybercog.su" + }, + { + "name": "Miguel Piedrafita", + "email": "soy@miguelpiedrafita.com" + }, + { + "name": "atymic", + "email": "atymicq@gmail.com", + "homepage": "https://atymic.dev" + } + ], + "description": "Easily add new or override built-in providers in Laravel Socialite.", + "homepage": "https://socialiteproviders.com/", + "support": { + "issues": "https://github.com/SocialiteProviders/Manager/issues", + "source": "https://github.com/SocialiteProviders/Manager/tree/4.0.1" + }, + "time": "2020-12-01T23:09:06+00:00" + }, { "name": "spatie/db-dumper", - "version": "2.18.0", + "version": "2.21.1", "source": { "type": "git", "url": "https://github.com/spatie/db-dumper.git", - "reference": "eddb2b7c6877817d97bbdc1c60d1a800bf5a267a" + "reference": "05e5955fb882008a8947c5a45146d86cfafa10d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/db-dumper/zipball/eddb2b7c6877817d97bbdc1c60d1a800bf5a267a", - "reference": "eddb2b7c6877817d97bbdc1c60d1a800bf5a267a", + "url": "https://api.github.com/repos/spatie/db-dumper/zipball/05e5955fb882008a8947c5a45146d86cfafa10d1", + "reference": "05e5955fb882008a8947c5a45146d86cfafa10d1", "shasum": "" }, "require": { @@ -6193,29 +6907,34 @@ "mysqldump", "spatie" ], + "support": { + "issues": "https://github.com/spatie/db-dumper/issues", + "source": "https://github.com/spatie/db-dumper/tree/2.21.1" + }, "funding": [ { "url": "https://github.com/spatie", "type": "github" } ], - "time": "2020-11-10T09:20:18+00:00" + "time": "2021-02-24T14:56:42+00:00" }, { "name": "spatie/laravel-backup", - "version": "6.13.1", + "version": "6.16.1", "source": { "type": "git", "url": "https://github.com/spatie/laravel-backup.git", - "reference": "a0ca6662fbc3d008fe9e17b0f74101d139aca6f1" + "reference": "11a3fdb6938566ba75f3dd9ab790319d5e90b0fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-backup/zipball/a0ca6662fbc3d008fe9e17b0f74101d139aca6f1", - "reference": "a0ca6662fbc3d008fe9e17b0f74101d139aca6f1", + "url": "https://api.github.com/repos/spatie/laravel-backup/zipball/11a3fdb6938566ba75f3dd9ab790319d5e90b0fc", + "reference": "11a3fdb6938566ba75f3dd9ab790319d5e90b0fc", "shasum": "" }, "require": { + "ext-zip": "^1.14.0", "illuminate/console": "^6.0|^7.0|^8.0", "illuminate/contracts": "^6.0|^7.0|^8.0", "illuminate/events": "^6.0|^7.0|^8.0", @@ -6274,6 +6993,10 @@ "laravel-backup", "spatie" ], + "support": { + "issues": "https://github.com/spatie/laravel-backup/issues", + "source": "https://github.com/spatie/laravel-backup/tree/6.16.1" + }, "funding": [ { "url": "https://github.com/sponsors/spatie", @@ -6284,7 +7007,7 @@ "type": "other" } ], - "time": "2020-12-01T07:29:53+00:00" + "time": "2021-07-10T14:54:21+00:00" }, { "name": "spatie/temporary-directory", @@ -6331,24 +7054,28 @@ "spatie", "temporary-directory" ], + "support": { + "issues": "https://github.com/spatie/temporary-directory/issues", + "source": "https://github.com/spatie/temporary-directory/tree/1.3.0" + }, "time": "2020-11-09T15:54:21+00:00" }, { "name": "swiftmailer/swiftmailer", - "version": "v6.2.4", + "version": "v6.2.7", "source": { "type": "git", "url": "https://github.com/swiftmailer/swiftmailer.git", - "reference": "56f0ab23f54c4ccbb0d5dcc67ff8552e0c98d59e" + "reference": "15f7faf8508e04471f666633addacf54c0ab5933" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/56f0ab23f54c4ccbb0d5dcc67ff8552e0c98d59e", - "reference": "56f0ab23f54c4ccbb0d5dcc67ff8552e0c98d59e", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/15f7faf8508e04471f666633addacf54c0ab5933", + "reference": "15f7faf8508e04471f666633addacf54c0ab5933", "shasum": "" }, "require": { - "egulias/email-validator": "^2.0", + "egulias/email-validator": "^2.0|^3.1", "php": ">=7.0.0", "symfony/polyfill-iconv": "^1.0", "symfony/polyfill-intl-idn": "^1.10", @@ -6392,6 +7119,10 @@ "mail", "mailer" ], + "support": { + "issues": "https://github.com/swiftmailer/swiftmailer/issues", + "source": "https://github.com/swiftmailer/swiftmailer/tree/v6.2.7" + }, "funding": [ { "url": "https://github.com/fabpot", @@ -6402,40 +7133,41 @@ "type": "tidelift" } ], - "time": "2020-12-08T18:02:06+00:00" + "time": "2021-03-09T12:30:35+00:00" }, { "name": "symfony/console", - "version": "v4.4.17", + "version": "v4.4.29", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "c8e37f6928c19816437a4dd7bf16e3bd79941470" + "reference": "8baf0bbcfddfde7d7225ae8e04705cfd1081cd7b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/c8e37f6928c19816437a4dd7bf16e3bd79941470", - "reference": "c8e37f6928c19816437a4dd7bf16e3bd79941470", + "url": "https://api.github.com/repos/symfony/console/zipball/8baf0bbcfddfde7d7225ae8e04705cfd1081cd7b", + "reference": "8baf0bbcfddfde7d7225ae8e04705cfd1081cd7b", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/service-contracts": "^1.1|^2" }, "conflict": { + "psr/log": ">=3", "symfony/dependency-injection": "<3.4", "symfony/event-dispatcher": "<4.3|>=5", "symfony/lock": "<4.4", "symfony/process": "<3.3" }, "provide": { - "psr/log-implementation": "1.0" + "psr/log-implementation": "1.0|2.0" }, "require-dev": { - "psr/log": "~1.0", + "psr/log": "^1|^2", "symfony/config": "^3.4|^4.0|^5.0", "symfony/dependency-injection": "^3.4|^4.0|^5.0", "symfony/event-dispatcher": "^4.3", @@ -6472,8 +7204,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Console Component", + "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/console/tree/v4.4.29" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6488,24 +7223,25 @@ "type": "tidelift" } ], - "time": "2020-11-28T10:15:42+00:00" + "time": "2021-07-27T19:04:53+00:00" }, { "name": "symfony/css-selector", - "version": "v5.2.0", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "b8d8eb06b0942e84a69e7acebc3e9c1e6e6e7256" + "reference": "7fb120adc7f600a59027775b224c13a33530dd90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/b8d8eb06b0942e84a69e7acebc3e9c1e6e6e7256", - "reference": "b8d8eb06b0942e84a69e7acebc3e9c1e6e6e7256", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/7fb120adc7f600a59027775b224c13a33530dd90", + "reference": "7fb120adc7f600a59027775b224c13a33530dd90", "shasum": "" }, "require": { - "php": ">=7.2.5" + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -6534,8 +7270,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony CssSelector Component", + "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v5.3.4" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6550,26 +7289,25 @@ "type": "tidelift" } ], - "time": "2020-10-28T21:31:18+00:00" + "time": "2021-07-21T12:38:00+00:00" }, { "name": "symfony/debug", - "version": "v4.4.17", + "version": "v4.4.27", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "65fe7b49868378319b82da3035fb30801b931c47" + "reference": "2f9160e92eb64c95da7368c867b663a8e34e980c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/65fe7b49868378319b82da3035fb30801b931c47", - "reference": "65fe7b49868378319b82da3035fb30801b931c47", + "url": "https://api.github.com/repos/symfony/debug/zipball/2f9160e92eb64c95da7368c867b663a8e34e980c", + "reference": "2f9160e92eb64c95da7368c867b663a8e34e980c", "shasum": "" }, "require": { "php": ">=7.1.3", - "psr/log": "~1.0", - "symfony/polyfill-php80": "^1.15" + "psr/log": "^1|^2|^3" }, "conflict": { "symfony/http-kernel": "<3.4" @@ -6600,8 +7338,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Debug Component", + "description": "Provides tools to ease debugging PHP code", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/debug/tree/v4.4.27" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6616,20 +7357,20 @@ "type": "tidelift" } ], - "time": "2020-10-28T20:42:29+00:00" + "time": "2021-07-22T07:21:39+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.2.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" + "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", - "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627", + "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627", "shasum": "" }, "require": { @@ -6638,7 +7379,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-main": "2.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -6666,6 +7407,9 @@ ], "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6680,27 +7424,28 @@ "type": "tidelift" } ], - "time": "2020-09-07T11:33:47+00:00" + "time": "2021-03-23T23:28:01+00:00" }, { "name": "symfony/dom-crawler", - "version": "v5.2.0", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "0969122fe144dd8ab2e8c98c7e03eedc621b368c" + "reference": "2dd8890bd01be59a5221999c05ccf0fcafcb354f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/0969122fe144dd8ab2e8c98c7e03eedc621b368c", - "reference": "0969122fe144dd8ab2e8c98c7e03eedc621b368c", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/2dd8890bd01be59a5221999c05ccf0fcafcb354f", + "reference": "2dd8890bd01be59a5221999c05ccf0fcafcb354f", "shasum": "" }, "require": { "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "conflict": { "masterminds/html5": "<2.6" @@ -6735,8 +7480,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony DomCrawler Component", + "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dom-crawler/tree/v5.3.4" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6751,27 +7499,26 @@ "type": "tidelift" } ], - "time": "2020-10-24T12:01:57+00:00" + "time": "2021-07-23T15:55:36+00:00" }, { "name": "symfony/error-handler", - "version": "v4.4.17", + "version": "v4.4.27", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "b0887cf8fc692eef2a4cf11cee3c5f5eb93fcfdf" + "reference": "16ac2be1c0f49d6d9eb9d3ce9324bde268717905" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/b0887cf8fc692eef2a4cf11cee3c5f5eb93fcfdf", - "reference": "b0887cf8fc692eef2a4cf11cee3c5f5eb93fcfdf", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/16ac2be1c0f49d6d9eb9d3ce9324bde268717905", + "reference": "16ac2be1c0f49d6d9eb9d3ce9324bde268717905", "shasum": "" }, "require": { "php": ">=7.1.3", - "psr/log": "~1.0", + "psr/log": "^1|^2|^3", "symfony/debug": "^4.4.5", - "symfony/polyfill-php80": "^1.15", "symfony/var-dumper": "^4.4|^5.0" }, "require-dev": { @@ -6801,8 +7548,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony ErrorHandler Component", + "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v4.4.27" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6817,25 +7567,26 @@ "type": "tidelift" } ], - "time": "2020-10-28T20:42:29+00:00" + "time": "2021-07-23T15:41:52+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.4.17", + "version": "v4.4.27", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "f029d6f21eac61ab23198e7aca40e7638e8c8924" + "reference": "958a128b184fcf0ba45ec90c0e88554c9327c2e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f029d6f21eac61ab23198e7aca40e7638e8c8924", - "reference": "f029d6f21eac61ab23198e7aca40e7638e8c8924", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/958a128b184fcf0ba45ec90c0e88554c9327c2e9", + "reference": "958a128b184fcf0ba45ec90c0e88554c9327c2e9", "shasum": "" }, "require": { "php": ">=7.1.3", - "symfony/event-dispatcher-contracts": "^1.1" + "symfony/event-dispatcher-contracts": "^1.1", + "symfony/polyfill-php80": "^1.16" }, "conflict": { "symfony/dependency-injection": "<3.4" @@ -6845,7 +7596,7 @@ "symfony/event-dispatcher-implementation": "1.1" }, "require-dev": { - "psr/log": "~1.0", + "psr/log": "^1|^2|^3", "symfony/config": "^3.4|^4.0|^5.0", "symfony/dependency-injection": "^3.4|^4.0|^5.0", "symfony/error-handler": "~3.4|~4.4", @@ -6881,8 +7632,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony EventDispatcher Component", + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v4.4.27" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6897,7 +7651,7 @@ "type": "tidelift" } ], - "time": "2020-10-31T22:44:29+00:00" + "time": "2021-07-23T15:41:52+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -6959,6 +7713,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v1.1.9" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6977,20 +7734,21 @@ }, { "name": "symfony/finder", - "version": "v4.4.17", + "version": "v4.4.27", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "9f1d1d883b79a91ef320c0c6e803494e042ef36e" + "reference": "42414d7ac96fc2880a783b872185789dea0d4262" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/9f1d1d883b79a91ef320c0c6e803494e042ef36e", - "reference": "9f1d1d883b79a91ef320c0c6e803494e042ef36e", + "url": "https://api.github.com/repos/symfony/finder/zipball/42414d7ac96fc2880a783b872185789dea0d4262", + "reference": "42414d7ac96fc2880a783b872185789dea0d4262", "shasum": "" }, "require": { - "php": ">=7.1.3" + "php": ">=7.1.3", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -7015,8 +7773,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Finder Component", + "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v4.4.27" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -7031,20 +7792,20 @@ "type": "tidelift" } ], - "time": "2020-11-17T19:45:34+00:00" + "time": "2021-07-23T15:41:52+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v2.3.1", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "41db680a15018f9c1d4b23516059633ce280ca33" + "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/41db680a15018f9c1d4b23516059633ce280ca33", - "reference": "41db680a15018f9c1d4b23516059633ce280ca33", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/7e82f6084d7cae521a75ef2cb5c9457bbda785f4", + "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4", "shasum": "" }, "require": { @@ -7055,9 +7816,8 @@ }, "type": "library", "extra": { - "branch-version": "2.3", "branch-alias": { - "dev-main": "2.3-dev" + "dev-main": "2.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -7093,6 +7853,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v2.4.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -7107,26 +7870,27 @@ "type": "tidelift" } ], - "time": "2020-10-14T17:08:19+00:00" + "time": "2021-04-11T23:07:08+00:00" }, { "name": "symfony/http-foundation", - "version": "v4.4.17", + "version": "v4.4.29", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "9eeb37ec0ff3049c782ca67041648e28ddd75a94" + "reference": "7016057b01f0ed3ec3ba1f31a580b6661667c2e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9eeb37ec0ff3049c782ca67041648e28ddd75a94", - "reference": "9eeb37ec0ff3049c782ca67041648e28ddd75a94", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/7016057b01f0ed3ec3ba1f31a580b6661667c2e1", + "reference": "7016057b01f0ed3ec3ba1f31a580b6661667c2e1", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/mime": "^4.3|^5.0", - "symfony/polyfill-mbstring": "~1.1" + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php80": "^1.16" }, "require-dev": { "predis/predis": "~1.0", @@ -7155,8 +7919,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony HttpFoundation Component", + "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v4.4.29" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -7171,32 +7938,32 @@ "type": "tidelift" } ], - "time": "2020-11-03T11:58:18+00:00" + "time": "2021-07-27T14:32:23+00:00" }, { "name": "symfony/http-kernel", - "version": "v4.4.17", + "version": "v4.4.29", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "9f5605ee05406d8afa40dc4f2954c6a61de3a984" + "reference": "752b170e1ba0dd4104e7fa17c1cef1ec8a7fc506" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/9f5605ee05406d8afa40dc4f2954c6a61de3a984", - "reference": "9f5605ee05406d8afa40dc4f2954c6a61de3a984", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/752b170e1ba0dd4104e7fa17c1cef1ec8a7fc506", + "reference": "752b170e1ba0dd4104e7fa17c1cef1ec8a7fc506", "shasum": "" }, "require": { "php": ">=7.1.3", - "psr/log": "~1.0", + "psr/log": "^1|^2", "symfony/error-handler": "^4.4", "symfony/event-dispatcher": "^4.4", "symfony/http-client-contracts": "^1.1|^2", "symfony/http-foundation": "^4.4|^5.0", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "conflict": { "symfony/browser-kit": "<4.3", @@ -7204,13 +7971,13 @@ "symfony/console": ">=5", "symfony/dependency-injection": "<4.3", "symfony/translation": "<4.2", - "twig/twig": "<1.34|<2.4,>=2" + "twig/twig": "<1.43|<2.13,>=2" }, "provide": { - "psr/log-implementation": "1.0" + "psr/log-implementation": "1.0|2.0" }, "require-dev": { - "psr/cache": "~1.0", + "psr/cache": "^1.0|^2.0|^3.0", "symfony/browser-kit": "^4.3|^5.0", "symfony/config": "^3.4|^4.0|^5.0", "symfony/console": "^3.4|^4.0", @@ -7225,7 +7992,7 @@ "symfony/templating": "^3.4|^4.0|^5.0", "symfony/translation": "^4.2|^5.0", "symfony/translation-contracts": "^1.1|^2", - "twig/twig": "^1.34|^2.4|^3.0" + "twig/twig": "^1.43|^2.13|^3.0.4" }, "suggest": { "symfony/browser-kit": "", @@ -7256,8 +8023,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony HttpKernel Component", + "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v4.4.29" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -7272,20 +8042,20 @@ "type": "tidelift" } ], - "time": "2020-11-29T09:23:08+00:00" + "time": "2021-07-29T06:45:05+00:00" }, { "name": "symfony/mime", - "version": "v5.2.0", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "05f667e8fa029568964fd3bec6bc17765b853cc5" + "reference": "633e4e8afe9e529e5599d71238849a4218dd497b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/05f667e8fa029568964fd3bec6bc17765b853cc5", - "reference": "05f667e8fa029568964fd3bec6bc17765b853cc5", + "url": "https://api.github.com/repos/symfony/mime/zipball/633e4e8afe9e529e5599d71238849a4218dd497b", + "reference": "633e4e8afe9e529e5599d71238849a4218dd497b", "shasum": "" }, "require": { @@ -7293,13 +8063,16 @@ "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", "symfony/mailer": "<4.4" }, "require-dev": { - "egulias/email-validator": "^2.1.10", + "egulias/email-validator": "^2.1.10|^3.1", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", "symfony/dependency-injection": "^4.4|^5.0", "symfony/property-access": "^4.4|^5.1", @@ -7329,12 +8102,15 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "A library to manipulate MIME messages", + "description": "Allows manipulating MIME messages", "homepage": "https://symfony.com", "keywords": [ "mime", "mime-type" ], + "support": { + "source": "https://github.com/symfony/mime/tree/v5.3.4" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -7349,20 +8125,20 @@ "type": "tidelift" } ], - "time": "2020-10-30T14:55:39+00:00" + "time": "2021-07-21T12:40:44+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.20.0", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", "shasum": "" }, "require": { @@ -7374,7 +8150,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7411,6 +8187,9 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -7425,20 +8204,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-iconv", - "version": "v1.20.0", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "c536646fdb4f29104dd26effc2fdcb9a5b085024" + "reference": "63b5bb7db83e5673936d6e3b8b3e022ff6474933" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/c536646fdb4f29104dd26effc2fdcb9a5b085024", - "reference": "c536646fdb4f29104dd26effc2fdcb9a5b085024", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/63b5bb7db83e5673936d6e3b8b3e022ff6474933", + "reference": "63b5bb7db83e5673936d6e3b8b3e022ff6474933", "shasum": "" }, "require": { @@ -7450,7 +8229,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7488,6 +8267,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.23.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -7502,20 +8284,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-05-27T09:27:20+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.20.0", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "3b75acd829741c768bc8b1f84eb33265e7cc5117" + "reference": "65bd267525e82759e7d8c4e8ceea44f398838e65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/3b75acd829741c768bc8b1f84eb33265e7cc5117", - "reference": "3b75acd829741c768bc8b1f84eb33265e7cc5117", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/65bd267525e82759e7d8c4e8ceea44f398838e65", + "reference": "65bd267525e82759e7d8c4e8ceea44f398838e65", "shasum": "" }, "require": { @@ -7529,7 +8311,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7572,6 +8354,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.23.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -7586,20 +8371,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-05-27T09:27:20+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.20.0", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "727d1096295d807c309fb01a851577302394c897" + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/727d1096295d807c309fb01a851577302394c897", - "reference": "727d1096295d807c309fb01a851577302394c897", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", "shasum": "" }, "require": { @@ -7611,7 +8396,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7653,6 +8438,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.23.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -7667,20 +8455,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.20.0", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", "shasum": "" }, "require": { @@ -7692,7 +8480,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7730,6 +8518,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -7744,20 +8535,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-05-27T12:26:48+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.20.0", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930" + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cede45fcdfabdd6043b3592e83678e42ec69e930", - "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", "shasum": "" }, "require": { @@ -7766,7 +8557,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7803,6 +8594,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.23.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -7817,20 +8611,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-05-27T09:17:38+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.20.0", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed" + "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/8ff431c517be11c78c48a39a66d37431e26a6bed", - "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fba8933c384d6476ab14fb7b8526e5287ca7e010", + "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010", "shasum": "" }, "require": { @@ -7839,7 +8633,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7879,6 +8673,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.23.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -7893,20 +8690,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.20.0", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de" + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de", - "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", "shasum": "" }, "require": { @@ -7915,7 +8712,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -7959,6 +8756,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -7973,24 +8773,25 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-07-28T13:41:28+00:00" }, { "name": "symfony/process", - "version": "v4.4.17", + "version": "v4.4.27", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "ec1482f13d53911a8a32e54ba6f9a3b43a57d943" + "reference": "0b7dc5599ac4aa6d7b936c8f7d10abae64f6cf7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/ec1482f13d53911a8a32e54ba6f9a3b43a57d943", - "reference": "ec1482f13d53911a8a32e54ba6f9a3b43a57d943", + "url": "https://api.github.com/repos/symfony/process/zipball/0b7dc5599ac4aa6d7b936c8f7d10abae64f6cf7f", + "reference": "0b7dc5599ac4aa6d7b936c8f7d10abae64f6cf7f", "shasum": "" }, "require": { - "php": ">=7.1.3" + "php": ">=7.1.3", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -8015,8 +8816,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Process Component", + "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v4.4.27" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -8031,20 +8835,20 @@ "type": "tidelift" } ], - "time": "2020-11-02T15:10:16+00:00" + "time": "2021-07-23T15:41:52+00:00" }, { "name": "symfony/psr-http-message-bridge", - "version": "v2.0.2", + "version": "v2.1.1", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "51a21cb3ba3927d4b4bf8f25cc55763351af5f2e" + "reference": "c9012994c4b4fb23e7c57dd86b763a417a04feba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/51a21cb3ba3927d4b4bf8f25cc55763351af5f2e", - "reference": "51a21cb3ba3927d4b4bf8f25cc55763351af5f2e", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/c9012994c4b4fb23e7c57dd86b763a417a04feba", + "reference": "c9012994c4b4fb23e7c57dd86b763a417a04feba", "shasum": "" }, "require": { @@ -8054,7 +8858,13 @@ }, "require-dev": { "nyholm/psr7": "^1.1", - "symfony/phpunit-bridge": "^4.4 || ^5.0" + "psr/log": "^1.1 || ^2 || ^3", + "symfony/browser-kit": "^4.4 || ^5.0", + "symfony/config": "^4.4 || ^5.0", + "symfony/event-dispatcher": "^4.4 || ^5.0", + "symfony/framework-bundle": "^4.4 || ^5.0", + "symfony/http-kernel": "^4.4 || ^5.0", + "symfony/phpunit-bridge": "^4.4.19 || ^5.2" }, "suggest": { "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" @@ -8062,7 +8872,7 @@ "type": "symfony-bridge", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "2.1-dev" } }, "autoload": { @@ -8095,6 +8905,10 @@ "psr-17", "psr-7" ], + "support": { + "issues": "https://github.com/symfony/psr-http-message-bridge/issues", + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.1.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -8109,24 +8923,25 @@ "type": "tidelift" } ], - "time": "2020-09-29T08:17:46+00:00" + "time": "2021-07-27T17:25:39+00:00" }, { "name": "symfony/routing", - "version": "v4.4.17", + "version": "v4.4.27", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "08712c5dd5041c03e997e13892f45884faccd868" + "reference": "244609821beece97167fa7ba4eef49d2a31862db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/08712c5dd5041c03e997e13892f45884faccd868", - "reference": "08712c5dd5041c03e997e13892f45884faccd868", + "url": "https://api.github.com/repos/symfony/routing/zipball/244609821beece97167fa7ba4eef49d2a31862db", + "reference": "244609821beece97167fa7ba4eef49d2a31862db", "shasum": "" }, "require": { - "php": ">=7.1.3" + "php": ">=7.1.3", + "symfony/polyfill-php80": "^1.16" }, "conflict": { "symfony/config": "<4.2", @@ -8134,8 +8949,8 @@ "symfony/yaml": "<3.4" }, "require-dev": { - "doctrine/annotations": "~1.2", - "psr/log": "~1.0", + "doctrine/annotations": "^1.10.4", + "psr/log": "^1|^2|^3", "symfony/config": "^4.2|^5.0", "symfony/dependency-injection": "^3.4|^4.0|^5.0", "symfony/expression-language": "^3.4|^4.0|^5.0", @@ -8172,7 +8987,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Routing Component", + "description": "Maps an HTTP request to a set of configuration variables", "homepage": "https://symfony.com", "keywords": [ "router", @@ -8180,6 +8995,9 @@ "uri", "url" ], + "support": { + "source": "https://github.com/symfony/routing/tree/v4.4.27" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -8194,25 +9012,25 @@ "type": "tidelift" } ], - "time": "2020-11-24T13:31:32+00:00" + "time": "2021-07-23T15:41:52+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.2.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" + "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", - "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", + "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/container": "^1.0" + "psr/container": "^1.1" }, "suggest": { "symfony/service-implementation": "" @@ -8220,7 +9038,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-main": "2.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -8256,6 +9074,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v2.4.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -8270,25 +9091,26 @@ "type": "tidelift" } ], - "time": "2020-09-07T11:33:47+00:00" + "time": "2021-04-01T10:43:52+00:00" }, { "name": "symfony/translation", - "version": "v4.4.17", + "version": "v4.4.27", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "84821e6a14a637e817f25d11147388695b6f790a" + "reference": "2e3c0f2bf704d635ba862e7198d72331a62d82ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/84821e6a14a637e817f25d11147388695b6f790a", - "reference": "84821e6a14a637e817f25d11147388695b6f790a", + "url": "https://api.github.com/repos/symfony/translation/zipball/2e3c0f2bf704d635ba862e7198d72331a62d82ba", + "reference": "2e3c0f2bf704d635ba862e7198d72331a62d82ba", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "^1.16", "symfony/translation-contracts": "^1.1.6|^2" }, "conflict": { @@ -8298,10 +9120,10 @@ "symfony/yaml": "<3.4" }, "provide": { - "symfony/translation-implementation": "1.0" + "symfony/translation-implementation": "1.0|2.0" }, "require-dev": { - "psr/log": "~1.0", + "psr/log": "^1|^2|^3", "symfony/config": "^3.4|^4.0|^5.0", "symfony/console": "^3.4|^4.0|^5.0", "symfony/dependency-injection": "^3.4|^4.0|^5.0", @@ -8339,8 +9161,11 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Translation Component", + "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v4.4.27" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -8355,20 +9180,20 @@ "type": "tidelift" } ], - "time": "2020-11-27T06:35:49+00:00" + "time": "2021-07-21T13:12:00+00:00" }, { "name": "symfony/translation-contracts", - "version": "v2.3.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "e2eaa60b558f26a4b0354e1bbb25636efaaad105" + "reference": "95c812666f3e91db75385749fe219c5e494c7f95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/e2eaa60b558f26a4b0354e1bbb25636efaaad105", - "reference": "e2eaa60b558f26a4b0354e1bbb25636efaaad105", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/95c812666f3e91db75385749fe219c5e494c7f95", + "reference": "95c812666f3e91db75385749fe219c5e494c7f95", "shasum": "" }, "require": { @@ -8380,7 +9205,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-main": "2.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -8416,6 +9241,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v2.4.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -8430,27 +9258,27 @@ "type": "tidelift" } ], - "time": "2020-09-28T13:05:58+00:00" + "time": "2021-03-23T23:28:01+00:00" }, { "name": "symfony/var-dumper", - "version": "v4.4.17", + "version": "v4.4.27", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "65c6f1e848cda840ef7278686c8e30a7cc353c93" + "reference": "391d6d0e7a06ab54eb7c38fab29b8d174471b3ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/65c6f1e848cda840ef7278686c8e30a7cc353c93", - "reference": "65c6f1e848cda840ef7278686c8e30a7cc353c93", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/391d6d0e7a06ab54eb7c38fab29b8d174471b3ba", + "reference": "391d6d0e7a06ab54eb7c38fab29b8d174471b3ba", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php72": "~1.5", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "conflict": { "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", @@ -8460,7 +9288,7 @@ "ext-iconv": "*", "symfony/console": "^3.4|^4.0|^5.0", "symfony/process": "^4.4|^5.0", - "twig/twig": "^1.34|^2.4|^3.0" + "twig/twig": "^1.43|^2.13|^3.0.4" }, "suggest": { "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", @@ -8496,12 +9324,15 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony mechanism for exploring and dumping PHP variables", + "description": "Provides mechanisms for walking through any arbitrary PHP variable", "homepage": "https://symfony.com", "keywords": [ "debug", "dump" ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v4.4.27" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -8516,7 +9347,7 @@ "type": "tidelift" } ], - "time": "2020-11-24T09:55:37+00:00" + "time": "2021-07-23T15:41:52+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -8565,20 +9396,24 @@ ], "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "support": { + "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.3" + }, "time": "2020-07-13T06:12:54+00:00" }, { "name": "vlucas/phpdotenv", - "version": "v3.6.7", + "version": "v3.6.8", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "2065beda6cbe75e2603686907b2e45f6f3a5ad82" + "reference": "5e679f7616db829358341e2d5cccbd18773bdab8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2065beda6cbe75e2603686907b2e45f6f3a5ad82", - "reference": "2065beda6cbe75e2603686907b2e45f6f3a5ad82", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/5e679f7616db829358341e2d5cccbd18773bdab8", + "reference": "5e679f7616db829358341e2d5cccbd18773bdab8", "shasum": "" }, "require": { @@ -8589,7 +9424,7 @@ "require-dev": { "ext-filter": "*", "ext-pcre": "*", - "phpunit/phpunit": "^4.8.35 || ^5.7.27 || ^6.5.6 || ^7.0" + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20" }, "suggest": { "ext-filter": "Required to use the boolean validator.", @@ -8628,6 +9463,10 @@ "env", "environment" ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v3.6.8" + }, "funding": [ { "url": "https://github.com/GrahamCampbell", @@ -8638,7 +9477,7 @@ "type": "tidelift" } ], - "time": "2020-07-14T19:04:52+00:00" + "time": "2021-01-20T14:39:46+00:00" }, { "name": "x3zvawq/noj_simplemde", @@ -8646,19 +9485,13 @@ "source": { "type": "git", "url": "https://github.com/X3ZvaWQ/NOJ_simpleMDE.git", - "reference": "077f2c81601138f86477f4f5a03bb347a29972a4" + "reference": "c4ed2fc8f9295b27472942fffe26dea8fd54e3b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/X3ZvaWQ/NOJ_simpleMDE/zipball/077f2c81601138f86477f4f5a03bb347a29972a4", - "reference": "077f2c81601138f86477f4f5a03bb347a29972a4", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] + "url": "https://api.github.com/repos/X3ZvaWQ/NOJ_simpleMDE/zipball/c4ed2fc8f9295b27472942fffe26dea8fd54e3b6", + "reference": "c4ed2fc8f9295b27472942fffe26dea8fd54e3b6", + "shasum": "" }, "require": { "encore/laravel-admin": "~1.6", @@ -8696,7 +9529,7 @@ "issues": "https://github.com/X3ZvaWQ/NOJ_simpleMDE/issues", "source": "https://github.com/X3ZvaWQ/NOJ_simpleMDE/tree/main" }, - "time": "2020-12-13T14:46:33+00:00" + "time": "2021-07-30T09:28:17+00:00" }, { "name": "zsgsdesign/noj-admin-clike-editor", @@ -8883,6 +9716,10 @@ "beyondcode", "laravel-dump-server" ], + "support": { + "issues": "https://github.com/beyondcode/laravel-dump-server/issues", + "source": "https://github.com/beyondcode/laravel-dump-server/tree/1.3.0" + }, "time": "2019-08-11T13:17:40+00:00" }, { @@ -8934,6 +9771,10 @@ "constructor", "instantiate" ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -8952,16 +9793,16 @@ }, { "name": "filp/whoops", - "version": "2.9.1", + "version": "2.14.0", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "307fb34a5ab697461ec4c9db865b20ff2fd40771" + "reference": "fdf92f03e150ed84d5967a833ae93abffac0315b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/307fb34a5ab697461ec4c9db865b20ff2fd40771", - "reference": "307fb34a5ab697461ec4c9db865b20ff2fd40771", + "url": "https://api.github.com/repos/filp/whoops/zipball/fdf92f03e150ed84d5967a833ae93abffac0315b", + "reference": "fdf92f03e150ed84d5967a833ae93abffac0315b", "shasum": "" }, "require": { @@ -9009,7 +9850,17 @@ "throwable", "whoops" ], - "time": "2020-11-01T12:00:00+00:00" + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.14.0" + }, + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2021-07-13T12:00:00+00:00" }, { "name": "fzaninotto/faker", @@ -9059,6 +9910,10 @@ "faker", "fixtures" ], + "support": { + "issues": "https://github.com/fzaninotto/Faker/issues", + "source": "https://github.com/fzaninotto/Faker/tree/v1.9.2" + }, "abandoned": true, "time": "2020-12-11T09:56:16+00:00" }, @@ -9107,20 +9962,24 @@ "keywords": [ "test" ], + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" + }, "time": "2020-07-09T08:09:16+00:00" }, { "name": "mockery/mockery", - "version": "1.3.3", + "version": "1.3.4", "source": { "type": "git", "url": "https://github.com/mockery/mockery.git", - "reference": "60fa2f67f6e4d3634bb4a45ff3171fa52215800d" + "reference": "31467aeb3ca3188158613322d66df81cedd86626" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/60fa2f67f6e4d3634bb4a45ff3171fa52215800d", - "reference": "60fa2f67f6e4d3634bb4a45ff3171fa52215800d", + "url": "https://api.github.com/repos/mockery/mockery/zipball/31467aeb3ca3188158613322d66df81cedd86626", + "reference": "31467aeb3ca3188158613322d66df81cedd86626", "shasum": "" }, "require": { @@ -9172,7 +10031,11 @@ "test double", "testing" ], - "time": "2020-08-11T18:10:21+00:00" + "support": { + "issues": "https://github.com/mockery/mockery/issues", + "source": "https://github.com/mockery/mockery/tree/1.3.4" + }, + "time": "2021-02-24T09:51:00+00:00" }, { "name": "myclabs/deep-copy", @@ -9220,6 +10083,10 @@ "object", "object graph" ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + }, "funding": [ { "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", @@ -9290,6 +10157,10 @@ "php", "symfony" ], + "support": { + "issues": "https://github.com/nunomaduro/collision/issues", + "source": "https://github.com/nunomaduro/collision" + }, "time": "2018-11-21T21:40:54+00:00" }, { @@ -9345,6 +10216,10 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/master" + }, "time": "2018-07-08T19:23:20+00:00" }, { @@ -9394,6 +10269,10 @@ "reflection", "static analysis" ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, "time": "2020-06-27T09:03:43+00:00" }, { @@ -9446,6 +10325,10 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master" + }, "time": "2020-09-03T19:13:55+00:00" }, { @@ -9491,20 +10374,24 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0" + }, "time": "2020-09-17T18:55:26+00:00" }, { "name": "phpspec/prophecy", - "version": "1.12.1", + "version": "1.13.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d" + "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d", - "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea", + "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea", "shasum": "" }, "require": { @@ -9516,7 +10403,7 @@ }, "require-dev": { "phpspec/phpspec": "^6.0", - "phpunit/phpunit": "^8.0 || ^9.0 <9.3" + "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", "extra": { @@ -9554,7 +10441,11 @@ "spy", "stub" ], - "time": "2020-09-29T09:10:42+00:00" + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/1.13.0" + }, + "time": "2021-03-17T13:42:18+00:00" }, { "name": "phpunit/php-code-coverage", @@ -9617,20 +10508,24 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/master" + }, "time": "2018-10-31T16:06:48+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357" + "reference": "28af674ff175d0768a5a978e6de83f697d4a7f05" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4b49fb70f067272b659ef0174ff9ca40fdaa6357", - "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/28af674ff175d0768a5a978e6de83f697d4a7f05", + "reference": "28af674ff175d0768a5a978e6de83f697d4a7f05", "shasum": "" }, "require": { @@ -9667,13 +10562,17 @@ "filesystem", "iterator" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2020-11-30T08:25:21+00:00" + "time": "2021-07-19T06:46:01+00:00" }, { "name": "phpunit/php-text-template", @@ -9714,6 +10613,10 @@ "keywords": [ "template" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" + }, "time": "2015-06-21T13:50:34+00:00" }, { @@ -9763,6 +10666,10 @@ "keywords": [ "timer" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -9773,16 +10680,16 @@ }, { "name": "phpunit/php-token-stream", - "version": "3.1.2", + "version": "3.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "472b687829041c24b25f475e14c2f38a09edf1c2" + "reference": "9c1da83261628cb24b6a6df371b6e312b3954768" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/472b687829041c24b25f475e14c2f38a09edf1c2", - "reference": "472b687829041c24b25f475e14c2f38a09edf1c2", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9c1da83261628cb24b6a6df371b6e312b3954768", + "reference": "9c1da83261628cb24b6a6df371b6e312b3954768", "shasum": "" }, "require": { @@ -9818,6 +10725,10 @@ "keywords": [ "tokenizer" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", + "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -9825,7 +10736,7 @@ } ], "abandoned": true, - "time": "2020-11-30T08:38:46+00:00" + "time": "2021-07-26T12:15:06+00:00" }, { "name": "phpunit/phpunit", @@ -9909,6 +10820,10 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/7.5.20" + }, "time": "2020-01-08T08:45:45+00:00" }, { @@ -9954,6 +10869,10 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -10024,6 +10943,10 @@ "compare", "equality" ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -10086,6 +11009,10 @@ "unidiff", "unified diff" ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -10145,6 +11072,10 @@ "environment", "hhvm" ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -10218,6 +11149,10 @@ "export", "exporter" ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -10275,6 +11210,10 @@ "keywords": [ "global state" ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0" + }, "time": "2017-04-27T15:39:26+00:00" }, { @@ -10322,6 +11261,10 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -10373,6 +11316,10 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -10432,6 +11379,10 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -10480,6 +11431,10 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -10490,16 +11445,16 @@ }, { "name": "theseer/tokenizer", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "75a63c33a8577608444246075ea0af0d052e452a" + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", - "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", "shasum": "" }, "require": { @@ -10526,40 +11481,49 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, "funding": [ { "url": "https://github.com/theseer", "type": "github" } ], - "time": "2020-07-12T23:59:07+00:00" + "time": "2021-07-28T10:34:58+00:00" }, { "name": "webmozart/assert", - "version": "1.9.1", + "version": "1.10.0", "source": { "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + "url": "https://github.com/webmozarts/assert.git", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", + "php": "^7.2 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" + "vimeo/psalm": "<4.6.1 || 4.6.2" }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "phpunit/phpunit": "^8.5.13" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -10581,7 +11545,11 @@ "check", "validate" ], - "time": "2020-07-08T17:02:28+00:00" + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.10.0" + }, + "time": "2021-03-09T10:59:23+00:00" } ], "aliases": [], @@ -10596,5 +11564,5 @@ "php": "^7.3" }, "platform-dev": [], - "plugin-api-version": "2.0.0" + "plugin-api-version": "2.1.0" } diff --git a/config/admin.php b/config/admin.php index a90ae2f78..76710957b 100644 --- a/config/admin.php +++ b/config/admin.php @@ -405,7 +405,7 @@ // 'guard' => 'api', // 'user_retriever' => function ($id) { - // return \App\User::find($id); + // return \App\Models\Eloquent\User::find($id); // }, // ] ], diff --git a/config/app.php b/config/app.php index fea9e3aff..cb2cfb367 100644 --- a/config/app.php +++ b/config/app.php @@ -55,16 +55,45 @@ /* |-------------------------------------------------------------------------- - | Application Enable Backup + | Application Info |-------------------------------------------------------------------------- | - | Set true when you want scheduling backup. + | Application Info. | */ 'logo' => env('APP_LOGO', "/static/img/icon/icon-white.png"), 'desc' => env('APP_DESC', ''), + /* + |-------------------------------------------------------------------------- + | Application Theme + |-------------------------------------------------------------------------- + | + | Set theme for NOJ. + | + */ + + 'theme' => in_array(env('APP_THEME', 'default'), [ + 'default', 'classic', 'cranberry', 'byzantium', + 'orchids', 'blueberry', 'starrynights', 'electric', + 'oceanic', 'emerald', 'aventurine', 'tropical', + 'ginger', 'espresso', 'enigma', + ]) ? env('APP_THEME', 'default') : 'default', + + /* + |-------------------------------------------------------------------------- + | Application OAuth Temp Account Allowance + |-------------------------------------------------------------------------- + | + | This OAuth Temp Account Allowance is used by the OAuth Controller to + | determine whether a user can login without a binding account + | established or not. + | + */ + + 'allow_oauth_temp_account' => env('APP_ALLOW_OAUTH_TEMP_ACCOUNT', false), + /* |-------------------------------------------------------------------------- | Application URL @@ -77,9 +106,20 @@ */ 'url' => env('APP_URL', 'http://localhost'), - 'asset_url' => env('ASSET_URL', null), + /* + |-------------------------------------------------------------------------- + | Application MultiDomain + |-------------------------------------------------------------------------- + | + | This Multi Domain is used by the Provider to determine whether this + | application should run on Mutli Domain mode or not. + | + */ + + 'multidomain' => env('APP_MULTI_DOMAIN', false), + /* |-------------------------------------------------------------------------- | Application Timezone @@ -190,11 +230,14 @@ /* * Package Service Providers... */ - Laravel\Socialite\SocialiteServiceProvider::class, + // Laravel\Socialite\SocialiteServiceProvider::class, + SocialiteProviders\Manager\ServiceProvider::class, Maatwebsite\Excel\ExcelServiceProvider::class, Barryvdh\DomPDF\ServiceProvider::class, Intervention\Image\ImageServiceProvider::class, Imtigger\LaravelJobStatus\LaravelJobStatusServiceProvider::class, + + /* * Application Service Providers... */ @@ -260,22 +303,4 @@ 'PDF' => Barryvdh\DomPDF\Facade::class, 'Image' => Intervention\Image\Facades\Image::class ], - - - /* - |-------------------------------------------------------------------------- - | Version Info - |-------------------------------------------------------------------------- - | - | This us the version info. - | - */ - - 'version' => [ - "author"=>"John Zhang", - "organization"=>"NJUPT ICPC Team", - "developers"=>"John Zhang, David Diao", - "major"=>"0.1.0", - ], - ]; diff --git a/config/auth.php b/config/auth.php index f8a1194bd..008fd5b64 100644 --- a/config/auth.php +++ b/config/auth.php @@ -67,7 +67,7 @@ 'providers' => [ 'users' => [ 'driver' => 'eloquent', - 'model' => App\User::class, + 'model' => App\Models\Eloquent\User::class, ], // 'users' => [ diff --git a/config/function.php b/config/function.php new file mode 100644 index 000000000..22bace83d --- /dev/null +++ b/config/function.php @@ -0,0 +1,5 @@ + env('FUNC_ENABLE_REGISTER', true), +]; diff --git a/config/moss.php b/config/moss.php deleted file mode 100644 index 6262a9748..000000000 --- a/config/moss.php +++ /dev/null @@ -1,15 +0,0 @@ - env('MOSS_USERID', ''), -]; diff --git a/config/services.php b/config/services.php index 73f07bd57..6a7bd801e 100644 --- a/config/services.php +++ b/config/services.php @@ -31,7 +31,7 @@ ], 'stripe' => [ - 'model' => App\User::class, + 'model' => App\Models\Eloquent\User::class, 'key' => env('STRIPE_KEY'), 'secret' => env('STRIPE_SECRET'), 'webhook' => [ @@ -41,9 +41,17 @@ ], 'github' => [ + 'enable' => env('GITHUB_ENABLE', false), 'client_id' => env('GITHUB_KEY'), 'client_secret' => env('GITHUB_SECRET'), 'redirect' => env('GITHUB_CALLBACK_URL'), ], + 'aauth' => [ + 'enable' => env('AAUTH_ENABLE', false), + 'client_id' => env('AAUTH_KEY'), + 'client_secret' => env('AAUTH_SECRET'), + 'redirect' => env('AAUTH_CALLBACK_URL'), + ], + ]; diff --git a/config/term.php b/config/term.php index 0489b60d8..a3f8e39ee 100644 --- a/config/term.php +++ b/config/term.php @@ -8,9 +8,9 @@ ], 'street' => env("TERM_STREET", '9 Wenyuan Road'), - 'city' => env("TERM_STREET", 'Nanjing'), - 'province' => env("TERM_STREET", 'Jiangsu'), - 'state' => env("TERM_STREET", 'China'), + 'city' => env("TERM_CITY", 'Nanjing'), + 'province' => env("TERM_PROVINCE", 'Jiangsu'), + 'state' => env("TERM_STATE", 'China'), 'zip' => env("TERM_ZIP", '221000'), 'contact' => [ diff --git a/config/version.php b/config/version.php new file mode 100644 index 000000000..168f98cfe --- /dev/null +++ b/config/version.php @@ -0,0 +1,86 @@ + [ + 'major' => 0, + 'minor' => 5, + 'build' => 0, + ], + + /* + |-------------------------------------------------------------------------- + | Version Name + |-------------------------------------------------------------------------- + | + | This is the current version name of NOJ. + | + */ + + 'name' => 'Aphyocharacinae', + + /* + |-------------------------------------------------------------------------- + | Insider Alias + |-------------------------------------------------------------------------- + | + | This is the insider alias of NOJ. + | + */ + + 'alias' => 'CodeMaster', + + /* + |-------------------------------------------------------------------------- + | Leader + |-------------------------------------------------------------------------- + | + | This is the leading developer of NOJ. + | + */ + + 'leader' => 'John Zhang', + + /* + |-------------------------------------------------------------------------- + | Developers + |-------------------------------------------------------------------------- + | + | This is the developers of NOJ. + | + */ + + 'developers' => 'John Zhang, Void Cao and other 13 dedicated contributors of the open-source community', + + /* + |-------------------------------------------------------------------------- + | Developers + |-------------------------------------------------------------------------- + | + | This is the developers of NOJ. + | + */ + + 'developers' => 'John Zhang, Void Cao and other 13 dedicated contributors of the open-source community', + + /* + |-------------------------------------------------------------------------- + | Organization + |-------------------------------------------------------------------------- + | + | This is the funding organization of NOJ. + | + */ + + 'organization' => 'Nanjing Fangtang Zhixing Network Technology Co., Ltd.', + +]; diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index ec15e586c..7253eb695 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -13,7 +13,7 @@ | */ -$factory->define(App\User::class, function (Faker $faker) { +$factory->define(App\Models\Eloquent\User::class, function (Faker $faker) { return [ 'name' => $faker->name, 'email' => $faker->unique()->safeEmail, diff --git a/database/migrations/2021_05_28_223705_add_missing_foreign_keys_for_admin.php b/database/migrations/2021_05_28_223705_add_missing_foreign_keys_for_admin.php new file mode 100644 index 000000000..a57c026d9 --- /dev/null +++ b/database/migrations/2021_05_28_223705_add_missing_foreign_keys_for_admin.php @@ -0,0 +1,116 @@ +integer('id')->change(); + }); + Schema::table('admin_operation_log', function(Blueprint $table) + { + $table->integer('id')->change(); + }); + Schema::table('admin_permissions', function(Blueprint $table) + { + $table->integer('id')->change(); + }); + Schema::table('admin_roles', function(Blueprint $table) + { + $table->integer('id')->change(); + }); + Schema::table('admin_users', function(Blueprint $table) + { + $table->integer('id')->change(); + }); + + // Schema::table('admin_role_menu', function(Blueprint $table) + // { + // $table->foreign('role_id')->references('id')->on('admin_roles')->onUpdate('CASCADE')->onDelete('CASCADE'); + // $table->foreign('menu_id')->references('id')->on('admin_menu')->onUpdate('CASCADE')->onDelete('CASCADE'); + // }); + // Schema::table('admin_operation_log', function(Blueprint $table) + // { + // $table->foreign('user_id')->references('id')->on('admin_users')->onUpdate('CASCADE')->onDelete('CASCADE'); + // }); + // Schema::table('admin_role_permissions', function(Blueprint $table) + // { + // $table->foreign('permission_id')->references('id')->on('admin_permissions')->onUpdate('CASCADE')->onDelete('CASCADE'); + // $table->foreign('role_id')->references('id')->on('admin_roles')->onUpdate('CASCADE')->onDelete('CASCADE'); + // }); + // Schema::table('admin_role_users', function(Blueprint $table) + // { + // $table->foreign('role_id')->references('id')->on('admin_roles')->onUpdate('CASCADE')->onDelete('CASCADE'); + // $table->foreign('user_id')->references('id')->on('admin_users')->onUpdate('CASCADE')->onDelete('CASCADE'); + // }); + // Schema::table('admin_user_permissions', function(Blueprint $table) + // { + // $table->foreign('permission_id')->references('id')->on('admin_permissions')->onUpdate('CASCADE')->onDelete('CASCADE'); + // $table->foreign('user_id')->references('id')->on('admin_users')->onUpdate('CASCADE')->onDelete('CASCADE'); + // }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // Schema::table('admin_role_menu', function(Blueprint $table) + // { + // $table->dropForeign(['role_id']); + // $table->dropForeign(['menu_id']); + // }); + // Schema::table('admin_operation_log', function(Blueprint $table) + // { + // $table->dropForeign(['user_id']); + // }); + // Schema::table('admin_role_permissions', function(Blueprint $table) + // { + // $table->dropForeign(['permission_id']); + // $table->dropForeign(['role_id']); + // }); + // Schema::table('admin_role_users', function(Blueprint $table) + // { + // $table->dropForeign(['user_id']); + // $table->dropForeign(['role_id']); + // }); + // Schema::table('admin_user_permissions', function(Blueprint $table) + // { + // $table->dropForeign(['permission_id']); + // $table->dropForeign(['user_id']); + // }); + + Schema::table('admin_menu', function(Blueprint $table) + { + $table->unsignedInteger('id')->change(); + }); + Schema::table('admin_operation_log', function(Blueprint $table) + { + $table->unsignedInteger('id')->change(); + }); + Schema::table('admin_permissions', function(Blueprint $table) + { + $table->unsignedInteger('id')->change(); + }); + Schema::table('admin_roles', function(Blueprint $table) + { + $table->unsignedInteger('id')->change(); + }); + Schema::table('admin_users', function(Blueprint $table) + { + $table->unsignedInteger('id')->change(); + }); + } +} diff --git a/database/migrations/2021_05_28_230312_add_missing_foreign_keys_for_contest.php b/database/migrations/2021_05_28_230312_add_missing_foreign_keys_for_contest.php new file mode 100644 index 000000000..35b537785 --- /dev/null +++ b/database/migrations/2021_05_28_230312_add_missing_foreign_keys_for_contest.php @@ -0,0 +1,36 @@ +foreign('cid')->references('cid')->on('contest')->onUpdate('CASCADE')->onDelete('CASCADE'); + $table->foreign('pid')->references('pid')->on('problem')->onUpdate('CASCADE')->onDelete('CASCADE'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('contest_problem', function(Blueprint $table) + { + $table->dropForeign(['cid']); + $table->dropForeign(['pid']); + }); + } +} diff --git a/database/migrations/2021_05_28_230538_add_missing_foreign_keys_for_group_and_abuse.php b/database/migrations/2021_05_28_230538_add_missing_foreign_keys_for_group_and_abuse.php new file mode 100644 index 000000000..04c6dcca3 --- /dev/null +++ b/database/migrations/2021_05_28_230538_add_missing_foreign_keys_for_group_and_abuse.php @@ -0,0 +1,76 @@ +integer('id')->change(); + }); + Schema::table('group_rated_change_log', function(Blueprint $table) + { + $table->foreign('gid')->references('gid')->on('group')->onUpdate('CASCADE')->onDelete('CASCADE'); + $table->foreign('cid')->references('cid')->on('contest')->onUpdate('CASCADE')->onDelete('CASCADE'); + $table->foreign('uid')->references('id')->on('users')->onUpdate('CASCADE')->onDelete('CASCADE'); + }); + Schema::table('group_problem_tag', function(Blueprint $table) + { + $table->foreign('gid')->references('gid')->on('group')->onUpdate('CASCADE')->onDelete('CASCADE'); + $table->foreign('pid')->references('pid')->on('problem')->onUpdate('CASCADE')->onDelete('CASCADE'); + }); + Schema::table('group_banneds', function(Blueprint $table) + { + $table->foreign('group_id')->references('gid')->on('group')->onUpdate('CASCADE')->onDelete('CASCADE'); + $table->foreign('abuse_id')->references('id')->on('abuses')->onUpdate('CASCADE')->onDelete('CASCADE'); + }); + Schema::table('user_banneds', function(Blueprint $table) + { + $table->foreign('user_id')->references('id')->on('users')->onUpdate('CASCADE')->onDelete('CASCADE'); + $table->foreign('abuse_id')->references('id')->on('abuses')->onUpdate('CASCADE')->onDelete('CASCADE'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('group_rated_change_log', function(Blueprint $table) + { + $table->dropForeign(['gid']); + $table->dropForeign(['cid']); + $table->dropForeign(['uid']); + }); + Schema::table('group_problem_tag', function(Blueprint $table) + { + $table->dropForeign(['gid']); + $table->dropForeign(['pid']); + }); + Schema::table('group_banneds', function(Blueprint $table) + { + $table->dropForeign(['group_id']); + $table->dropForeign(['abuse_id']); + }); + Schema::table('user_banneds', function(Blueprint $table) + { + $table->dropForeign(['user_id']); + $table->dropForeign(['abuse_id']); + }); + Schema::table('abuses', function(Blueprint $table) + { + $table->unsignedBigInteger('id')->change(); + }); + } +} diff --git a/database/migrations/2021_05_28_231255_add_missing_foreign_keys_for_user.php b/database/migrations/2021_05_28_231255_add_missing_foreign_keys_for_user.php new file mode 100644 index 000000000..44250d233 --- /dev/null +++ b/database/migrations/2021_05_28_231255_add_missing_foreign_keys_for_user.php @@ -0,0 +1,36 @@ +integer('uid')->change(); + $table->foreign('uid')->references('id')->on('users')->onUpdate('CASCADE')->onDelete('CASCADE'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('users_extra', function(Blueprint $table) + { + $table->dropForeign(['uid']); + $table->bigInteger('uid')->change(); + }); + } +} diff --git a/database/migrations/2021_05_28_231750_add_missing_foreign_keys_for_discussion.php b/database/migrations/2021_05_28_231750_add_missing_foreign_keys_for_discussion.php new file mode 100644 index 000000000..e07aea94d --- /dev/null +++ b/database/migrations/2021_05_28_231750_add_missing_foreign_keys_for_discussion.php @@ -0,0 +1,48 @@ +foreign('uid')->references('id')->on('users')->onUpdate('CASCADE')->onDelete('CASCADE'); + $table->foreign('pid')->references('pid')->on('problem')->onUpdate('CASCADE')->onDelete('CASCADE'); + }); + Schema::table('problem_discussion_comment', function(Blueprint $table) + { + $table->foreign('pdid')->references('pdid')->on('problem_discussion')->onUpdate('CASCADE')->onDelete('CASCADE'); + $table->foreign('uid')->references('id')->on('users')->onUpdate('CASCADE')->onDelete('CASCADE'); + $table->foreign('pid')->references('pid')->on('problem')->onUpdate('CASCADE')->onDelete('CASCADE'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('problem_discussion', function(Blueprint $table) + { + $table->dropForeign(['uid']); + $table->dropForeign(['pid']); + }); + Schema::table('problem_discussion_comment', function(Blueprint $table) + { + $table->dropForeign(['pdid']); + $table->dropForeign(['uid']); + $table->dropForeign(['pid']); + }); + } +} diff --git a/database/migrations/2021_07_26_113350_add_img_to_group.php b/database/migrations/2021_07_26_113350_add_img_to_group.php new file mode 100644 index 000000000..dde623c4b --- /dev/null +++ b/database/migrations/2021_07_26_113350_add_img_to_group.php @@ -0,0 +1,32 @@ +string('img')->default("/static/img/group/default.png")->change(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('group', function (Blueprint $table) { + $table->string('img')->default(null)->change(); + }); + } +} diff --git a/database/migrations/2021_08_05_031051_create_image_hostings_table.php b/database/migrations/2021_08_05_031051_create_image_hostings_table.php new file mode 100644 index 000000000..4eaf4e285 --- /dev/null +++ b/database/migrations/2021_08_05_031051_create_image_hostings_table.php @@ -0,0 +1,33 @@ +integer('id', true); + $table->integer('user_id'); + $table->string('relative_path', 255)->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('image_hostings'); + } +} diff --git a/database/migrations/2021_08_05_032755_add_foreign_keys_to_image_hostings_table.php b/database/migrations/2021_08_05_032755_add_foreign_keys_to_image_hostings_table.php new file mode 100644 index 000000000..1fffa42c1 --- /dev/null +++ b/database/migrations/2021_08_05_032755_add_foreign_keys_to_image_hostings_table.php @@ -0,0 +1,32 @@ +foreign('user_id', 'image_hostings_user_id')->references('id')->on('users')->onUpdate('CASCADE')->onDelete('CASCADE'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('image_hostings', function (Blueprint $table) { + $table->dropForeign('image_hostings_user_id'); + }); + } +} diff --git a/database/migrations/2021_08_05_033313_create_user_permissions_table.php b/database/migrations/2021_08_05_033313_create_user_permissions_table.php new file mode 100644 index 000000000..85b4fd80d --- /dev/null +++ b/database/migrations/2021_08_05_033313_create_user_permissions_table.php @@ -0,0 +1,33 @@ +integer('id', true); + $table->integer('user_id'); + $table->integer('permission_id'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('user_permissions'); + } +} diff --git a/database/migrations/2021_08_05_033413_add_foreign_keys_to_user_permissions_table.php b/database/migrations/2021_08_05_033413_add_foreign_keys_to_user_permissions_table.php new file mode 100644 index 000000000..b3db7404c --- /dev/null +++ b/database/migrations/2021_08_05_033413_add_foreign_keys_to_user_permissions_table.php @@ -0,0 +1,32 @@ +foreign('user_id', 'user_permissions_user_id')->references('id')->on('users')->onUpdate('CASCADE')->onDelete('CASCADE'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('user_permissions', function (Blueprint $table) { + $table->dropForeign('user_permissions_user_id'); + }); + } +} diff --git a/database/migrations/2021_08_12_204942_create_settings_table.php b/database/migrations/2021_08_12_204942_create_settings_table.php new file mode 100644 index 000000000..96076d4bf --- /dev/null +++ b/database/migrations/2021_08_12_204942_create_settings_table.php @@ -0,0 +1,34 @@ +integer('id', true); + $table->string('key')->unique(); + $table->longText('content')->nullable(); + $table->boolean('is_json'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('settings'); + } +} diff --git a/public/static/css/main.css b/public/static/css/main.css index c569cff48..02f30ba72 100644 --- a/public/static/css/main.css +++ b/public/static/css/main.css @@ -375,3 +375,69 @@ img.cm-colorful-text { height: 5rem; width: 5rem; } + +nav.navbar .dropdown-menu .dropdown-item { + max-width: none; +} + +/* NOJ Theme Data */ + +html[noj-theme="default"] .bg-dark{ + background-color: #3E4551!important; +} + +html[noj-theme="classic"] .bg-dark{ + background-color: #424242!important; +} + +html[noj-theme="cranberry"] .bg-dark{ + background-color: var(--wemd-red-darken-3)!important; +} + +html[noj-theme="byzantium"] .bg-dark{ + background-color: var(--wemd-pink-darken-3)!important; +} + +html[noj-theme="orchids"] .bg-dark{ + background-color: var(--wemd-purple-darken-3)!important; +} + +html[noj-theme="blueberry"] .bg-dark{ + background-color: var(--wemd-deep-purple-darken-3)!important; +} + +html[noj-theme="starrynights"] .bg-dark{ + background-color: var(--wemd-indigo-darken-3)!important; +} + +html[noj-theme="electric"] .bg-dark{ + background-color: var(--wemd-blue-darken-3)!important; +} + +html[noj-theme="oceanic"] .bg-dark{ + background-color: var(--wemd-light-blue-darken-3)!important; +} + +html[noj-theme="emerald"] .bg-dark{ + background-color: var(--wemd-teal-darken-3)!important; +} + +html[noj-theme="aventurine"] .bg-dark{ + background-color: var(--wemd-green-darken-3)!important; +} + +html[noj-theme="tropical"] .bg-dark{ + background-color: var(--wemd-orange-darken-3)!important; +} + +html[noj-theme="ginger"] .bg-dark{ + background-color: var(--wemd-deep-orange-darken-3)!important; +} + +html[noj-theme="espresso"] .bg-dark{ + background-color: var(--wemd-brown-darken-3)!important; +} + +html[noj-theme="enigma"] .bg-dark{ + background-color: var(--wemd-blue-grey-darken-3)!important; +} diff --git a/public/static/img/.gitignore b/public/static/img/.gitignore index 335d87ead..e07db9ff3 100644 --- a/public/static/img/.gitignore +++ b/public/static/img/.gitignore @@ -7,6 +7,7 @@ !notify !icon !carousel +!upload !njupt.png !noj.png !icpc.png diff --git a/public/static/img/icon/.gitignore b/public/static/img/icon/.gitignore index 0ea3f2841..334ae786a 100644 --- a/public/static/img/icon/.gitignore +++ b/public/static/img/icon/.gitignore @@ -4,3 +4,4 @@ !icon-blue.png !icon-white.png !icon-pastebin.png +!icon-imagehosting.png diff --git a/public/static/img/icon/icon-imagehosting.png b/public/static/img/icon/icon-imagehosting.png new file mode 100644 index 000000000..c021087c2 Binary files /dev/null and b/public/static/img/icon/icon-imagehosting.png differ diff --git a/public/static/img/upload/.gitignore b/public/static/img/upload/.gitignore new file mode 100644 index 000000000..d6b7ef32c --- /dev/null +++ b/public/static/img/upload/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/public/static/js/bootstrap-material-design.js b/public/static/js/bootstrap-material-design.js deleted file mode 100644 index f50c93ddd..000000000 --- a/public/static/js/bootstrap-material-design.js +++ /dev/null @@ -1,6537 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('jquery'), require('popper.js')) : - typeof define === 'function' && define.amd ? define(['jquery', 'popper.js'], factory) : - (factory(global.jQuery,global.Popper)); -}(this, (function ($,Popper$1) { 'use strict'; - -$ = $ && $.hasOwnProperty('default') ? $['default'] : $; -Popper$1 = Popper$1 && Popper$1.hasOwnProperty('default') ? Popper$1['default'] : Popper$1; - -function _defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } -} - -function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) _defineProperties(Constructor.prototype, protoProps); - if (staticProps) _defineProperties(Constructor, staticProps); - return Constructor; -} - -function _extends() { - _extends = Object.assign || function (target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i]; - - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - - return target; - }; - - return _extends.apply(this, arguments); -} - -function _inheritsLoose(subClass, superClass) { - subClass.prototype = Object.create(superClass.prototype); - subClass.prototype.constructor = subClass; - subClass.__proto__ = superClass; -} - -/** - * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0): util.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * -------------------------------------------------------------------------- - */ - -var Util = function ($$$1) { - /** - * ------------------------------------------------------------------------ - * Private TransitionEnd Helpers - * ------------------------------------------------------------------------ - */ - var transition = false; - var MAX_UID = 1000000; // Shoutout AngusCroll (https://goo.gl/pxwQGp) - - function toType(obj) { - return {}.toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase(); - } - - function getSpecialTransitionEndEvent() { - return { - bindType: transition.end, - delegateType: transition.end, - handle: function handle(event) { - if ($$$1(event.target).is(this)) { - return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params - } - - return undefined; // eslint-disable-line no-undefined - } - }; - } - - function transitionEndTest() { - if (typeof window !== 'undefined' && window.QUnit) { - return false; - } - - return { - end: 'transitionend' - }; - } - - function transitionEndEmulator(duration) { - var _this = this; - - var called = false; - $$$1(this).one(Util.TRANSITION_END, function () { - called = true; - }); - setTimeout(function () { - if (!called) { - Util.triggerTransitionEnd(_this); - } - }, duration); - return this; - } - - function setTransitionEndSupport() { - transition = transitionEndTest(); - $$$1.fn.emulateTransitionEnd = transitionEndEmulator; - - if (Util.supportsTransitionEnd()) { - $$$1.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent(); - } - } - - function escapeId(selector) { - // We escape IDs in case of special selectors (selector = '#myId:something') - // $.escapeSelector does not exist in jQuery < 3 - selector = typeof $$$1.escapeSelector === 'function' ? $$$1.escapeSelector(selector).substr(1) : selector.replace(/(:|\.|\[|\]|,|=|@)/g, '\\$1'); - return selector; - } - /** - * -------------------------------------------------------------------------- - * Public Util Api - * -------------------------------------------------------------------------- - */ - - - var Util = { - TRANSITION_END: 'bsTransitionEnd', - getUID: function getUID(prefix) { - do { - // eslint-disable-next-line no-bitwise - prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here - } while (document.getElementById(prefix)); - - return prefix; - }, - getSelectorFromElement: function getSelectorFromElement(element) { - var selector = element.getAttribute('data-target'); - - if (!selector || selector === '#') { - selector = element.getAttribute('href') || ''; - } // If it's an ID - - - if (selector.charAt(0) === '#') { - selector = escapeId(selector); - } - - try { - var $selector = $$$1(document).find(selector); - return $selector.length > 0 ? selector : null; - } catch (err) { - return null; - } - }, - reflow: function reflow(element) { - return element.offsetHeight; - }, - triggerTransitionEnd: function triggerTransitionEnd(element) { - $$$1(element).trigger(transition.end); - }, - supportsTransitionEnd: function supportsTransitionEnd() { - return Boolean(transition); - }, - isElement: function isElement(obj) { - return (obj[0] || obj).nodeType; - }, - typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) { - for (var property in configTypes) { - if (Object.prototype.hasOwnProperty.call(configTypes, property)) { - var expectedTypes = configTypes[property]; - var value = config[property]; - var valueType = value && Util.isElement(value) ? 'element' : toType(value); - - if (!new RegExp(expectedTypes).test(valueType)) { - throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\".")); - } - } - } - } - }; - setTransitionEndSupport(); - return Util; -}($); - -/** - * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0): alert.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * -------------------------------------------------------------------------- - */ - -var Alert = function ($$$1) { - /** - * ------------------------------------------------------------------------ - * Constants - * ------------------------------------------------------------------------ - */ - var NAME = 'alert'; - var VERSION = '4.0.0'; - var DATA_KEY = 'bs.alert'; - var EVENT_KEY = "." + DATA_KEY; - var DATA_API_KEY = '.data-api'; - var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; - var TRANSITION_DURATION = 150; - var Selector = { - DISMISS: '[data-dismiss="alert"]' - }; - var Event = { - CLOSE: "close" + EVENT_KEY, - CLOSED: "closed" + EVENT_KEY, - CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY - }; - var ClassName = { - ALERT: 'alert', - FADE: 'fade', - SHOW: 'show' - /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ - */ - - }; - - var Alert = - /*#__PURE__*/ - function () { - function Alert(element) { - this._element = element; - } // Getters - - - var _proto = Alert.prototype; - - // Public - _proto.close = function close(element) { - element = element || this._element; - - var rootElement = this._getRootElement(element); - - var customEvent = this._triggerCloseEvent(rootElement); - - if (customEvent.isDefaultPrevented()) { - return; - } - - this._removeElement(rootElement); - }; - - _proto.dispose = function dispose() { - $$$1.removeData(this._element, DATA_KEY); - this._element = null; - }; // Private - - - _proto._getRootElement = function _getRootElement(element) { - var selector = Util.getSelectorFromElement(element); - var parent = false; - - if (selector) { - parent = $$$1(selector)[0]; - } - - if (!parent) { - parent = $$$1(element).closest("." + ClassName.ALERT)[0]; - } - - return parent; - }; - - _proto._triggerCloseEvent = function _triggerCloseEvent(element) { - var closeEvent = $$$1.Event(Event.CLOSE); - $$$1(element).trigger(closeEvent); - return closeEvent; - }; - - _proto._removeElement = function _removeElement(element) { - var _this = this; - - $$$1(element).removeClass(ClassName.SHOW); - - if (!Util.supportsTransitionEnd() || !$$$1(element).hasClass(ClassName.FADE)) { - this._destroyElement(element); - - return; - } - - $$$1(element).one(Util.TRANSITION_END, function (event) { - return _this._destroyElement(element, event); - }).emulateTransitionEnd(TRANSITION_DURATION); - }; - - _proto._destroyElement = function _destroyElement(element) { - $$$1(element).detach().trigger(Event.CLOSED).remove(); - }; // Static - - - Alert._jQueryInterface = function _jQueryInterface(config) { - return this.each(function () { - var $element = $$$1(this); - var data = $element.data(DATA_KEY); - - if (!data) { - data = new Alert(this); - $element.data(DATA_KEY, data); - } - - if (config === 'close') { - data[config](this); - } - }); - }; - - Alert._handleDismiss = function _handleDismiss(alertInstance) { - return function (event) { - if (event) { - event.preventDefault(); - } - - alertInstance.close(this); - }; - }; - - _createClass(Alert, null, [{ - key: "VERSION", - get: function get() { - return VERSION; - } - }]); - return Alert; - }(); - /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ - */ - - - $$$1(document).on(Event.CLICK_DATA_API, Selector.DISMISS, Alert._handleDismiss(new Alert())); - /** - * ------------------------------------------------------------------------ - * jQuery - * ------------------------------------------------------------------------ - */ - - $$$1.fn[NAME] = Alert._jQueryInterface; - $$$1.fn[NAME].Constructor = Alert; - - $$$1.fn[NAME].noConflict = function () { - $$$1.fn[NAME] = JQUERY_NO_CONFLICT; - return Alert._jQueryInterface; - }; - - return Alert; -}($); - -/** - * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0): button.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * -------------------------------------------------------------------------- - */ - -var Button = function ($$$1) { - /** - * ------------------------------------------------------------------------ - * Constants - * ------------------------------------------------------------------------ - */ - var NAME = 'button'; - var VERSION = '4.0.0'; - var DATA_KEY = 'bs.button'; - var EVENT_KEY = "." + DATA_KEY; - var DATA_API_KEY = '.data-api'; - var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; - var ClassName = { - ACTIVE: 'active', - BUTTON: 'btn', - FOCUS: 'focus' - }; - var Selector = { - DATA_TOGGLE_CARROT: '[data-toggle^="button"]', - DATA_TOGGLE: '[data-toggle="buttons"]', - INPUT: 'input', - ACTIVE: '.active', - BUTTON: '.btn' - }; - var Event = { - CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY, - FOCUS_BLUR_DATA_API: "focus" + EVENT_KEY + DATA_API_KEY + " " + ("blur" + EVENT_KEY + DATA_API_KEY) - /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ - */ - - }; - - var Button = - /*#__PURE__*/ - function () { - function Button(element) { - this._element = element; - } // Getters - - - var _proto = Button.prototype; - - // Public - _proto.toggle = function toggle() { - var triggerChangeEvent = true; - var addAriaPressed = true; - var rootElement = $$$1(this._element).closest(Selector.DATA_TOGGLE)[0]; - - if (rootElement) { - var input = $$$1(this._element).find(Selector.INPUT)[0]; - - if (input) { - if (input.type === 'radio') { - if (input.checked && $$$1(this._element).hasClass(ClassName.ACTIVE)) { - triggerChangeEvent = false; - } else { - var activeElement = $$$1(rootElement).find(Selector.ACTIVE)[0]; - - if (activeElement) { - $$$1(activeElement).removeClass(ClassName.ACTIVE); - } - } - } - - if (triggerChangeEvent) { - if (input.hasAttribute('disabled') || rootElement.hasAttribute('disabled') || input.classList.contains('disabled') || rootElement.classList.contains('disabled')) { - return; - } - - input.checked = !$$$1(this._element).hasClass(ClassName.ACTIVE); - $$$1(input).trigger('change'); - } - - input.focus(); - addAriaPressed = false; - } - } - - if (addAriaPressed) { - this._element.setAttribute('aria-pressed', !$$$1(this._element).hasClass(ClassName.ACTIVE)); - } - - if (triggerChangeEvent) { - $$$1(this._element).toggleClass(ClassName.ACTIVE); - } - }; - - _proto.dispose = function dispose() { - $$$1.removeData(this._element, DATA_KEY); - this._element = null; - }; // Static - - - Button._jQueryInterface = function _jQueryInterface(config) { - return this.each(function () { - var data = $$$1(this).data(DATA_KEY); - - if (!data) { - data = new Button(this); - $$$1(this).data(DATA_KEY, data); - } - - if (config === 'toggle') { - data[config](); - } - }); - }; - - _createClass(Button, null, [{ - key: "VERSION", - get: function get() { - return VERSION; - } - }]); - return Button; - }(); - /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ - */ - - - $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) { - event.preventDefault(); - var button = event.target; - - if (!$$$1(button).hasClass(ClassName.BUTTON)) { - button = $$$1(button).closest(Selector.BUTTON); - } - - Button._jQueryInterface.call($$$1(button), 'toggle'); - }).on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) { - var button = $$$1(event.target).closest(Selector.BUTTON)[0]; - $$$1(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type)); - }); - /** - * ------------------------------------------------------------------------ - * jQuery - * ------------------------------------------------------------------------ - */ - - $$$1.fn[NAME] = Button._jQueryInterface; - $$$1.fn[NAME].Constructor = Button; - - $$$1.fn[NAME].noConflict = function () { - $$$1.fn[NAME] = JQUERY_NO_CONFLICT; - return Button._jQueryInterface; - }; - - return Button; -}($); - -/** - * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0): carousel.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * -------------------------------------------------------------------------- - */ - -var Carousel = function ($$$1) { - /** - * ------------------------------------------------------------------------ - * Constants - * ------------------------------------------------------------------------ - */ - var NAME = 'carousel'; - var VERSION = '4.0.0'; - var DATA_KEY = 'bs.carousel'; - var EVENT_KEY = "." + DATA_KEY; - var DATA_API_KEY = '.data-api'; - var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; - var TRANSITION_DURATION = 600; - var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key - - var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key - - var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch - - var Default = { - interval: 5000, - keyboard: true, - slide: false, - pause: 'hover', - wrap: true - }; - var DefaultType = { - interval: '(number|boolean)', - keyboard: 'boolean', - slide: '(boolean|string)', - pause: '(string|boolean)', - wrap: 'boolean' - }; - var Direction = { - NEXT: 'next', - PREV: 'prev', - LEFT: 'left', - RIGHT: 'right' - }; - var Event = { - SLIDE: "slide" + EVENT_KEY, - SLID: "slid" + EVENT_KEY, - KEYDOWN: "keydown" + EVENT_KEY, - MOUSEENTER: "mouseenter" + EVENT_KEY, - MOUSELEAVE: "mouseleave" + EVENT_KEY, - TOUCHEND: "touchend" + EVENT_KEY, - LOAD_DATA_API: "load" + EVENT_KEY + DATA_API_KEY, - CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY - }; - var ClassName = { - CAROUSEL: 'carousel', - ACTIVE: 'active', - SLIDE: 'slide', - RIGHT: 'carousel-item-right', - LEFT: 'carousel-item-left', - NEXT: 'carousel-item-next', - PREV: 'carousel-item-prev', - ITEM: 'carousel-item' - }; - var Selector = { - ACTIVE: '.active', - ACTIVE_ITEM: '.active.carousel-item', - ITEM: '.carousel-item', - NEXT_PREV: '.carousel-item-next, .carousel-item-prev', - INDICATORS: '.carousel-indicators', - DATA_SLIDE: '[data-slide], [data-slide-to]', - DATA_RIDE: '[data-ride="carousel"]' - /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ - */ - - }; - - var Carousel = - /*#__PURE__*/ - function () { - function Carousel(element, config) { - this._items = null; - this._interval = null; - this._activeElement = null; - this._isPaused = false; - this._isSliding = false; - this.touchTimeout = null; - this._config = this._getConfig(config); - this._element = $$$1(element)[0]; - this._indicatorsElement = $$$1(this._element).find(Selector.INDICATORS)[0]; - - this._addEventListeners(); - } // Getters - - - var _proto = Carousel.prototype; - - // Public - _proto.next = function next() { - if (!this._isSliding) { - this._slide(Direction.NEXT); - } - }; - - _proto.nextWhenVisible = function nextWhenVisible() { - // Don't call next when the page isn't visible - // or the carousel or its parent isn't visible - if (!document.hidden && $$$1(this._element).is(':visible') && $$$1(this._element).css('visibility') !== 'hidden') { - this.next(); - } - }; - - _proto.prev = function prev() { - if (!this._isSliding) { - this._slide(Direction.PREV); - } - }; - - _proto.pause = function pause(event) { - if (!event) { - this._isPaused = true; - } - - if ($$$1(this._element).find(Selector.NEXT_PREV)[0] && Util.supportsTransitionEnd()) { - Util.triggerTransitionEnd(this._element); - this.cycle(true); - } - - clearInterval(this._interval); - this._interval = null; - }; - - _proto.cycle = function cycle(event) { - if (!event) { - this._isPaused = false; - } - - if (this._interval) { - clearInterval(this._interval); - this._interval = null; - } - - if (this._config.interval && !this._isPaused) { - this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval); - } - }; - - _proto.to = function to(index) { - var _this = this; - - this._activeElement = $$$1(this._element).find(Selector.ACTIVE_ITEM)[0]; - - var activeIndex = this._getItemIndex(this._activeElement); - - if (index > this._items.length - 1 || index < 0) { - return; - } - - if (this._isSliding) { - $$$1(this._element).one(Event.SLID, function () { - return _this.to(index); - }); - return; - } - - if (activeIndex === index) { - this.pause(); - this.cycle(); - return; - } - - var direction = index > activeIndex ? Direction.NEXT : Direction.PREV; - - this._slide(direction, this._items[index]); - }; - - _proto.dispose = function dispose() { - $$$1(this._element).off(EVENT_KEY); - $$$1.removeData(this._element, DATA_KEY); - this._items = null; - this._config = null; - this._element = null; - this._interval = null; - this._isPaused = null; - this._isSliding = null; - this._activeElement = null; - this._indicatorsElement = null; - }; // Private - - - _proto._getConfig = function _getConfig(config) { - config = _extends({}, Default, config); - Util.typeCheckConfig(NAME, config, DefaultType); - return config; - }; - - _proto._addEventListeners = function _addEventListeners() { - var _this2 = this; - - if (this._config.keyboard) { - $$$1(this._element).on(Event.KEYDOWN, function (event) { - return _this2._keydown(event); - }); - } - - if (this._config.pause === 'hover') { - $$$1(this._element).on(Event.MOUSEENTER, function (event) { - return _this2.pause(event); - }).on(Event.MOUSELEAVE, function (event) { - return _this2.cycle(event); - }); - - if ('ontouchstart' in document.documentElement) { - // If it's a touch-enabled device, mouseenter/leave are fired as - // part of the mouse compatibility events on first tap - the carousel - // would stop cycling until user tapped out of it; - // here, we listen for touchend, explicitly pause the carousel - // (as if it's the second time we tap on it, mouseenter compat event - // is NOT fired) and after a timeout (to allow for mouse compatibility - // events to fire) we explicitly restart cycling - $$$1(this._element).on(Event.TOUCHEND, function () { - _this2.pause(); - - if (_this2.touchTimeout) { - clearTimeout(_this2.touchTimeout); - } - - _this2.touchTimeout = setTimeout(function (event) { - return _this2.cycle(event); - }, TOUCHEVENT_COMPAT_WAIT + _this2._config.interval); - }); - } - } - }; - - _proto._keydown = function _keydown(event) { - if (/input|textarea/i.test(event.target.tagName)) { - return; - } - - switch (event.which) { - case ARROW_LEFT_KEYCODE: - event.preventDefault(); - this.prev(); - break; - - case ARROW_RIGHT_KEYCODE: - event.preventDefault(); - this.next(); - break; - - default: - } - }; - - _proto._getItemIndex = function _getItemIndex(element) { - this._items = $$$1.makeArray($$$1(element).parent().find(Selector.ITEM)); - return this._items.indexOf(element); - }; - - _proto._getItemByDirection = function _getItemByDirection(direction, activeElement) { - var isNextDirection = direction === Direction.NEXT; - var isPrevDirection = direction === Direction.PREV; - - var activeIndex = this._getItemIndex(activeElement); - - var lastItemIndex = this._items.length - 1; - var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex; - - if (isGoingToWrap && !this._config.wrap) { - return activeElement; - } - - var delta = direction === Direction.PREV ? -1 : 1; - var itemIndex = (activeIndex + delta) % this._items.length; - return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex]; - }; - - _proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) { - var targetIndex = this._getItemIndex(relatedTarget); - - var fromIndex = this._getItemIndex($$$1(this._element).find(Selector.ACTIVE_ITEM)[0]); - - var slideEvent = $$$1.Event(Event.SLIDE, { - relatedTarget: relatedTarget, - direction: eventDirectionName, - from: fromIndex, - to: targetIndex - }); - $$$1(this._element).trigger(slideEvent); - return slideEvent; - }; - - _proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) { - if (this._indicatorsElement) { - $$$1(this._indicatorsElement).find(Selector.ACTIVE).removeClass(ClassName.ACTIVE); - - var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)]; - - if (nextIndicator) { - $$$1(nextIndicator).addClass(ClassName.ACTIVE); - } - } - }; - - _proto._slide = function _slide(direction, element) { - var _this3 = this; - - var activeElement = $$$1(this._element).find(Selector.ACTIVE_ITEM)[0]; - - var activeElementIndex = this._getItemIndex(activeElement); - - var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement); - - var nextElementIndex = this._getItemIndex(nextElement); - - var isCycling = Boolean(this._interval); - var directionalClassName; - var orderClassName; - var eventDirectionName; - - if (direction === Direction.NEXT) { - directionalClassName = ClassName.LEFT; - orderClassName = ClassName.NEXT; - eventDirectionName = Direction.LEFT; - } else { - directionalClassName = ClassName.RIGHT; - orderClassName = ClassName.PREV; - eventDirectionName = Direction.RIGHT; - } - - if (nextElement && $$$1(nextElement).hasClass(ClassName.ACTIVE)) { - this._isSliding = false; - return; - } - - var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName); - - if (slideEvent.isDefaultPrevented()) { - return; - } - - if (!activeElement || !nextElement) { - // Some weirdness is happening, so we bail - return; - } - - this._isSliding = true; - - if (isCycling) { - this.pause(); - } - - this._setActiveIndicatorElement(nextElement); - - var slidEvent = $$$1.Event(Event.SLID, { - relatedTarget: nextElement, - direction: eventDirectionName, - from: activeElementIndex, - to: nextElementIndex - }); - - if (Util.supportsTransitionEnd() && $$$1(this._element).hasClass(ClassName.SLIDE)) { - $$$1(nextElement).addClass(orderClassName); - Util.reflow(nextElement); - $$$1(activeElement).addClass(directionalClassName); - $$$1(nextElement).addClass(directionalClassName); - $$$1(activeElement).one(Util.TRANSITION_END, function () { - $$$1(nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(ClassName.ACTIVE); - $$$1(activeElement).removeClass(ClassName.ACTIVE + " " + orderClassName + " " + directionalClassName); - _this3._isSliding = false; - setTimeout(function () { - return $$$1(_this3._element).trigger(slidEvent); - }, 0); - }).emulateTransitionEnd(TRANSITION_DURATION); - } else { - $$$1(activeElement).removeClass(ClassName.ACTIVE); - $$$1(nextElement).addClass(ClassName.ACTIVE); - this._isSliding = false; - $$$1(this._element).trigger(slidEvent); - } - - if (isCycling) { - this.cycle(); - } - }; // Static - - - Carousel._jQueryInterface = function _jQueryInterface(config) { - return this.each(function () { - var data = $$$1(this).data(DATA_KEY); - - var _config = _extends({}, Default, $$$1(this).data()); - - if (typeof config === 'object') { - _config = _extends({}, _config, config); - } - - var action = typeof config === 'string' ? config : _config.slide; - - if (!data) { - data = new Carousel(this, _config); - $$$1(this).data(DATA_KEY, data); - } - - if (typeof config === 'number') { - data.to(config); - } else if (typeof action === 'string') { - if (typeof data[action] === 'undefined') { - throw new TypeError("No method named \"" + action + "\""); - } - - data[action](); - } else if (_config.interval) { - data.pause(); - data.cycle(); - } - }); - }; - - Carousel._dataApiClickHandler = function _dataApiClickHandler(event) { - var selector = Util.getSelectorFromElement(this); - - if (!selector) { - return; - } - - var target = $$$1(selector)[0]; - - if (!target || !$$$1(target).hasClass(ClassName.CAROUSEL)) { - return; - } - - var config = _extends({}, $$$1(target).data(), $$$1(this).data()); - var slideIndex = this.getAttribute('data-slide-to'); - - if (slideIndex) { - config.interval = false; - } - - Carousel._jQueryInterface.call($$$1(target), config); - - if (slideIndex) { - $$$1(target).data(DATA_KEY).to(slideIndex); - } - - event.preventDefault(); - }; - - _createClass(Carousel, null, [{ - key: "VERSION", - get: function get() { - return VERSION; - } - }, { - key: "Default", - get: function get() { - return Default; - } - }]); - return Carousel; - }(); - /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ - */ - - - $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler); - $$$1(window).on(Event.LOAD_DATA_API, function () { - $$$1(Selector.DATA_RIDE).each(function () { - var $carousel = $$$1(this); - - Carousel._jQueryInterface.call($carousel, $carousel.data()); - }); - }); - /** - * ------------------------------------------------------------------------ - * jQuery - * ------------------------------------------------------------------------ - */ - - $$$1.fn[NAME] = Carousel._jQueryInterface; - $$$1.fn[NAME].Constructor = Carousel; - - $$$1.fn[NAME].noConflict = function () { - $$$1.fn[NAME] = JQUERY_NO_CONFLICT; - return Carousel._jQueryInterface; - }; - - return Carousel; -}($); - -/** - * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0): collapse.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * -------------------------------------------------------------------------- - */ - -var Collapse = function ($$$1) { - /** - * ------------------------------------------------------------------------ - * Constants - * ------------------------------------------------------------------------ - */ - var NAME = 'collapse'; - var VERSION = '4.0.0'; - var DATA_KEY = 'bs.collapse'; - var EVENT_KEY = "." + DATA_KEY; - var DATA_API_KEY = '.data-api'; - var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; - var TRANSITION_DURATION = 600; - var Default = { - toggle: true, - parent: '' - }; - var DefaultType = { - toggle: 'boolean', - parent: '(string|element)' - }; - var Event = { - SHOW: "show" + EVENT_KEY, - SHOWN: "shown" + EVENT_KEY, - HIDE: "hide" + EVENT_KEY, - HIDDEN: "hidden" + EVENT_KEY, - CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY - }; - var ClassName = { - SHOW: 'show', - COLLAPSE: 'collapse', - COLLAPSING: 'collapsing', - COLLAPSED: 'collapsed' - }; - var Dimension = { - WIDTH: 'width', - HEIGHT: 'height' - }; - var Selector = { - ACTIVES: '.show, .collapsing', - DATA_TOGGLE: '[data-toggle="collapse"]' - /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ - */ - - }; - - var Collapse = - /*#__PURE__*/ - function () { - function Collapse(element, config) { - this._isTransitioning = false; - this._element = element; - this._config = this._getConfig(config); - this._triggerArray = $$$1.makeArray($$$1("[data-toggle=\"collapse\"][href=\"#" + element.id + "\"]," + ("[data-toggle=\"collapse\"][data-target=\"#" + element.id + "\"]"))); - var tabToggles = $$$1(Selector.DATA_TOGGLE); - - for (var i = 0; i < tabToggles.length; i++) { - var elem = tabToggles[i]; - var selector = Util.getSelectorFromElement(elem); - - if (selector !== null && $$$1(selector).filter(element).length > 0) { - this._selector = selector; - - this._triggerArray.push(elem); - } - } - - this._parent = this._config.parent ? this._getParent() : null; - - if (!this._config.parent) { - this._addAriaAndCollapsedClass(this._element, this._triggerArray); - } - - if (this._config.toggle) { - this.toggle(); - } - } // Getters - - - var _proto = Collapse.prototype; - - // Public - _proto.toggle = function toggle() { - if ($$$1(this._element).hasClass(ClassName.SHOW)) { - this.hide(); - } else { - this.show(); - } - }; - - _proto.show = function show() { - var _this = this; - - if (this._isTransitioning || $$$1(this._element).hasClass(ClassName.SHOW)) { - return; - } - - var actives; - var activesData; - - if (this._parent) { - actives = $$$1.makeArray($$$1(this._parent).find(Selector.ACTIVES).filter("[data-parent=\"" + this._config.parent + "\"]")); - - if (actives.length === 0) { - actives = null; - } - } - - if (actives) { - activesData = $$$1(actives).not(this._selector).data(DATA_KEY); - - if (activesData && activesData._isTransitioning) { - return; - } - } - - var startEvent = $$$1.Event(Event.SHOW); - $$$1(this._element).trigger(startEvent); - - if (startEvent.isDefaultPrevented()) { - return; - } - - if (actives) { - Collapse._jQueryInterface.call($$$1(actives).not(this._selector), 'hide'); - - if (!activesData) { - $$$1(actives).data(DATA_KEY, null); - } - } - - var dimension = this._getDimension(); - - $$$1(this._element).removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING); - this._element.style[dimension] = 0; - - if (this._triggerArray.length > 0) { - $$$1(this._triggerArray).removeClass(ClassName.COLLAPSED).attr('aria-expanded', true); - } - - this.setTransitioning(true); - - var complete = function complete() { - $$$1(_this._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).addClass(ClassName.SHOW); - _this._element.style[dimension] = ''; - - _this.setTransitioning(false); - - $$$1(_this._element).trigger(Event.SHOWN); - }; - - if (!Util.supportsTransitionEnd()) { - complete(); - return; - } - - var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); - var scrollSize = "scroll" + capitalizedDimension; - $$$1(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION); - this._element.style[dimension] = this._element[scrollSize] + "px"; - }; - - _proto.hide = function hide() { - var _this2 = this; - - if (this._isTransitioning || !$$$1(this._element).hasClass(ClassName.SHOW)) { - return; - } - - var startEvent = $$$1.Event(Event.HIDE); - $$$1(this._element).trigger(startEvent); - - if (startEvent.isDefaultPrevented()) { - return; - } - - var dimension = this._getDimension(); - - this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px"; - Util.reflow(this._element); - $$$1(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.SHOW); - - if (this._triggerArray.length > 0) { - for (var i = 0; i < this._triggerArray.length; i++) { - var trigger = this._triggerArray[i]; - var selector = Util.getSelectorFromElement(trigger); - - if (selector !== null) { - var $elem = $$$1(selector); - - if (!$elem.hasClass(ClassName.SHOW)) { - $$$1(trigger).addClass(ClassName.COLLAPSED).attr('aria-expanded', false); - } - } - } - } - - this.setTransitioning(true); - - var complete = function complete() { - _this2.setTransitioning(false); - - $$$1(_this2._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).trigger(Event.HIDDEN); - }; - - this._element.style[dimension] = ''; - - if (!Util.supportsTransitionEnd()) { - complete(); - return; - } - - $$$1(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION); - }; - - _proto.setTransitioning = function setTransitioning(isTransitioning) { - this._isTransitioning = isTransitioning; - }; - - _proto.dispose = function dispose() { - $$$1.removeData(this._element, DATA_KEY); - this._config = null; - this._parent = null; - this._element = null; - this._triggerArray = null; - this._isTransitioning = null; - }; // Private - - - _proto._getConfig = function _getConfig(config) { - config = _extends({}, Default, config); - config.toggle = Boolean(config.toggle); // Coerce string values - - Util.typeCheckConfig(NAME, config, DefaultType); - return config; - }; - - _proto._getDimension = function _getDimension() { - var hasWidth = $$$1(this._element).hasClass(Dimension.WIDTH); - return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT; - }; - - _proto._getParent = function _getParent() { - var _this3 = this; - - var parent = null; - - if (Util.isElement(this._config.parent)) { - parent = this._config.parent; // It's a jQuery object - - if (typeof this._config.parent.jquery !== 'undefined') { - parent = this._config.parent[0]; - } - } else { - parent = $$$1(this._config.parent)[0]; - } - - var selector = "[data-toggle=\"collapse\"][data-parent=\"" + this._config.parent + "\"]"; - $$$1(parent).find(selector).each(function (i, element) { - _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]); - }); - return parent; - }; - - _proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) { - if (element) { - var isOpen = $$$1(element).hasClass(ClassName.SHOW); - - if (triggerArray.length > 0) { - $$$1(triggerArray).toggleClass(ClassName.COLLAPSED, !isOpen).attr('aria-expanded', isOpen); - } - } - }; // Static - - - Collapse._getTargetFromElement = function _getTargetFromElement(element) { - var selector = Util.getSelectorFromElement(element); - return selector ? $$$1(selector)[0] : null; - }; - - Collapse._jQueryInterface = function _jQueryInterface(config) { - return this.each(function () { - var $this = $$$1(this); - var data = $this.data(DATA_KEY); - - var _config = _extends({}, Default, $this.data(), typeof config === 'object' && config); - - if (!data && _config.toggle && /show|hide/.test(config)) { - _config.toggle = false; - } - - if (!data) { - data = new Collapse(this, _config); - $this.data(DATA_KEY, data); - } - - if (typeof config === 'string') { - if (typeof data[config] === 'undefined') { - throw new TypeError("No method named \"" + config + "\""); - } - - data[config](); - } - }); - }; - - _createClass(Collapse, null, [{ - key: "VERSION", - get: function get() { - return VERSION; - } - }, { - key: "Default", - get: function get() { - return Default; - } - }]); - return Collapse; - }(); - /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ - */ - - - $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { - // preventDefault only for elements (which change the URL) not inside the collapsible element - if (event.currentTarget.tagName === 'A') { - event.preventDefault(); - } - - var $trigger = $$$1(this); - var selector = Util.getSelectorFromElement(this); - $$$1(selector).each(function () { - var $target = $$$1(this); - var data = $target.data(DATA_KEY); - var config = data ? 'toggle' : $trigger.data(); - - Collapse._jQueryInterface.call($target, config); - }); - }); - /** - * ------------------------------------------------------------------------ - * jQuery - * ------------------------------------------------------------------------ - */ - - $$$1.fn[NAME] = Collapse._jQueryInterface; - $$$1.fn[NAME].Constructor = Collapse; - - $$$1.fn[NAME].noConflict = function () { - $$$1.fn[NAME] = JQUERY_NO_CONFLICT; - return Collapse._jQueryInterface; - }; - - return Collapse; -}($); - -/** - * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0): modal.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * -------------------------------------------------------------------------- - */ - -var Modal = function ($$$1) { - /** - * ------------------------------------------------------------------------ - * Constants - * ------------------------------------------------------------------------ - */ - var NAME = 'modal'; - var VERSION = '4.0.0'; - var DATA_KEY = 'bs.modal'; - var EVENT_KEY = "." + DATA_KEY; - var DATA_API_KEY = '.data-api'; - var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; - var TRANSITION_DURATION = 300; - var BACKDROP_TRANSITION_DURATION = 150; - var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key - - var Default = { - backdrop: true, - keyboard: true, - focus: true, - show: true - }; - var DefaultType = { - backdrop: '(boolean|string)', - keyboard: 'boolean', - focus: 'boolean', - show: 'boolean' - }; - var Event = { - HIDE: "hide" + EVENT_KEY, - HIDDEN: "hidden" + EVENT_KEY, - SHOW: "show" + EVENT_KEY, - SHOWN: "shown" + EVENT_KEY, - FOCUSIN: "focusin" + EVENT_KEY, - RESIZE: "resize" + EVENT_KEY, - CLICK_DISMISS: "click.dismiss" + EVENT_KEY, - KEYDOWN_DISMISS: "keydown.dismiss" + EVENT_KEY, - MOUSEUP_DISMISS: "mouseup.dismiss" + EVENT_KEY, - MOUSEDOWN_DISMISS: "mousedown.dismiss" + EVENT_KEY, - CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY - }; - var ClassName = { - SCROLLBAR_MEASURER: 'modal-scrollbar-measure', - BACKDROP: 'modal-backdrop', - OPEN: 'modal-open', - FADE: 'fade', - SHOW: 'show' - }; - var Selector = { - DIALOG: '.modal-dialog', - DATA_TOGGLE: '[data-toggle="modal"]', - DATA_DISMISS: '[data-dismiss="modal"]', - FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top', - STICKY_CONTENT: '.sticky-top', - NAVBAR_TOGGLER: '.navbar-toggler' - /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ - */ - - }; - - var Modal = - /*#__PURE__*/ - function () { - function Modal(element, config) { - this._config = this._getConfig(config); - this._element = element; - this._dialog = $$$1(element).find(Selector.DIALOG)[0]; - this._backdrop = null; - this._isShown = false; - this._isBodyOverflowing = false; - this._ignoreBackdropClick = false; - this._originalBodyPadding = 0; - this._scrollbarWidth = 0; - } // Getters - - - var _proto = Modal.prototype; - - // Public - _proto.toggle = function toggle(relatedTarget) { - return this._isShown ? this.hide() : this.show(relatedTarget); - }; - - _proto.show = function show(relatedTarget) { - var _this = this; - - if (this._isTransitioning || this._isShown) { - return; - } - - if (Util.supportsTransitionEnd() && $$$1(this._element).hasClass(ClassName.FADE)) { - this._isTransitioning = true; - } - - var showEvent = $$$1.Event(Event.SHOW, { - relatedTarget: relatedTarget - }); - $$$1(this._element).trigger(showEvent); - - if (this._isShown || showEvent.isDefaultPrevented()) { - return; - } - - this._isShown = true; - - this._checkScrollbar(); - - this._setScrollbar(); - - this._adjustDialog(); - - $$$1(document.body).addClass(ClassName.OPEN); - - this._setEscapeEvent(); - - this._setResizeEvent(); - - $$$1(this._element).on(Event.CLICK_DISMISS, Selector.DATA_DISMISS, function (event) { - return _this.hide(event); - }); - $$$1(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () { - $$$1(_this._element).one(Event.MOUSEUP_DISMISS, function (event) { - if ($$$1(event.target).is(_this._element)) { - _this._ignoreBackdropClick = true; - } - }); - }); - - this._showBackdrop(function () { - return _this._showElement(relatedTarget); - }); - }; - - _proto.hide = function hide(event) { - var _this2 = this; - - if (event) { - event.preventDefault(); - } - - if (this._isTransitioning || !this._isShown) { - return; - } - - var hideEvent = $$$1.Event(Event.HIDE); - $$$1(this._element).trigger(hideEvent); - - if (!this._isShown || hideEvent.isDefaultPrevented()) { - return; - } - - this._isShown = false; - var transition = Util.supportsTransitionEnd() && $$$1(this._element).hasClass(ClassName.FADE); - - if (transition) { - this._isTransitioning = true; - } - - this._setEscapeEvent(); - - this._setResizeEvent(); - - $$$1(document).off(Event.FOCUSIN); - $$$1(this._element).removeClass(ClassName.SHOW); - $$$1(this._element).off(Event.CLICK_DISMISS); - $$$1(this._dialog).off(Event.MOUSEDOWN_DISMISS); - - if (transition) { - $$$1(this._element).one(Util.TRANSITION_END, function (event) { - return _this2._hideModal(event); - }).emulateTransitionEnd(TRANSITION_DURATION); - } else { - this._hideModal(); - } - }; - - _proto.dispose = function dispose() { - $$$1.removeData(this._element, DATA_KEY); - $$$1(window, document, this._element, this._backdrop).off(EVENT_KEY); - this._config = null; - this._element = null; - this._dialog = null; - this._backdrop = null; - this._isShown = null; - this._isBodyOverflowing = null; - this._ignoreBackdropClick = null; - this._scrollbarWidth = null; - }; - - _proto.handleUpdate = function handleUpdate() { - this._adjustDialog(); - }; // Private - - - _proto._getConfig = function _getConfig(config) { - config = _extends({}, Default, config); - Util.typeCheckConfig(NAME, config, DefaultType); - return config; - }; - - _proto._showElement = function _showElement(relatedTarget) { - var _this3 = this; - - var transition = Util.supportsTransitionEnd() && $$$1(this._element).hasClass(ClassName.FADE); - - if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) { - // Don't move modal's DOM position - document.body.appendChild(this._element); - } - - this._element.style.display = 'block'; - - this._element.removeAttribute('aria-hidden'); - - this._element.scrollTop = 0; - - if (transition) { - Util.reflow(this._element); - } - - $$$1(this._element).addClass(ClassName.SHOW); - - if (this._config.focus) { - this._enforceFocus(); - } - - var shownEvent = $$$1.Event(Event.SHOWN, { - relatedTarget: relatedTarget - }); - - var transitionComplete = function transitionComplete() { - if (_this3._config.focus) { - _this3._element.focus(); - } - - _this3._isTransitioning = false; - $$$1(_this3._element).trigger(shownEvent); - }; - - if (transition) { - $$$1(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(TRANSITION_DURATION); - } else { - transitionComplete(); - } - }; - - _proto._enforceFocus = function _enforceFocus() { - var _this4 = this; - - $$$1(document).off(Event.FOCUSIN) // Guard against infinite focus loop - .on(Event.FOCUSIN, function (event) { - if (document !== event.target && _this4._element !== event.target && $$$1(_this4._element).has(event.target).length === 0) { - _this4._element.focus(); - } - }); - }; - - _proto._setEscapeEvent = function _setEscapeEvent() { - var _this5 = this; - - if (this._isShown && this._config.keyboard) { - $$$1(this._element).on(Event.KEYDOWN_DISMISS, function (event) { - if (event.which === ESCAPE_KEYCODE) { - event.preventDefault(); - - _this5.hide(); - } - }); - } else if (!this._isShown) { - $$$1(this._element).off(Event.KEYDOWN_DISMISS); - } - }; - - _proto._setResizeEvent = function _setResizeEvent() { - var _this6 = this; - - if (this._isShown) { - $$$1(window).on(Event.RESIZE, function (event) { - return _this6.handleUpdate(event); - }); - } else { - $$$1(window).off(Event.RESIZE); - } - }; - - _proto._hideModal = function _hideModal() { - var _this7 = this; - - this._element.style.display = 'none'; - - this._element.setAttribute('aria-hidden', true); - - this._isTransitioning = false; - - this._showBackdrop(function () { - $$$1(document.body).removeClass(ClassName.OPEN); - - _this7._resetAdjustments(); - - _this7._resetScrollbar(); - - $$$1(_this7._element).trigger(Event.HIDDEN); - }); - }; - - _proto._removeBackdrop = function _removeBackdrop() { - if (this._backdrop) { - $$$1(this._backdrop).remove(); - this._backdrop = null; - } - }; - - _proto._showBackdrop = function _showBackdrop(callback) { - var _this8 = this; - - var animate = $$$1(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : ''; - - if (this._isShown && this._config.backdrop) { - var doAnimate = Util.supportsTransitionEnd() && animate; - this._backdrop = document.createElement('div'); - this._backdrop.className = ClassName.BACKDROP; - - if (animate) { - $$$1(this._backdrop).addClass(animate); - } - - $$$1(this._backdrop).appendTo(document.body); - $$$1(this._element).on(Event.CLICK_DISMISS, function (event) { - if (_this8._ignoreBackdropClick) { - _this8._ignoreBackdropClick = false; - return; - } - - if (event.target !== event.currentTarget) { - return; - } - - if (_this8._config.backdrop === 'static') { - _this8._element.focus(); - } else { - _this8.hide(); - } - }); - - if (doAnimate) { - Util.reflow(this._backdrop); - } - - $$$1(this._backdrop).addClass(ClassName.SHOW); - - if (!callback) { - return; - } - - if (!doAnimate) { - callback(); - return; - } - - $$$1(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION); - } else if (!this._isShown && this._backdrop) { - $$$1(this._backdrop).removeClass(ClassName.SHOW); - - var callbackRemove = function callbackRemove() { - _this8._removeBackdrop(); - - if (callback) { - callback(); - } - }; - - if (Util.supportsTransitionEnd() && $$$1(this._element).hasClass(ClassName.FADE)) { - $$$1(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION); - } else { - callbackRemove(); - } - } else if (callback) { - callback(); - } - }; // ---------------------------------------------------------------------- - // the following methods are used to handle overflowing modals - // todo (fat): these should probably be refactored out of modal.js - // ---------------------------------------------------------------------- - - - _proto._adjustDialog = function _adjustDialog() { - var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; - - if (!this._isBodyOverflowing && isModalOverflowing) { - this._element.style.paddingLeft = this._scrollbarWidth + "px"; - } - - if (this._isBodyOverflowing && !isModalOverflowing) { - this._element.style.paddingRight = this._scrollbarWidth + "px"; - } - }; - - _proto._resetAdjustments = function _resetAdjustments() { - this._element.style.paddingLeft = ''; - this._element.style.paddingRight = ''; - }; - - _proto._checkScrollbar = function _checkScrollbar() { - var rect = document.body.getBoundingClientRect(); - this._isBodyOverflowing = rect.left + rect.right < window.innerWidth; - this._scrollbarWidth = this._getScrollbarWidth(); - }; - - _proto._setScrollbar = function _setScrollbar() { - var _this9 = this; - - if (this._isBodyOverflowing) { - // Note: DOMNode.style.paddingRight returns the actual value or '' if not set - // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set - // Adjust fixed content padding - $$$1(Selector.FIXED_CONTENT).each(function (index, element) { - var actualPadding = $$$1(element)[0].style.paddingRight; - var calculatedPadding = $$$1(element).css('padding-right'); - $$$1(element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this9._scrollbarWidth + "px"); - }); // Adjust sticky content margin - - $$$1(Selector.STICKY_CONTENT).each(function (index, element) { - var actualMargin = $$$1(element)[0].style.marginRight; - var calculatedMargin = $$$1(element).css('margin-right'); - $$$1(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - _this9._scrollbarWidth + "px"); - }); // Adjust navbar-toggler margin - - $$$1(Selector.NAVBAR_TOGGLER).each(function (index, element) { - var actualMargin = $$$1(element)[0].style.marginRight; - var calculatedMargin = $$$1(element).css('margin-right'); - $$$1(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) + _this9._scrollbarWidth + "px"); - }); // Adjust body padding - - var actualPadding = document.body.style.paddingRight; - var calculatedPadding = $$$1('body').css('padding-right'); - $$$1('body').data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px"); - } - }; - - _proto._resetScrollbar = function _resetScrollbar() { - // Restore fixed content padding - $$$1(Selector.FIXED_CONTENT).each(function (index, element) { - var padding = $$$1(element).data('padding-right'); - - if (typeof padding !== 'undefined') { - $$$1(element).css('padding-right', padding).removeData('padding-right'); - } - }); // Restore sticky content and navbar-toggler margin - - $$$1(Selector.STICKY_CONTENT + ", " + Selector.NAVBAR_TOGGLER).each(function (index, element) { - var margin = $$$1(element).data('margin-right'); - - if (typeof margin !== 'undefined') { - $$$1(element).css('margin-right', margin).removeData('margin-right'); - } - }); // Restore body padding - - var padding = $$$1('body').data('padding-right'); - - if (typeof padding !== 'undefined') { - $$$1('body').css('padding-right', padding).removeData('padding-right'); - } - }; - - _proto._getScrollbarWidth = function _getScrollbarWidth() { - // thx d.walsh - var scrollDiv = document.createElement('div'); - scrollDiv.className = ClassName.SCROLLBAR_MEASURER; - document.body.appendChild(scrollDiv); - var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth; - document.body.removeChild(scrollDiv); - return scrollbarWidth; - }; // Static - - - Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) { - return this.each(function () { - var data = $$$1(this).data(DATA_KEY); - - var _config = _extends({}, Modal.Default, $$$1(this).data(), typeof config === 'object' && config); - - if (!data) { - data = new Modal(this, _config); - $$$1(this).data(DATA_KEY, data); - } - - if (typeof config === 'string') { - if (typeof data[config] === 'undefined') { - throw new TypeError("No method named \"" + config + "\""); - } - - data[config](relatedTarget); - } else if (_config.show) { - data.show(relatedTarget); - } - }); - }; - - _createClass(Modal, null, [{ - key: "VERSION", - get: function get() { - return VERSION; - } - }, { - key: "Default", - get: function get() { - return Default; - } - }]); - return Modal; - }(); - /** - * ------------------------------------------------------------------------ - * Data Api implementation - * ------------------------------------------------------------------------ - */ - - - $$$1(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) { - var _this10 = this; - - var target; - var selector = Util.getSelectorFromElement(this); - - if (selector) { - target = $$$1(selector)[0]; - } - - var config = $$$1(target).data(DATA_KEY) ? 'toggle' : _extends({}, $$$1(target).data(), $$$1(this).data()); - - if (this.tagName === 'A' || this.tagName === 'AREA') { - event.preventDefault(); - } - - var $target = $$$1(target).one(Event.SHOW, function (showEvent) { - if (showEvent.isDefaultPrevented()) { - // Only register focus restorer if modal will actually get shown - return; - } - - $target.one(Event.HIDDEN, function () { - if ($$$1(_this10).is(':visible')) { - _this10.focus(); - } - }); - }); - - Modal._jQueryInterface.call($$$1(target), config, this); - }); - /** - * ------------------------------------------------------------------------ - * jQuery - * ------------------------------------------------------------------------ - */ - - $$$1.fn[NAME] = Modal._jQueryInterface; - $$$1.fn[NAME].Constructor = Modal; - - $$$1.fn[NAME].noConflict = function () { - $$$1.fn[NAME] = JQUERY_NO_CONFLICT; - return Modal._jQueryInterface; - }; - - return Modal; -}($); - -/** - * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0): tooltip.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * -------------------------------------------------------------------------- - */ - -var Tooltip = function ($$$1) { - /** - * ------------------------------------------------------------------------ - * Constants - * ------------------------------------------------------------------------ - */ - var NAME = 'tooltip'; - var VERSION = '4.0.0'; - var DATA_KEY = 'bs.tooltip'; - var EVENT_KEY = "." + DATA_KEY; - var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; - var TRANSITION_DURATION = 150; - var CLASS_PREFIX = 'bs-tooltip'; - var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); - var DefaultType = { - animation: 'boolean', - template: 'string', - title: '(string|element|function)', - trigger: 'string', - delay: '(number|object)', - html: 'boolean', - selector: '(string|boolean)', - placement: '(string|function)', - offset: '(number|string)', - container: '(string|element|boolean)', - fallbackPlacement: '(string|array)', - boundary: '(string|element)' - }; - var AttachmentMap = { - AUTO: 'auto', - TOP: 'top', - RIGHT: 'right', - BOTTOM: 'bottom', - LEFT: 'left' - }; - var Default = { - animation: true, - template: '', - trigger: 'hover focus', - title: '', - delay: 0, - html: false, - selector: false, - placement: 'top', - offset: 0, - container: false, - fallbackPlacement: 'flip', - boundary: 'scrollParent' - }; - var HoverState = { - SHOW: 'show', - OUT: 'out' - }; - var Event = { - HIDE: "hide" + EVENT_KEY, - HIDDEN: "hidden" + EVENT_KEY, - SHOW: "show" + EVENT_KEY, - SHOWN: "shown" + EVENT_KEY, - INSERTED: "inserted" + EVENT_KEY, - CLICK: "click" + EVENT_KEY, - FOCUSIN: "focusin" + EVENT_KEY, - FOCUSOUT: "focusout" + EVENT_KEY, - MOUSEENTER: "mouseenter" + EVENT_KEY, - MOUSELEAVE: "mouseleave" + EVENT_KEY - }; - var ClassName = { - FADE: 'fade', - SHOW: 'show' - }; - var Selector = { - TOOLTIP: '.tooltip', - TOOLTIP_INNER: '.tooltip-inner', - ARROW: '.arrow' - }; - var Trigger = { - HOVER: 'hover', - FOCUS: 'focus', - CLICK: 'click', - MANUAL: 'manual' - /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ - */ - - }; - - var Tooltip = - /*#__PURE__*/ - function () { - function Tooltip(element, config) { - /** - * Check for Popper dependency - * Popper - https://popper.js.org - */ - if (typeof Popper$1 === 'undefined') { - throw new TypeError('Bootstrap tooltips require Popper.js (https://popper.js.org)'); - } // private - - - this._isEnabled = true; - this._timeout = 0; - this._hoverState = ''; - this._activeTrigger = {}; - this._popper = null; // Protected - - this.element = element; - this.config = this._getConfig(config); - this.tip = null; - - this._setListeners(); - } // Getters - - - var _proto = Tooltip.prototype; - - // Public - _proto.enable = function enable() { - this._isEnabled = true; - }; - - _proto.disable = function disable() { - this._isEnabled = false; - }; - - _proto.toggleEnabled = function toggleEnabled() { - this._isEnabled = !this._isEnabled; - }; - - _proto.toggle = function toggle(event) { - if (!this._isEnabled) { - return; - } - - if (event) { - var dataKey = this.constructor.DATA_KEY; - var context = $$$1(event.currentTarget).data(dataKey); - - if (!context) { - context = new this.constructor(event.currentTarget, this._getDelegateConfig()); - $$$1(event.currentTarget).data(dataKey, context); - } - - context._activeTrigger.click = !context._activeTrigger.click; - - if (context._isWithActiveTrigger()) { - context._enter(null, context); - } else { - context._leave(null, context); - } - } else { - if ($$$1(this.getTipElement()).hasClass(ClassName.SHOW)) { - this._leave(null, this); - - return; - } - - this._enter(null, this); - } - }; - - _proto.dispose = function dispose() { - clearTimeout(this._timeout); - $$$1.removeData(this.element, this.constructor.DATA_KEY); - $$$1(this.element).off(this.constructor.EVENT_KEY); - $$$1(this.element).closest('.modal').off('hide.bs.modal'); - - if (this.tip) { - $$$1(this.tip).remove(); - } - - this._isEnabled = null; - this._timeout = null; - this._hoverState = null; - this._activeTrigger = null; - - if (this._popper !== null) { - this._popper.destroy(); - } - - this._popper = null; - this.element = null; - this.config = null; - this.tip = null; - }; - - _proto.show = function show() { - var _this = this; - - if ($$$1(this.element).css('display') === 'none') { - throw new Error('Please use show on visible elements'); - } - - var showEvent = $$$1.Event(this.constructor.Event.SHOW); - - if (this.isWithContent() && this._isEnabled) { - $$$1(this.element).trigger(showEvent); - var isInTheDom = $$$1.contains(this.element.ownerDocument.documentElement, this.element); - - if (showEvent.isDefaultPrevented() || !isInTheDom) { - return; - } - - var tip = this.getTipElement(); - var tipId = Util.getUID(this.constructor.NAME); - tip.setAttribute('id', tipId); - this.element.setAttribute('aria-describedby', tipId); - this.setContent(); - - if (this.config.animation) { - $$$1(tip).addClass(ClassName.FADE); - } - - var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement; - - var attachment = this._getAttachment(placement); - - this.addAttachmentClass(attachment); - var container = this.config.container === false ? document.body : $$$1(this.config.container); - $$$1(tip).data(this.constructor.DATA_KEY, this); - - if (!$$$1.contains(this.element.ownerDocument.documentElement, this.tip)) { - $$$1(tip).appendTo(container); - } - - $$$1(this.element).trigger(this.constructor.Event.INSERTED); - this._popper = new Popper$1(this.element, tip, { - placement: attachment, - modifiers: { - offset: { - offset: this.config.offset - }, - flip: { - behavior: this.config.fallbackPlacement - }, - arrow: { - element: Selector.ARROW - }, - preventOverflow: { - boundariesElement: this.config.boundary - } - }, - onCreate: function onCreate(data) { - if (data.originalPlacement !== data.placement) { - _this._handlePopperPlacementChange(data); - } - }, - onUpdate: function onUpdate(data) { - _this._handlePopperPlacementChange(data); - } - }); - $$$1(tip).addClass(ClassName.SHOW); // If this is a touch-enabled device we add extra - // empty mouseover listeners to the body's immediate children; - // only needed because of broken event delegation on iOS - // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html - - if ('ontouchstart' in document.documentElement) { - $$$1('body').children().on('mouseover', null, $$$1.noop); - } - - var complete = function complete() { - if (_this.config.animation) { - _this._fixTransition(); - } - - var prevHoverState = _this._hoverState; - _this._hoverState = null; - $$$1(_this.element).trigger(_this.constructor.Event.SHOWN); - - if (prevHoverState === HoverState.OUT) { - _this._leave(null, _this); - } - }; - - if (Util.supportsTransitionEnd() && $$$1(this.tip).hasClass(ClassName.FADE)) { - $$$1(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(Tooltip._TRANSITION_DURATION); - } else { - complete(); - } - } - }; - - _proto.hide = function hide(callback) { - var _this2 = this; - - var tip = this.getTipElement(); - var hideEvent = $$$1.Event(this.constructor.Event.HIDE); - - var complete = function complete() { - if (_this2._hoverState !== HoverState.SHOW && tip.parentNode) { - tip.parentNode.removeChild(tip); - } - - _this2._cleanTipClass(); - - _this2.element.removeAttribute('aria-describedby'); - - $$$1(_this2.element).trigger(_this2.constructor.Event.HIDDEN); - - if (_this2._popper !== null) { - _this2._popper.destroy(); - } - - if (callback) { - callback(); - } - }; - - $$$1(this.element).trigger(hideEvent); - - if (hideEvent.isDefaultPrevented()) { - return; - } - - $$$1(tip).removeClass(ClassName.SHOW); // If this is a touch-enabled device we remove the extra - // empty mouseover listeners we added for iOS support - - if ('ontouchstart' in document.documentElement) { - $$$1('body').children().off('mouseover', null, $$$1.noop); - } - - this._activeTrigger[Trigger.CLICK] = false; - this._activeTrigger[Trigger.FOCUS] = false; - this._activeTrigger[Trigger.HOVER] = false; - - if (Util.supportsTransitionEnd() && $$$1(this.tip).hasClass(ClassName.FADE)) { - $$$1(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION); - } else { - complete(); - } - - this._hoverState = ''; - }; - - _proto.update = function update() { - if (this._popper !== null) { - this._popper.scheduleUpdate(); - } - }; // Protected - - - _proto.isWithContent = function isWithContent() { - return Boolean(this.getTitle()); - }; - - _proto.addAttachmentClass = function addAttachmentClass(attachment) { - $$$1(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment); - }; - - _proto.getTipElement = function getTipElement() { - this.tip = this.tip || $$$1(this.config.template)[0]; - return this.tip; - }; - - _proto.setContent = function setContent() { - var $tip = $$$1(this.getTipElement()); - this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle()); - $tip.removeClass(ClassName.FADE + " " + ClassName.SHOW); - }; - - _proto.setElementContent = function setElementContent($element, content) { - var html = this.config.html; - - if (typeof content === 'object' && (content.nodeType || content.jquery)) { - // Content is a DOM node or a jQuery - if (html) { - if (!$$$1(content).parent().is($element)) { - $element.empty().append(content); - } - } else { - $element.text($$$1(content).text()); - } - } else { - $element[html ? 'html' : 'text'](content); - } - }; - - _proto.getTitle = function getTitle() { - var title = this.element.getAttribute('data-original-title'); - - if (!title) { - title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title; - } - - return title; - }; // Private - - - _proto._getAttachment = function _getAttachment(placement) { - return AttachmentMap[placement.toUpperCase()]; - }; - - _proto._setListeners = function _setListeners() { - var _this3 = this; - - var triggers = this.config.trigger.split(' '); - triggers.forEach(function (trigger) { - if (trigger === 'click') { - $$$1(_this3.element).on(_this3.constructor.Event.CLICK, _this3.config.selector, function (event) { - return _this3.toggle(event); - }); - } else if (trigger !== Trigger.MANUAL) { - var eventIn = trigger === Trigger.HOVER ? _this3.constructor.Event.MOUSEENTER : _this3.constructor.Event.FOCUSIN; - var eventOut = trigger === Trigger.HOVER ? _this3.constructor.Event.MOUSELEAVE : _this3.constructor.Event.FOCUSOUT; - $$$1(_this3.element).on(eventIn, _this3.config.selector, function (event) { - return _this3._enter(event); - }).on(eventOut, _this3.config.selector, function (event) { - return _this3._leave(event); - }); - } - - $$$1(_this3.element).closest('.modal').on('hide.bs.modal', function () { - return _this3.hide(); - }); - }); - - if (this.config.selector) { - this.config = _extends({}, this.config, { - trigger: 'manual', - selector: '' - }); - } else { - this._fixTitle(); - } - }; - - _proto._fixTitle = function _fixTitle() { - var titleType = typeof this.element.getAttribute('data-original-title'); - - if (this.element.getAttribute('title') || titleType !== 'string') { - this.element.setAttribute('data-original-title', this.element.getAttribute('title') || ''); - this.element.setAttribute('title', ''); - } - }; - - _proto._enter = function _enter(event, context) { - var dataKey = this.constructor.DATA_KEY; - context = context || $$$1(event.currentTarget).data(dataKey); - - if (!context) { - context = new this.constructor(event.currentTarget, this._getDelegateConfig()); - $$$1(event.currentTarget).data(dataKey, context); - } - - if (event) { - context._activeTrigger[event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER] = true; - } - - if ($$$1(context.getTipElement()).hasClass(ClassName.SHOW) || context._hoverState === HoverState.SHOW) { - context._hoverState = HoverState.SHOW; - return; - } - - clearTimeout(context._timeout); - context._hoverState = HoverState.SHOW; - - if (!context.config.delay || !context.config.delay.show) { - context.show(); - return; - } - - context._timeout = setTimeout(function () { - if (context._hoverState === HoverState.SHOW) { - context.show(); - } - }, context.config.delay.show); - }; - - _proto._leave = function _leave(event, context) { - var dataKey = this.constructor.DATA_KEY; - context = context || $$$1(event.currentTarget).data(dataKey); - - if (!context) { - context = new this.constructor(event.currentTarget, this._getDelegateConfig()); - $$$1(event.currentTarget).data(dataKey, context); - } - - if (event) { - context._activeTrigger[event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER] = false; - } - - if (context._isWithActiveTrigger()) { - return; - } - - clearTimeout(context._timeout); - context._hoverState = HoverState.OUT; - - if (!context.config.delay || !context.config.delay.hide) { - context.hide(); - return; - } - - context._timeout = setTimeout(function () { - if (context._hoverState === HoverState.OUT) { - context.hide(); - } - }, context.config.delay.hide); - }; - - _proto._isWithActiveTrigger = function _isWithActiveTrigger() { - for (var trigger in this._activeTrigger) { - if (this._activeTrigger[trigger]) { - return true; - } - } - - return false; - }; - - _proto._getConfig = function _getConfig(config) { - config = _extends({}, this.constructor.Default, $$$1(this.element).data(), config); - - if (typeof config.delay === 'number') { - config.delay = { - show: config.delay, - hide: config.delay - }; - } - - if (typeof config.title === 'number') { - config.title = config.title.toString(); - } - - if (typeof config.content === 'number') { - config.content = config.content.toString(); - } - - Util.typeCheckConfig(NAME, config, this.constructor.DefaultType); - return config; - }; - - _proto._getDelegateConfig = function _getDelegateConfig() { - var config = {}; - - if (this.config) { - for (var key in this.config) { - if (this.constructor.Default[key] !== this.config[key]) { - config[key] = this.config[key]; - } - } - } - - return config; - }; - - _proto._cleanTipClass = function _cleanTipClass() { - var $tip = $$$1(this.getTipElement()); - var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); - - if (tabClass !== null && tabClass.length > 0) { - $tip.removeClass(tabClass.join('')); - } - }; - - _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(data) { - this._cleanTipClass(); - - this.addAttachmentClass(this._getAttachment(data.placement)); - }; - - _proto._fixTransition = function _fixTransition() { - var tip = this.getTipElement(); - var initConfigAnimation = this.config.animation; - - if (tip.getAttribute('x-placement') !== null) { - return; - } - - $$$1(tip).removeClass(ClassName.FADE); - this.config.animation = false; - this.hide(); - this.show(); - this.config.animation = initConfigAnimation; - }; // Static - - - Tooltip._jQueryInterface = function _jQueryInterface(config) { - return this.each(function () { - var data = $$$1(this).data(DATA_KEY); - - var _config = typeof config === 'object' && config; - - if (!data && /dispose|hide/.test(config)) { - return; - } - - if (!data) { - data = new Tooltip(this, _config); - $$$1(this).data(DATA_KEY, data); - } - - if (typeof config === 'string') { - if (typeof data[config] === 'undefined') { - throw new TypeError("No method named \"" + config + "\""); - } - - data[config](); - } - }); - }; - - _createClass(Tooltip, null, [{ - key: "VERSION", - get: function get() { - return VERSION; - } - }, { - key: "Default", - get: function get() { - return Default; - } - }, { - key: "NAME", - get: function get() { - return NAME; - } - }, { - key: "DATA_KEY", - get: function get() { - return DATA_KEY; - } - }, { - key: "Event", - get: function get() { - return Event; - } - }, { - key: "EVENT_KEY", - get: function get() { - return EVENT_KEY; - } - }, { - key: "DefaultType", - get: function get() { - return DefaultType; - } - }]); - return Tooltip; - }(); - /** - * ------------------------------------------------------------------------ - * jQuery - * ------------------------------------------------------------------------ - */ - - - $$$1.fn[NAME] = Tooltip._jQueryInterface; - $$$1.fn[NAME].Constructor = Tooltip; - - $$$1.fn[NAME].noConflict = function () { - $$$1.fn[NAME] = JQUERY_NO_CONFLICT; - return Tooltip._jQueryInterface; - }; - - return Tooltip; -}($, Popper$1); - -/** - * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0): popover.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * -------------------------------------------------------------------------- - */ - -var Popover = function ($$$1) { - /** - * ------------------------------------------------------------------------ - * Constants - * ------------------------------------------------------------------------ - */ - var NAME = 'popover'; - var VERSION = '4.0.0'; - var DATA_KEY = 'bs.popover'; - var EVENT_KEY = "." + DATA_KEY; - var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; - var CLASS_PREFIX = 'bs-popover'; - var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); - var Default = _extends({}, Tooltip.Default, { - placement: 'right', - trigger: 'click', - content: '', - template: '' - }); - var DefaultType = _extends({}, Tooltip.DefaultType, { - content: '(string|element|function)' - }); - var ClassName = { - FADE: 'fade', - SHOW: 'show' - }; - var Selector = { - TITLE: '.popover-header', - CONTENT: '.popover-body' - }; - var Event = { - HIDE: "hide" + EVENT_KEY, - HIDDEN: "hidden" + EVENT_KEY, - SHOW: "show" + EVENT_KEY, - SHOWN: "shown" + EVENT_KEY, - INSERTED: "inserted" + EVENT_KEY, - CLICK: "click" + EVENT_KEY, - FOCUSIN: "focusin" + EVENT_KEY, - FOCUSOUT: "focusout" + EVENT_KEY, - MOUSEENTER: "mouseenter" + EVENT_KEY, - MOUSELEAVE: "mouseleave" + EVENT_KEY - /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ - */ - - }; - - var Popover = - /*#__PURE__*/ - function (_Tooltip) { - _inheritsLoose(Popover, _Tooltip); - - function Popover() { - return _Tooltip.apply(this, arguments) || this; - } - - var _proto = Popover.prototype; - - // Overrides - _proto.isWithContent = function isWithContent() { - return this.getTitle() || this._getContent(); - }; - - _proto.addAttachmentClass = function addAttachmentClass(attachment) { - $$$1(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment); - }; - - _proto.getTipElement = function getTipElement() { - this.tip = this.tip || $$$1(this.config.template)[0]; - return this.tip; - }; - - _proto.setContent = function setContent() { - var $tip = $$$1(this.getTipElement()); // We use append for html objects to maintain js events - - this.setElementContent($tip.find(Selector.TITLE), this.getTitle()); - - var content = this._getContent(); - - if (typeof content === 'function') { - content = content.call(this.element); - } - - this.setElementContent($tip.find(Selector.CONTENT), content); - $tip.removeClass(ClassName.FADE + " " + ClassName.SHOW); - }; // Private - - - _proto._getContent = function _getContent() { - return this.element.getAttribute('data-content') || this.config.content; - }; - - _proto._cleanTipClass = function _cleanTipClass() { - var $tip = $$$1(this.getTipElement()); - var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); - - if (tabClass !== null && tabClass.length > 0) { - $tip.removeClass(tabClass.join('')); - } - }; // Static - - - Popover._jQueryInterface = function _jQueryInterface(config) { - return this.each(function () { - var data = $$$1(this).data(DATA_KEY); - - var _config = typeof config === 'object' ? config : null; - - if (!data && /destroy|hide/.test(config)) { - return; - } - - if (!data) { - data = new Popover(this, _config); - $$$1(this).data(DATA_KEY, data); - } - - if (typeof config === 'string') { - if (typeof data[config] === 'undefined') { - throw new TypeError("No method named \"" + config + "\""); - } - - data[config](); - } - }); - }; - - _createClass(Popover, null, [{ - key: "VERSION", - // Getters - get: function get() { - return VERSION; - } - }, { - key: "Default", - get: function get() { - return Default; - } - }, { - key: "NAME", - get: function get() { - return NAME; - } - }, { - key: "DATA_KEY", - get: function get() { - return DATA_KEY; - } - }, { - key: "Event", - get: function get() { - return Event; - } - }, { - key: "EVENT_KEY", - get: function get() { - return EVENT_KEY; - } - }, { - key: "DefaultType", - get: function get() { - return DefaultType; - } - }]); - return Popover; - }(Tooltip); - /** - * ------------------------------------------------------------------------ - * jQuery - * ------------------------------------------------------------------------ - */ - - - $$$1.fn[NAME] = Popover._jQueryInterface; - $$$1.fn[NAME].Constructor = Popover; - - $$$1.fn[NAME].noConflict = function () { - $$$1.fn[NAME] = JQUERY_NO_CONFLICT; - return Popover._jQueryInterface; - }; - - return Popover; -}($); - -/** - * -------------------------------------------------------------------------- - * Bootstrap (v4.0.0): scrollspy.js - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - * -------------------------------------------------------------------------- - */ - -var ScrollSpy = function ($$$1) { - /** - * ------------------------------------------------------------------------ - * Constants - * ------------------------------------------------------------------------ - */ - var NAME = 'scrollspy'; - var VERSION = '4.0.0'; - var DATA_KEY = 'bs.scrollspy'; - var EVENT_KEY = "." + DATA_KEY; - var DATA_API_KEY = '.data-api'; - var JQUERY_NO_CONFLICT = $$$1.fn[NAME]; - var Default = { - offset: 10, - method: 'auto', - target: '' - }; - var DefaultType = { - offset: 'number', - method: 'string', - target: '(string|element)' - }; - var Event = { - ACTIVATE: "activate" + EVENT_KEY, - SCROLL: "scroll" + EVENT_KEY, - LOAD_DATA_API: "load" + EVENT_KEY + DATA_API_KEY - }; - var ClassName = { - DROPDOWN_ITEM: 'dropdown-item', - DROPDOWN_MENU: 'dropdown-menu', - ACTIVE: 'active' - }; - var Selector = { - DATA_SPY: '[data-spy="scroll"]', - ACTIVE: '.active', - NAV_LIST_GROUP: '.nav, .list-group', - NAV_LINKS: '.nav-link', - NAV_ITEMS: '.nav-item', - LIST_ITEMS: '.list-group-item', - DROPDOWN: '.dropdown', - DROPDOWN_ITEMS: '.dropdown-item', - DROPDOWN_TOGGLE: '.dropdown-toggle' - }; - var OffsetMethod = { - OFFSET: 'offset', - POSITION: 'position' - /** - * ------------------------------------------------------------------------ - * Class Definition - * ------------------------------------------------------------------------ - */ - - }; - - var ScrollSpy = - /*#__PURE__*/ - function () { - function ScrollSpy(element, config) { - var _this = this; - - this._element = element; - this._scrollElement = element.tagName === 'BODY' ? window : element; - this._config = this._getConfig(config); - this._selector = this._config.target + " " + Selector.NAV_LINKS + "," + (this._config.target + " " + Selector.LIST_ITEMS + ",") + (this._config.target + " " + Selector.DROPDOWN_ITEMS); - this._offsets = []; - this._targets = []; - this._activeTarget = null; - this._scrollHeight = 0; - $$$1(this._scrollElement).on(Event.SCROLL, function (event) { - return _this._process(event); - }); - this.refresh(); - - this._process(); - } // Getters - - - var _proto = ScrollSpy.prototype; - - // Public - _proto.refresh = function refresh() { - var _this2 = this; - - var autoMethod = this._scrollElement === this._scrollElement.window ? OffsetMethod.OFFSET : OffsetMethod.POSITION; - var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method; - var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0; - this._offsets = []; - this._targets = []; - this._scrollHeight = this._getScrollHeight(); - var targets = $$$1.makeArray($$$1(this._selector)); - targets.map(function (element) { - var target; - var targetSelector = Util.getSelectorFromElement(element); - - if (targetSelector) { - target = $$$1(targetSelector)[0]; - } - - if (target) { - var targetBCR = target.getBoundingClientRect(); - - if (targetBCR.width || targetBCR.height) { - // TODO (fat): remove sketch reliance on jQuery position/offset - return [$$$1(target)[offsetMethod]().top + offsetBase, targetSelector]; - } - } - - return null; - }).filter(function (item) { - return item; - }).sort(function (a, b) { - return a[0] - b[0]; - }).forEach(function (item) { - _this2._offsets.push(item[0]); - - _this2._targets.push(item[1]); - }); - }; - - _proto.dispose = function dispose() { - $$$1.removeData(this._element, DATA_KEY); - $$$1(this._scrollElement).off(EVENT_KEY); - this._element = null; - this._scrollElement = null; - this._config = null; - this._selector = null; - this._offsets = null; - this._targets = null; - this._activeTarget = null; - this._scrollHeight = null; - }; // Private - - - _proto._getConfig = function _getConfig(config) { - config = _extends({}, Default, config); - - if (typeof config.target !== 'string') { - var id = $$$1(config.target).attr('id'); - - if (!id) { - id = Util.getUID(NAME); - $$$1(config.target).attr('id', id); - } - - config.target = "#" + id; - } - - Util.typeCheckConfig(NAME, config, DefaultType); - return config; - }; - - _proto._getScrollTop = function _getScrollTop() { - return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop; - }; - - _proto._getScrollHeight = function _getScrollHeight() { - return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight); - }; - - _proto._getOffsetHeight = function _getOffsetHeight() { - return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height; - }; - - _proto._process = function _process() { - var scrollTop = this._getScrollTop() + this._config.offset; - - var scrollHeight = this._getScrollHeight(); - - var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight(); - - if (this._scrollHeight !== scrollHeight) { - this.refresh(); - } - - if (scrollTop >= maxScroll) { - var target = this._targets[this._targets.length - 1]; - - if (this._activeTarget !== target) { - this._activate(target); - } - - return; - } - - if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) { - this._activeTarget = null; - - this._clear(); - - return; - } - - for (var i = this._offsets.length; i--;) { - var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]); - - if (isActiveTarget) { - this._activate(this._targets[i]); - } - } - }; - - _proto._activate = function _activate(target) { - this._activeTarget = target; - - this._clear(); - - var queries = this._selector.split(','); // eslint-disable-next-line arrow-body-style - - - queries = queries.map(function (selector) { - return selector + "[data-target=\"" + target + "\"]," + (selector + "[href=\"" + target + "\"]"); - }); - var $link = $$$1(queries.join(',')); - - if ($link.hasClass(ClassName.DROPDOWN_ITEM)) { - $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE); - $link.addClass(ClassName.ACTIVE); - } else { - // Set triggered link as active - $link.addClass(ClassName.ACTIVE); // Set triggered links parents as active - // With both
    and