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; $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, "news/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' => 'news', '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__news') ->where('target_table', 'news') ; if( $limit = $this->option('limit') ){ $query->limit((int)$limit); } $rows = $query->get(['source_id', 'target_id']); $this->info("{$rows->count()} news need to be migrated"); $stats = ['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 Galleries: {$stats['gallery_images']}, Missing files: {$stats['missing_files']}"); return self::SUCCESS; } }