Implement creator studio and upload updates
This commit is contained in:
116
app/Console/Commands/SyncArtworkCreatedAtCommand.php
Normal file
116
app/Console/Commands/SyncArtworkCreatedAtCommand.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Services\UserStatsService;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class SyncArtworkCreatedAtCommand extends Command
|
||||
{
|
||||
public function __construct(private readonly UserStatsService $userStats)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected $signature = 'artworks:sync-created-at
|
||||
{--chunk=500 : Number of artworks to process per batch}
|
||||
{--only-null : Update only artworks whose created_at is null}
|
||||
{--dry-run : Preview changes without writing updates}';
|
||||
|
||||
protected $description = 'Copy artworks.published_at into artworks.created_at for published artworks.';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$chunk = max(1, (int) $this->option('chunk'));
|
||||
$onlyNull = (bool) $this->option('only-null');
|
||||
$dryRun = (bool) $this->option('dry-run');
|
||||
|
||||
if ($dryRun) {
|
||||
$this->warn('[DRY RUN] No changes will be written.');
|
||||
}
|
||||
|
||||
$query = DB::table('artworks')
|
||||
->select(['id', 'user_id', 'created_at', 'published_at'])
|
||||
->whereNotNull('published_at')
|
||||
->orderBy('id');
|
||||
|
||||
if ($onlyNull) {
|
||||
$query->whereNull('created_at');
|
||||
}
|
||||
|
||||
$processed = 0;
|
||||
$updated = 0;
|
||||
$unchanged = 0;
|
||||
|
||||
$affectedUserIds = [];
|
||||
|
||||
$query->chunkById($chunk, function (Collection $rows) use (&$processed, &$updated, &$unchanged, &$affectedUserIds, $dryRun): void {
|
||||
foreach ($rows as $row) {
|
||||
$processed++;
|
||||
|
||||
$publishedAt = $this->normalizeTimestamp($row->published_at ?? null);
|
||||
$createdAt = $this->normalizeTimestamp($row->created_at ?? null);
|
||||
|
||||
if ($publishedAt === null) {
|
||||
$unchanged++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($createdAt === $publishedAt) {
|
||||
$unchanged++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($dryRun) {
|
||||
$this->line(sprintf(
|
||||
'[dry] Would update artwork id=%d created_at %s => %s',
|
||||
(int) $row->id,
|
||||
$createdAt ?? '<null>',
|
||||
$publishedAt
|
||||
));
|
||||
$updated++;
|
||||
continue;
|
||||
}
|
||||
|
||||
DB::table('artworks')
|
||||
->where('id', (int) $row->id)
|
||||
->update([
|
||||
'created_at' => $publishedAt,
|
||||
'updated_at' => now()->toDateTimeString(),
|
||||
]);
|
||||
|
||||
$affectedUserIds[(int) $row->user_id] = true;
|
||||
$updated++;
|
||||
$this->line(sprintf('[update] artwork id=%d created_at => %s', (int) $row->id, $publishedAt));
|
||||
}
|
||||
}, 'id');
|
||||
|
||||
if (! $dryRun) {
|
||||
foreach (array_keys($affectedUserIds) as $userId) {
|
||||
$this->userStats->recomputeUser((int) $userId);
|
||||
}
|
||||
}
|
||||
|
||||
$this->info(sprintf('Finished. processed=%d updated=%d unchanged=%d', $processed, $updated, $unchanged));
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
private function normalizeTimestamp(mixed $value): ?string
|
||||
{
|
||||
if ($value === null || $value === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return Carbon::parse((string) $value)->toDateTimeString();
|
||||
} catch (\Throwable) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user