*/ public function rules(): array { $project = $this->route('project'); $creating = ! $project instanceof Project; $sometimes = $creating ? 'required' : 'sometimes'; return [ 'title' => [$sometimes, new Translatable(requireDefaultLocale: $creating, max: 255)], 'slug' => [ $sometimes, new Translatable(requireDefaultLocale: $creating, max: 255), new UniqueTranslatedSlug(Project::class, $project?->id), ], 'tagline' => ['sometimes', 'nullable', new Translatable(max: 300)], 'description' => ['sometimes', 'nullable', new Translatable], 'decisions' => ['sometimes', 'nullable', new Translatable], 'postmortem' => ['sometimes', 'nullable', new Translatable], 'meta_title' => ['sometimes', 'nullable', new Translatable(max: 60)], 'meta_description' => ['sometimes', 'nullable', new Translatable(max: 160)], 'status' => ['sometimes', Rule::enum(ProjectStatus::class)], 'is_featured' => ['sometimes', 'boolean'], 'needs_help' => ['sometimes', 'boolean'], 'demo_url' => ['sometimes', 'nullable', 'url', 'max:2048'], 'cover_image' => ['sometimes', 'nullable', 'string', 'max:2048'], 'cover_image_alt' => ['sometimes', 'nullable', new Translatable(max: 255)], 'started_at' => ['sometimes', 'nullable', 'date'], 'ended_at' => ['sometimes', 'nullable', 'date', 'after_or_equal:started_at'], 'published_at' => ['sometimes', 'nullable', 'date'], 'unpublish_at' => ['sometimes', 'nullable', 'date', 'after:published_at'], 'position' => ['sometimes', 'integer', 'min:0'], 'client_id' => ['sometimes', 'nullable', 'integer', Rule::exists('clients', 'id')->whereNull('deleted_at')], 'lead_member_id' => ['sometimes', 'nullable', 'integer', Rule::exists('members', 'id')->whereNull('deleted_at')], 'technology_ids' => ['sometimes', 'array'], 'technology_ids.*' => ['integer', 'distinct', Rule::exists('technologies', 'id')], 'service_ids' => ['sometimes', 'array'], 'service_ids.*' => ['integer', 'distinct', Rule::exists('services', 'id')->whereNull('deleted_at')], 'members' => ['sometimes', 'array'], 'members.*.id' => ['required', 'integer', 'distinct', Rule::exists('members', 'id')->whereNull('deleted_at')], 'members.*.role' => ['nullable', 'string', 'max:120'], // The key is only read along with `taskstream`: a client PATCHing // back what it read sends the key it got, which changes nothing. 'taskstream' => ['sometimes', 'boolean'], 'taskstream_key' => ['sometimes', 'nullable', 'string', 'regex:/^[A-Za-z][A-Za-z0-9]{1,9}$/'], ]; } public function withValidator(Validator $validator): void { $this->guardPublication($validator, 'projects.publish', ['published_at', 'unpublish_at']); } }