Hooks migration, import et export

Disponible dans :Free

Ces hooks servent à proposer un import depuis une extension d’événements que HappenBoard ne gère pas. Ils permettent aussi de copier des données supplémentaires pendant un import The Events Calendar et d’ajouter vos propres réglages au fichier de sauvegarde JSON. Les cinq sont fournis par l’extension gratuite.

Le côté administrateur est décrit dans Migrer depuis une autre extension. Le fichier de sauvegarde est présenté dans Import/export CSV et sauvegarde des réglages. Si vous n’avez jamais utilisé les hooks de HappenBoard, commencez par Étendre HappenBoard avec les hooks.

Les imports et exports sans hook

L’import de fichier .ics, l’import et l’export CSV des événements, ainsi que l’import CSV des participants et l’export CSV des commandes de Pro n’ont pas de hook. Le téléchargement du CSV des commandes dépend d’une permission : la capacité Pro happenboard_export_orders, donnée aux administrateurs par défaut. Pour l’accorder à d’autres rôles, utilisez les filtres décrits dans Hooks administration, rôles et permissions.

Écrire un adaptateur de migration

Une source de migration est une classe PHP qui implémente HappenBoard\Service\Migration\MigratorAdapter. Vous l’enregistrez avec happenboard_migration_adapters. Elle apparaît ensuite dans HappenBoard → Settings → Migration dès que sa méthode detect() trouve les données de la source.

MéthodeRetourRôle
id()stringIdentifiant stable : minuscules, chiffres et tirets. Il entre dans la route REST et dans la méta _happenboard_migrated_from de chaque contenu importé.
name(), description()stringTitre et ligne d’aide de la source.
logo_url()stringURL du logo, ou '' pour afficher une lettre.
detect()boolIndique si les données de la source sont sur le site. Une source non détectée est masquée de l’écran et refusée par la route REST.
summary()arrayNombres affichés avant l’import : events, venues, organizers, categories, attendees. Une clé absente vaut 0.
migrate( array $options )ResultImporte un lot.

L’écran propose Preview (dry run), puis Migrate for real. Chaque passage appelle migrate() en boucle avec dry_run, batch_size (50), offset et include (vide pour tout importer). Remplissez un HappenBoard\Service\Migration\Result avec count_created(), count_skipped(), count_failed() et add_error(), puis renseignez next_offset et done. L’écran s’arrête quand done vaut true. Si next_offset n’avance plus sans que done soit true, il affiche le passage comme interrompu, avec un bouton Continue qui reprend au dernier offset.

Pour un élément importé qui a perdu quelque chose en route, appelez add_warning( $resource, $source_id, $reason ) : il ne compte pas comme un échec et s’affiche sous View N warnings.

Le trait HappenBoard\Service\Migration\MigrationHelpers regroupe les outils des adaptateurs fournis. find_migrated() et mark_migrated() permettent à un second passage d’ignorer ce que le premier a importé (un contenu importé mis à la corbeille compte comme non importé). local_to_utc_iso() convertit une date locale au format UTC que stocke HappenBoard. Pour une source qui enregistre ses événements comme des articles, migrate() peut ressembler à ceci :

