diff --git a/app/Http/Controllers/admin/Catalog/Direction/SubjectController.php b/app/Http/Controllers/admin/Catalog/Direction/SubjectController.php new file mode 100644 index 0000000..800ae0d --- /dev/null +++ b/app/Http/Controllers/admin/Catalog/Direction/SubjectController.php @@ -0,0 +1,72 @@ +validated(); + + $subject = new Subject(); + $subject->name = $validated['name']; + $subject->description = $validated['description']; + $subject->slug = $validated['slug']; + $subject->position = $validated['position']; + $subject->save(); + + return redirect()->route('subjects.index'); + } + + public function show(Subject $subject): View + { + return view('admin.catalog.direction.subject.show', compact('subject')); + } + + public function edit(Subject $subject): View + { + return view('admin.catalog.direction.subject.edit', compact('subject')); + } + + public function update(UpdateSubjectRequest $request, Subject $subject): RedirectResponse + { + $validated = $request->validated(); + + $subject->name = $validated['name']; + $subject->description = $validated['description']; + $subject->slug = $validated['slug']; + $subject->position = $validated['position']; + $subject->save(); + + return redirect()->route('subjects.index'); + } + + public function destroy(Subject $subject): RedirectResponse + { + if ($subject->entranceExaminations()->exists()) { + return back(); + } + $subject->delete(); + return redirect()->route('subjects.index'); + } +} diff --git a/app/Http/Requests/admin/Catalog/Direction/StoreSubjectRequest.php b/app/Http/Requests/admin/Catalog/Direction/StoreSubjectRequest.php new file mode 100644 index 0000000..966f2a4 --- /dev/null +++ b/app/Http/Requests/admin/Catalog/Direction/StoreSubjectRequest.php @@ -0,0 +1,23 @@ + 'required|int|numeric|max:255', + 'name' => 'required|string|max:255|unique:subjects,name', + 'description' => 'string', + 'slug' => 'required|string|max:255|unique:subjects,slug', + ]; + } +} diff --git a/app/Http/Requests/admin/Catalog/Direction/UpdateEntranceExaminationRequest.php b/app/Http/Requests/admin/Catalog/Direction/UpdateEntranceExaminationRequest.php new file mode 100644 index 0000000..fef7be6 --- /dev/null +++ b/app/Http/Requests/admin/Catalog/Direction/UpdateEntranceExaminationRequest.php @@ -0,0 +1,20 @@ + 'required|int|numeric|max:255', + 'description' => 'string', + 'slug' => [ + 'string', + 'required', + 'max:255', + "unique:subjects,slug,{$this->subject->id}", + ], + 'name' => [ + 'required', + 'string', + 'max:255', + "unique:subjects,name,{$this->subject->id}", + ], + ]; + } +} diff --git a/app/Models/Subject.php b/app/Models/Subject.php new file mode 100644 index 0000000..e1fdb9c --- /dev/null +++ b/app/Models/Subject.php @@ -0,0 +1,25 @@ +hasMany('App\Models\EntranceExamination', 'subject_id'); + } +} diff --git a/database/factories/SubjectFactory.php b/database/factories/SubjectFactory.php new file mode 100644 index 0000000..e761e71 --- /dev/null +++ b/database/factories/SubjectFactory.php @@ -0,0 +1,18 @@ + fake()->name(), + 'description' => fake()->text(), + 'slug' => fake()->slug(), + 'position' => fake()->randomDigit(), + ]; + } +} diff --git a/database/migrations/2024_02_15_075912_create_subjects_table.php b/database/migrations/2024_02_15_075912_create_subjects_table.php new file mode 100644 index 0000000..d36c7b8 --- /dev/null +++ b/database/migrations/2024_02_15_075912_create_subjects_table.php @@ -0,0 +1,31 @@ +id(); + $table->integer('position'); + $table->string('name'); + $table->text('description')->nullable(); + $table->string('slug'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('subjects'); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 04e3826..fb798da 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -28,6 +28,7 @@ class DatabaseSeeder extends Seeder EducationLevelSeeder::class, EducationFormSeeder::class, ExaminationTypeSeeder::class, + SubjectSeeder::class, DirectionSeeder::class, ]); diff --git a/database/seeders/SubjectSeeder.php b/database/seeders/SubjectSeeder.php new file mode 100644 index 0000000..ad646c0 --- /dev/null +++ b/database/seeders/SubjectSeeder.php @@ -0,0 +1,33 @@ +insert([ + [ + 'name' => 'Обществознание', + 'description' => 'social studies', + 'position' => '1', + 'slug' => 'social-studies', + ], + [ + 'name' => 'Русский язык', + 'description' => 'a Russian language course', + 'position' => '2', + 'slug' => 'russian-language', + ], + [ + 'name' => 'математика', + 'description' => 'mathematics', + 'position' => '3', + 'slug' => 'mathematics', + ], + ]); + } +} diff --git a/resources/views/admin/catalog/direction/subject/create.blade.php b/resources/views/admin/catalog/direction/subject/create.blade.php new file mode 100644 index 0000000..5ae0bf2 --- /dev/null +++ b/resources/views/admin/catalog/direction/subject/create.blade.php @@ -0,0 +1,65 @@ +@extends('layouts.admin_layout') +@section('content') + @auth() +
+
+

