Recipe: add your plugin’s data to Tools > Content
Goal: your plugin's data shows up in Tools > Content under "Other items". Site owners export it to a file, import it on another site with a preview first, and undo the import when they change their mind.
Posts, pages, products and their terms already travel. A source is for everything else: settings, rows of your own table, anything that is no post.
The source
A source implements AddoBack\Modules\Transfer\TransferSource. Addofy does the rest: the file, the steps for large exports, the preview with update, add as new or skip per item, the report, undo, WP-CLI and fetching from another site with a key.
use AddoBack\Modules\Transfer\TransferSource;
final class Myplugin_Forms_Source implements TransferSource {
public function id(): string {
return 'myplugin-forms'; // Stable, lowercase, prefixed with your plugin.
}
public function label(): string {
return __( 'My plugin forms', 'myplugin' );
}
public function cap(): string {
return 'manage_options'; // Who may export and import this.
}
public function remote(): bool {
return true; // Return false for personal data: a key on another site then cannot fetch it.
}
public function count(): int {
return myplugin_count_forms();
}
public function export( int $offset, int $limit ): array {
$items = array();
foreach ( myplugin_get_forms( $offset, $limit ) as $form ) {
$items[] = array(
'key' => $form->uuid, // Unique and the same on every site.
'title' => $form->name, // Shown in the preview.
'data' => $form->to_array(),
);
}
return $items;
}
public function match( array $item ): string {
return myplugin_form_exists( $item['key'] ) ? $item['key'] : ''; // '' means new here.
}
public function diff( array $item, string $existing ): array {
return myplugin_form_changes( $existing, $item['data'] ); // Labels, like array( 'Fields' ).
}
public function import( array $item, string $mode, string $existing ): array {
$data = myplugin_clean_form( $item['data'] ); // The file can come from anywhere: clean it.
$before = 'update' === $mode ? myplugin_get_form( $existing ) : null;
$id = 'update' === $mode ? myplugin_update_form( $existing, $data ) : myplugin_add_form( $data );
return array( 'id' => $id, 'before' => $before ); // What undo() needs.
}
public function undo( array $record ): void {
null === $record['before'] ? myplugin_delete_form( $record['id'] ) : myplugin_restore_form( $record['before'] );
}
}
Register it
add_action( 'adba_transfer_register_sources', function ( $sources ) {
if ( interface_exists( 'AddoBack\Modules\Transfer\TransferSource' ) ) {
$sources->add( new Myplugin_Forms_Source() );
}
} );
Load the class file only inside that check, so your plugin keeps working with an older Addofy or without it.
Rules
- Clean in import(). Addofy checks the shape of an item, not its data. Treat
dataas user input. - Stable keys. The key decides whether an item is new or an update. A database id is not stable between sites; a uuid or a slug is.
- Undo is yours. Return everything you need to put the site back. Records come back newest first and are kept for a week.
- Fail per item. Throw an exception in
import()and the item shows as failed in the report; the rest of the import goes on. - Personal data stays home. Return false from
remote()for anything about people. The source is then only in files the site owner downloads. - No filters on source items.
adba_transfer_export_itemandadba_transfer_import_itemare for posts, products and terms. Your source decides what its items hold.
Try it with WP-CLI: wp adba content export --type=myplugin-forms --user=admin.