Code
public function migrate( array $options ): \HappenBoard\Service\Migration\Result {
    $result = new \HappenBoard\Service\Migration\Result();
    $batch  = max( 1, (int) ( $options['batch_size'] ?? 50 ) );
    $offset = max( 0, (int) ( $options['offset'] ?? 0 ) );
    $ids    = get_posts( array(
        'post_type'      => 'mycal_event',
        'post_status'    => 'any',
        'posts_per_page' => $batch,
        'offset'         => $offset,
        'orderby'        => 'ID',
        'order'          => 'ASC',
        'fields'         => 'ids',
    ) );

    foreach ( $ids as $source_id ) {
        if ( $this->find_migrated( 'my-calendar', 'hboard_event', $source_id ) > 0 ) {
            $result->count_skipped( 'events' ); // Déjà importé par un passage précédent.
            continue;
        }
        if ( ! empty( $options['dry_run'] ) ) {
            $result->count_created( 'events' ); // Aperçu : on compte, on n'écrit rien.
            continue;
        }
        $new_id = wp_insert_post( array(
            'post_type'   => 'hboard_event',
            'post_status' => get_post_status( $source_id ),
            'post_title'  => get_the_title( $source_id ),
        ), true );
        if ( is_wp_error( $new_id ) ) {
            $result->count_failed( 'events' );
            $result->add_error( 'events', $source_id, $new_id->get_error_message() );
            continue;
        }
        $start = $this->local_to_utc_iso( (string) get_post_meta( $source_id, 'mycal_start', true ) );
        update_post_meta( $new_id, '_happenboard_start', $start );
        update_post_meta( $new_id, '_happenboard_end', $start );
        // Les dates n'existaient pas pendant wp_insert_post() : on les construit maintenant.
        ( new \HappenBoard\Service\Events\OccurrenceSyncer() )->sync( (int) $new_id );
        $this->mark_migrated( (int) $new_id, 'my-calendar', $source_id );
        $result->count_created( 'events' );
    }

    $result->next_offset = $offset + count( $ids );
    $result->done        = count( $ids ) < $batch;

    return $result;
}

happenboard_migration_adapters

Filtre Free src/Service/Migration/Registry.php

Filtre la liste des sources de migration. Ajoutez-y votre adaptateur pour proposer un import depuis une extension que HappenBoard ne gère pas, ou pour remplacer un adaptateur fourni.

Signature

apply_filters( 'happenboard_migration_adapters', array $adapters )

Paramètres

$adapters array<int,MigratorAdapter>
Les adaptateurs fournis, dans cet ordre : The Events Calendar, Events Manager, Sugar Calendar, EventKoi et Amelia. Une simple liste à clés numériques.

Valeur de retour

array La liste des adaptateurs. Une entrée qui n’implémente pas HappenBoard\Service\Migration\MigratorAdapter est ignorée sans avertissement.

Exemple

add_filter(
    'happenboard_migration_adapters',
    function ( array $adapters ): array {
        // My_Calendar_Adapter implémente
        // \HappenBoard\Service\Migration\MigratorAdapter.
        require_once __DIR__ . '/class-my-calendar-adapter.php';
        $adapters[] = new My_Calendar_Adapter();

        return $adapters;
    }
);

Remarques

  • La liste est indexée par id() et le dernier adaptateur d’un même identifiant l’emporte. Un adaptateur dont l’identifiant vaut the-events-calendar, events-manager, sugar-calendar, eventkoi ou amelia remplace celui fourni, dans l’administration comme dans sa commande WP-CLI.
  • Une nouvelle source se lance depuis l’écran Migration et par POST /happenboard/v1/migration/{id} (capacité happenboard_manage_settings, administrateurs par défaut). Elle n’a pas de commande WP-CLI : wp happenboard migrate ne connaît que tec, em, sugar et ics.
  • Le filtre s’exécute à chaque affichage des sources et à chaque lot, souvent plusieurs fois par requête. Gardez un constructeur léger et faites le travail en base dans summary() et migrate().
  • L’écran Migration envoie des lots de 50 jusqu’à ce que done vaille true, sans limite fixe sur la taille de la source. Pour se protéger d’un adaptateur qui ne termine jamais, il fait une pause après deux fois le nombre de requêtes que demande le compte events de summary() (200 au minimum) et propose Continue. Comptez vos événements dans summary() pour que la barre de progression et cette limite correspondent à votre source.

happenboard_migration_before_events

Action Free src/Service/Migration/Sources/TheEventsCalendar.php

Se déclenche au début de chaque lot d’événements d’un import The Events Calendar, avant la lecture du premier événement du lot. Sert à préparer ce dont l’étape par événement a besoin, par exemple une table de correspondance des champs.

Signature

do_action( 'happenboard_migration_before_events', string $source_id, bool $dry )

Paramètres

