101 خطوط
4.6 KiB
PHP
101 خطوط
4.6 KiB
PHP
<?php
|
|
|
|
namespace App\Modules\Assets\Application;
|
|
|
|
use App\Modules\Courses\Domain\Block;
|
|
use App\Modules\Courses\Domain\Course;
|
|
use App\Modules\Courses\Domain\CourseVersion;
|
|
use App\Modules\Courses\Domain\Enums\CourseVersionStatus;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Validation\ValidationException;
|
|
|
|
final class AssetUsage
|
|
{
|
|
/** @return array<string, int> */
|
|
public function counts(string $organizationId): array
|
|
{
|
|
$counts = [];
|
|
Block::query()->where('organization_id', $organizationId)->get(['data'])->each(function (Block $block) use (&$counts) {
|
|
foreach ($this->assetIds($block->data) as $id) {
|
|
$counts[$id] = ($counts[$id] ?? 0) + 1;
|
|
}
|
|
});
|
|
Course::query()->where('organization_id', $organizationId)->whereNotNull('cover_asset_id')->pluck('cover_asset_id')->each(function (string $id) use (&$counts) {
|
|
$counts[$id] = ($counts[$id] ?? 0) + 1;
|
|
});
|
|
foreach (['review_threads', 'review_replies'] as $table) {
|
|
DB::table($table)->where('organization_id', $organizationId)->whereNotNull('attachment_asset_ids')->pluck('attachment_asset_ids')->each(function ($value) use (&$counts) {
|
|
foreach (json_decode($value, true) ?? [] as $id) {
|
|
$counts[$id] = ($counts[$id] ?? 0) + 1;
|
|
}
|
|
});
|
|
}
|
|
|
|
return $counts;
|
|
}
|
|
|
|
/** @param array<string, mixed>|list<mixed> $value @return list<string> */
|
|
public function assetIds(array $value): array
|
|
{
|
|
$ids = [];
|
|
foreach ($value as $key => $item) {
|
|
if (is_string($key) && ($key === 'assetId' || str_ends_with($key, 'AssetId')) && is_string($item) && $item !== '') {
|
|
$ids[] = $item;
|
|
} elseif (is_array($item)) {
|
|
array_push($ids, ...$this->assetIds($item));
|
|
}
|
|
}
|
|
|
|
return array_values(array_unique($ids));
|
|
}
|
|
|
|
public function detach(string $organizationId, string $assetId): void
|
|
{
|
|
$publishedVersionIds = CourseVersion::query()
|
|
->where('organization_id', $organizationId)
|
|
->where('status', CourseVersionStatus::Published)
|
|
->pluck('id')
|
|
->map(fn ($id): string => (string) $id)
|
|
->all();
|
|
$blocks = Block::query()->where('organization_id', $organizationId)->get();
|
|
foreach ($blocks as $block) {
|
|
if (in_array($assetId, $this->assetIds($block->data), true) && in_array((string) $block->course_version_id, $publishedVersionIds, true)) {
|
|
throw ValidationException::withMessages(['asset' => ['این فایل در نسخه منتشرشده استفاده شده و تا زمان ایجاد نسخه قابلویرایش قابل حذف نیست.']]);
|
|
}
|
|
}
|
|
foreach ($blocks as $block) {
|
|
if (! in_array($assetId, $this->assetIds($block->data), true)) {
|
|
continue;
|
|
}
|
|
$block->update(['data' => $this->withoutAsset($block->data, $assetId), 'revision' => $block->revision + 1]);
|
|
}
|
|
Course::query()->where('organization_id', $organizationId)->where('cover_asset_id', $assetId)->update(['cover_asset_id' => null]);
|
|
foreach (['review_threads', 'review_replies'] as $table) {
|
|
DB::table($table)->where('organization_id', $organizationId)->whereNotNull('attachment_asset_ids')->get(['id', 'attachment_asset_ids'])->each(function ($row) use ($table, $assetId): void {
|
|
$ids = array_values(array_filter(json_decode($row->attachment_asset_ids, true) ?? [], fn ($id) => $id !== $assetId));
|
|
DB::table($table)->where('id', $row->id)->update(['attachment_asset_ids' => json_encode($ids), 'updated_at' => now()]);
|
|
});
|
|
}
|
|
}
|
|
|
|
/** @param array<string, mixed>|list<mixed> $value @return array<string, mixed>|list<mixed> */
|
|
private function withoutAsset(array $value, string $assetId): array
|
|
{
|
|
if (array_is_list($value)) {
|
|
return array_values(array_map(
|
|
fn ($item) => is_array($item) ? $this->withoutAsset($item, $assetId) : $item,
|
|
array_filter($value, fn ($item): bool => ! (is_array($item) && ($item['assetId'] ?? null) === $assetId)),
|
|
));
|
|
}
|
|
foreach ($value as $key => $item) {
|
|
if (is_string($key) && ($key === 'assetId' || str_ends_with($key, 'AssetId')) && $item === $assetId) {
|
|
$value[$key] = null;
|
|
} elseif (is_array($item)) {
|
|
$value[$key] = $this->withoutAsset($item, $assetId);
|
|
}
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
}
|