Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 76 additions & 1 deletion admin/admin-menu-and-tabs.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,74 @@ public function __construct() {
$this->page_title = __( 'Migration', 'disciple-tools-migration' );
} // End __construct()

/**
* Post type slugs returned by Disciple.Tools for migratable records, or a minimal fallback.
*
* @return string[]
*/
public static function get_migratable_post_types(): array {
if ( class_exists( 'DT_Posts' ) ) {
$types = DT_Posts::get_post_types();
return is_array( $types ) ? array_values( array_unique( $types ) ) : [];
}
return [ 'contacts', 'groups' ];
}

/**
* Default "allowed" flag for record migration for a post type (new installs / newly registered types).
*
* @param string $post_type Sanitized post type slug.
*/
public static function get_default_record_allowed_for_type( string $post_type ): bool {
return in_array( $post_type, [ 'contacts', 'groups' ], true );
}

/**
* Merges stored record toggles with all current DT post types.
*
* @param array<string, mixed> $stored Values from options (may omit new types or contain stale keys).
*
* @return array<string, bool>
*/
public static function normalize_records_allowed( array $stored ): array {
$types = self::get_migratable_post_types();
$out = [];

foreach ( $types as $post_type ) {
if ( array_key_exists( $post_type, $stored ) ) {
$out[ $post_type ] = ! empty( $stored[ $post_type ] );
} else {
$out[ $post_type ] = self::get_default_record_allowed_for_type( $post_type );
}
}

return $out;
}

/**
* Human-readable label for a DT post type (plural preferred).
*
* @param string $post_type Post type slug.
*/
public static function get_post_type_label( string $post_type ): string {
if ( ! class_exists( 'DT_Posts' ) ) {
return $post_type;
}
try {
$settings = DT_Posts::get_post_settings( $post_type, false );
if ( is_array( $settings ) ) {
if ( ! empty( $settings['label_plural'] ) ) {
return (string) $settings['label_plural'];
}
if ( ! empty( $settings['label'] ) ) {
return (string) $settings['label'];
}
}
} catch ( Throwable $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
}
return $post_type;
}

