Files
RomhackPlaza/app/Console/Commands/MigrateEntriesImages.php
2026-06-23 19:24:38 +02:00

147 lines
5.0 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
#[Signature('migrate:entries:images {--wp-uploads-path=} {--limit=}')]
#[Description("Migrate WP Main images and galeries for entries.")]
class MigrateEntriesImages extends Command
{
private const string GALLERYABLE_TYPE = 'App\\Models\\Entry';
private function copyAttachment( int $attachmentId, string $wpUploadsPath, string $destinationPath ): ?string
{
$relativePath = DB::connection('old_wp')
->table('postmeta')
->where('post_id', $attachmentId)
->where('meta_key', '_wp_attached_file')
->value('meta_value');
if( !$relativePath )
return null;
$sourcePath = rtrim($wpUploadsPath, '/') . '/' . $relativePath;
if( !is_file($sourcePath) )
return null;
$extension = pathinfo($sourcePath, PATHINFO_EXTENSION);
$filename = Str::random(40) . ($extension ? '.' . $extension : '');
$destinationRelative = $destinationPath . '/' . $filename;
$stream = fopen($sourcePath, 'r');
Storage::disk('public')->put($destinationRelative, $stream);
if( is_resource($stream) )
fclose($stream);
return $destinationRelative;
}
private function processEntry( int $wpPostId, int $entryId, string $wpUploadsPath, array &$stats ): void
{
$exists = DB::table('migrations_logs')
->where('source_system', 'wp')
->where('source_table', 'wp_posts__attachments')
->where('source_id', $wpPostId)
->exists();
if( $exists )
return;
$thumbnailId = DB::connection('old_wp')
->table('postmeta')
->where('post_id', $wpPostId)
->where('meta_key', '_thumbnail_id')
->value('meta_value');
if( $thumbnailId ){
$newPath = $this->copyAttachment( (int) $thumbnailId, $wpUploadsPath, 'entries/main-images' );
if( $newPath ){
DB::table('entries')
->where('id', $entryId)
->update(['main_image' => $newPath]);
$stats['main_image']++;
} else {
$stats['missing_files']++;
}
}
$galleryRaw = DB::connection('old_wp')
->table('postmeta')
->where('post_id', $wpPostId)
->where('meta_key', 'my_gallery')
->value('meta_value');
$attachmentIds = $galleryRaw ? (@unserialize($galleryRaw) ?: []) : [];
foreach ( array_values( $attachmentIds ) as $order => $attachmentId ) {
$newPath = $this->copyAttachment( (int) $attachmentId, $wpUploadsPath, "entries/gallery-images/{$entryId}" );
if( !$newPath ){
$stats['missing_files']++;
continue;
}
DB::table('galleries')
->insert([
'galleryable_type' => self::GALLERYABLE_TYPE,
'galleryable_id' => $entryId,
'image' => $newPath,
'order' => $order,
'created_at' => now(),
'updated_at' => now(),
]);
$stats['gallery_images']++;
}
DB::table('migrations_logs')
->insert([
'source_system' => 'wp',
'source_table' => 'wp_posts__attachments',
'source_id' => $wpPostId,
'target_table' => 'entries',
'target_id' => $entryId,
'status' => 'done',
'migrated_at' => now(),
'created_at' => now(),
'updated_at' => now(),
]);
}
public function handle()
{
$wpUploadsPath = $this->option('wp-uploads-path');
if( !$wpUploadsPath || !is_dir($wpUploadsPath) ){
$this->error('Missing WP Uploads Path');
return self::FAILURE;
}
$query = DB::table('migrations_logs')
->where('source_system', 'wp')
->where('source_table', 'wp_posts')
->where('target_table', 'entries')
;
if( $limit = $this->option('limit') ){
$query->limit((int)$limit);
}
$rows = $query->get(['source_id', 'target_id']);
$this->info("{$rows->count()} entries need to be migrated");
$stats = ['main_image' => 0, 'gallery_images' => 0, 'missing_files' => 0 ];
$this->withProgressBar($rows, function($row) use($wpUploadsPath, &$stats) {
$this->processEntry( $row->source_id, $row->target_id, $wpUploadsPath, $stats );
});
$this->newLine();
$this->info("Migrated attachments. Main images: {$stats['main_image']}, Galleries: {$stats['gallery_images']}, Missing files: {$stats['missing_files']}");
return self::SUCCESS;
}
}