$source_id string
L’identifiant de l’adaptateur. Toujours the-events-calendar aujourd’hui, aucune autre source ne déclenchant cette action. Testez-le quand même.
$dry bool
Vrai pour un aperçu (bouton Preview (dry run), ou --dry-run en WP-CLI). N’écrivez rien en base dans ce cas.

Exemple

add_action(
    'happenboard_migration_before_events',
    function ( string $source_id, bool $dry ): void {
        if ( 'the-events-calendar' !== $source_id ) {
            return;
        }
        // Lire ce dont le lot aura besoin.
        $map = my_build_field_map();

        // N'enregistrer que lors d'un vrai passage.
        if ( ! $dry ) {
            update_option( 'my_field_map', $map, false );
        }
    },
    10,
    2
);

Remarques

  • Deux arguments : inscrivez-vous avec 10, 2. Un callback typé inscrit avec la valeur par défaut de 1 lève une ArgumentCountError et interrompt l’import.
  • Seul l’import The Events Calendar la déclenche. Events Manager, Sugar Calendar, EventKoi, Amelia et l’import .ics ne le font pas.
  • Elle se déclenche une fois par lot (50 événements depuis l’écran, 100 en WP-CLI), y compris pendant un aperçu et même quand le lot est vide. Gardez-la rapide et sans effet en cas d’appels répétés.
  • Elle ne se déclenche pas quand l’option include du passage exclut events. Pro s’en sert pour créer les définitions de champs personnalisés à partir des champs additionnels de The Events Calendar.

happenboard_migration_event_imported

Action Free src/Service/Migration/Sources/TheEventsCalendar.php

Se déclenche quand l’import The Events Calendar a créé un événement, avec ses dates, son lieu, son organisateur et ses catégories, et l’a marqué comme importé. Sert à copier des données supplémentaires de l’événement source et à les signaler dans les résultats de l’import.

Signature

do_action( 'happenboard_migration_event_imported', int $new_id, int $source_id, string $adapter_id, Result $result )

Paramètres

$new_id int
Le nouvel événement HappenBoard (ID de l’article hboard_event).
$source_id int
L’ID de l’article source, un article tribe_events de The Events Calendar. Ses métas d’origine sont toujours là.
$adapter_id string
L’identifiant de l’adaptateur, the-events-calendar.
$result Result
Le HappenBoard\Service\Migration\Result du lot en cours. Ce que vous y ajoutez apparaît dans les résultats de l’écran Migration.

Exemple

add_action(
    'happenboard_migration_event_imported',
    function ( $new_id, $source_id, $adapter_id, $result ) {
        if ( 'the-events-calendar' !== $adapter_id ) {
            return;
        }
        $cost = (string) get_post_meta( $source_id, '_EventCost', true );
        if ( '' === $cost ) {
            return;
        }
        if ( ! is_numeric( $cost ) ) {
            $result->add_error( 'prices', $source_id, 'Unreadable cost.' );
            return;
        }
        update_post_meta( $new_id, '_my_price', $cost );
        $result->count_created( 'prices' ); // Ajoute une ligne « prices » aux résultats.
    },
    10,
    4
);

Remarques

  • Quatre arguments : inscrivez-vous avec 10, 4. Le deuxième est l’ID de l’article source (un entier), le troisième l’identifiant de l’adaptateur (une chaîne).
  • Elle ne se déclenche jamais pendant un aperçu, ni pour un événement ignoré parce qu’un passage précédent l’a importé. Les dates d’une ancienne série que The Events Calendar stockait en articles enfants ne la déclenchent pas non plus. Un événement importé puis mis à la corbeille est importé de nouveau.
  • Un nom de ressource que l’import n’utilise pas, comme prices, ajoute sa propre ligne au tableau des résultats, sous ce nom. Les erreurs ajoutées avec add_error() s’affichent dans la liste des erreurs, et les avertissements ajoutés avec add_warning() dans la liste des avertissements. Chaque liste montre les 100 premiers éléments.
  • Pro s’en sert pour copier les valeurs des champs personnalisés de The Events Calendar.

happenboard_settings_backup_export

Filtre Free src/Service/IO/SettingsBackup.php

