optimizations
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class AttachCollectionArtworksRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'artwork_ids' => ['required', 'array', 'min:1'],
|
||||
'artwork_ids.*' => ['integer', 'distinct'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use App\Models\Collection;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CollectionBulkActionsRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'action' => ['required', 'string', 'in:archive,assign_campaign,update_lifecycle,request_ai_review,mark_editorial_review'],
|
||||
'collection_ids' => ['required', 'array', 'min:1'],
|
||||
'collection_ids.*' => ['integer', 'distinct'],
|
||||
'campaign_key' => ['nullable', 'string', 'max:80'],
|
||||
'campaign_label' => ['nullable', 'string', 'max:120'],
|
||||
'lifecycle_state' => ['nullable', 'string', 'in:' . implode(',', [
|
||||
Collection::LIFECYCLE_DRAFT,
|
||||
Collection::LIFECYCLE_PUBLISHED,
|
||||
Collection::LIFECYCLE_ARCHIVED,
|
||||
])],
|
||||
];
|
||||
}
|
||||
|
||||
public function withValidator($validator): void
|
||||
{
|
||||
$validator->after(function ($validator): void {
|
||||
$action = (string) $this->input('action', '');
|
||||
|
||||
if ($action === 'assign_campaign' && blank($this->input('campaign_key'))) {
|
||||
$validator->errors()->add('campaign_key', 'Campaign key is required for campaign assignment.');
|
||||
}
|
||||
|
||||
if ($action === 'update_lifecycle' && blank($this->input('lifecycle_state'))) {
|
||||
$validator->errors()->add('lifecycle_state', 'Lifecycle state is required for lifecycle updates.');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use App\Models\Collection;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CollectionOwnerSearchRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'q' => ['nullable', 'string', 'max:120'],
|
||||
'type' => ['nullable', 'string', 'in:' . implode(',', [
|
||||
Collection::TYPE_PERSONAL,
|
||||
Collection::TYPE_COMMUNITY,
|
||||
Collection::TYPE_EDITORIAL,
|
||||
])],
|
||||
'visibility' => ['nullable', 'string', 'in:' . implode(',', [
|
||||
Collection::VISIBILITY_PUBLIC,
|
||||
Collection::VISIBILITY_UNLISTED,
|
||||
Collection::VISIBILITY_PRIVATE,
|
||||
])],
|
||||
'lifecycle_state' => ['nullable', 'string', 'in:' . implode(',', [
|
||||
Collection::LIFECYCLE_DRAFT,
|
||||
Collection::LIFECYCLE_SCHEDULED,
|
||||
Collection::LIFECYCLE_PUBLISHED,
|
||||
Collection::LIFECYCLE_FEATURED,
|
||||
Collection::LIFECYCLE_ARCHIVED,
|
||||
Collection::LIFECYCLE_HIDDEN,
|
||||
Collection::LIFECYCLE_RESTRICTED,
|
||||
Collection::LIFECYCLE_UNDER_REVIEW,
|
||||
Collection::LIFECYCLE_EXPIRED,
|
||||
])],
|
||||
'mode' => ['nullable', 'string', 'in:' . implode(',', [
|
||||
Collection::MODE_MANUAL,
|
||||
Collection::MODE_SMART,
|
||||
])],
|
||||
'campaign_key' => ['nullable', 'string', 'max:80'],
|
||||
'program_key' => ['nullable', 'string', 'max:80'],
|
||||
'workflow_state' => ['nullable', 'string', 'in:' . implode(',', [
|
||||
Collection::WORKFLOW_DRAFT,
|
||||
Collection::WORKFLOW_IN_REVIEW,
|
||||
Collection::WORKFLOW_APPROVED,
|
||||
Collection::WORKFLOW_PROGRAMMED,
|
||||
Collection::WORKFLOW_ARCHIVED,
|
||||
])],
|
||||
'health_state' => ['nullable', 'string', 'in:' . implode(',', [
|
||||
Collection::HEALTH_HEALTHY,
|
||||
Collection::HEALTH_NEEDS_METADATA,
|
||||
Collection::HEALTH_STALE,
|
||||
Collection::HEALTH_LOW_CONTENT,
|
||||
Collection::HEALTH_BROKEN_ITEMS,
|
||||
Collection::HEALTH_WEAK_COVER,
|
||||
Collection::HEALTH_LOW_ENGAGEMENT,
|
||||
Collection::HEALTH_ATTRIBUTION_INCOMPLETE,
|
||||
Collection::HEALTH_NEEDS_REVIEW,
|
||||
Collection::HEALTH_DUPLICATE_RISK,
|
||||
Collection::HEALTH_MERGE_CANDIDATE,
|
||||
])],
|
||||
'partner_key' => ['nullable', 'string', 'max:80'],
|
||||
'experiment_key' => ['nullable', 'string', 'max:80'],
|
||||
'placement_eligibility' => ['nullable', 'boolean'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CollectionProgramAssignmentRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'collection_id' => ['required', 'integer', 'exists:collections,id'],
|
||||
'program_key' => ['required', 'string', 'max:80'],
|
||||
'campaign_key' => ['nullable', 'string', 'max:80'],
|
||||
'placement_scope' => ['nullable', 'string', 'max:80'],
|
||||
'starts_at' => ['nullable', 'date'],
|
||||
'ends_at' => ['nullable', 'date', 'after:starts_at'],
|
||||
'priority' => ['nullable', 'integer', 'min:-100', 'max:100'],
|
||||
'notes' => ['nullable', 'string', 'max:1000'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CollectionProgrammingCollectionRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'collection_id' => ['nullable', 'integer', 'exists:collections,id'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CollectionProgrammingMergePairRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'source_collection_id' => ['required', 'integer', 'exists:collections,id'],
|
||||
'target_collection_id' => ['required', 'integer', 'exists:collections,id', 'different:source_collection_id'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CollectionProgrammingMetadataRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'collection_id' => ['required', 'integer', 'exists:collections,id'],
|
||||
'experiment_key' => ['nullable', 'string', 'max:80'],
|
||||
'experiment_treatment' => ['nullable', 'string', 'max:80'],
|
||||
'placement_variant' => ['nullable', 'string', 'max:80'],
|
||||
'ranking_mode_variant' => ['nullable', 'string', 'max:80'],
|
||||
'collection_pool_version' => ['nullable', 'string', 'max:80'],
|
||||
'test_label' => ['nullable', 'string', 'max:120'],
|
||||
'placement_eligibility' => ['nullable', 'boolean'],
|
||||
'promotion_tier' => ['nullable', 'string', 'max:40'],
|
||||
'partner_key' => ['nullable', 'string', 'max:80'],
|
||||
'trust_tier' => ['nullable', 'string', 'max:40'],
|
||||
'sponsorship_state' => ['nullable', 'string', 'max:40'],
|
||||
'ownership_domain' => ['nullable', 'string', 'max:80'],
|
||||
'commercial_review_state' => ['nullable', 'string', 'max:40'],
|
||||
'legal_review_state' => ['nullable', 'string', 'max:40'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CollectionProgrammingPreviewRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'program_key' => ['required', 'string', 'max:80'],
|
||||
'limit' => ['nullable', 'integer', 'min:1', 'max:24'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CollectionSavedLibraryRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'q' => ['nullable', 'string', 'max:120'],
|
||||
'filter' => ['nullable', 'string', 'in:all,editorial,community,personal,seasonal,noted,revisited'],
|
||||
'sort' => ['nullable', 'string', 'in:saved_desc,saved_asc,updated_desc,revisited_desc,ranking_desc,title_asc'],
|
||||
'list' => ['nullable', 'integer', 'min:1'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use App\Models\Collection;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CollectionTargetActionRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'target_collection_id' => ['required', 'integer', 'exists:collections,id'],
|
||||
];
|
||||
}
|
||||
|
||||
public function withValidator($validator): void
|
||||
{
|
||||
$validator->after(function ($validator): void {
|
||||
$targetCollectionId = (int) $this->input('target_collection_id');
|
||||
$collection = $this->route('collection');
|
||||
|
||||
if ($collection instanceof Collection && $targetCollectionId === (int) $collection->id) {
|
||||
$validator->errors()->add('target_collection_id', 'Choose a different target collection.');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ReorderCollectionArtworksRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'ordered_artwork_ids' => ['required', 'array'],
|
||||
'ordered_artwork_ids.*' => ['integer', 'distinct'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ReorderProfileCollectionsRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'collection_ids' => ['required', 'array', 'min:1'],
|
||||
'collection_ids.*' => ['required', 'integer'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ReorderSavedCollectionListItemsRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'collection_ids' => ['required', 'array', 'min:1'],
|
||||
'collection_ids.*' => ['required', 'integer', 'distinct'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class SmartCollectionRulesRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'smart_rules_json' => ['required', 'array'],
|
||||
'smart_rules_json.match' => ['nullable', 'string'],
|
||||
'smart_rules_json.sort' => ['nullable', 'string'],
|
||||
'smart_rules_json.rules' => ['required', 'array'],
|
||||
];
|
||||
}
|
||||
}
|
||||
173
app/Http/Requests/Collections/StoreCollectionRequest.php
Normal file
173
app/Http/Requests/Collections/StoreCollectionRequest.php
Normal file
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use App\Models\Collection;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class StoreCollectionRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$title = (string) $this->input('title', '');
|
||||
$slug = (string) $this->input('slug', '');
|
||||
$mode = (string) ($this->input('mode') ?: Collection::MODE_MANUAL);
|
||||
$sortMode = (string) ($this->input('sort_mode') ?: ($mode === Collection::MODE_SMART ? Collection::SORT_NEWEST : Collection::SORT_MANUAL));
|
||||
|
||||
if ($slug === '' && $title !== '') {
|
||||
$slug = Str::slug(Str::limit($title, 140, ''));
|
||||
}
|
||||
|
||||
$this->merge([
|
||||
'slug' => $slug,
|
||||
'mode' => $mode,
|
||||
'sort_mode' => $sortMode,
|
||||
]);
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'title' => ['required', 'string', 'min:2', 'max:120'],
|
||||
'slug' => ['required', 'string', 'min:2', 'max:140', 'regex:/^[a-z0-9]+(?:-[a-z0-9]+)*$/'],
|
||||
'type' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::TYPE_PERSONAL,
|
||||
Collection::TYPE_COMMUNITY,
|
||||
Collection::TYPE_EDITORIAL,
|
||||
])],
|
||||
'editorial_owner_mode' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::EDITORIAL_OWNER_CREATOR,
|
||||
Collection::EDITORIAL_OWNER_STAFF_ACCOUNT,
|
||||
Collection::EDITORIAL_OWNER_SYSTEM,
|
||||
])],
|
||||
'editorial_owner_username' => ['nullable', 'string', 'max:60'],
|
||||
'editorial_owner_label' => ['nullable', 'string', 'max:120'],
|
||||
'description' => ['nullable', 'string', 'max:1000'],
|
||||
'subtitle' => ['nullable', 'string', 'max:160'],
|
||||
'summary' => ['nullable', 'string', 'max:320'],
|
||||
'lifecycle_state' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::LIFECYCLE_DRAFT,
|
||||
Collection::LIFECYCLE_SCHEDULED,
|
||||
Collection::LIFECYCLE_PUBLISHED,
|
||||
Collection::LIFECYCLE_FEATURED,
|
||||
Collection::LIFECYCLE_ARCHIVED,
|
||||
Collection::LIFECYCLE_EXPIRED,
|
||||
])],
|
||||
'collaboration_mode' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::COLLABORATION_CLOSED,
|
||||
Collection::COLLABORATION_INVITE_ONLY,
|
||||
Collection::COLLABORATION_OPEN,
|
||||
])],
|
||||
'allow_submissions' => ['nullable', 'boolean'],
|
||||
'allow_comments' => ['nullable', 'boolean'],
|
||||
'allow_saves' => ['nullable', 'boolean'],
|
||||
'event_key' => ['nullable', 'string', 'max:80'],
|
||||
'event_label' => ['nullable', 'string', 'max:120'],
|
||||
'season_key' => ['nullable', 'string', 'max:80'],
|
||||
'banner_text' => ['nullable', 'string', 'max:200'],
|
||||
'badge_label' => ['nullable', 'string', 'max:80'],
|
||||
'spotlight_style' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::SPOTLIGHT_STYLE_DEFAULT,
|
||||
Collection::SPOTLIGHT_STYLE_EDITORIAL,
|
||||
Collection::SPOTLIGHT_STYLE_SEASONAL,
|
||||
Collection::SPOTLIGHT_STYLE_CHALLENGE,
|
||||
Collection::SPOTLIGHT_STYLE_COMMUNITY,
|
||||
])],
|
||||
'analytics_enabled' => ['nullable', 'boolean'],
|
||||
'presentation_style' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::PRESENTATION_STANDARD,
|
||||
Collection::PRESENTATION_EDITORIAL_GRID,
|
||||
Collection::PRESENTATION_HERO_GRID,
|
||||
Collection::PRESENTATION_MASONRY,
|
||||
])],
|
||||
'emphasis_mode' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::EMPHASIS_COVER_HEAVY,
|
||||
Collection::EMPHASIS_BALANCED,
|
||||
Collection::EMPHASIS_ARTWORK_FIRST,
|
||||
])],
|
||||
'theme_token' => ['nullable', 'in:default,subtle-blue,violet,amber'],
|
||||
'series_key' => ['nullable', 'string', 'max:80'],
|
||||
'series_title' => ['nullable', 'string', 'max:160'],
|
||||
'series_description' => ['nullable', 'string', 'max:400'],
|
||||
'series_order' => ['nullable', 'integer', 'min:1', 'max:9999'],
|
||||
'campaign_key' => ['nullable', 'string', 'max:80'],
|
||||
'campaign_label' => ['nullable', 'string', 'max:120'],
|
||||
'commercial_eligibility' => ['nullable', 'boolean'],
|
||||
'promotion_tier' => ['nullable', 'string', 'max:40'],
|
||||
'sponsorship_label' => ['nullable', 'string', 'max:120'],
|
||||
'partner_label' => ['nullable', 'string', 'max:120'],
|
||||
'monetization_ready_status' => ['nullable', 'string', 'max:40'],
|
||||
'brand_safe_status' => ['nullable', 'string', 'max:40'],
|
||||
'published_at' => ['nullable', 'date'],
|
||||
'unpublished_at' => ['nullable', 'date', 'after:published_at'],
|
||||
'archived_at' => ['nullable', 'date'],
|
||||
'expired_at' => ['nullable', 'date'],
|
||||
'visibility' => ['required', 'in:' . implode(',', [
|
||||
Collection::VISIBILITY_PUBLIC,
|
||||
Collection::VISIBILITY_UNLISTED,
|
||||
Collection::VISIBILITY_PRIVATE,
|
||||
])],
|
||||
'mode' => ['required', 'in:' . implode(',', [
|
||||
Collection::MODE_MANUAL,
|
||||
Collection::MODE_SMART,
|
||||
])],
|
||||
'sort_mode' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::SORT_MANUAL,
|
||||
Collection::SORT_NEWEST,
|
||||
Collection::SORT_OLDEST,
|
||||
Collection::SORT_POPULAR,
|
||||
])],
|
||||
'smart_rules_json' => ['nullable', 'array'],
|
||||
'layout_modules_json' => ['nullable', 'array'],
|
||||
'layout_modules_json.*.key' => ['required_with:layout_modules_json', 'string', 'max:60'],
|
||||
'layout_modules_json.*.enabled' => ['nullable', 'boolean'],
|
||||
'layout_modules_json.*.slot' => ['nullable', 'string', 'max:20'],
|
||||
];
|
||||
}
|
||||
|
||||
public function withValidator($validator): void
|
||||
{
|
||||
$validator->after(function ($validator): void {
|
||||
$type = (string) ($this->input('type') ?: Collection::TYPE_PERSONAL);
|
||||
|
||||
if ($type === Collection::TYPE_EDITORIAL && ! $this->user()?->hasRole('admin')) {
|
||||
$validator->errors()->add('type', 'Only staff can create editorial collections.');
|
||||
}
|
||||
|
||||
if ($type === Collection::TYPE_EDITORIAL && (string) $this->input('editorial_owner_mode') === Collection::EDITORIAL_OWNER_STAFF_ACCOUNT) {
|
||||
$username = trim((string) $this->input('editorial_owner_username', ''));
|
||||
|
||||
if ($username === '') {
|
||||
$validator->errors()->add('editorial_owner_username', 'Choose the staff account that should own this editorial collection.');
|
||||
} else {
|
||||
$target = User::query()->whereRaw('LOWER(username) = ?', [Str::lower($username)])->first();
|
||||
|
||||
if (! $target || ! ($target->isAdmin() || $target->isModerator())) {
|
||||
$validator->errors()->add('editorial_owner_username', 'The editorial owner must be an admin or moderator account.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->filled('unpublished_at') && ! $this->filled('published_at')) {
|
||||
$validator->errors()->add('published_at', 'Set a publish time before adding an unpublish time.');
|
||||
}
|
||||
|
||||
if ((string) $this->input('mode') !== Collection::MODE_SMART) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! is_array($this->input('smart_rules_json'))) {
|
||||
$validator->errors()->add('smart_rules_json', 'Smart collections require at least one valid rule.');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use App\Models\Collection;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateCollectionCampaignRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
foreach ([
|
||||
'event_key',
|
||||
'event_label',
|
||||
'season_key',
|
||||
'banner_text',
|
||||
'badge_label',
|
||||
'campaign_key',
|
||||
'campaign_label',
|
||||
'promotion_tier',
|
||||
'sponsorship_label',
|
||||
'partner_label',
|
||||
'monetization_ready_status',
|
||||
'brand_safe_status',
|
||||
'editorial_notes',
|
||||
'staff_commercial_notes',
|
||||
] as $field) {
|
||||
if ($this->has($field) && trim((string) $this->input($field)) === '') {
|
||||
$this->merge([$field => null]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'event_key' => ['nullable', 'string', 'max:80'],
|
||||
'event_label' => ['nullable', 'string', 'max:120'],
|
||||
'season_key' => ['nullable', 'string', 'max:80'],
|
||||
'banner_text' => ['nullable', 'string', 'max:200'],
|
||||
'badge_label' => ['nullable', 'string', 'max:80'],
|
||||
'spotlight_style' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::SPOTLIGHT_STYLE_DEFAULT,
|
||||
Collection::SPOTLIGHT_STYLE_EDITORIAL,
|
||||
Collection::SPOTLIGHT_STYLE_SEASONAL,
|
||||
Collection::SPOTLIGHT_STYLE_CHALLENGE,
|
||||
Collection::SPOTLIGHT_STYLE_COMMUNITY,
|
||||
])],
|
||||
'campaign_key' => ['nullable', 'string', 'max:80'],
|
||||
'campaign_label' => ['nullable', 'string', 'max:120'],
|
||||
'commercial_eligibility' => ['nullable', 'boolean'],
|
||||
'promotion_tier' => ['nullable', 'string', 'max:40'],
|
||||
'sponsorship_label' => ['nullable', 'string', 'max:120'],
|
||||
'partner_label' => ['nullable', 'string', 'max:120'],
|
||||
'monetization_ready_status' => ['nullable', 'string', 'max:40'],
|
||||
'brand_safe_status' => ['nullable', 'string', 'max:40'],
|
||||
'editorial_notes' => ['nullable', 'string', 'max:2000'],
|
||||
'staff_commercial_notes' => ['nullable', 'string', 'max:2000'],
|
||||
];
|
||||
}
|
||||
|
||||
public function withValidator($validator): void
|
||||
{
|
||||
$validator->after(function ($validator): void {
|
||||
if ($this->filled('staff_commercial_notes') && ! $this->user()?->isAdmin()) {
|
||||
$validator->errors()->add('staff_commercial_notes', 'Only admins can update staff commercial notes.');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use App\Services\CollectionLinkService;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateCollectionEntityLinksRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'entity_links' => ['nullable', 'array', 'max:18'],
|
||||
'entity_links.*.linked_type' => ['required', 'string', Rule::in(CollectionLinkService::supportedTypes())],
|
||||
'entity_links.*.linked_id' => ['required', 'integer', 'min:1'],
|
||||
'entity_links.*.relationship_type' => ['nullable', 'string', 'max:80'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use App\Models\Collection;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateCollectionLifecycleRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
foreach (['published_at', 'unpublished_at', 'archived_at', 'expired_at'] as $field) {
|
||||
if ($this->has($field) && trim((string) $this->input($field)) === '') {
|
||||
$this->merge([$field => null]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'lifecycle_state' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::LIFECYCLE_DRAFT,
|
||||
Collection::LIFECYCLE_SCHEDULED,
|
||||
Collection::LIFECYCLE_PUBLISHED,
|
||||
Collection::LIFECYCLE_FEATURED,
|
||||
Collection::LIFECYCLE_ARCHIVED,
|
||||
Collection::LIFECYCLE_EXPIRED,
|
||||
])],
|
||||
'visibility' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::VISIBILITY_PUBLIC,
|
||||
Collection::VISIBILITY_UNLISTED,
|
||||
Collection::VISIBILITY_PRIVATE,
|
||||
])],
|
||||
'published_at' => ['nullable', 'date'],
|
||||
'unpublished_at' => ['nullable', 'date', 'after:published_at'],
|
||||
'archived_at' => ['nullable', 'date'],
|
||||
'expired_at' => ['nullable', 'date'],
|
||||
];
|
||||
}
|
||||
|
||||
public function withValidator($validator): void
|
||||
{
|
||||
$validator->after(function ($validator): void {
|
||||
if ($this->filled('unpublished_at')) {
|
||||
$collection = $this->route('collection');
|
||||
|
||||
if (! $this->filled('published_at') && ! optional($collection)->published_at) {
|
||||
$validator->errors()->add('published_at', 'Set a publish time before adding an unpublish time.');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateCollectionLinkedCollectionsRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'related_collection_ids' => ['nullable', 'array', 'max:12'],
|
||||
'related_collection_ids.*' => ['required', 'integer', 'distinct'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use App\Models\Collection;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateCollectionPresentationRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
foreach (['subtitle', 'summary', 'theme_token'] as $field) {
|
||||
if ($this->has($field) && trim((string) $this->input($field)) === '') {
|
||||
$this->merge([$field => null]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'subtitle' => ['nullable', 'string', 'max:160'],
|
||||
'summary' => ['nullable', 'string', 'max:320'],
|
||||
'presentation_style' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::PRESENTATION_STANDARD,
|
||||
Collection::PRESENTATION_EDITORIAL_GRID,
|
||||
Collection::PRESENTATION_HERO_GRID,
|
||||
Collection::PRESENTATION_MASONRY,
|
||||
])],
|
||||
'emphasis_mode' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::EMPHASIS_COVER_HEAVY,
|
||||
Collection::EMPHASIS_BALANCED,
|
||||
Collection::EMPHASIS_ARTWORK_FIRST,
|
||||
])],
|
||||
'theme_token' => ['nullable', 'in:default,subtle-blue,violet,amber'],
|
||||
'layout_modules_json' => ['nullable', 'array'],
|
||||
'layout_modules_json.*.key' => ['required_with:layout_modules_json', 'string', 'max:60'],
|
||||
'layout_modules_json.*.enabled' => ['nullable', 'boolean'],
|
||||
'layout_modules_json.*.slot' => ['nullable', 'string', 'max:20'],
|
||||
];
|
||||
}
|
||||
}
|
||||
217
app/Http/Requests/Collections/UpdateCollectionRequest.php
Normal file
217
app/Http/Requests/Collections/UpdateCollectionRequest.php
Normal file
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use App\Models\Artwork;
|
||||
use App\Models\Collection;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class UpdateCollectionRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$title = (string) $this->input('title', '');
|
||||
$slug = (string) $this->input('slug', '');
|
||||
/** @var \App\Models\Collection|null $collection */
|
||||
$collection = $this->route('collection');
|
||||
$mode = (string) ($this->input('mode') ?: ($collection?->mode ?? Collection::MODE_MANUAL));
|
||||
$defaultSortMode = $collection?->sort_mode ?? Collection::SORT_MANUAL;
|
||||
$sortMode = (string) ($this->input('sort_mode') ?: ($mode === Collection::MODE_SMART ? ($defaultSortMode ?: Collection::SORT_NEWEST) : $defaultSortMode));
|
||||
|
||||
if ($slug === '' && $title !== '') {
|
||||
$slug = Str::slug(Str::limit($title, 140, ''));
|
||||
}
|
||||
|
||||
$this->merge([
|
||||
'slug' => $slug,
|
||||
'mode' => $mode,
|
||||
'sort_mode' => $sortMode,
|
||||
]);
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'title' => ['required', 'string', 'min:2', 'max:120'],
|
||||
'slug' => ['required', 'string', 'min:2', 'max:140', 'regex:/^[a-z0-9]+(?:-[a-z0-9]+)*$/'],
|
||||
'type' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::TYPE_PERSONAL,
|
||||
Collection::TYPE_COMMUNITY,
|
||||
Collection::TYPE_EDITORIAL,
|
||||
])],
|
||||
'editorial_owner_mode' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::EDITORIAL_OWNER_CREATOR,
|
||||
Collection::EDITORIAL_OWNER_STAFF_ACCOUNT,
|
||||
Collection::EDITORIAL_OWNER_SYSTEM,
|
||||
])],
|
||||
'editorial_owner_username' => ['nullable', 'string', 'max:60'],
|
||||
'editorial_owner_label' => ['nullable', 'string', 'max:120'],
|
||||
'description' => ['nullable', 'string', 'max:1000'],
|
||||
'subtitle' => ['nullable', 'string', 'max:160'],
|
||||
'summary' => ['nullable', 'string', 'max:320'],
|
||||
'lifecycle_state' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::LIFECYCLE_DRAFT,
|
||||
Collection::LIFECYCLE_SCHEDULED,
|
||||
Collection::LIFECYCLE_PUBLISHED,
|
||||
Collection::LIFECYCLE_FEATURED,
|
||||
Collection::LIFECYCLE_ARCHIVED,
|
||||
Collection::LIFECYCLE_EXPIRED,
|
||||
])],
|
||||
'collaboration_mode' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::COLLABORATION_CLOSED,
|
||||
Collection::COLLABORATION_INVITE_ONLY,
|
||||
Collection::COLLABORATION_OPEN,
|
||||
])],
|
||||
'allow_submissions' => ['nullable', 'boolean'],
|
||||
'allow_comments' => ['nullable', 'boolean'],
|
||||
'allow_saves' => ['nullable', 'boolean'],
|
||||
'event_key' => ['nullable', 'string', 'max:80'],
|
||||
'event_label' => ['nullable', 'string', 'max:120'],
|
||||
'season_key' => ['nullable', 'string', 'max:80'],
|
||||
'banner_text' => ['nullable', 'string', 'max:200'],
|
||||
'badge_label' => ['nullable', 'string', 'max:80'],
|
||||
'spotlight_style' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::SPOTLIGHT_STYLE_DEFAULT,
|
||||
Collection::SPOTLIGHT_STYLE_EDITORIAL,
|
||||
Collection::SPOTLIGHT_STYLE_SEASONAL,
|
||||
Collection::SPOTLIGHT_STYLE_CHALLENGE,
|
||||
Collection::SPOTLIGHT_STYLE_COMMUNITY,
|
||||
])],
|
||||
'analytics_enabled' => ['nullable', 'boolean'],
|
||||
'presentation_style' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::PRESENTATION_STANDARD,
|
||||
Collection::PRESENTATION_EDITORIAL_GRID,
|
||||
Collection::PRESENTATION_HERO_GRID,
|
||||
Collection::PRESENTATION_MASONRY,
|
||||
])],
|
||||
'emphasis_mode' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::EMPHASIS_COVER_HEAVY,
|
||||
Collection::EMPHASIS_BALANCED,
|
||||
Collection::EMPHASIS_ARTWORK_FIRST,
|
||||
])],
|
||||
'theme_token' => ['nullable', 'in:default,subtle-blue,violet,amber'],
|
||||
'series_key' => ['nullable', 'string', 'max:80'],
|
||||
'series_title' => ['nullable', 'string', 'max:160'],
|
||||
'series_description' => ['nullable', 'string', 'max:400'],
|
||||
'series_order' => ['nullable', 'integer', 'min:1', 'max:9999'],
|
||||
'campaign_key' => ['nullable', 'string', 'max:80'],
|
||||
'campaign_label' => ['nullable', 'string', 'max:120'],
|
||||
'commercial_eligibility' => ['nullable', 'boolean'],
|
||||
'promotion_tier' => ['nullable', 'string', 'max:40'],
|
||||
'sponsorship_label' => ['nullable', 'string', 'max:120'],
|
||||
'partner_label' => ['nullable', 'string', 'max:120'],
|
||||
'monetization_ready_status' => ['nullable', 'string', 'max:40'],
|
||||
'brand_safe_status' => ['nullable', 'string', 'max:40'],
|
||||
'published_at' => ['nullable', 'date'],
|
||||
'unpublished_at' => ['nullable', 'date', 'after:published_at'],
|
||||
'archived_at' => ['nullable', 'date'],
|
||||
'expired_at' => ['nullable', 'date'],
|
||||
'visibility' => ['required', 'in:' . implode(',', [
|
||||
Collection::VISIBILITY_PUBLIC,
|
||||
Collection::VISIBILITY_UNLISTED,
|
||||
Collection::VISIBILITY_PRIVATE,
|
||||
])],
|
||||
'mode' => ['required', 'in:' . implode(',', [
|
||||
Collection::MODE_MANUAL,
|
||||
Collection::MODE_SMART,
|
||||
])],
|
||||
'sort_mode' => ['nullable', 'in:' . implode(',', [
|
||||
Collection::SORT_MANUAL,
|
||||
Collection::SORT_NEWEST,
|
||||
Collection::SORT_OLDEST,
|
||||
Collection::SORT_POPULAR,
|
||||
])],
|
||||
'cover_artwork_id' => ['nullable', 'integer'],
|
||||
'smart_rules_json' => ['nullable', 'array'],
|
||||
'layout_modules_json' => ['nullable', 'array'],
|
||||
'layout_modules_json.*.key' => ['required_with:layout_modules_json', 'string', 'max:60'],
|
||||
'layout_modules_json.*.enabled' => ['nullable', 'boolean'],
|
||||
'layout_modules_json.*.slot' => ['nullable', 'string', 'max:20'],
|
||||
];
|
||||
}
|
||||
|
||||
public function withValidator($validator): void
|
||||
{
|
||||
$validator->after(function ($validator): void {
|
||||
$type = (string) ($this->input('type') ?: Collection::TYPE_PERSONAL);
|
||||
|
||||
if ($type === Collection::TYPE_EDITORIAL && ! $this->user()?->hasRole('admin')) {
|
||||
$validator->errors()->add('type', 'Only staff can edit collections into editorial collections.');
|
||||
}
|
||||
|
||||
if ($type === Collection::TYPE_EDITORIAL && (string) $this->input('editorial_owner_mode') === Collection::EDITORIAL_OWNER_STAFF_ACCOUNT) {
|
||||
$username = trim((string) $this->input('editorial_owner_username', ''));
|
||||
|
||||
if ($username === '') {
|
||||
$validator->errors()->add('editorial_owner_username', 'Choose the staff account that should own this editorial collection.');
|
||||
} else {
|
||||
$target = User::query()->whereRaw('LOWER(username) = ?', [Str::lower($username)])->first();
|
||||
|
||||
if (! $target || ! ($target->isAdmin() || $target->isModerator())) {
|
||||
$validator->errors()->add('editorial_owner_username', 'The editorial owner must be an admin or moderator account.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->filled('unpublished_at') && ! $this->filled('published_at') && ! optional($this->route('collection'))->published_at) {
|
||||
$validator->errors()->add('published_at', 'Set a publish time before adding an unpublish time.');
|
||||
}
|
||||
|
||||
if ((string) $this->input('mode') !== Collection::MODE_SMART) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! is_array($this->input('smart_rules_json'))) {
|
||||
$validator->errors()->add('smart_rules_json', 'Smart collections require at least one valid rule.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function passedValidation(): void
|
||||
{
|
||||
if (($this->input('mode') ?? Collection::MODE_MANUAL) === Collection::MODE_SMART) {
|
||||
return;
|
||||
}
|
||||
|
||||
$coverArtworkId = $this->integer('cover_artwork_id');
|
||||
if (! $coverArtworkId) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var \App\Models\Collection|null $collection */
|
||||
$collection = $this->route('collection');
|
||||
$userId = $this->user()?->id;
|
||||
|
||||
if (! $collection || ! $userId) {
|
||||
return;
|
||||
}
|
||||
|
||||
$belongsToUser = Artwork::query()
|
||||
->where('id', $coverArtworkId)
|
||||
->where('user_id', $userId)
|
||||
->whereNull('deleted_at')
|
||||
->exists();
|
||||
|
||||
$isAttached = DB::table('collection_artwork')
|
||||
->where('collection_id', $collection->id)
|
||||
->where('artwork_id', $coverArtworkId)
|
||||
->exists();
|
||||
|
||||
if (! $belongsToUser || ! $isAttached) {
|
||||
throw ValidationException::withMessages([
|
||||
'cover_artwork_id' => 'Choose a cover artwork that is already attached to this collection.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateCollectionSeriesRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
foreach (['series_key', 'series_title', 'series_description'] as $field) {
|
||||
if ($this->has($field) && trim((string) $this->input($field)) === '') {
|
||||
$this->merge([$field => null]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->has('series_order') && trim((string) $this->input('series_order')) === '') {
|
||||
$this->merge(['series_order' => null]);
|
||||
}
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'series_key' => ['nullable', 'string', 'max:80'],
|
||||
'series_title' => ['nullable', 'string', 'max:160'],
|
||||
'series_description' => ['nullable', 'string', 'max:400'],
|
||||
'series_order' => ['nullable', 'integer', 'min:1', 'max:9999'],
|
||||
];
|
||||
}
|
||||
|
||||
public function withValidator($validator): void
|
||||
{
|
||||
$validator->after(function ($validator): void {
|
||||
$seriesKey = $this->input('series_key');
|
||||
$seriesTitle = $this->input('series_title');
|
||||
$seriesDescription = $this->input('series_description');
|
||||
$seriesOrder = $this->input('series_order');
|
||||
|
||||
$hasSeriesMetadata = filled($seriesTitle) || filled($seriesDescription) || filled($seriesOrder);
|
||||
|
||||
if ($hasSeriesMetadata && blank($seriesKey)) {
|
||||
$validator->errors()->add('series_key', 'Series key is required when series metadata is provided.');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Collections;
|
||||
|
||||
use App\Models\Collection;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateCollectionWorkflowRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return $this->user() !== null;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'workflow_state' => ['nullable', 'string', 'in:' . implode(',', [
|
||||
Collection::WORKFLOW_DRAFT,
|
||||
Collection::WORKFLOW_IN_REVIEW,
|
||||
Collection::WORKFLOW_APPROVED,
|
||||
Collection::WORKFLOW_PROGRAMMED,
|
||||
Collection::WORKFLOW_ARCHIVED,
|
||||
])],
|
||||
'program_key' => ['nullable', 'string', 'max:80'],
|
||||
'partner_key' => ['nullable', 'string', 'max:80'],
|
||||
'experiment_key' => ['nullable', 'string', 'max:80'],
|
||||
'placement_eligibility' => ['nullable', 'boolean'],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user