diff --git a/app/Http/Controllers/Api/Pages/PagesController.php b/app/Http/Controllers/Api/Pages/PagesController.php index 9c73633..304e0d0 100644 --- a/app/Http/Controllers/Api/Pages/PagesController.php +++ b/app/Http/Controllers/Api/Pages/PagesController.php @@ -20,7 +20,7 @@ class PagesController extends Controller { } public function find(Request $request): ?JsonResponse { - return ($page = Page::byUrl($request->get('url'))) ? fractal($page, new PageTransformer())->respond() : null; + return ($model = Page::byUrl($request->get('url'))) ? fractal($model, new PageTransformer())->respond() : null; } public function index(Request $request): JsonResponse { diff --git a/app/Http/Controllers/Api/Publications/PublicationsController.php b/app/Http/Controllers/Api/Publications/PublicationsController.php new file mode 100644 index 0000000..e0db9dc --- /dev/null +++ b/app/Http/Controllers/Api/Publications/PublicationsController.php @@ -0,0 +1,50 @@ +model = $model; + } + + + public function find(Request $request): ?JsonResponse { + return ($model = Publication::byUrl($request->get('url'))) ? fractal($model, new PublicationTransformer())->respond() : null; + } + + public function index(Request $request): JsonResponse { + $query = $this->model->query(); + if ($page = Page::byUuid($request->get('page'))->first()) $query->where(['page_id' => $page->id]); + $paginator = $query->paginate(config('app.pagination_limit')); + return fractal($paginator, new PublicationTransformer())->respond(); + } + + public function show(Request $request, $id): JsonResponse { + $model = $this->model->byUuid($id)->firstOrFail(); + return fractal($model, new PublicationTransformer())->respond(); + } + + + public function store(Request $request): void { + } + + + public function update(Request $request, $uuid): void { + } + + public function destroy(Request $request, $uuid): JsonResponse { + $model = $this->model->byUuid($uuid)->firstOrFail(); + $model->delete(); + return response()->json(null, 204); + } + +} diff --git a/app/Models/Pages/Page.php b/app/Models/Pages/Page.php index 0143555..1809557 100644 --- a/app/Models/Pages/Page.php +++ b/app/Models/Pages/Page.php @@ -2,6 +2,7 @@ namespace App\Models\Pages; +use App\Models\Publications\Publication; use App\Support\HasObjectsTrait; use App\Support\RelationValuesTrait; use App\Support\UuidScopeTrait; @@ -50,6 +51,10 @@ class Page extends Model { return $this->objects()->wherePivot('group', '=', 'sidebars'); } + public function publications(): HasMany { + return $this->hasMany(Publication::class); + } + public function scopeBySlug($query, $slug) { $query->where(['slug' => $slug]); @@ -91,7 +96,7 @@ class Page extends Model { public static function byUrl($url) { if ($url = trim($url, '/ ')) { $query = self::query(); - collect(explode('/', $url))->reverse()->values()->each(function ($slug, $index) use ($query) { + collect(explode('/', $url))->reverse()->values()->each(function($slug, $index) use ($query) { if ($slug !== '') { $index ? $query->nthParentSlug($index, $slug) : $query->bySlug($slug); } diff --git a/app/Models/Pages/PageType.php b/app/Models/Pages/PageType.php index 840770b..cd888a4 100644 --- a/app/Models/Pages/PageType.php +++ b/app/Models/Pages/PageType.php @@ -4,10 +4,12 @@ namespace App\Models\Pages; class PageType { public const CONTENT = 'content'; + public const PUBLICATIONS = 'publications'; public const REGISTRY = 'registry'; public const TITLES = [ self::CONTENT => 'Контентная страница', + self::PUBLICATIONS => 'Страница публикаций', self::REGISTRY => 'Страница реестра' ]; } \ No newline at end of file diff --git a/app/Models/Publications/Publication.php b/app/Models/Publications/Publication.php new file mode 100644 index 0000000..a03476d --- /dev/null +++ b/app/Models/Publications/Publication.php @@ -0,0 +1,96 @@ +belongsTo(Page::class); + } + + public function poster(): BelongsTo { + return $this->belongsTo(Asset::class); + } + + public function author(): BelongsTo { + return $this->belongsTo(User::class); + } + + public function sections(): MorphToMany { + return $this->objects()->wherePivot('group', '=', 'sections'); + } + + public function sidebars(): MorphToMany { + return $this->objects()->wherePivot('group', '=', 'sidebars'); + } + + + public function scopeBySlug($query, $slug) { + $query->where(['slug' => $slug]); + } + + + public function getLinkAttribute(): string { + return ($this->page->link ?? '') . "/{$this->slug}"; + } + + public function getParsedTypeAttribute(): array { + return ['name' => $this->type, 'title' => PublicationType::TITLES[$this->type] ?? null]; + } + + + + public function addSection($typeName, $ord = null): ?Model { + return $this->createObject($typeName, $ord, 'sections'); + } + + public function addSidebar($typeName = 'page-sidebar', $ord = null): ?Model { + return $this->createObject($typeName, $ord, 'sidebars'); + } + + + public static function byUrl($url) { + if ($url = trim($url, '/ ')) { + $slugs = explode('/', $url); + $publicationSlug = array_pop($slugs); + $pageUrl = implode('/', $slugs); + if ($pageUrl) { + return ($page = Page::byUrl($pageUrl)) ? $page->publications()->bySlug($publicationSlug)->first() : null; + } else return self::bySlug($publicationSlug)->first(); + } + return null; + } + +} diff --git a/app/Models/Publications/PublicationType.php b/app/Models/Publications/PublicationType.php new file mode 100644 index 0000000..2d405ba --- /dev/null +++ b/app/Models/Publications/PublicationType.php @@ -0,0 +1,11 @@ + 'Новость' + ]; +} \ No newline at end of file diff --git a/app/Transformers/Pages/PageTransformer.php b/app/Transformers/Pages/PageTransformer.php index ec1c39b..4f547a4 100644 --- a/app/Transformers/Pages/PageTransformer.php +++ b/app/Transformers/Pages/PageTransformer.php @@ -5,6 +5,7 @@ namespace App\Transformers\Pages; use App\Models\Pages\Page; use App\Services\PermissionsService; use App\Transformers\Objects\ObjectTransformer; +use App\Transformers\Publications\PublicationTransformer; use League\Fractal\Resource\Collection; use League\Fractal\Resource\Item; use League\Fractal\Resource\Primitive; @@ -16,7 +17,7 @@ class PageTransformer extends TransformerAbstract { ]; protected array $availableIncludes = [ - 'children', 'parent', 'parents', 'sections', 'sidebars', 'permissions' + 'children', 'parent', 'parents', 'sections', 'sidebars', 'publications', 'permissions' ]; public function transform(Page $model): array { @@ -53,6 +54,10 @@ class PageTransformer extends TransformerAbstract { return $this->collection($model->sidebars, new ObjectTransformer()); } + public function includePublications(Page $model): Collection { + return $this->collection($model->publications, new PublicationTransformer()); + } + public function includePermissions(Page $model): Primitive { return $this->primitive((new PermissionsService($model))->get()); } diff --git a/app/Transformers/Publications/PublicationTransformer.php b/app/Transformers/Publications/PublicationTransformer.php new file mode 100644 index 0000000..a051564 --- /dev/null +++ b/app/Transformers/Publications/PublicationTransformer.php @@ -0,0 +1,65 @@ + $model->uuid, + 'slug' => $model->slug, + 'link' => $model->link, + 'type' => $model->parsedType, + 'name' => $model->name, + 'excerpt' => $model->excerpt, + 'is_published' => boolval($model->is_published), + 'created_at' => $model->created_at ? $model->created_at->toIso8601String() : null, + 'updated_at' => $model->updated_at ? $model->updated_at->toIso8601String() : null + ]; + } + + public function includePage(Publication $model): ?Item { + return $model->page ? $this->item($model->page, new PageTransformer()) : null; + } + + public function includePoster(Publication $model): ?Item { + return $model->poster ? $this->item($model->poster, new AssetTransformer()) : null; + } + + public function includeAuthor(Publication $model): ?Item { + return $model->author ? $this->item($model->author, new UserTransformer()) : null; + } + + public function includeSections(Publication $model): Collection { + return $this->collection($model->sections, new ObjectTransformer()); + } + + public function includeSidebars(Publication $model): Collection { + return $this->collection($model->sidebars, new ObjectTransformer()); + } + + public function includePermissions(Publication $model): Primitive { + return $this->primitive((new PermissionsService($model))->get()); + } + + +} diff --git a/database/migrations/2023_06_07_153956_create_publications_table.php b/database/migrations/2023_06_07_153956_create_publications_table.php new file mode 100644 index 0000000..0651dce --- /dev/null +++ b/database/migrations/2023_06_07_153956_create_publications_table.php @@ -0,0 +1,41 @@ +id(); + $table->char('uuid', 36)->index()->unique(); + $table->integer('page_id')->index()->default(0); + $table->integer('poster_id')->index()->nullable(); + $table->integer('author_id')->index()->nullable(); + $table->string('slug')->index()->nullable(); + $table->string('type')->index()->nullable(); + $table->string('name')->index()->nullable(); + $table->text('excerpt')->nullable(); + $table->boolean('is_published')->index()->default(0); + $table->timestamps(); + $table->softDeletes(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('publications'); + } +} diff --git a/database/seeders/Pages/PagesTableSeeder.php b/database/seeders/Pages/PagesTableSeeder.php index 0c987ae..a8c30c7 100644 --- a/database/seeders/Pages/PagesTableSeeder.php +++ b/database/seeders/Pages/PagesTableSeeder.php @@ -3,6 +3,7 @@ namespace Database\Seeders\Pages; use App\Models\Pages\Page; +use App\Models\Pages\PageType; use Illuminate\Database\Seeder; use Illuminate\Support\Str; @@ -128,8 +129,8 @@ class PagesTableSeeder extends Seeder ], 'Пресс-центр' => [ 'children' => [ - 'Новости' => [], - 'СМИ о нас' => [], + 'Новости' => ['type' => PageType::PUBLICATIONS], + 'СМИ о нас' => ['type' => PageType::REGISTRY], 'Фотогалерея' => [], 'Видеоархив' => [], 'Контакты для СМИ' => [], @@ -152,7 +153,7 @@ class PagesTableSeeder extends Seeder { $slug = Str::slug(Str::transliterate($name)); $page = Page::firstOrCreate(['parent_id' => $parent->id ?? 0, 'slug' => $slug]); - $page->update(['name' => $name]); + $page->update(['name' => $name, 'type' => $data['type'] ?? PageType::CONTENT]); if ($v = collect($data)->except('children')->all()) $page->update($v); $ord = 0; collect($data['children'] ?? [])->each(function ($data, $name) use ($page, &$ord) { diff --git a/routes/api.php b/routes/api.php index 3785990..3a689d7 100644 --- a/routes/api.php +++ b/routes/api.php @@ -19,6 +19,10 @@ Route::get('pages/root', 'Api\Pages\PagesController@root'); Route::get('pages/find', 'Api\Pages\PagesController@find'); Route::get('pages/{id}', 'Api\Pages\PagesController@show'); +Route::get('publications', 'Api\Publications\PublicationsController@index'); +Route::get('publications/find', 'Api\Publications\PublicationsController@find'); +Route::get('publications/{id}', 'Api\Publications\PublicationsController@show'); + Route::group(['middleware' => ['auth:api']], function() { Route::apiResource('users', 'Api\Users\UsersController'); Route::apiResource('roles', 'Api\Users\RolesController');