- 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.
87 lines
2.4 KiB
PHP
87 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace App\Domains\Shared\Rules;
|
|
|
|
use Closure;
|
|
use Illuminate\Contracts\Validation\ValidationRule;
|
|
|
|
class CroppedImageOrBase64Rule implements ValidationRule
|
|
{
|
|
public function validate(string $attribute, mixed $value, Closure $fail): void
|
|
{
|
|
if (! is_array($value)) {
|
|
(new ImageOrBase64Rule)->validate($attribute, $value, $fail);
|
|
|
|
return;
|
|
}
|
|
|
|
if (! array_key_exists('image', $value)) {
|
|
$fail('The :attribute.image field is required.');
|
|
|
|
return;
|
|
}
|
|
|
|
$valid = true;
|
|
(new ImageOrBase64Rule)->validate(
|
|
"{$attribute}.image",
|
|
$value['image'],
|
|
function (string $message) use ($fail, &$valid): void {
|
|
$valid = false;
|
|
$fail($message);
|
|
}
|
|
);
|
|
|
|
if (! $valid) {
|
|
return;
|
|
}
|
|
|
|
if (isset($value['crops']) && is_array($value['crops'])) {
|
|
foreach (['desktop', 'mobile'] as $variant) {
|
|
$crop = $value['crops'][$variant] ?? null;
|
|
|
|
if (! is_array($crop)) {
|
|
$fail("The :attribute.crops.{$variant} field must be an object.");
|
|
|
|
continue;
|
|
}
|
|
|
|
$this->validateRange("{$attribute}.crops.{$variant}", 'crop_horizontal', $crop, $fail);
|
|
$this->validateRange("{$attribute}.crops.{$variant}", 'crop_vertical', $crop, $fail);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// Backwards compatibility with the original single-crop payload.
|
|
$this->validateRange($attribute, 'crop_horizontal', $value, $fail);
|
|
$this->validateRange($attribute, 'crop_vertical', $value, $fail);
|
|
}
|
|
|
|
private function validateRange(string $attribute, string $axis, array $value, Closure $fail): void
|
|
{
|
|
$range = $value[$axis] ?? null;
|
|
|
|
if (! is_array($range)) {
|
|
$fail("The :attribute.{$axis} field must be an object.");
|
|
|
|
return;
|
|
}
|
|
|
|
$start = $range['start_percentage'] ?? null;
|
|
$end = $range['end_percentage'] ?? null;
|
|
|
|
if (
|
|
! is_numeric($start)
|
|
|| ! is_numeric($end)
|
|
|| (float) $start < 0
|
|
|| (float) $end > 100
|
|
|| (float) $start >= (float) $end
|
|
) {
|
|
$fail(
|
|
"The :attribute.{$axis} field must satisfy "
|
|
.'0 <= start_percentage < end_percentage <= 100.'
|
|
);
|
|
}
|
|
}
|
|
}
|