Filtre la sauvegarde des réglages que télécharge le bouton Export settings (JSON) de HappenBoard → Settings → Tools. Ajoutez-y votre section pour qu’elle suive le fichier jusqu’au site qui l’importe.

Signature

apply_filters( 'happenboard_settings_backup_export', array $payload )

Paramètres

$payload array<string,mixed>
Le document construit par HappenBoard : format (toujours happenboard.settings), version (1), plugin, site, exportedAt et general (les réglages HappenBoard).

Valeur de retour

array Le document complet, avec votre section sous votre propre clé de premier niveau.

Exemple

add_filter(
    'happenboard_settings_backup_export',
    function ( array $payload ): array {
        $settings = (array) get_option( 'my_plugin_settings', array() );

        // Le fichier est téléchargé et circule : pas de secrets dedans.
        unset( $settings['api_secret'] );

        $payload['my_plugin'] = $settings;

        return $payload;
    }
);

Remarques

  • Utilisez une clé de premier niveau à vous et ne touchez pas aux autres. Un fichier dont le format n’est pas happenboard.settings est refusé à l’import.
  • Renvoyez un tableau. Toute autre valeur donne un document vide au téléchargement, sans message d’erreur.
  • HappenBoard exclut ses propres secrets (secret Turnstile, clé Akismet, clés d’API Google Maps et météo), et l’import conserve les clés du site cible. Faites de même avec les vôtres.
  • Pro n’ajoute rien à ce fichier : ses réglages, comme les clés Stripe, ne sont pas dans la sauvegarde. Tout ce que vous ajoutez doit pouvoir être encodé en JSON.

happenboard_settings_backup_import

Filtre Free src/Service/IO/SettingsBackup.php

Filtre la liste des sections restaurées depuis une sauvegarde de réglages envoyée. Lisez votre section dans le fichier, enregistrez-la et indiquez si vous l’avez appliquée.

Signature

apply_filters( 'happenboard_settings_backup_import', array $applied, array $payload )

Paramètres

$applied array<string,bool>
Nom de section => vrai ou faux. Vaut d’abord array( 'general' => false ), et general passe à vrai quand le fichier contenait des réglages HappenBoard et qu’ils ont été enregistrés.
$payload array<string,mixed>
Le fichier décodé en entier, tel que l’autre site l’a exporté. Votre section peut être absente.

Valeur de retour

array La liste des sections, avec vos clés en plus. La route REST la renvoie sous applied ; l’écran Tools affiche seulement « Settings imported. ».

Exemple

add_filter(
    'happenboard_settings_backup_import',
    function ( array $applied, array $payload ): array {
        // Le fichier peut venir d'un site sans votre extension.
        if ( empty( $payload['my_plugin'] ) || ! is_array( $payload['my_plugin'] ) ) {
            $applied['my_plugin'] = false;
            return $applied;
        }
        // Mise à jour partielle : les clés absentes du fichier gardent leur valeur.
        $current = (array) get_option( 'my_plugin_settings', array() );
        $clean   = map_deep( $payload['my_plugin'], 'sanitize_text_field' );
        update_option( 'my_plugin_settings', array_merge( $current, $clean ) );
        $applied['my_plugin'] = true;

        return $applied;
    },
    10,
    2
);

Remarques

  • Deux arguments : inscrivez-vous avec 10, 2, sinon vous ne pouvez pas lire le fichier.
  • Il s’exécute pour chaque fichier valide, y compris ceux qui n’ont pas votre section. Vérifiez que votre clé existe et contient un tableau avant d’enregistrer, sinon vous écrasez les réglages en place avec rien.
  • Seuls format et version sont vérifiés avant son exécution. Traitez votre section comme une saisie non fiable et nettoyez-la. HappenBoard fusionne sa propre section general dans les réglages actuels : les clés absentes gardent leur valeur.
  • Renvoyez un tableau. Toute autre valeur est remplacée par array( 'general' => true ), qui annonce les réglages généraux comme restaurés même s’ils ne l’ont pas été. L’export et l’import demandent la capacité happenboard_manage_settings (administrateurs par défaut).

Pour aller plus loin