Создать Предмет

+ {{ Form::open(['url' => route('subjects.store'), 'method' => 'POST', 'class' => '']) }} +
+
+ {{ Form::label('name', 'Название') }} +
+
+ {{ Form::text('name', '', ['class' => 'form-control']) }} +
+
+ @if ($errors->any()) + {{ $errors->first('name') }} + @endif +
+ +
+ {{ Form::label('description', 'Описание') }} +
+
+ {{ Form::text('description', '', ['class' => 'form-control']) }} +
+
+ @if ($errors->any()) + {{ $errors->first('description') }} + @endif +
+ +
+ {{ Form::label('slug', 'URL') }} +
+
+ {{ Form::text('slug', '', ['class' => 'form-control']) }} +
+
+ @if ($errors->any()) + {{ $errors->first('slug') }} + @endif +
+ +
+ {{ Form::label('position', 'Позиция') }} +
+
+ {{ Form::text('position', '', ['class' => 'form-control']) }} +
+
+ @if ($errors->any()) + {{ $errors->first('position') }} + @endif +
+ +
+ {{ Form::submit('Создать', ['class' => 'btn btn-primary']) }} +
+
+ {{ Form::close() }} +
+
+ @endauth +@endsection diff --git a/resources/views/admin/catalog/direction/examination_type/edit.blade.php b/resources/views/admin/catalog/direction/subject/edit.blade.php similarity index 75% rename from resources/views/admin/catalog/direction/examination_type/edit.blade.php rename to resources/views/admin/catalog/direction/subject/edit.blade.php index 5998ef2..e25fea9 100644 --- a/resources/views/admin/catalog/direction/examination_type/edit.blade.php +++ b/resources/views/admin/catalog/direction/subject/edit.blade.php @@ -4,14 +4,14 @@ @auth()
-

Изменить тип экзамена

- {{ Form::open(['url' => route('examination_types.update', $examinationType), 'method' => 'PATCH', 'class' => '']) }} +

Изменить предмет

+ {{ Form::open(['url' => route('subjects.update', $subject), 'method' => 'PATCH', 'class' => '']) }}
{{ Form::label('name', 'Название') }}
- {{ Form::text('name', $examinationType->name, ['class' => 'form-control']) }} + {{ Form::text('name', $subject->name, ['class' => 'form-control']) }}
@if ($errors->any()) @@ -23,7 +23,7 @@ {{ Form::label('description', 'Описание') }}
- {{ Form::text('description', $examinationType->description, ['class' => 'form-control']) }} + {{ Form::text('description', $subject->description, ['class' => 'form-control']) }}
@if ($errors->any()) @@ -35,7 +35,7 @@ {{ Form::label('slug', 'URL') }}
- {{ Form::text('slug', $examinationType->slug, ['class' => 'form-control']) }} + {{ Form::text('slug', $subject->slug, ['class' => 'form-control']) }}
@if ($errors->any()) @@ -47,7 +47,7 @@ {{ Form::label('position', 'Позиция') }}
- {{ Form::text('position', $examinationType->position, ['class' => 'form-control']) }} + {{ Form::text('position', $subject->position, ['class' => 'form-control']) }}
@if ($errors->any()) diff --git a/resources/views/admin/catalog/direction/examination_type/index.blade.php b/resources/views/admin/catalog/direction/subject/index.blade.php similarity index 65% rename from resources/views/admin/catalog/direction/examination_type/index.blade.php rename to resources/views/admin/catalog/direction/subject/index.blade.php index 3cc2417..23888fc 100644 --- a/resources/views/admin/catalog/direction/examination_type/index.blade.php +++ b/resources/views/admin/catalog/direction/subject/index.blade.php @@ -3,7 +3,7 @@

Тип Экзамена


- Создать тип экзамена + Создать предмет

@@ -18,17 +18,17 @@ - @foreach($types as $type) + @foreach($subjects as $subject) - - - - + + + + diff --git a/resources/views/admin/catalog/direction/subject/show.blade.php b/resources/views/admin/catalog/direction/subject/show.blade.php new file mode 100644 index 0000000..b2b1b96 --- /dev/null +++ b/resources/views/admin/catalog/direction/subject/show.blade.php @@ -0,0 +1,19 @@ +@extends('layouts.admin_layout') +@section('content') + @auth() +
+

