diff --git a/app/Filters/JournalFilter.php b/app/Filters/JournalFilter.php new file mode 100644 index 0000000..0666450 --- /dev/null +++ b/app/Filters/JournalFilter.php @@ -0,0 +1,53 @@ +builder = $this->builder->where('student_id', $value); + } + + protected function teacher($value) + { + $this->builder = $this->builder->where('teacher_id', $value); + } + + protected function subject($value) + { + $this->builder = $this->builder->where('subject_id', $value); + } + + protected function start($value) + { + $this->builder = $this->builder->where('updated_at', '>=', $this->transformDate($value)); + } + + protected function end($value) + { + $this->builder = $this->builder->where('updated_at', '<=', $this->transformDate($value)); + } + + protected function transformDate($value) + { + return Carbon::createFromTimestamp($value/1000)->floorDays();; + } + +// protected function date($value) +// { +// $value = Carbon::createFromTimestamp($value/1000)->floorDays(); +// $this->builder = $this->builder->where('updated_at', $value); +// } + + protected function last($value) + { + $date = Carbon::now()->subDays($value); + $this->builder = $this->builder->where('updated_at', '>=', $date); + } + +} diff --git a/app/Http/Controllers/JournalController.php b/app/Http/Controllers/JournalController.php new file mode 100644 index 0000000..284210a --- /dev/null +++ b/app/Http/Controllers/JournalController.php @@ -0,0 +1,115 @@ +apply()->values(); + return response()->json($journal, 200); + } + + /** + * Show the form for creating a new resource. + * + * @return Response + */ +// public function create() +// { +// // +// } + + /** + * Store a newly created resource in storage. + * + * @param JournalRequest $request + * @return JsonResponse + */ + public function store(JournalRequest $request) + { + if ($request->has('date')) + $date = Carbon::createFromTimestamp($request->get('date')/1000)->floorDays(); + else + $date = Carbon::now()->floorDays(); + + + $exist = Journal::where('updated_at', $date) + ->where('student_id', $request->get('student_id')) + ->where('subject_id', $request->get('subject_id')) + ->get(); + + if ($exist->isNotEmpty()) + return response()->json('Оценка на эту дату уже выставлена', 200); + + $data = array_merge(['updated_at' => $date], $request->all()); + + $journal = Journal::create($data); + return response()->json($journal, 200); + } + + /** + * Display the specified resource. + * + * @param int $journal + * @return JsonResponse + */ + public function show(int $journal) + { + return response()->json(Journal::find($journal), 200); + } + + /** + * Show the form for editing the specified resource. + * + * @param Journal $journal + * @return Response + */ +// public function edit(Journal $journal) +// { +// // +// } + + /** + * Update the specified resource in storage. + * + * @param JournalRequest $request + * @param Journal $journal + * @return JsonResponse + */ + public function update(Request $request, int $journal) + { + $j = Journal::find($journal); + $j->score = $request->get('score'); + $j->comment = $request->get('comment'); + $j->timestamps = false; + $j->save(); + return response()->json(['id' => $j->id], 200); + } + + /** + * Remove the specified resource from storage. + * + * @param Journal $journal + * @return JsonResponse + */ + public function destroy(Journal $journal) + { + $journal->delete(); + return response()->json(null, 200); + } +} diff --git a/app/Http/Controllers/News/NewsController.php b/app/Http/Controllers/News/NewsController.php new file mode 100644 index 0000000..61b9583 --- /dev/null +++ b/app/Http/Controllers/News/NewsController.php @@ -0,0 +1,60 @@ +has('count')) { + $temp = (int)$request->count; + if ($temp>0 && $temp<= 100) { + $count = $temp; + } + } + + return response()->json($news->orderByDesc('created_at')->paginate($count), 200); + + } + + public function store(Request $request) { + // Добавить проверку, после добавление авторизации + $request->validate([ + 'title' => 'required|min:5', + 'description' => 'required', + ]); + $news = News::create($request->all()); + + return response()->json($news, 201); + } + + public function show(News $news) { + + return response()->json([ + $news, + 'photo_id' => NewsFile::where('news_id', '=', $news->id)->get(['id']) + ], 200); + } + + public function edit(News $news, Request $request) { + $request->validate([ + 'title' => 'required|min:5', + 'description' => 'required' + ]); + $news->update($request->all()); + + return response()->json($news, 200); + + } + + public function delete(News $news) { + $news->delete(); + + return response()->json(true, 204); + } +} diff --git a/app/Http/Controllers/News/NewsFileController.php b/app/Http/Controllers/News/NewsFileController.php new file mode 100644 index 0000000..1ba8439 --- /dev/null +++ b/app/Http/Controllers/News/NewsFileController.php @@ -0,0 +1,82 @@ +id; + $max_size = (int)ini_get('upload_max_filesize') * 1000; + $all_ext = implode(',', $this->allExtensions()); + + $this->validate($request, [ + 'name' => 'required', + 'file' => 'required|file|mimes:' . $all_ext . '|max:' . $max_size + ]); + + $file = $request->file('file'); + $ext = $file->getClientOriginalExtension(); + $type = $this->getType($ext); + + if (Storage::putFileAs('public/news/' . $newsId . '/' . $type . '/', $file, $request->name)) { + NewsFile::create([ + 'name' => $request->name, + 'type' => $type, + 'extension' => $ext, + 'news_id' => $newsId, + $file, + $request->name . $ext + ]); + $news->photo_uri = '/storage/news' . '/' . $newsId . '/' . $type . '/' . $request->name; + $news->save(); + return true; + } + return false; + } + + + + + + public function delete(NewsFile $file) { + + if (Storage::disk('local')->exists('/public/news/' . $file->news_id . '/' . $file->type . '/' . $file->name)) { + if (Storage::disk('local')->delete('/public/news/' . $file->news_id . '/' . $file->type . '/' . $file->name)) { + return response()->json($file->delete(), 204); + } + } + return response()->json(['News not found'], 404); + } + + + private function getType($ext) + { + if (in_array(strtolower($ext), $this->image_ext)) { + return 'image'; + } + + if (in_array(strtolower($ext), $this->file_ext)) { + return 'file'; + } + } + + private function allExtensions() + { + return array_merge($this->image_ext, $this->file_ext); + } + + + +} diff --git a/app/Http/Controllers/SchoolClassController.php b/app/Http/Controllers/SchoolClassController.php index 574eadc..5940e90 100644 --- a/app/Http/Controllers/SchoolClassController.php +++ b/app/Http/Controllers/SchoolClassController.php @@ -2,9 +2,11 @@ namespace App\Http\Controllers; +use App\Filters\JournalFilter; use App\Http\Requests\SchoolClassRequest; use App\Models\SchoolClass; use App\Models\Teacher; +use Carbon\Carbon; use Illuminate\Database\QueryException; use Illuminate\Http\Request; @@ -65,11 +67,26 @@ class SchoolClassController extends Controller $students = $class->students; $studentsOnlyFIO = []; foreach ($students as $student) { - array_push($studentsOnlyFIO, $student->only('id', 'name', 'surname', 'patronymic')); + array_push($studentsOnlyFIO, $student->only('id', 'name', 'surname', 'patronymic')); } return response()->json($studentsOnlyFIO, 200); } + public function getStudentsJournal(SchoolClass $class, Request $request) + { + $students = $class->students; + $allStudents = []; + + foreach ($students as $student) + { + $cpys = clone $student; + $cpys->scores = (new JournalFilter($student->scores, $request))->apply()->values(); + $allStudents[] = $cpys; + } + + return response()->json($allStudents, 200); + } + //получение всех предметов для класса public function getSubjects(SchoolClass $class) { diff --git a/app/Http/Controllers/TimetableController.php b/app/Http/Controllers/TimetableController.php index 351b720..093a623 100644 --- a/app/Http/Controllers/TimetableController.php +++ b/app/Http/Controllers/TimetableController.php @@ -45,6 +45,7 @@ class TimetableController extends Controller 'class' => $class, ]); } + $dateTimetables = []; //if (!$filterTimetables->isEmpty()) { for ($i = 0; $i < 6; $i++) { @@ -53,9 +54,8 @@ class TimetableController extends Controller ->addDays($i) ->format('Y-m-d'); array_push($dateTimetables, [$date => $filterTimetables->where('date', $date)->values()]); - } - - //} + // } + } return response()->json($dateTimetables, 200); } diff --git a/app/Http/Controllers/Users/StudentController.php b/app/Http/Controllers/Users/StudentController.php index 49c376b..0cc6bfa 100644 --- a/app/Http/Controllers/Users/StudentController.php +++ b/app/Http/Controllers/Users/StudentController.php @@ -7,6 +7,7 @@ use App\Http\Requests\StudentRequest; use App\Models\SchoolClass; use App\Models\Student; use Illuminate\Http\JsonResponse; +use App\Models\AnswerToTask; class StudentController extends Controller { @@ -31,6 +32,18 @@ class StudentController extends Controller return response()->json($student, 200); } + /** + * Создание ученика + * + * @param StudentRequest $request + * @return JsonResponse + */ + /*public function store(StudentRequest $request) + { + $student = Student::creat($request->all()); + return response()->json($student, 200); + }*/ + /** * Обновление ученика * @@ -54,6 +67,7 @@ class StudentController extends Controller return response()->json(collect($student)->except('school_class'), 200); } + public function destroy(Student $student) { $user = $student->user; @@ -61,4 +75,9 @@ class StudentController extends Controller return response()->json(null, 204); } + + public function getAnswers(Student $student) { + return AnswerToTask::where('student_id', '=', $student->id)->get(); + } + } diff --git a/app/Http/Controllers/Users/TeacherController.php b/app/Http/Controllers/Users/TeacherController.php index 81a3205..5b61d62 100644 --- a/app/Http/Controllers/Users/TeacherController.php +++ b/app/Http/Controllers/Users/TeacherController.php @@ -10,7 +10,7 @@ use App\Models\Task; use App\Models\Teacher; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Response; +use App\Models\Subject; class TeacherController extends Controller { @@ -71,11 +71,27 @@ class TeacherController extends Controller public function getClasses(Teacher $teacher) { $timetables = $teacher->timetables; - $classes = []; + $classes = collect([]); foreach ($timetables as $timetable) { - array_push($classes, $timetable->schoolClass->only('id','number','letter')); + $subjects = collect([]); + $class = $timetable->schoolClass->only('id','number','letter'); + $forClassTimetables = $timetables->where('class_id', $class['id']); + + foreach ($forClassTimetables as $forClassTimetable) { + $subjects->push(Subject::find($forClassTimetable['subject_id'])); + } + $subjects = $subjects->unique()->values(); + + $classes->push([ + 'id' => $class['id'], + 'number' => $class['number'], + 'letter' => $class['letter'], + 'subjects' => $subjects, + ]); + } - return response()->json(collect($classes)->unique(), 200); + + return response()->json($classes->unique()->values(), 200); } public function getUncheckedTask(Teacher $teacher, SchoolClass $class) { diff --git a/app/Http/Requests/Auth/LoginRequest.php b/app/Http/Requests/Auth/LoginRequest.php index 5103286..78aa16e 100644 --- a/app/Http/Requests/Auth/LoginRequest.php +++ b/app/Http/Requests/Auth/LoginRequest.php @@ -14,6 +14,8 @@ class LoginRequest extends UserRequest */ public function specific() { - return []; + return [ + 'remember_me' => 'integer' + ]; } } diff --git a/app/Http/Requests/JournalRequest.php b/app/Http/Requests/JournalRequest.php new file mode 100644 index 0000000..035e2d0 --- /dev/null +++ b/app/Http/Requests/JournalRequest.php @@ -0,0 +1,25 @@ + 'required|integer', + 'teacher_id' => 'required|integer', + 'subject_id' => 'required|integer', + 'score' => 'required|integer', + 'comment' => 'string|nullable', + 'date' => 'integer', + ]; + } +} diff --git a/app/Models/HeadTeacher.php b/app/Models/HeadTeacher.php index 9c8ecde..cf0eadc 100644 --- a/app/Models/HeadTeacher.php +++ b/app/Models/HeadTeacher.php @@ -9,7 +9,7 @@ class HeadTeacher extends Model { use HasFactory; - protected $guarded = [ + protected $fillable = [ 'user_id', 'updated_at', ]; diff --git a/app/Models/Journal.php b/app/Models/Journal.php new file mode 100644 index 0000000..66258c0 --- /dev/null +++ b/app/Models/Journal.php @@ -0,0 +1,22 @@ +hasMany(Task::class, 'class_id'); } diff --git a/app/Models/Student.php b/app/Models/Student.php index 5105002..88796e4 100644 --- a/app/Models/Student.php +++ b/app/Models/Student.php @@ -2,6 +2,7 @@ namespace App\Models; +use Carbon\Carbon; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Validator; @@ -10,8 +11,11 @@ class Student extends Model { use HasFactory; - protected $guarded = [ + protected $fillable = [ 'user_id', + ]; + + protected $guarded = [ 'updated_at', ]; @@ -21,7 +25,11 @@ class Student extends Model public function schoolClass() { - return $this->belongsTo(SchoolClass::class, 'class_id'); + return $this->belongsTo(SchoolClass::class, 'class_id')->where(''); + } + public function scores() + { + return $this->hasMany(Journal::class, 'student_id'); } public function user() diff --git a/app/Models/Teacher.php b/app/Models/Teacher.php index 9b008e1..5abfce6 100644 --- a/app/Models/Teacher.php +++ b/app/Models/Teacher.php @@ -10,7 +10,7 @@ class Teacher extends Model { use HasFactory; - protected $guarded = [ + protected $fillable = [ 'user_id', 'updated_at', ]; @@ -34,4 +34,9 @@ class Teacher extends Model return $this->belongsTo(User::class); } + + public function tasks(){ + return $this->hasMany(Task::class); + } + } diff --git a/app/Models/User.php b/app/Models/User.php index 2605b9e..0d9deba 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -5,7 +5,6 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; -use Carbon\Carbon; use Laravel\Passport\HasApiTokens; class User extends Authenticatable diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index f7ec0a6..f09b364 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -26,6 +26,6 @@ class AuthServiceProvider extends ServiceProvider { $this->registerPolicies(); - Passport::routes(); +// Passport::routes(); } } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 4283423..e9ef2f7 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -38,7 +38,7 @@ class RouteServiceProvider extends ServiceProvider $this->configureRateLimiting(); $this->routes(function () { - Route::prefix('/api') + Route::prefix('api') ->middleware('api') ->namespace($this->namespace) ->group(base_path('routes/api.php')); @@ -57,7 +57,7 @@ class RouteServiceProvider extends ServiceProvider protected function configureRateLimiting() { RateLimiter::for('api', function (Request $request) { - return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip()); + return Limit::perMinute(100)->by(optional($request->user())->id ?: $request->ip()); }); } } diff --git a/composer.json b/composer.json index 5a6b38d..0e19528 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ "license": "MIT", "require": { "php": "^7.3|^8.0", - "barryvdh/laravel-cors": "^2.0", + "cboden/ratchet": "^0.4.3", "fideloper/proxy": "^4.4", "fruitcake/laravel-cors": "^2.0", "guzzlehttp/guzzle": "^7.0.1", diff --git a/composer.lock b/composer.lock index 744785b..12e7f46 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": "94e022aa2f8a4e9c7f1f2b9740b6dbd5", + "content-hash": "7a7b53e8f06f6bcd7118e6f3b9093703", "packages": [ { "name": "asm89/stack-cors", @@ -58,79 +58,6 @@ ], "time": "2020-10-29T16:03:21+00:00" }, - { - "name": "barryvdh/laravel-cors", - "version": "v2.0.3", - "source": { - "type": "git", - "url": "https://github.com/fruitcake/laravel-cors.git", - "reference": "01de0fe5f71c70d1930ee9a80385f9cc28e0f63a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/fruitcake/laravel-cors/zipball/01de0fe5f71c70d1930ee9a80385f9cc28e0f63a", - "reference": "01de0fe5f71c70d1930ee9a80385f9cc28e0f63a", - "shasum": "" - }, - "require": { - "asm89/stack-cors": "^2.0.1", - "illuminate/contracts": "^6|^7|^8|^9", - "illuminate/support": "^6|^7|^8|^9", - "php": ">=7.2", - "symfony/http-foundation": "^4|^5", - "symfony/http-kernel": "^4.3.4|^5" - }, - "require-dev": { - "laravel/framework": "^6|^7|^8", - "orchestra/testbench-dusk": "^4|^5|^6", - "phpunit/phpunit": "^6|^7|^8", - "squizlabs/php_codesniffer": "^3.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - }, - "laravel": { - "providers": [ - "Fruitcake\\Cors\\CorsServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Fruitcake\\Cors\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fruitcake", - "homepage": "https://fruitcake.nl" - }, - { - "name": "Barry vd. Heuvel", - "email": "barryvdh@gmail.com" - } - ], - "description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Laravel application", - "keywords": [ - "api", - "cors", - "crossdomain", - "laravel" - ], - "funding": [ - { - "url": "https://github.com/barryvdh", - "type": "github" - } - ], - "time": "2020-10-22T13:57:20+00:00" - }, { "name": "brick/math", "version": "0.9.1", @@ -183,6 +110,63 @@ ], "time": "2020-08-18T23:57:15+00:00" }, + { + "name": "cboden/ratchet", + "version": "v0.4.3", + "source": { + "type": "git", + "url": "https://github.com/ratchetphp/Ratchet.git", + "reference": "466a0ecc83209c75b76645eb823401b5c52e5f21" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ratchetphp/Ratchet/zipball/466a0ecc83209c75b76645eb823401b5c52e5f21", + "reference": "466a0ecc83209c75b76645eb823401b5c52e5f21", + "shasum": "" + }, + "require": { + "guzzlehttp/psr7": "^1.0", + "php": ">=5.4.2", + "ratchet/rfc6455": "^0.3", + "react/socket": "^1.0 || ^0.8 || ^0.7 || ^0.6 || ^0.5", + "symfony/http-foundation": "^2.6|^3.0|^4.0|^5.0", + "symfony/routing": "^2.6|^3.0|^4.0|^5.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ratchet\\": "src/Ratchet" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "role": "Developer" + }, + { + "name": "Matt Bonneau", + "role": "Developer" + } + ], + "description": "PHP WebSocket library", + "homepage": "http://socketo.me", + "keywords": [ + "Ratchet", + "WebSockets", + "server", + "sockets", + "websocket" + ], + "time": "2020-07-07T15:50:14+00:00" + }, { "name": "defuse/php-encryption", "version": "v2.2.1", @@ -567,6 +551,49 @@ ], "time": "2020-11-14T15:56:27+00:00" }, + { + "name": "evenement/evenement", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/igorw/evenement.git", + "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/igorw/evenement/zipball/531bfb9d15f8aa57454f5f0285b18bec903b8fb7", + "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "Evenement": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "Événement is a very simple event dispatching library for PHP", + "keywords": [ + "event-dispatcher", + "event-emitter" + ], + "time": "2017-07-23T21:35:13+00:00" + }, { "name": "fideloper/proxy", "version": "4.4.1", @@ -3001,6 +3028,473 @@ ], "time": "2020-08-18T17:17:46+00:00" }, + { + "name": "ratchet/rfc6455", + "version": "v0.3", + "source": { + "type": "git", + "url": "https://github.com/ratchetphp/RFC6455.git", + "reference": "c8651c7938651c2d55f5d8c2422ac5e57a183341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ratchetphp/RFC6455/zipball/c8651c7938651c2d55f5d8c2422ac5e57a183341", + "reference": "c8651c7938651c2d55f5d8c2422ac5e57a183341", + "shasum": "" + }, + "require": { + "guzzlehttp/psr7": "^1.0", + "php": ">=5.4.2" + }, + "require-dev": { + "phpunit/phpunit": "5.7.*", + "react/socket": "^1.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ratchet\\RFC6455\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "role": "Developer" + }, + { + "name": "Matt Bonneau", + "role": "Developer" + } + ], + "description": "RFC6455 WebSocket protocol handler", + "homepage": "http://socketo.me", + "keywords": [ + "WebSockets", + "rfc6455", + "websocket" + ], + "time": "2020-05-15T18:31:24+00:00" + }, + { + "name": "react/cache", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/cache.git", + "reference": "44a568925556b0bd8cacc7b49fb0f1cf0d706a0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/cache/zipball/44a568925556b0bd8cacc7b49fb0f1cf0d706a0c", + "reference": "44a568925556b0bd8cacc7b49fb0f1cf0d706a0c", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, Promise-based cache interface for ReactPHP", + "keywords": [ + "cache", + "caching", + "promise", + "reactphp" + ], + "funding": [ + { + "url": "https://github.com/WyriHaximus", + "type": "github" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2020-09-18T12:12:35+00:00" + }, + { + "name": "react/dns", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "665260757171e2ab17485b44e7ffffa7acb6ca1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/665260757171e2ab17485b44e7ffffa7acb6ca1f", + "reference": "665260757171e2ab17485b44e7ffffa7acb6ca1f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/cache": "^1.0 || ^0.6 || ^0.5", + "react/event-loop": "^1.0 || ^0.5", + "react/promise": "^3.0 || ^2.7 || ^1.2.1", + "react/promise-timer": "^1.2" + }, + "require-dev": { + "clue/block-react": "^1.2", + "phpunit/phpunit": "^9.3 || ^4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Dns\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async DNS resolver for ReactPHP", + "keywords": [ + "async", + "dns", + "dns-resolver", + "reactphp" + ], + "funding": [ + { + "url": "https://github.com/WyriHaximus", + "type": "github" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2020-09-18T12:12:55+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "6d24de090cd59cfc830263cfba965be77b563c13" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/6d24de090cd59cfc830263cfba965be77b563c13", + "reference": "6d24de090cd59cfc830263cfba965be77b563c13", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 || ^6.4 || ^5.7 || ^4.8.35" + }, + "suggest": { + "ext-event": "~1.0 for ExtEventLoop", + "ext-pcntl": "For signal handling support when using the StreamSelectLoop", + "ext-uv": "* for ExtUvLoop" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\EventLoop\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", + "keywords": [ + "asynchronous", + "event-loop" + ], + "time": "2020-01-01T18:39:52+00:00" + }, + { + "name": "react/promise", + "version": "v2.8.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise.git", + "reference": "f3cff96a19736714524ca0dd1d4130de73dbbbc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise/zipball/f3cff96a19736714524ca0dd1d4130de73dbbbc4", + "reference": "f3cff96a19736714524ca0dd1d4130de73dbbbc4", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 || ^6.5 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "time": "2020-05-12T15:16:56+00:00" + }, + { + "name": "react/promise-timer", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/promise-timer.git", + "reference": "daee9baf6ef30c43ea4c86399f828bb5f558f6e6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/promise-timer/zipball/daee9baf6ef30c43ea4c86399f828bb5f558f6e6", + "reference": "daee9baf6ef30c43ea4c86399f828bb5f558f6e6", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5", + "react/promise": "^3.0 || ^2.7.0 || ^1.2.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.0 || ^5.7 || ^4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Promise\\Timer\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@lueck.tv" + } + ], + "description": "A trivial implementation of timeouts for Promises, built on top of ReactPHP.", + "homepage": "https://github.com/reactphp/promise-timer", + "keywords": [ + "async", + "event-loop", + "promise", + "reactphp", + "timeout", + "timer" + ], + "time": "2020-07-10T12:18:06+00:00" + }, + { + "name": "react/socket", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/socket.git", + "reference": "e2b96b23a13ca9b41ab343268dbce3f8ef4d524a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/socket/zipball/e2b96b23a13ca9b41ab343268dbce3f8ef4d524a", + "reference": "e2b96b23a13ca9b41ab343268dbce3f8ef4d524a", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^1.1", + "react/event-loop": "^1.0 || ^0.5", + "react/promise": "^2.6.0 || ^1.2.1", + "react/promise-timer": "^1.4.0", + "react/stream": "^1.1" + }, + "require-dev": { + "clue/block-react": "^1.2", + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35", + "react/promise-stream": "^1.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Socket\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", + "keywords": [ + "Connection", + "Socket", + "async", + "reactphp", + "stream" + ], + "funding": [ + { + "url": "https://github.com/WyriHaximus", + "type": "github" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2020-08-28T12:49:05+00:00" + }, + { + "name": "react/stream", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/reactphp/stream.git", + "reference": "7c02b510ee3f582c810aeccd3a197b9c2f52ff1a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/stream/zipball/7c02b510ee3f582c810aeccd3a197b9c2f52ff1a", + "reference": "7c02b510ee3f582c810aeccd3a197b9c2f52ff1a", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.8", + "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3.5" + }, + "require-dev": { + "clue/stream-filter": "~1.2", + "phpunit/phpunit": "^7.0 || ^6.4 || ^5.7 || ^4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Stream\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", + "keywords": [ + "event-driven", + "io", + "non-blocking", + "pipe", + "reactphp", + "readable", + "stream", + "writable" + ], + "time": "2020-05-04T10:17:57+00:00" + }, { "name": "swiftmailer/swiftmailer", "version": "v6.2.4", diff --git a/database/migrations/2020_12_03_104028_create_bank_task_files_table.php b/database/migrations/2020_12_03_104028_create_bank_task_files_table.php index 38e0ce9..82b8c38 100644 --- a/database/migrations/2020_12_03_104028_create_bank_task_files_table.php +++ b/database/migrations/2020_12_03_104028_create_bank_task_files_table.php @@ -19,12 +19,11 @@ class CreateBankTaskFilesTable extends Migration $table->string('type'); $table->string('extension'); $table->string('url', 400); - $table->timestamps(); $table->unsignedInteger('banktask_id'); $table->foreign('banktask_id') ->references('id')->on('bank_tasks') - ->onDelete('cascade')->onUpdate('no action'); + ->onDelete('cascade'); }); } @@ -36,6 +35,6 @@ class CreateBankTaskFilesTable extends Migration */ public function down() { - Schema::dropIfExists('bank_tasks_files'); + Schema::dropIfExists('bank_task_files'); } } diff --git a/database/migrations/2020_12_13_200032_create_journals_table.php b/database/migrations/2020_12_13_200032_create_journals_table.php new file mode 100644 index 0000000..93f215c --- /dev/null +++ b/database/migrations/2020_12_13_200032_create_journals_table.php @@ -0,0 +1,47 @@ +id(); + $table->unsignedBigInteger('teacher_id'); + $table->unsignedBigInteger('student_id'); + $table->unsignedBigInteger('subject_id'); + $table->unsignedBigInteger('score'); + $table->string('comment')->nullable(); + $table->timestamps(); + + $table->foreign('subject_id') + ->references('id')->on('subjects'); + + $table->foreign('teacher_id') + ->references('id')->on('teachers') + ->onDelete('cascade'); + + $table->foreign('student_id') + ->references('id')->on('students') + ->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('journals'); + } +} diff --git a/database/migrations/2020_12_14_170701_create_news_table.php b/database/migrations/2020_12_14_170701_create_news_table.php new file mode 100644 index 0000000..69457cb --- /dev/null +++ b/database/migrations/2020_12_14_170701_create_news_table.php @@ -0,0 +1,37 @@ +id(); + $table->string('title'); + $table->text('description'); + $table->string('photo_uri')->nullable(); + $table->unsignedInteger('headteacher_id'); + + $table->foreign('headteacher_id')->references('id')->on('head_teachers'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('news'); + } +} diff --git a/database/migrations/2020_12_15_092036_create_news_files_table.php b/database/migrations/2020_12_15_092036_create_news_files_table.php new file mode 100644 index 0000000..0b2e63d --- /dev/null +++ b/database/migrations/2020_12_15_092036_create_news_files_table.php @@ -0,0 +1,39 @@ +bigIncrements('id'); + $table->string('name'); + $table->string('type'); + $table->string('extension'); + $table->timestamps(); + $table->unsignedInteger('news_id'); + $table->foreign('news_id') + ->references('id')->on('news') + ->onDelete('cascade'); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('news'); + } +} diff --git a/routes/api.php b/routes/api.php index 6886fad..0c7ee4f 100644 --- a/routes/api.php +++ b/routes/api.php @@ -17,8 +17,11 @@ Route::apiResource('headteachers', 'Users\HeadTeacherController'); Route::apiResource('teachers', 'Users\TeacherController');//->middleware(['auth:api','role:headteacher|teacher']); Route::get('teacher/{teacher}/classes', 'Users\TeacherController@getClasses'); //получить классы у которых ведет учитель +Route::get('teacher/{teacher}/classes', 'Users\TeacherController@getClasses'); +Route::get('teacher/{teacher}/classes/{class}/unchecked-task', 'Users\TeacherController@getUncheckedTask'); Route::apiResource('students', 'Users\StudentController'); +Route::get('/student/{student}/answers', 'Users\StudentController@getAnswers'); Route::apiResource('parents', 'Users\ParenttController'); @@ -27,9 +30,13 @@ Route::apiResource('subjects', 'BankTask\SubjectController'); Route::apiResource('classes', 'SchoolClassController'); Route::post('classes/{class}/teacher', 'SchoolClassController@addTeacher'); Route::get('classes/{class}/students', 'SchoolClassController@getStudents'); //все ученики класса +Route::get('classes/{class}/journal', 'SchoolClassController@getStudentsJournal'); //все ученики класса с оценками Route::get('classes/{class}/subjects', 'SchoolClassController@getSubjects'); //все предметы класса -Route::apiResource('themes', 'BankTask\ThemeController'); + +Route::apiResource('journal', 'JournalController'); + +Route::apiResource('themes', 'BankTask\ThemeController'); Route::apiResource('timetables', 'TimetableController'); @@ -41,8 +48,38 @@ Route::group(['prefix' => 'banktask'], function () { Route::delete('{banktask}', 'BankTask\BankTaskController@delete'); //удаление задания Route::post('{banktask}/addfile', 'BankTask\BankTaskFileController@store'); Route::get('{banktask}/files', 'BankTask\BankTaskFileController@showFiles'); + Route::delete('banktask/file/{file}/delete', 'BankTask\BankTaskFileController@delete'); + Route::put('banktask/file/{file}/update', 'BankTask\BankTaskFileController@update'); +}); + + + + +Route::group(['prefix' => 'news'], function () { + Route::post('', 'News\NewsController@store'); + Route::get('', 'News\NewsController@index'); + Route::get('/{news}', 'News\NewsController@show'); + Route::put('/{news}', 'News\NewsController@edit'); + Route::delete('/{news}', 'News\NewsController@delete'); + Route::post('/{news}/addphoto', 'News\NewsFileController@store'); + Route::delete('/photo/{file}', 'News\NewsFileController@delete'); +}); + +Route::group(['prefix' => 'task'], function () { + Route::post('', 'TaskController@store'); // Добавить таск + Route::get('', 'TaskController@index'); // Показать задания для класса (в запросе нужно указывать Id класса) + Route::get('/{task}', 'TaskController@show'); //Показать задание + Route::put('/{task}', 'TaskController@update'); // Обновить задание + Route::delete('/{task}', 'TaskController@delete'); // Удалить задание + Route::put('/answer/check/{answer}', 'TaskController@checkAnswer'); // Проверить ответ ученика + Route::post('/{task}/addanswer', 'AnswerToTaskController@store'); // Добавить ответ(для ученика) + Route::get('/{task}/student/{student}', 'AnswerToTaskController@show'); // Показать ответ ученика + Route::delete('/answer/{answer}', 'AnswerToTaskController@delete'); // Удалить ответ + Route::put('/answer/{answer}', 'AnswerToTaskController@update'); // Изменить ответ + Route::post('/{task}/addfile', 'TaskFileController@store'); // Добавить файл + Route::get('/{task}/files', 'TaskFileController@showFiles'); // Посмотреть файлы у таска(только файлы + // которые добавил учитель). + Route::get('/{task}/file/{file}', 'TaskFileController@download'); // Скачать файл + Route::delete('/file/{file}', 'TaskFileController@delete'); // Удалить файл }); -Route::get('/file/{file}/download', 'BankTaskFileController@download'); -Route::delete('/file/{file}/delete', 'BankTaskFileController@delete'); -Route::put('/file/{file}/update', 'BankTaskFileController@update'); diff --git a/routes/web.php b/routes/web.php index 84fc59a..efa1311 100644 --- a/routes/web.php +++ b/routes/web.php @@ -12,3 +12,5 @@ | contains the "web" middleware group. Now create something great! | */ + +