has('dominio')) { $rawDomain = $this->input('dominio'); $normalizedDomain = TenantDomainNormalizer::normalize($rawDomain); $embeddedBasePath = TenantDomainNormalizer::pathFromDomain($rawDomain); $this->hasInvalidDomain = TenantDomainNormalizer::hasValue($rawDomain) && ($normalizedDomain === null || $embeddedBasePath === null); $this->merge([ 'dominio' => $normalizedDomain, ]); if (! $this->has('base_path') && $embeddedBasePath !== null && $embeddedBasePath !== '/') { $this->merge(['base_path' => $embeddedBasePath]); } } if ($this->has('base_path')) { $rawBasePath = $this->input('base_path'); $normalizedBasePath = TenantDomainNormalizer::normalizePath($rawBasePath); $this->hasInvalidBasePath = ! is_string($rawBasePath) || $normalizedBasePath === null; $this->merge(['base_path' => $normalizedBasePath]); } } /** * @return array */ public function rules(): array { /** @var Tenant|null $tenant */ $tenant = $this->route('tenant'); $domain = $this->input('dominio', $tenant?->dominio); $basePath = $this->input('base_path', $tenant?->base_path ?? '/'); $logoRule = ['nullable', new ImageOrBase64Rule]; return [ 'client_id' => ['sometimes', 'integer', Rule::exists('clients', 'id')], 'codigo' => [ 'nullable', 'string', 'max:255', Rule::unique('tenants', 'codigo')->ignore($tenant?->id), ], 'nombre' => ['nullable', 'string', 'max:255'], 'dominio' => [ 'bail', function (string $attribute, mixed $value, Closure $fail): void { if ($this->hasInvalidDomain) { $fail("The {$attribute} field must contain a valid domain or URL."); } }, 'nullable', 'string', 'max:255', Rule::unique('tenants', 'dominio') ->where('base_path', $basePath) ->ignore($tenant?->id), ], 'base_path' => [ 'bail', function (string $attribute, mixed $value, Closure $fail): void { if ($this->hasInvalidBasePath) { $fail("The {$attribute} field must contain a valid URL path."); } }, 'nullable', 'string', 'max:255', Rule::unique('tenants', 'base_path') ->where('dominio', $domain) ->ignore($tenant?->id), ], 'site_title' => ['sometimes', 'nullable', 'string', 'max:255'], 'primary_color' => ['nullable', 'string', 'regex:/^#([a-fA-F0-9]{3,4}|[a-fA-F0-9]{6}|[a-fA-F0-9]{8})$/'], 'secondary_color' => ['nullable', 'string', 'regex:/^#([a-fA-F0-9]{3,4}|[a-fA-F0-9]{6}|[a-fA-F0-9]{8})$/'], 'danger_color' => ['nullable', 'string', 'regex:/^#([a-fA-F0-9]{3,4}|[a-fA-F0-9]{6}|[a-fA-F0-9]{8})$/'], 'success_color' => ['nullable', 'string', 'regex:/^#([a-fA-F0-9]{3,4}|[a-fA-F0-9]{6}|[a-fA-F0-9]{8})$/'], 'header_bg_color' => ['nullable', 'string', 'regex:/^#([a-fA-F0-9]{3,4}|[a-fA-F0-9]{6}|[a-fA-F0-9]{8})$/'], 'footer_bg_color' => ['nullable', 'string', 'regex:/^#([a-fA-F0-9]{3,4}|[a-fA-F0-9]{6}|[a-fA-F0-9]{8})$/'], 'header_logo' => $logoRule, 'footer_logo' => $logoRule, 'favicon' => ['sometimes', 'nullable', new ImageOrBase64Rule], 'header_bg_image' => ['sometimes', 'nullable', new ImageOrBase64Rule], 'footer_bg_image' => ['sometimes', 'nullable', new ImageOrBase64Rule], 'social_media' => ['sometimes', 'array'], 'social_media.*.code' => [ 'required', 'string', 'distinct', Rule::exists('social_media', 'code'), ], 'social_media.*.url' => ['required', 'url', 'max:2048'], 'social_media.*.orden' => ['sometimes', 'integer', 'min:0', 'distinct'], 'search_product_layout' => ['sometimes', Rule::enum(ProductLayout::class)], 'search_group_layout' => ['sometimes', Rule::enum(GroupLayout::class)], 'search_items_per_page' => ['sometimes', 'integer', 'min:4', 'max:48'], 'display_categories' => ['sometimes', 'boolean'], 'display_seach_bar' => ['sometimes', 'boolean'], 'display_cart' => ['sometimes', 'boolean'], 'cart_editing_enabled' => ['sometimes', 'boolean'], 'display_cart_item_images' => ['sometimes', 'boolean'], 'scanner_category_validation_enabled' => ['sometimes', 'boolean'], ]; } }