Название

+

{{ $subject->name }}

+

Описание

+

{{ $subject->description }}

+

URL

+

{{ $subject->slug }}

+

Позиция

+

{{ $subject->position }}

+

Вступительные испытания

+ @foreach($subject->entranceExaminations as $entranceExamination) +

{{ $entranceExamination->name }}

+ @endforeach +
+ @endauth +@endsection diff --git a/resources/views/layouts/admin_layout.blade.php b/resources/views/layouts/admin_layout.blade.php index 140dd25..c2bda8d 100644 --- a/resources/views/layouts/admin_layout.blade.php +++ b/resources/views/layouts/admin_layout.blade.php @@ -58,7 +58,8 @@
  • Направления
  • Уровни образования
  • Формы образования
  • -
  • Тип Экзаменов
  • +
  • Типы Экзаменов
  • +
  • Предметы
  • @yield('content')
    diff --git a/routes/admin.php b/routes/admin.php index 520742d..b4016da 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -5,6 +5,7 @@ use App\Http\Controllers\admin\Catalog\DepartmentController; use App\Http\Controllers\admin\Catalog\Direction\EducationFormController; use App\Http\Controllers\admin\Catalog\Direction\EducationLevelController; use App\Http\Controllers\admin\Catalog\Direction\ExaminationTypeController; +use App\Http\Controllers\admin\Catalog\Direction\SubjectController; use App\Http\Controllers\admin\Catalog\DirectionController; use App\Http\Controllers\admin\Catalog\EducationalInstitutionController; use App\Http\Controllers\admin\Catalog\FacultyController; @@ -45,6 +46,9 @@ Route::middleware(['auth', 'verified'])->prefix('admin')->group(function () { Route::resource('/examination_types', ExaminationTypeController::class) ->scoped(['examination_type' => 'slug']); + Route::resource('/subjects', SubjectController::class) + ->scoped(['subject' => 'slug']); + Route::resources([ '/documents' => DocumentController::class, '/users' => UserController::class, diff --git a/tests/Feature/admin/catalog/direction/SubjectTest.php b/tests/Feature/admin/catalog/direction/SubjectTest.php new file mode 100644 index 0000000..44cd9a1 --- /dev/null +++ b/tests/Feature/admin/catalog/direction/SubjectTest.php @@ -0,0 +1,102 @@ +subject = Subject::factory()->create(); + + $this->data = Subject::factory()->make()->only([ + 'name', + 'description', + 'position', + 'slug', + ]); + + $this->user = User::factory()->create([ + 'name' => 'admin', + 'email' => 'test@example.com', + 'password' => 123456 + ]); + } + + public function testIndexSubjectsPage(): void + { + $response = $this->actingAs($this->user) + ->withSession(['banned' => false]) + ->get(route('subjects.index')); + + $response->assertOk(); + } + + public function testCreateSubjectPage(): void + { + $response = $this->actingAs($this->user) + ->withSession(['banned' => false]) + ->get(route('subjects.create')); + + $response->assertOk(); + } + + public function testStoreSubject(): void + { + $response = $this->actingAs($this->user) + ->withSession(['banned' => false]) + ->post(route('subjects.store', $this->data)); + + $response->assertRedirect(route('subjects.index')); + + $this->assertDatabaseHas('subjects', $this->data); + } + + public function testShowSubjectPage(): void + { + $response = $this->actingAs($this->user) + ->withSession(['banned' => false]) + ->get(route('subjects.show', $this->subject)); + + $response->assertOk(); + } + + public function testEditSubjectPage(): void + { + $response = $this->actingAs($this->user) + ->withSession(['banned' => false]) + ->get(route('subjects.edit', $this->subject)); + + $response->assertOk(); + } + + public function testUpdateSubject(): void + { + $response = $this->actingAs($this->user) + ->withSession(['banned' => false]) + ->patch(route('subjects.update', $this->subject), $this->data); + + $response->assertRedirect(route('subjects.index')); + + $this->assertDatabaseHas('subjects', $this->data); + } + + public function testDestroySubject(): void + { + $response = $this->actingAs($this->user) + ->withSession(['banned' => false]) + ->delete(route('subjects.destroy', $this->subject)); + + $response->assertRedirect(route('subjects.index')); + + $this->assertDatabaseMissing('subjects', $this->subject->toArray()); + } +}
    {{ $type->position }}{{ $type->name }}{{ Str::words($type->description, 10, '...') }}{{ $type->slug }}{{ $subject->position }}{{ $subject->name }}{{ Str::words($subject->description, 10, '...') }}{{ $subject->slug }} - редактировать удалить