feat(social-media): add 'orden' field to social media pivot table and update related functionality
This commit is contained in:
parent
25891cefbc
commit
217f86f624
|
|
@ -28,7 +28,8 @@ class SocialMedia extends Model
|
||||||
'code',
|
'code',
|
||||||
'codigo'
|
'codigo'
|
||||||
)
|
)
|
||||||
->withPivot('url')
|
->withPivot(['url', 'orden'])
|
||||||
->withTimestamps();
|
->withTimestamps()
|
||||||
|
->orderByPivot('orden');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -107,8 +107,9 @@ class Tenant extends Model
|
||||||
'codigo',
|
'codigo',
|
||||||
'code'
|
'code'
|
||||||
)
|
)
|
||||||
->withPivot('url')
|
->withPivot(['url', 'orden'])
|
||||||
->withTimestamps();
|
->withTimestamps()
|
||||||
|
->orderByPivot('orden');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function menues(): BelongsToMany
|
public function menues(): BelongsToMany
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ class StoreTenantRequest extends FormRequest
|
||||||
Rule::exists('social_media', 'code'),
|
Rule::exists('social_media', 'code'),
|
||||||
],
|
],
|
||||||
'social_media.*.url' => ['required', 'url', 'max:2048'],
|
'social_media.*.url' => ['required', 'url', 'max:2048'],
|
||||||
|
'social_media.*.orden' => ['sometimes', 'integer', 'min:0', 'distinct'],
|
||||||
'hero_config' => ['nullable', 'array'],
|
'hero_config' => ['nullable', 'array'],
|
||||||
'hero_config.title_html' => ['nullable', 'string'],
|
'hero_config.title_html' => ['nullable', 'string'],
|
||||||
'hero_config.description_html' => ['nullable', 'string'],
|
'hero_config.description_html' => ['nullable', 'string'],
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ class UpdateTenantRequest extends FormRequest
|
||||||
Rule::exists('social_media', 'code'),
|
Rule::exists('social_media', 'code'),
|
||||||
],
|
],
|
||||||
'social_media.*.url' => ['required', 'url', 'max:2048'],
|
'social_media.*.url' => ['required', 'url', 'max:2048'],
|
||||||
|
'social_media.*.orden' => ['sometimes', 'integer', 'min:0', 'distinct'],
|
||||||
'hero_config' => ['nullable', 'array'],
|
'hero_config' => ['nullable', 'array'],
|
||||||
'hero_config.title_html' => ['nullable', 'string'],
|
'hero_config.title_html' => ['nullable', 'string'],
|
||||||
'hero_config.description_html' => ['nullable', 'string'],
|
'hero_config.description_html' => ['nullable', 'string'],
|
||||||
|
|
|
||||||
|
|
@ -197,14 +197,17 @@ class TenantService
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<int, array{code: string, url: string}> $socialMedia
|
* @param array<int, array{code: string, url: string, orden?: int}> $socialMedia
|
||||||
*/
|
*/
|
||||||
private function syncSocialMedia(Tenant $tenant, array $socialMedia): void
|
private function syncSocialMedia(Tenant $tenant, array $socialMedia): void
|
||||||
{
|
{
|
||||||
$associations = [];
|
$associations = [];
|
||||||
|
|
||||||
foreach ($socialMedia as $item) {
|
foreach (array_values($socialMedia) as $index => $item) {
|
||||||
$associations[$item['code']] = ['url' => $item['url']];
|
$associations[$item['code']] = [
|
||||||
|
'url' => $item['url'],
|
||||||
|
'orden' => $item['orden'] ?? $index,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$tenant->socialMedia()->sync($associations);
|
$tenant->socialMedia()->sync($associations);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('tenant_social_media', function (Blueprint $table): void {
|
||||||
|
$table->unsignedInteger('orden')->default(0)->after('url');
|
||||||
|
$table->index(['tenant_code', 'orden']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('tenant_social_media', function (Blueprint $table): void {
|
||||||
|
$table->dropIndex(['tenant_code', 'orden']);
|
||||||
|
$table->dropColumn('orden');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -30,6 +30,7 @@ class TenantSocialMediaTest extends TestCase
|
||||||
'tenant_code',
|
'tenant_code',
|
||||||
'social_media_code',
|
'social_media_code',
|
||||||
'url',
|
'url',
|
||||||
|
'orden',
|
||||||
'created_at',
|
'created_at',
|
||||||
'updated_at',
|
'updated_at',
|
||||||
], Schema::getColumnListing('tenant_social_media'));
|
], Schema::getColumnListing('tenant_social_media'));
|
||||||
|
|
@ -46,6 +47,7 @@ class TenantSocialMediaTest extends TestCase
|
||||||
|
|
||||||
$tenant->socialMedia()->attach($instagram->code, [
|
$tenant->socialMedia()->attach($instagram->code, [
|
||||||
'url' => 'https://instagram.com/acme',
|
'url' => 'https://instagram.com/acme',
|
||||||
|
'orden' => 3,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->assertTrue($tenant->socialMedia()->firstOrFail()->is($instagram));
|
$this->assertTrue($tenant->socialMedia()->firstOrFail()->is($instagram));
|
||||||
|
|
@ -53,6 +55,7 @@ class TenantSocialMediaTest extends TestCase
|
||||||
'https://instagram.com/acme',
|
'https://instagram.com/acme',
|
||||||
$tenant->socialMedia()->firstOrFail()->pivot->url
|
$tenant->socialMedia()->firstOrFail()->pivot->url
|
||||||
);
|
);
|
||||||
|
$this->assertSame(3, $tenant->socialMedia()->firstOrFail()->pivot->orden);
|
||||||
$this->assertTrue($instagram->tenants()->firstOrFail()->is($tenant));
|
$this->assertTrue($instagram->tenants()->firstOrFail()->is($tenant));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,6 +94,7 @@ class TenantSocialMediaTest extends TestCase
|
||||||
[
|
[
|
||||||
'code' => $instagram->code,
|
'code' => $instagram->code,
|
||||||
'url' => 'https://instagram.com/acme',
|
'url' => 'https://instagram.com/acme',
|
||||||
|
'orden' => 4,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
])
|
])
|
||||||
|
|
@ -105,6 +109,7 @@ class TenantSocialMediaTest extends TestCase
|
||||||
'tenant_code' => $tenant->codigo,
|
'tenant_code' => $tenant->codigo,
|
||||||
'social_media_code' => $instagram->code,
|
'social_media_code' => $instagram->code,
|
||||||
'url' => 'https://instagram.com/acme',
|
'url' => 'https://instagram.com/acme',
|
||||||
|
'orden' => 4,
|
||||||
]);
|
]);
|
||||||
$this->assertDatabaseMissing('tenant_social_media', [
|
$this->assertDatabaseMissing('tenant_social_media', [
|
||||||
'tenant_code' => $tenant->codigo,
|
'tenant_code' => $tenant->codigo,
|
||||||
|
|
@ -112,6 +117,33 @@ class TenantSocialMediaTest extends TestCase
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_tenant_social_media_are_returned_in_configured_order(): void
|
||||||
|
{
|
||||||
|
$tenant = $this->createTenant();
|
||||||
|
$instagram = $this->createSocialMedia('instagram', 'Instagram');
|
||||||
|
$facebook = $this->createSocialMedia('facebook', 'Facebook');
|
||||||
|
|
||||||
|
$this->putJson("/api/tenants/{$tenant->codigo}", [
|
||||||
|
'social_media' => [
|
||||||
|
[
|
||||||
|
'code' => $instagram->code,
|
||||||
|
'url' => 'https://instagram.com/acme',
|
||||||
|
'orden' => 20,
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'code' => $facebook->code,
|
||||||
|
'url' => 'https://facebook.com/acme',
|
||||||
|
'orden' => 10,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
])
|
||||||
|
->assertOk()
|
||||||
|
->assertJsonPath('data.social_media.0.code', 'facebook')
|
||||||
|
->assertJsonPath('data.social_media.1.code', 'instagram')
|
||||||
|
->assertJsonMissingPath('data.social_media.0.orden')
|
||||||
|
->assertJsonMissingPath('data.social_media.1.orden');
|
||||||
|
}
|
||||||
|
|
||||||
public function test_tenant_store_synchronizes_social_media(): void
|
public function test_tenant_store_synchronizes_social_media(): void
|
||||||
{
|
{
|
||||||
$instagram = $this->createSocialMedia('instagram', 'Instagram');
|
$instagram = $this->createSocialMedia('instagram', 'Instagram');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue