publications module updated
parent
c655bac34e
commit
c9b746115f
|
|
@ -26,23 +26,16 @@ class PublicationsController extends Controller {
|
||||||
public function index(Request $request): JsonResponse {
|
public function index(Request $request): JsonResponse {
|
||||||
$filters = collect($request->has('filters') ? json_decode($request->get('filters'), true) : [])->filter(function($val) {return $val;});
|
$filters = collect($request->has('filters') ? json_decode($request->get('filters'), true) : [])->filter(function($val) {return $val;});
|
||||||
$query = $this->model->query()->orderBy('published_at', 'desc');
|
$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 = FiltersService::getService('publications');
|
||||||
$service->applyFilters($query, $filters);
|
$service->applyFilters($query, $filters);
|
||||||
$paginator = $query->paginate($request->get('limit', config('app.pagination_limit')));
|
$paginator = $query->paginate($request->get('limit', config('app.pagination_limit')));
|
||||||
if ($request->has('limit')) {
|
if ($request->has('limit')) $paginator->appends('limit', $request->get('limit'));
|
||||||
$paginator->appends('limit', $request->get('limit'));
|
|
||||||
}
|
|
||||||
return fractal($paginator, new PublicationTransformer())->respond();
|
return fractal($paginator, new PublicationTransformer())->respond();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show(Request $request, $id): JsonResponse {
|
public function show(Request $request, $id): JsonResponse {
|
||||||
$model = $this->model->ByUuid($id)->firstOrFail();
|
$model = $this->model->ByUuid($id)->firstOrFail();
|
||||||
return fractal($model, new RegistryTransformer())->respond();
|
return fractal($model, new PublicationTransformer())->respond();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ class Page extends Model {
|
||||||
'picture_id',
|
'picture_id',
|
||||||
'slug',
|
'slug',
|
||||||
'type',
|
'type',
|
||||||
'sub_type',
|
|
||||||
'name',
|
'name',
|
||||||
'title',
|
'title',
|
||||||
'description',
|
'description',
|
||||||
|
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models\Pages;
|
|
||||||
|
|
||||||
class PageSubType {
|
|
||||||
public const PUBLICATION_NEWS = 'publication-news';
|
|
||||||
public const PUBLICATION_SMI = 'publication-smi';
|
|
||||||
public const PUBLICATION_PHOTOS = 'publication-photos';
|
|
||||||
public const PUBLICATION_VIDEO = 'publication-video';
|
|
||||||
public const PUBLICATION_PORTFOLIO = 'publication-portfolio';
|
|
||||||
|
|
||||||
public const TITLES = [
|
|
||||||
self::PUBLICATION_NEWS => 'Новость',
|
|
||||||
self::PUBLICATION_SMI => 'СМИ о нас',
|
|
||||||
self::PUBLICATION_PHOTOS => 'Фотогаллерея',
|
|
||||||
self::PUBLICATION_VIDEO => 'Видеоархив',
|
|
||||||
self::PUBLICATION_PORTFOLIO => 'Портфолио'
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -24,15 +24,15 @@ class Publication extends Model {
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'uuid',
|
'uuid',
|
||||||
'page_id',
|
'page_id',
|
||||||
'poster_id',
|
|
||||||
'author_id',
|
'author_id',
|
||||||
'slug',
|
'slug',
|
||||||
'type',
|
'type',
|
||||||
'name',
|
'name',
|
||||||
'excerpt',
|
'excerpt',
|
||||||
'params',
|
'content',
|
||||||
'published_at',
|
|
||||||
'is_published',
|
'is_published',
|
||||||
|
'is_blank',
|
||||||
|
'published_at'
|
||||||
];
|
];
|
||||||
|
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
|
|
@ -53,11 +53,11 @@ class Publication extends Model {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sections(): MorphToMany {
|
public function sections(): MorphToMany {
|
||||||
return $this->objects()->wherePivot('group', '=', 'sections');
|
return $this->objectsByGroup('sections');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function sidebars(): MorphToMany {
|
public function sidebars(): MorphToMany {
|
||||||
return $this->objects()->wherePivot('group', '=', 'sidebars');
|
return $this->objectsByGroup('sidebars');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -77,14 +77,6 @@ class Publication extends Model {
|
||||||
return $result;
|
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 {
|
public function getPublishDateRusAttribute(): string {
|
||||||
return $this->published_at ? $this->published_at->format('d') . ' ' . $this->published_at->getTranslatedMonthName('Do MMMM') . ' ' . $this->published_at->format('Y') . ' г.' : 'Дата не указана';
|
return $this->published_at ? $this->published_at->format('d') . ' ' . $this->published_at->getTranslatedMonthName('Do MMMM') . ' ' . $this->published_at->format('Y') . ' г.' : 'Дата не указана';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Services\Filters\Publications;
|
namespace App\Services\Filters\Publications;
|
||||||
|
|
||||||
use App\Models\Companies\CompanyMember;
|
use App\Models\Publications\Publication;
|
||||||
use App\Services\Filters\FiltersService;
|
use App\Services\Filters\FiltersService;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
@ -17,7 +17,7 @@ class PublicationFilters extends FiltersService {
|
||||||
'fields' => $this->nativeFields($filters)
|
'fields' => $this->nativeFields($filters)
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
$query = CompanyMember::query();
|
$query = Publication::query();
|
||||||
$this->applyFilters($query, $filters);
|
$this->applyFilters($query, $filters);
|
||||||
return ['groups' => ['data' => $groups], 'total' => $query->count()];
|
return ['groups' => ['data' => $groups], 'total' => $query->count()];
|
||||||
}
|
}
|
||||||
|
|
@ -41,7 +41,7 @@ class PublicationFilters extends FiltersService {
|
||||||
|
|
||||||
public function applyNativeFilter(Builder $query, $prop, $value) {
|
public function applyNativeFilter(Builder $query, $prop, $value) {
|
||||||
if ($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);
|
elseif ($prop === 'page') $this->applyRelationFilter($query, 'page', $value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Forms\Publications;
|
||||||
|
|
||||||
|
use App\Models\Objects\FieldType;
|
||||||
|
use App\Models\Pages\Page;
|
||||||
|
use App\Models\Publications\Publication;
|
||||||
|
use App\Services\Forms\FormsService;
|
||||||
|
use App\Transformers\Assets\AssetTransformer;
|
||||||
|
use App\Transformers\Publications\PublicationTransformer;
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class PublicationForms extends FormsService {
|
||||||
|
public array $formTitles = ['create' => 'Создание новой публикации', '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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,10 +4,6 @@ namespace App\Services\Forms\Publications;
|
||||||
|
|
||||||
class PublicationFormsServices {
|
class PublicationFormsServices {
|
||||||
public static array $services = [
|
public static array $services = [
|
||||||
'publication-news' => PublicationNewsForms::class,
|
'publication' => PublicationForms::class
|
||||||
'publication-smi' => PublicationSmiForms::class,
|
|
||||||
'publication-photos' => PublicationPhotosForms::class,
|
|
||||||
'publication-video' => PublicationVideoForms::class,
|
|
||||||
'publication-portfolio' => PublicationPortfolioForms::class,
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ use App\Models\Objects\NirObject;
|
||||||
use App\Models\Objects\ObjectType;
|
use App\Models\Objects\ObjectType;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\MorphToMany;
|
use Illuminate\Database\Eloquent\Relations\MorphToMany;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
trait HasObjectsTrait {
|
trait HasObjectsTrait {
|
||||||
public function objects(): MorphToMany {
|
public function objects(): MorphToMany {
|
||||||
|
|
@ -21,6 +22,22 @@ trait HasObjectsTrait {
|
||||||
return $this->objects()->first();
|
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 {
|
public function getObject($typeName, $group = null): ?Model {
|
||||||
if ($type = ObjectType::byName($typeName)->first()) {
|
if ($type = ObjectType::byName($typeName)->first()) {
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ use League\Fractal\Resource\Primitive;
|
||||||
use League\Fractal\TransformerAbstract;
|
use League\Fractal\TransformerAbstract;
|
||||||
|
|
||||||
class PageTransformer extends 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;
|
$this->withTrashed = $withTrashed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,7 +35,6 @@ class PageTransformer extends TransformerAbstract {
|
||||||
'slug' => $model->slug,
|
'slug' => $model->slug,
|
||||||
'link' => $model->link,
|
'link' => $model->link,
|
||||||
'type' => $model->parsedType,
|
'type' => $model->parsedType,
|
||||||
'sub_type' => $model->sub_type,
|
|
||||||
'name' => $model->name,
|
'name' => $model->name,
|
||||||
'title' => $model->title,
|
'title' => $model->title,
|
||||||
'h1' => $model->h1,
|
'h1' => $model->h1,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
namespace App\Transformers\Publications;
|
namespace App\Transformers\Publications;
|
||||||
|
|
||||||
use App\Models\Asset;
|
use App\Models\Asset;
|
||||||
use App\Models\Pages\Page;
|
|
||||||
use App\Models\Publications\Publication;
|
use App\Models\Publications\Publication;
|
||||||
use App\Models\Publications\PublicationType;
|
use App\Models\Publications\PublicationType;
|
||||||
use App\Services\PermissionsService;
|
use App\Services\PermissionsService;
|
||||||
|
|
@ -18,38 +17,28 @@ use League\Fractal\TransformerAbstract;
|
||||||
|
|
||||||
class PublicationTransformer extends TransformerAbstract {
|
class PublicationTransformer extends TransformerAbstract {
|
||||||
protected array $defaultIncludes = [
|
protected array $defaultIncludes = [
|
||||||
'poster'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
protected array $availableIncludes = [
|
protected array $availableIncludes = [
|
||||||
'page', 'parents', 'poster', 'author', 'sections', 'sidebars', 'permissions'
|
'page', 'parents', 'posters', 'author', 'sections', 'sidebars', 'permissions'
|
||||||
];
|
];
|
||||||
|
|
||||||
public function transform(Publication $model): array {
|
public function transform(Publication $model): array {
|
||||||
$params = $model->parsedParams;
|
return [
|
||||||
|
|
||||||
$result = [
|
|
||||||
'id' => $model->uuid,
|
'id' => $model->uuid,
|
||||||
'slug' => $model->slug,
|
'slug' => $model->slug,
|
||||||
'link' => $model->link,
|
'link' => $model->link,
|
||||||
'type' => 'publication',
|
'type' => ['name' => 'publication', 'title' => 'Публикация'],
|
||||||
'subtype' => $model->parsedType,
|
|
||||||
'params' => $params,
|
|
||||||
'name' => $model->name,
|
'name' => $model->name,
|
||||||
'excerpt' => $model->excerpt,
|
'excerpt' => $model->excerpt,
|
||||||
|
'content' => $model->content,
|
||||||
'publish_date_rus' => $model->publish_date_rus,
|
'publish_date_rus' => $model->publish_date_rus,
|
||||||
'is_published' => boolval($model->is_published),
|
'is_published' => boolval($model->is_published),
|
||||||
|
'is_blank' => boolval($model->is_blank),
|
||||||
'published_at' => $model->published_at ? $model->published_at->toIso8601String() : null,
|
'published_at' => $model->published_at ? $model->published_at->toIso8601String() : null,
|
||||||
'created_at' => $model->created_at ? $model->created_at->toIso8601String() : null,
|
'created_at' => $model->created_at ? $model->created_at->toIso8601String() : null,
|
||||||
'updated_at' => $model->updated_at ? $model->updated_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 {
|
public function includePage(Publication $model): ?Item {
|
||||||
|
|
@ -60,8 +49,8 @@ class PublicationTransformer extends TransformerAbstract {
|
||||||
return $this->collection($model->parents->reverse(), new PageTransformer());
|
return $this->collection($model->parents->reverse(), new PageTransformer());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function includePoster(Publication $model): ?Item {
|
public function includePosters(Publication $model): Collection {
|
||||||
return $model->poster ? $this->item($model->poster, new AssetTransformer()) : null;
|
return $this->collection($model->images, new AssetTransformer());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function includeAuthor(Publication $model): ?Item {
|
public function includeAuthor(Publication $model): ?Item {
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,14 @@ class CreatePublicationsTable extends Migration
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->char('uuid', 36)->index()->unique();
|
$table->char('uuid', 36)->index()->unique();
|
||||||
$table->integer('page_id')->index()->default(0);
|
$table->integer('page_id')->index()->default(0);
|
||||||
$table->integer('poster_id')->index()->nullable();
|
|
||||||
$table->integer('author_id')->index()->nullable();
|
$table->integer('author_id')->index()->nullable();
|
||||||
$table->string('slug')->index()->nullable();
|
$table->string('slug')->index()->nullable();
|
||||||
$table->string('type')->index()->nullable();
|
|
||||||
$table->string('name', 750)->index()->nullable();
|
$table->string('name', 750)->index()->nullable();
|
||||||
$table->text('excerpt')->nullable();
|
$table->text('excerpt')->fulltext()->nullable();
|
||||||
$table->text('params')->nullable();
|
$table->mediumText('content')->fulltext()->nullable();
|
||||||
$table->boolean('is_published')->index()->default(0);
|
$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->timestamps();
|
||||||
$table->softDeletes();
|
$table->softDeletes();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,12 @@ use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
class ObjectTypeFieldsTableSeeder extends Seeder {
|
class ObjectTypeFieldsTableSeeder extends Seeder {
|
||||||
public array $objectTypeFields = [
|
public array $objectTypeFields = [
|
||||||
|
'basic-container' => [
|
||||||
|
'common' => [
|
||||||
|
'fields' => ['images', 'documents']
|
||||||
|
]
|
||||||
|
],
|
||||||
|
|
||||||
'page-sidebar' => [
|
'page-sidebar' => [
|
||||||
'common' => [
|
'common' => [
|
||||||
'fields' => ['header', 'html', 'documents']
|
'fields' => ['header', 'html', 'documents']
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,10 @@ use Illuminate\Database\Seeder;
|
||||||
|
|
||||||
class ObjectTypesTableSeeder extends Seeder {
|
class ObjectTypesTableSeeder extends Seeder {
|
||||||
public array $types = [
|
public array $types = [
|
||||||
|
'basic-container' => [
|
||||||
|
'title' => 'Контейнер для изображений и документов'
|
||||||
|
],
|
||||||
|
|
||||||
'page-sidebar' => [
|
'page-sidebar' => [
|
||||||
'title' => 'Сторонний блок контентной страницы'
|
'title' => 'Сторонний блок контентной страницы'
|
||||||
],
|
],
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue