__( 'Verify engine unavailable.', 'ai-eshop-optimizer' ) ) );
}
$result = AIEO_SEO_Verify::run_sample();
if ( class_exists( 'AIEO_Setup_Checklist' ) && is_array( $result ) ) {
AIEO_Setup_Checklist::stamp_verify( $result );
}
if ( is_array( $result ) ) {
$result['table'] = $this->verify_table( (array) ( $result['rows'] ?? array() ) );
}
wp_send_json_success( $result );
}
private function verify_table( array $rows ) {
if ( ! class_exists( '\Rooster\Admin\Ui' ) && ( ! function_exists( 'rooster_admin_builders' ) || ! rooster_admin_builders() ) ) {
return array( 'html' => '', 'icons' => '' );
}
$live = static function ( $value ) {
return '
' . esc_html__( 'Live:', 'ai-eshop-optimizer' ) . ' ' . esc_html( (string) $value ) . '';
};
$mark = static function ( $ok, $aieo, $was ) use ( $live ) {
return array( 'html' => \Rooster\Admin\Ui::badge( $ok ? '✓' : '✗', $ok ? 'success' : 'destructive', array( 'sm' => true ) ) . ' ' . esc_html( (string) $aieo ) . ( $ok ? '' : $live( $was ) ) );
};
$out = array();
foreach ( $rows as $i => $r ) {
$object = '' . esc_html( (string) ( $r['object'] ?? '' ) ) . ''
. ( ! empty( $r['fetch_ok'] ) ? '' : ' ' . \Rooster\Admin\Ui::badge( __( 'Live fetch failed', 'ai-eshop-optimizer' ), 'warning', array( 'sm' => true ) ) )
. ( ! empty( $r['canon_self_ok'] ) ? '' : ' ' . \Rooster\Admin\Ui::badge( __( 'Canonical is not the permalink', 'ai-eshop-optimizer' ), 'destructive', array( 'sm' => true ) ) )
. '
' . esc_html( (string) ( $r['url'] ?? '' ) ) . '';
$schema = esc_html( (string) ( $r['schema_aieo'] ?? '' ) )
. ( ! empty( $r['schema_live'] ) && $r['schema_live'] !== ( $r['schema_aieo'] ?? '' ) ? $live( $r['schema_live'] ) : '' );
$out[] = array(
'_id' => (string) ( $i + 1 ),
'_name' => (string) ( $r['object'] ?? '' ),
'object' => array( 'html' => $object ),
'title' => $mark( ! empty( $r['title_ok'] ), $r['title_aieo'] ?? '', $r['title_live'] ?? '' ),
'canonical' => $mark( ! empty( $r['canon_ok'] ), $r['canon_aieo'] ?? '', $r['canon_live'] ?? '' ),
'robots' => $mark( ! empty( $r['robots_ok'] ), $r['robots_aieo'] ?? '', $r['robots_live'] ?? '' ),
'schema' => array( 'html' => $schema ),
'_s' => array(
'object' => (string) ( $r['object'] ?? '' ),
'title' => (string) ( $r['title_aieo'] ?? '' ),
'canonical' => (string) ( $r['canon_aieo'] ?? '' ),
'robots' => (string) ( $r['robots_aieo'] ?? '' ),
'schema' => (string) ( $r['schema_aieo'] ?? '' ),
),
);
}
$columns = array();
foreach ( array(
'object' => __( 'Object', 'ai-eshop-optimizer' ),
'title' => __( 'Title', 'ai-eshop-optimizer' ),
'canonical' => __( 'Canonical', 'ai-eshop-optimizer' ),
'robots' => __( 'Robots', 'ai-eshop-optimizer' ),
'schema' => __( 'Schema', 'ai-eshop-optimizer' ),
) as $key => $label ) {
$columns[] = array(
'key' => $key,
'label' => $label,
'type' => 'html',
'sort_type' => 'text',
);
}
return AIEO_Table::local_answer( 'aieo-seo-verify-table', $columns, $out, array(
'prefix' => 'sv_',
'size' => 0,
'caption' => __( 'Head parity before cutover', 'ai-eshop-optimizer' ),
'empty' => esc_html__( 'Nothing to compare yet — import first.', 'ai-eshop-optimizer' ),
) );
}
public function render_subtab() {
$reports = array();
$labels = array();
foreach ( AIEO_SEO_Import_Registry::all() as $id => $source ) {
$reports[ $id ] = $source->mapping_report();
$labels[ $id ] = $source->label();
}
$this->render_template(
'seo/import.php',
array(
'detected' => AIEO_SEO_Import_Registry::detected(),
'selected' => AIEO_SEO_Import_Registry::best(),
'reports' => $reports,
'labels' => $labels,
'last' => (array) get_option( self::LAST_OPTION, array() ),
'nonce' => wp_create_nonce( AIEO_DMM::NONCE_ACTION ),
'ajax' => admin_url( 'admin-ajax.php' ),
)
);
}
public function ajax_import_run() {
AIEO_DMM::verify_ajax_request();
if ( ! current_user_can( 'manage_woocommerce' ) && ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( array( 'message' => __( 'Insufficient permissions for a store-wide import.', 'ai-eshop-optimizer' ) ) );
}
if ( ! class_exists( 'AIEO_SEO_Import_Registry' ) ) {
wp_send_json_error( array( 'message' => __( 'Importer unavailable.', 'ai-eshop-optimizer' ) ) );
}
$source_id = isset( $_POST['source'] ) ? sanitize_key( wp_unslash( $_POST['source'] ) ) : 'aioseo';
$source = AIEO_SEO_Import_Registry::get( $source_id );
if ( ! $source ) {
wp_send_json_error( array( 'message' => __( 'Unknown import source.', 'ai-eshop-optimizer' ) ) );
}
$phase = isset( $_POST['phase'] ) ? sanitize_key( wp_unslash( $_POST['phase'] ) ) : 'posts';
$after = isset( $_POST['after_id'] ) ? (int) $_POST['after_id'] : 0;
if ( 'options' === $phase ) {
$opt = $source->import_options();
$last = (array) get_option( self::LAST_OPTION, array() );
$last['settings_imported'] = ! empty( $opt['imported'] );
$last['source'] = $source_id;
$last['finished_at'] = time();
update_option( self::LAST_OPTION, $last, false );
wp_send_json_success( array( 'phase' => 'options', 'done' => true, 'imported' => 0, 'stripped' => 0, 'last_id' => 0, 'options' => $opt ) );
}
if ( 'redirects' === $phase ) {
$red = $source->import_redirects();
$last = (array) get_option( self::LAST_OPTION, array() );
$last['redirects'] = (int) ( $red['imported'] ?? 0 );
$last['source'] = $source_id;
$last['finished_at'] = time();
update_option( self::LAST_OPTION, $last, false );
wp_send_json_success( array( 'phase' => 'redirects', 'done' => true, 'imported' => 0, 'stripped' => 0, 'last_id' => 0, 'redirects' => $red ) );
}
if ( 'terms' === $phase ) {
$res = $source->import_terms_chunk( $after, 200 );
} else {
$phase = 'posts';
if ( 0 === $after ) {
delete_option( self::LAST_OPTION );
}
$res = $source->import_posts_chunk( $after, 200 );
}
$res['phase'] = $phase;
$last = (array) get_option( self::LAST_OPTION, array() );
$last[ $phase . '_imported' ] = (int) ( $last[ $phase . '_imported' ] ?? 0 ) + (int) $res['imported'];
$last['stripped'] = (int) ( $last['stripped'] ?? 0 ) + (int) $res['stripped'];
$last['skipped'] = (int) ( $last['skipped'] ?? 0 ) + (int) $res['skipped'];
$last['source'] = $source_id;
$last['finished_at'] = time();
update_option( self::LAST_OPTION, $last, false );
wp_send_json_success( $res );
}
}