From c00b3d609c863c6939b340d5ab126bd73f78113d Mon Sep 17 00:00:00 2001 From: ncoronel Date: Tue, 18 Aug 2026 12:54:53 -0300 Subject: [PATCH] feat(attachment): update crop data columns to use decimal types and add migration for legacy data --- ...000_add_crop_data_to_attachments_table.php | 10 +- ...te_attachment_crop_percentages_to_json.php | 108 ++++++++++++++++++ 2 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 database/migrations/2026_08_18_020000_migrate_attachment_crop_percentages_to_json.php diff --git a/database/migrations/2026_08_18_000000_add_crop_data_to_attachments_table.php b/database/migrations/2026_08_18_000000_add_crop_data_to_attachments_table.php index 4bf6234..c21f80c 100644 --- a/database/migrations/2026_08_18_000000_add_crop_data_to_attachments_table.php +++ b/database/migrations/2026_08_18_000000_add_crop_data_to_attachments_table.php @@ -9,12 +9,12 @@ return new class extends Migration public function up(): void { Schema::table('attachments', function (Blueprint $table): void { - $table->json('crop_horizontal')->nullable()->after('size'); - $table->json('crop_vertical')->nullable()->after('crop_horizontal'); + $table->decimal('crop_horizontal_start_percent', 7, 4)->nullable()->after('size'); + $table->decimal('crop_vertical_start_percent', 7, 4)->nullable()->after('crop_horizontal_start_percent'); $table->foreignId('cropped_attachment_id') ->nullable() ->unique() - ->after('crop_vertical') + ->after('crop_vertical_start_percent') ->constrained('attachments') ->nullOnDelete(); }); @@ -26,8 +26,8 @@ return new class extends Migration $table->dropForeign(['cropped_attachment_id']); $table->dropColumn([ 'cropped_attachment_id', - 'crop_horizontal', - 'crop_vertical', + 'crop_horizontal_start_percent', + 'crop_vertical_start_percent', ]); }); } diff --git a/database/migrations/2026_08_18_020000_migrate_attachment_crop_percentages_to_json.php b/database/migrations/2026_08_18_020000_migrate_attachment_crop_percentages_to_json.php new file mode 100644 index 0000000..f981e6e --- /dev/null +++ b/database/migrations/2026_08_18_020000_migrate_attachment_crop_percentages_to_json.php @@ -0,0 +1,108 @@ +json('crop_horizontal')->nullable()->after('size'); + }); + } + + if (! Schema::hasColumn('attachments', 'crop_vertical')) { + Schema::table('attachments', function (Blueprint $table): void { + $table->json('crop_vertical')->nullable()->after('crop_horizontal'); + }); + } + + $hasLegacyHorizontal = Schema::hasColumn('attachments', 'crop_horizontal_start_percent'); + $hasLegacyVertical = Schema::hasColumn('attachments', 'crop_vertical_start_percent'); + + if ($hasLegacyHorizontal || $hasLegacyVertical) { + $columns = array_values(array_filter([ + 'id', + $hasLegacyHorizontal ? 'crop_horizontal_start_percent' : null, + $hasLegacyVertical ? 'crop_vertical_start_percent' : null, + ])); + + DB::table('attachments') + ->select($columns) + ->orderBy('id') + ->chunkById(100, function ($attachments) use ($hasLegacyHorizontal, $hasLegacyVertical): void { + foreach ($attachments as $attachment) { + $updates = []; + + if ($hasLegacyHorizontal && $attachment->crop_horizontal_start_percent !== null) { + $updates['crop_horizontal'] = json_encode([ + 'start_percentage' => (float) $attachment->crop_horizontal_start_percent, + 'end_percentage' => 100, + ]); + } + + if ($hasLegacyVertical && $attachment->crop_vertical_start_percent !== null) { + $updates['crop_vertical'] = json_encode([ + 'start_percentage' => (float) $attachment->crop_vertical_start_percent, + 'end_percentage' => 100, + ]); + } + + if ($updates !== []) { + DB::table('attachments')->where('id', $attachment->id)->update($updates); + } + } + }); + + Schema::table('attachments', function (Blueprint $table) use ($hasLegacyHorizontal, $hasLegacyVertical): void { + if ($hasLegacyHorizontal) { + $table->dropColumn('crop_horizontal_start_percent'); + } + + if ($hasLegacyVertical) { + $table->dropColumn('crop_vertical_start_percent'); + } + }); + } + } + + public function down(): void + { + if (! Schema::hasColumn('attachments', 'crop_horizontal_start_percent')) { + Schema::table('attachments', function (Blueprint $table): void { + $table->decimal('crop_horizontal_start_percent', 7, 4)->nullable()->after('size'); + }); + } + + if (! Schema::hasColumn('attachments', 'crop_vertical_start_percent')) { + Schema::table('attachments', function (Blueprint $table): void { + $table->decimal('crop_vertical_start_percent', 7, 4) + ->nullable() + ->after('crop_horizontal_start_percent'); + }); + } + + DB::table('attachments') + ->select(['id', 'crop_horizontal', 'crop_vertical']) + ->orderBy('id') + ->chunkById(100, function ($attachments): void { + foreach ($attachments as $attachment) { + $horizontal = json_decode($attachment->crop_horizontal ?? '', true); + $vertical = json_decode($attachment->crop_vertical ?? '', true); + + DB::table('attachments')->where('id', $attachment->id)->update([ + 'crop_horizontal_start_percent' => $horizontal['start_percentage'] ?? null, + 'crop_vertical_start_percent' => $vertical['start_percentage'] ?? null, + ]); + } + }); + + Schema::table('attachments', function (Blueprint $table): void { + $table->dropColumn(['crop_horizontal', 'crop_vertical']); + }); + } +};