- Introduced AttachmentCrop model to manage crop variants for attachments. - Updated Attachment model to remove direct crop fields and establish relationships with AttachmentCrop. - Modified AttachmentService to handle storing and updating multiple crop variants (desktop and mobile). - Adjusted validation rules to accommodate new crop structure. - Updated database migration to create attachment_crops table and migrate existing crop data. - Refactored tests to ensure compatibility with the new cropping structure and validate multiple crop variants. - Enhanced documentation to reflect changes in attachment handling and cropping capabilities.
112 lines
3.8 KiB
PHP
112 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace App\Domains\Tenant\Resources\AdminApp;
|
|
|
|
use App\Domains\Attachable\Models\Attachment;
|
|
use App\Domains\Attachable\Models\AttachmentCrop;
|
|
use App\Domains\Tenant\Models\Tenant;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Resources\Json\JsonResource;
|
|
|
|
/**
|
|
* @mixin Tenant
|
|
*/
|
|
class WebsiteExtrasResource extends JsonResource
|
|
{
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function toArray(Request $request): array
|
|
{
|
|
$websiteExtras = $this->websiteExtras->keyBy(
|
|
fn ($extra) => $extra->websiteTypeExtra->codigo
|
|
);
|
|
|
|
return [
|
|
'website_type' => $this->websiteType ? [
|
|
'codigo' => $this->websiteType->codigo,
|
|
'nombre' => $this->websiteType->nombre,
|
|
] : null,
|
|
'definitions' => $this->websiteType?->extras
|
|
->mapWithKeys(fn ($definition) => [
|
|
$definition->codigo => [
|
|
'codigo' => $definition->codigo,
|
|
'nombre' => $definition->nombre,
|
|
'descripcion' => $definition->descripcion,
|
|
'is_required' => $definition->is_required,
|
|
'is_enabled' => $websiteExtras
|
|
->get($definition->codigo)?->is_enabled,
|
|
'request_rules' => $definition->config_schema['request_rules'] ?? [],
|
|
],
|
|
]) ?? [],
|
|
'extras' => $websiteExtras->mapWithKeys(fn ($extra) => [
|
|
$extra->websiteTypeExtra->codigo => $this->formatConfig(
|
|
$extra->resolvedConfig(),
|
|
fn (Attachment $attachment): string => $attachment->key
|
|
),
|
|
]),
|
|
'resolved_extras' => $websiteExtras->mapWithKeys(fn ($extra) => [
|
|
$extra->websiteTypeExtra->codigo => $this->formatResolvedConfig($extra),
|
|
]),
|
|
];
|
|
}
|
|
|
|
private function formatResolvedConfig(mixed $extra): mixed
|
|
{
|
|
$config = $extra->resolvedConfig();
|
|
|
|
if (
|
|
$extra->websiteTypeExtra->codigo === 'heroConfig'
|
|
&& is_array($config)
|
|
&& ($config['background_image_id'] ?? null) instanceof Attachment
|
|
) {
|
|
$attachment = $config['background_image_id'];
|
|
$config['background_image_id'] = $this->formatHeroAttachment($attachment);
|
|
}
|
|
|
|
return $this->formatConfig(
|
|
$config,
|
|
fn (Attachment $attachment): string => $attachment->getTemporaryUrl(1440)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @return array{url: string, crops: array<string, array<string, array<string, float>>>}
|
|
*/
|
|
private function formatHeroAttachment(Attachment $attachment): array
|
|
{
|
|
$fullRange = ['start_percentage' => 0.0, 'end_percentage' => 100.0];
|
|
$crops = $attachment->cropVariants->keyBy('variant');
|
|
|
|
return [
|
|
'url' => $attachment->getTemporaryUrl(1440),
|
|
'crops' => collect(AttachmentCrop::VARIANTS)->mapWithKeys(
|
|
function (string $variant) use ($crops, $fullRange): array {
|
|
$crop = $crops->get($variant);
|
|
|
|
return [$variant => [
|
|
'crop_horizontal' => $crop?->crop_horizontal ?? $fullRange,
|
|
'crop_vertical' => $crop?->crop_vertical ?? $fullRange,
|
|
]];
|
|
}
|
|
)->all(),
|
|
];
|
|
}
|
|
|
|
private function formatConfig(mixed $value, callable $formatAttachment): mixed
|
|
{
|
|
if ($value instanceof Attachment) {
|
|
return $formatAttachment($value);
|
|
}
|
|
|
|
if (! is_array($value)) {
|
|
return $value;
|
|
}
|
|
|
|
return array_map(
|
|
fn (mixed $item): mixed => $this->formatConfig($item, $formatAttachment),
|
|
$value
|
|
);
|
|
}
|
|
}
|