Migration Assistant Extension Points
Migration Assistant imports, exports, reviews, and rolls back content moves between Capell sites. Extension points should describe what a package owns, not patch the import job from the outside.
Main Extension Points
Section titled “Main Extension Points”| Need | Extension point |
|---|---|
| Read a new source format | ImportSourceReader registered in ImportSourceRegistry |
| Add import targets | ImportTargetRegistry::register() |
| Resolve imported relations | RelationMatchResolverRegistry::register() |
| Contribute review rows | MigrationAssistantRowContributor |
| Resolve package context | MigrationAssistantContextResolver |
| Detect URL/page collisions | PageCollisionDetector |
| Resolve page import target | PageImportTargetResolver |
| Mark relation ownership | OwnershipMap::register() |
The package ships CSV and XML readers, default targets for page, type, and collection, and relation resolvers for layouts, types, sites, and media.
Register a Source Reader
Section titled “Register a Source Reader”use Capell\MigrationAssistant\Contracts\ImportSourceReader;use Capell\MigrationAssistant\Data\ExternalImportReadResult;use Capell\MigrationAssistant\Support\ImportSourceRegistry;
final class JsonImportSourceReader implements ImportSourceReader{ public function supports(string $extension): bool { return $extension === 'json'; }
public function read(string $path): ExternalImportReadResult { $payload = json_decode((string) file_get_contents($path), true, 512, JSON_THROW_ON_ERROR);
return new ExternalImportReadResult( sourceType: 'json', columns: array_keys($payload[0] ?? []), rows: $payload, metadata: ['filename' => basename($path)], ); }}
$this->app->afterResolving(ImportSourceRegistry::class, static function (ImportSourceRegistry $registry): void { $registry->register(new JsonImportSourceReader, prepend: true);});Use prepend: true only when the new reader should win over a built-in reader for the same extension.
Register an Import Target
Section titled “Register an Import Target”use Capell\MigrationAssistant\Support\ImportTargetRegistry;use Vendor\KnowledgeBase\Models\Article;
$this->app->afterResolving(ImportTargetRegistry::class, static function (ImportTargetRegistry $registry): void { $registry->register('knowledge_article', Article::class);});Target keys become part of import payloads. Keep them stable once exported.
Register Relation Resolvers
Section titled “Register Relation Resolvers”Relation resolvers are checked in priority order for each group.
use Capell\MigrationAssistant\Services\Import\Resolvers\KeyedMatchResolver;use Capell\MigrationAssistant\Services\Import\Resolvers\RelationMatchResolverRegistry;use Vendor\KnowledgeBase\Models\Category;
$this->app->afterResolving(RelationMatchResolverRegistry::class, static function (RelationMatchResolverRegistry $registry): void { $registry->register('knowledge_categories', new KeyedMatchResolver(Category::class, keyColumn: 'slug'));});Use package-specific group names unless the resolver intentionally contributes to a core group such as layouts, types, sites, or media.
Config Keys
Section titled “Config Keys”| Key | Use |
|---|---|
migration-assistant.enabled | Enables the package surface. |
migration-assistant.disk | Storage disk for import/export files. |
migration-assistant.channels | Notification channels for completed or failed imports. |
migration-assistant.completed | Completion notification settings. |
migration-assistant.failed | Failure notification settings. |
migration-assistant.connection | Queue/database connection setting where configured. |
The package also has model, table, and path config used by import internals. Document those only when a host app needs to change them.
Verification
Section titled “Verification”vendor/bin/pest packages/migration-assistant/tests --configuration=phpunit.xml