diff --git a/app/Http/Controllers/Api/Publications/PublicationsController.php b/app/Http/Controllers/Api/Publications/PublicationsController.php index dcf6ce2..75865d7 100644 --- a/app/Http/Controllers/Api/Publications/PublicationsController.php +++ b/app/Http/Controllers/Api/Publications/PublicationsController.php @@ -26,23 +26,16 @@ class PublicationsController extends Controller { public function index(Request $request): JsonResponse { $filters = collect($request->has('filters') ? json_decode($request->get('filters'), true) : [])->filter(function($val) {return $val;}); $query = $this->model->query()->orderBy('published_at', 'desc'); - if ($page = Page::byUuid($request->get('page_id'))->first()) { - $query->where(['page_id' => $page->id]); - } elseif ($page = Page::query()->where(['sub_type' => 'publication-' . $request->get('type')])->first()) { - $query->where('page_id', $page->id); - } $service = FiltersService::getService('publications'); $service->applyFilters($query, $filters); $paginator = $query->paginate($request->get('limit', config('app.pagination_limit'))); - if ($request->has('limit')) { - $paginator->appends('limit', $request->get('limit')); - } + if ($request->has('limit')) $paginator->appends('limit', $request->get('limit')); return fractal($paginator, new PublicationTransformer())->respond(); } public function show(Request $request, $id): JsonResponse { $model = $this->model->ByUuid($id)->firstOrFail(); - return fractal($model, new RegistryTransformer())->respond(); + return fractal($model, new PublicationTransformer())->respond(); } diff --git a/app/Models/Pages/Page.php b/app/Models/Pages/Page.php index c92e04a..3047cab 100644 --- a/app/Models/Pages/Page.php +++ b/app/Models/Pages/Page.php @@ -30,7 +30,6 @@ class Page extends Model { 'picture_id', 'slug', 'type', - 'sub_type', 'name', 'title', 'description', diff --git a/app/Models/Pages/PageSubType.php b/app/Models/Pages/PageSubType.php deleted file mode 100644 index 8e45ddb..0000000 --- a/app/Models/Pages/PageSubType.php +++ /dev/null @@ -1,19 +0,0 @@ - 'Новость', - self::PUBLICATION_SMI => 'СМИ о нас', - self::PUBLICATION_PHOTOS => 'Фотогаллерея', - self::PUBLICATION_VIDEO => 'Видеоархив', - self::PUBLICATION_PORTFOLIO => 'Портфолио' - ]; -} \ No newline at end of file diff --git a/app/Models/Publications/Publication.php b/app/Models/Publications/Publication.php index 4943ec9..4bb23ff 100644 --- a/app/Models/Publications/Publication.php +++ b/app/Models/Publications/Publication.php @@ -24,15 +24,15 @@ class Publication extends Model { protected $fillable = [ 'uuid', 'page_id', - 'poster_id', 'author_id', 'slug', 'type', 'name', 'excerpt', - 'params', - 'published_at', + 'content', 'is_published', + 'is_blank', + 'published_at' ]; protected $hidden = [ @@ -53,11 +53,11 @@ class Publication extends Model { } public function sections(): MorphToMany { - return $this->objects()->wherePivot('group', '=', 'sections'); + return $this->objectsByGroup('sections'); } public function sidebars(): MorphToMany { - return $this->objects()->wherePivot('group', '=', 'sidebars'); + return $this->objectsByGroup('sidebars'); } @@ -77,14 +77,6 @@ class Publication extends Model { return $result; } - public function getParsedTypeAttribute(): array { - return ['name' => $this->type, 'title' => PublicationType::TITLES[$this->type] ?? null]; - } - - public function getParsedParamsAttribute() { - return json_decode($this->params); - } - public function getPublishDateRusAttribute(): string { return $this->published_at ? $this->published_at->format('d') . ' ' . $this->published_at->getTranslatedMonthName('Do MMMM') . ' ' . $this->published_at->format('Y') . ' г.' : 'Дата не указана'; } diff --git a/app/Services/Filters/Publications/PublicationFilters.php b/app/Services/Filters/Publications/PublicationFilters.php index b7d3708..3da7eda 100644 --- a/app/Services/Filters/Publications/PublicationFilters.php +++ b/app/Services/Filters/Publications/PublicationFilters.php @@ -2,7 +2,7 @@ namespace App\Services\Filters\Publications; -use App\Models\Companies\CompanyMember; +use App\Models\Publications\Publication; use App\Services\Filters\FiltersService; use Illuminate\Database\Eloquent\Builder; use Illuminate\Support\Collection; @@ -17,7 +17,7 @@ class PublicationFilters extends FiltersService { 'fields' => $this->nativeFields($filters) ] ]; - $query = CompanyMember::query(); + $query = Publication::query(); $this->applyFilters($query, $filters); return ['groups' => ['data' => $groups], 'total' => $query->count()]; } @@ -41,7 +41,7 @@ class PublicationFilters extends FiltersService { public function applyNativeFilter(Builder $query, $prop, $value) { if ($value) { - if ($prop === 'search') $this->applySearchFilter($query, $value, ['name', 'excerpt']); + if ($prop === 'search') $this->applySearchFilter($query, $value, ['name', 'excerpt', 'content']); elseif ($prop === 'page') $this->applyRelationFilter($query, 'page', $value); } } diff --git a/app/Services/Forms/Publications/PublicationForms.php b/app/Services/Forms/Publications/PublicationForms.php new file mode 100644 index 0000000..4f5efe6 --- /dev/null +++ b/app/Services/Forms/Publications/PublicationForms.php @@ -0,0 +1,95 @@ + 'Создание новой публикации', 'update' => 'Редактирование публикации']; + + public function form(?string $id = null, array $data = []): array { + $model = Publication::byUuid($id)->first(); + $groups = [ + ['name' => 'common', 'fields' => $this->commonGroupFields($model)] + ]; + return ['title' => $this->formTitle($model), 'data' => $groups]; + } + + public function commonGroupFields(?Publication $model): array { + $fields = [ + [ + 'name' => 'name', + 'title' => 'Название', + 'type' => FieldType::STRING, + 'required' => true, + 'max_length' => 750, + 'value' => $model->name ?? null + ], + [ + 'name' => 'excerpt', + 'title' => 'Краткое содержание', + 'type' => FieldType::TEXT, + 'required' => true, + 'value' => $model->excerpt ?? null + ], + [ + 'name' => 'is_published', + 'title' => 'Опубликовано', + 'type' => FieldType::BOOLEAN, + 'value' => $model->is_published ?? null + ], + [ + 'name' => 'published_at', + 'title' => 'Дата публикации', + 'type' => FieldType::DATE, + 'value' => $model->published_at ?? null, + 'required' => true, + ], + [ + 'name' => 'images', + 'title' => 'Изображения', + 'type' => FieldType::IMAGE, + 'multiple' => true, + 'value' => ($v = $model->images ?? null) ? fractal($v, new AssetTransformer()) : null + ], + [ + 'name' => 'is_blank', + 'title' => 'Скрыть постер и анонс на странице публикации', + 'type' => FieldType::BOOLEAN, + 'value' => $model->is_blank ?? null + ], + [ + 'name' => 'content', + 'title' => 'Содержимое публикации', + 'type' => FieldType::HTML, + 'value' => $model->content ?? null + ] + ]; + return ['data' => $fields]; + } + + + public function store(array $data): ?JsonResponse { + $page = Page::byUuid($data['page'] ?? null)->firstOrFail(); + $data = array_merge($data, ['author_id' => Auth::user()->id, 'slug' => Str::slug($data['slug'] ?? $data['name']), 'is_published' => !empty($data['is_published']), 'is_blank' => !empty($data['is_blank'])]); + $model = $page->publications()->create($data); + $model->setImages($data['images'] ?? null); + return fractal($model, new PublicationTransformer())->respond(); + } + + public function update(string $id, array $data): ?JsonResponse { + $model = Publication::byUuid($id)->firstOrFail(); + $data = array_merge($data, ['slug' => Str::slug($data['slug'] ?? $data['name']), 'is_published' => !empty($data['is_published']), 'is_blank' => !empty($data['is_blank'])]); + $model->update($data); + $model->setImages($data['images'] ?? null); + return fractal($model->fresh(), new PublicationTransformer())->respond(); + } +} diff --git a/app/Services/Forms/Publications/PublicationFormsServices.php b/app/Services/Forms/Publications/PublicationFormsServices.php index f50339e..745785b 100644 --- a/app/Services/Forms/Publications/PublicationFormsServices.php +++ b/app/Services/Forms/Publications/PublicationFormsServices.php @@ -4,10 +4,6 @@ namespace App\Services\Forms\Publications; class PublicationFormsServices { public static array $services = [ - 'publication-news' => PublicationNewsForms::class, - 'publication-smi' => PublicationSmiForms::class, - 'publication-photos' => PublicationPhotosForms::class, - 'publication-video' => PublicationVideoForms::class, - 'publication-portfolio' => PublicationPortfolioForms::class, + 'publication' => PublicationForms::class ]; } diff --git a/app/Support/HasObjectsTrait.php b/app/Support/HasObjectsTrait.php index 47b3c48..948a1c0 100644 --- a/app/Support/HasObjectsTrait.php +++ b/app/Support/HasObjectsTrait.php @@ -6,6 +6,7 @@ use App\Models\Objects\NirObject; use App\Models\Objects\ObjectType; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\MorphToMany; +use Illuminate\Support\Collection; trait HasObjectsTrait { public function objects(): MorphToMany { @@ -21,6 +22,22 @@ trait HasObjectsTrait { return $this->objects()->first(); } + public function getImagesAttribute(): ?Collection { + return $this->getObject('basic-container', 'container')->getValue('images'); + } + public function getDocumentsAttribute(): ?Collection { + return $this->getObject('basic-container', 'container')->getValue('documents'); + } + + + public function setImages($value) { + return $this->getObject('basic-container', 'container')->setValue('images', $value); + } + public function setDocuments($value) { + return $this->getObject('basic-container', 'container')->setValue('documents', $value); + } + + public function getObject($typeName, $group = null): ?Model { if ($type = ObjectType::byName($typeName)->first()) { diff --git a/app/Transformers/Pages/PageTransformer.php b/app/Transformers/Pages/PageTransformer.php index 25d66e1..70bffbf 100644 --- a/app/Transformers/Pages/PageTransformer.php +++ b/app/Transformers/Pages/PageTransformer.php @@ -14,9 +14,9 @@ use League\Fractal\Resource\Primitive; use League\Fractal\TransformerAbstract; class PageTransformer extends TransformerAbstract { - public bool $withTrashed = false; + public ?bool $withTrashed = false; - public function __construct(bool $withTrashed = false) { + public function __construct(?bool $withTrashed = false) { $this->withTrashed = $withTrashed; } @@ -35,7 +35,6 @@ class PageTransformer extends TransformerAbstract { 'slug' => $model->slug, 'link' => $model->link, 'type' => $model->parsedType, - 'sub_type' => $model->sub_type, 'name' => $model->name, 'title' => $model->title, 'h1' => $model->h1, diff --git a/app/Transformers/Publications/PublicationTransformer.php b/app/Transformers/Publications/PublicationTransformer.php index ee34fb3..3809405 100644 --- a/app/Transformers/Publications/PublicationTransformer.php +++ b/app/Transformers/Publications/PublicationTransformer.php @@ -3,7 +3,6 @@ namespace App\Transformers\Publications; use App\Models\Asset; -use App\Models\Pages\Page; use App\Models\Publications\Publication; use App\Models\Publications\PublicationType; use App\Services\PermissionsService; @@ -18,38 +17,28 @@ use League\Fractal\TransformerAbstract; class PublicationTransformer extends TransformerAbstract { protected array $defaultIncludes = [ - 'poster' ]; protected array $availableIncludes = [ - 'page', 'parents', 'poster', 'author', 'sections', 'sidebars', 'permissions' + 'page', 'parents', 'posters', 'author', 'sections', 'sidebars', 'permissions' ]; public function transform(Publication $model): array { - $params = $model->parsedParams; - - $result = [ + return [ 'id' => $model->uuid, 'slug' => $model->slug, 'link' => $model->link, - 'type' => 'publication', - 'subtype' => $model->parsedType, - 'params' => $params, + 'type' => ['name' => 'publication', 'title' => 'Публикация'], 'name' => $model->name, 'excerpt' => $model->excerpt, + 'content' => $model->content, 'publish_date_rus' => $model->publish_date_rus, 'is_published' => boolval($model->is_published), + 'is_blank' => boolval($model->is_blank), 'published_at' => $model->published_at ? $model->published_at->toIso8601String() : null, 'created_at' => $model->created_at ? $model->created_at->toIso8601String() : null, 'updated_at' => $model->updated_at ? $model->updated_at->toIso8601String() : null ]; - - if ($model->parsedType['name'] === PublicationType::PHOTOS && $params->assets) { - $models = Asset::query()->whereIn('uuid', $params->assets)->orderBy('id')->get(); - $result['assets'] = fractal($models, new AssetTransformer()); - } - - return $result; } public function includePage(Publication $model): ?Item { @@ -60,8 +49,8 @@ class PublicationTransformer extends TransformerAbstract { return $this->collection($model->parents->reverse(), new PageTransformer()); } - public function includePoster(Publication $model): ?Item { - return $model->poster ? $this->item($model->poster, new AssetTransformer()) : null; + public function includePosters(Publication $model): Collection { + return $this->collection($model->images, new AssetTransformer()); } public function includeAuthor(Publication $model): ?Item { diff --git a/database/migrations/2023_06_07_153956_create_publications_table.php b/database/migrations/2023_06_07_153956_create_publications_table.php index 6629065..77c1146 100644 --- a/database/migrations/2023_06_07_153956_create_publications_table.php +++ b/database/migrations/2023_06_07_153956_create_publications_table.php @@ -17,15 +17,14 @@ class CreatePublicationsTable extends Migration $table->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', 750)->index()->nullable(); - $table->text('excerpt')->nullable(); - $table->text('params')->nullable(); + $table->text('excerpt')->fulltext()->nullable(); + $table->mediumText('content')->fulltext()->nullable(); $table->boolean('is_published')->index()->default(0); - $table->timestamp('published_at')->nullable(); + $table->boolean('is_blank')->index()->default(0); + $table->dateTime('published_at')->nullable(); $table->timestamps(); $table->softDeletes(); }); diff --git a/database/seeders/Objects/ObjectTypeFieldsTableSeeder.php b/database/seeders/Objects/ObjectTypeFieldsTableSeeder.php index 8e1415d..09bc8cc 100644 --- a/database/seeders/Objects/ObjectTypeFieldsTableSeeder.php +++ b/database/seeders/Objects/ObjectTypeFieldsTableSeeder.php @@ -9,6 +9,12 @@ use Illuminate\Database\Seeder; class ObjectTypeFieldsTableSeeder extends Seeder { public array $objectTypeFields = [ + 'basic-container' => [ + 'common' => [ + 'fields' => ['images', 'documents'] + ] + ], + 'page-sidebar' => [ 'common' => [ 'fields' => ['header', 'html', 'documents'] diff --git a/database/seeders/Objects/ObjectTypesTableSeeder.php b/database/seeders/Objects/ObjectTypesTableSeeder.php index 0467840..e961673 100644 --- a/database/seeders/Objects/ObjectTypesTableSeeder.php +++ b/database/seeders/Objects/ObjectTypesTableSeeder.php @@ -7,6 +7,10 @@ use Illuminate\Database\Seeder; class ObjectTypesTableSeeder extends Seeder { public array $types = [ + 'basic-container' => [ + 'title' => 'Контейнер для изображений и документов' + ], + 'page-sidebar' => [ 'title' => 'Сторонний блок контентной страницы' ],