Skip to content

Extension contracts

<?php
declare(strict_types=1);
final class ExampleVoyagerImportContributor implements \Capell\VoyagerImporter\Contracts\VoyagerImportContributor
{
public function columns(): array
{
return ['posts.subtitle' => 'subtitle'];
}
public function tables(): array
{
return ['legacy_events' => 'events'];
}
public function settings(): array
{
return ['site.title' => 'general.site_name'];
}
public function templates(): array
{
return ['landing' => 'landing-page'];
}
}
app()->tag([ExampleVoyagerImportContributor::class], \Capell\VoyagerImporter\Support\VoyagerContributorRegistry::TAG);
<?php
declare(strict_types=1);
final class ExampleVoyagerTableImportContributor implements \Capell\VoyagerImporter\Contracts\VoyagerTableImportContributor
{
public function tableImports(): array
{
return [
new \Capell\VoyagerImporter\Data\VoyagerTableImportDefinition(
sourceTable: 'legacy_events',
identityColumns: ['id'],
targetClass: \App\Models\Event::class,
fields: ['title' => 'title', 'page_id' => 'page_id'],
siteScoped: true,
converters: [
'page_id' => static fn (mixed $value, \Capell\VoyagerImporter\Support\VoyagerSourceKeyResolver $resolver): int|string|null => $resolver->resolve('page', $value),
],
),
];
}
}
app()->tag([ExampleVoyagerTableImportContributor::class], \Capell\VoyagerImporter\Support\VoyagerContributorRegistry::TAG);

Implement VoyagerImportContributor and tag its container binding with VoyagerContributorRegistry::TAG.

columns() maps source_table.column to an existing, unprotected destination column for pages or posts. settings() maps a source key to a destination group.name or to a name within the source group. templates() maps a source template to a layout key on the destination site. Duplicate mappings and unavailable destinations fail the import. Mapped JSON column values can rewrite imported media paths.

Existing tables() declarations continue to describe inventory mappings. To import rows, also implement VoyagerTableImportContributor::tableImports() and return VoyagerTableImportDefinition objects. Each definition supplies the source table, one or more source identity columns, the destination Eloquent model, a source-column-to-attribute map, whether the rows belong to a site, and optional converters keyed by source column. Converters receive the source value and a VoyagerSourceKeyResolver, and must return a scalar or null. A converter for a foreign key column calls $resolver->resolve('page', $value) (entity types page, post, user, role, permission and setting) to get the id of the Capell record imported from that source id, or null when it has not been imported. Import the referenced entities in the same or an earlier run; --only runs entities before contributed tables, so --only=pages,tables resolves page ids. Identity columns must contain strings or integers and uniquely identify source rows.

The destination model must be registered in Migration Assistant’s rollback_targets and its mapped attributes must be fillable, present in its table and outside the protected-attribute list. For site-scoped definitions the importer supplies site_id; contributors cannot map it themselves. Select --only=tables, with --site-id for site-scoped definitions. A session imports only the contributed tables whose scope matches it: site-scoped tables with --site-id, global tables without. Tables of the other scope are skipped with a notice and need their own run. Source-key provenance tracks creates and updates and supports reruns and rollback. Unmapped source columns are reported by name, without values.

Category assignment is also pending. Capell’s Taggable model represents a composite-key pivot without an ID or timestamps; SourceKeyImporter requires a scalar model key, and database rollback provenance requires an allowlisted model with timestamps. Pages and articles can be soft-deleted during rollback, so relying on a database cascade would leave their pivot assignments behind. A reversible assignment representation and rollback path are needed before categories can be imported without losing or silently retaining relationships.