/**
* Returns the current migration settings from the options table.
*
Expand Down Expand Up @@ -102,7 +170,14 @@ public static function get_settings(): array {
$current = [];
}

return wp_parse_args( $current, $defaults );
$parsed = wp_parse_args( $current, $defaults );
if ( ! isset( $parsed['allowed_items'] ) || ! is_array( $parsed['allowed_items'] ) ) {
$parsed['allowed_items'] = $defaults['allowed_items'];
}
$rec = $parsed['allowed_items']['records'] ?? [];
$parsed['allowed_items']['records'] = self::normalize_records_allowed( is_array( $rec ) ? $rec : [] );

return $parsed;
}

/**
Expand Down
35 changes: 32 additions & 3 deletions admin/class-dt-migration-import-ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,19 @@ public function enqueue_scripts( string $hook ) : void {
'dt-migration-import',
$plugin_url . 'admin/js/import.js',
[ 'jquery' ],
'0.3.5',
'0.3.6',
true
);
$record_order = class_exists( 'Disciple_Tools_Migration_Import_Engine' )
? Disciple_Tools_Migration_Import_Engine::get_record_import_order()
: [ 'peoplegroups', 'groups', 'contacts', 'trainings' ];
wp_localize_script(
'dt-migration-import',
'dtMigrationImport',
[
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'dt_migration_import' ),
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'dt_migration_import' ),
'recordImportOrder' => array_values( $record_order ),
'strings' => [
'continue' => __( 'Continue', 'disciple-tools-migration' ),
'confirm' => __( 'Confirm', 'disciple-tools-migration' ),
Expand Down Expand Up @@ -218,6 +222,27 @@ public function handle_import_batch() : void {
wp_send_json_error( [ 'message' => __( 'Post type required.', 'disciple-tools-migration' ) ] );
}

if ( $init_q ) {
$export_res = wp_remote_post(
$base . '/wp-json/dt-migration/v1/export',
[
'timeout' => 60,
'headers' => [
'Authorization' => 'Bearer ' . $jwt,
'Content-Type' => 'application/json',
],
'body' => wp_json_encode( [ 'settings_only' => true ] ),
]
);
if ( ! is_wp_error( $export_res ) ) {
$ex_code = wp_remote_retrieve_response_code( $export_res );
$ex_body = json_decode( (string) wp_remote_retrieve_body( $export_res ), true );
if ( $ex_code >= 200 && $ex_code < 300 && is_array( $ex_body ) ) {
Disciple_Tools_Migration_Import_Engine::bootstrap_post_types_from_export( $ex_body );
}
}
}

$records_url = add_query_arg(
[ 'offset' => $offset, 'limit' => $limit ],
$base . '/wp-json/dt-migration/v1/records/' . $post_type
Expand Down Expand Up @@ -331,6 +356,10 @@ private function handle_file_mode_batch( string $step, array $settings ) : void
$slice = array_slice( $records_all, $offset, $limit );
$has_more = ( $offset + count( $slice ) ) < $total;

if ( $init_q ) {
Disciple_Tools_Migration_Import_Engine::bootstrap_post_types_from_export( $payload );
}

try {
$batch_result = Disciple_Tools_Migration_Import_Engine::import_records_batch( $post_type, $slice, $offset, $init_q );
} catch ( Throwable $e ) {
Expand Down
11 changes: 6 additions & 5 deletions admin/class-dt-migration-tab-import.php
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,12 @@ public function main_column( array $settings ) {
<?php
$records = $this->connection_result['allowed_items']['records'] ?? [];
$record_labels = [];
if ( ! empty( $records['contacts'] ) ) {
$record_labels[] = esc_html__( 'Contacts', 'disciple-tools-migration' );
}
if ( ! empty( $records['groups'] ) ) {
$record_labels[] = esc_html__( 'Groups', 'disciple-tools-migration' );
if ( is_array( $records ) ) {
foreach ( $records as $post_type => $enabled ) {
if ( ! empty( $enabled ) ) {
$record_labels[] = Disciple_Tools_Migration_Menu::get_post_type_label( (string) $post_type );
}
}
}
echo esc_html( implode( ', ', $record_labels ) );
?>
Expand Down
37 changes: 22 additions & 15 deletions admin/class-dt-migration-tab-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,28 @@ public function main_column( array $settings ) {
</td>
<td>
<fieldset>
<?php
$record_types = Disciple_Tools_Migration_Menu::get_migratable_post_types();
$records_cfg = $settings['allowed_items']['records'] ?? [];
foreach ( $record_types as $post_type ) {
$label = Disciple_Tools_Migration_Menu::get_post_type_label( $post_type );
?>
<label>
<input type="checkbox" name="dt_migration_allowed_items[records][contacts]" value="1" <?php checked( ! empty( $settings['allowed_items']['records']['contacts'] ) ); ?> />
<?php esc_html_e( 'Contacts', 'disciple-tools-migration' ); ?>
<input type="checkbox" name="dt_migration_allowed_items[records][<?php echo esc_attr( $post_type ); ?>]" value="1" <?php checked( ! empty( $records_cfg[ $post_type ] ) ); ?> />
<?php echo esc_html( $label ); ?>
<span class="description">(<?php echo esc_html( $post_type ); ?>)</span>
</label>
<br>
<label>
<input type="checkbox" name="dt_migration_allowed_items[records][groups]" value="1" <?php checked( ! empty( $settings['allowed_items']['records']['groups'] ) ); ?> />
<?php esc_html_e( 'Groups', 'disciple-tools-migration' ); ?>
</label>
<?php
}
if ( empty( $record_types ) ) {
?>
<p class="description"><?php esc_html_e( 'No Disciple.Tools record types are registered.', 'disciple-tools-migration' ); ?></p>
<?php
}
?>
<p class="description">
<?php esc_html_e( 'Additional record types can be added in future phases. For selected types, imports will delete existing records on the target before re-creating them with preserved IDs.', 'disciple-tools-migration' ); ?>
<?php esc_html_e( 'For selected types, imports will delete existing records on the target before re-creating them with preserved IDs.', 'disciple-tools-migration' ); ?>
</p>
</fieldset>
</td>
Expand Down Expand Up @@ -170,16 +181,12 @@ public function process_form_fields(): void {
$settings['allowed_items']['workflows'] = ! empty( $allowed['workflows'] );
$settings['allowed_items']['system_users'] = ! empty( $allowed['system_users'] );

if ( ! isset( $settings['allowed_items']['records'] ) || ! is_array( $settings['allowed_items']['records'] ) ) {
$settings['allowed_items']['records'] = [
'contacts' => true,
'groups' => true,
];
$incoming_records = isset( $allowed['records'] ) && is_array( $allowed['records'] ) ? $allowed['records'] : [];
$settings['allowed_items']['records'] = [];
foreach ( Disciple_Tools_Migration_Menu::get_migratable_post_types() as $post_type ) {
$settings['allowed_items']['records'][ $post_type ] = ! empty( $incoming_records[ $post_type ] );
}

$settings['allowed_items']['records']['contacts'] = ! empty( $allowed['records']['contacts'] );
$settings['allowed_items']['records']['groups'] = ! empty( $allowed['records']['groups'] );

Disciple_Tools_Migration_Menu::update_settings( $settings );
}

Expand Down
4 changes: 3 additions & 1 deletion admin/js/import.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,9 @@
records: null
} );
}
const order = [ 'peoplegroups', 'groups', 'contacts', 'trainings' ];
const order = ( window.dtMigrationImport && Array.isArray( window.dtMigrationImport.recordImportOrder ) && window.dtMigrationImport.recordImportOrder.length )
? window.dtMigrationImport.recordImportOrder
: [ 'peoplegroups', 'groups', 'contacts', 'trainings' ];
const rest = Object.keys( records ).filter( pt => ! order.includes( pt ) );
const ordered = order.filter( pt => records[ pt ] ).concat( rest );
const recordPts = ordered.filter( pt => records[ pt ] );
Expand Down
Loading
Loading