Import des offres d'emploi
Source de données
L'import interroge l'API HRMaps via une requête POST :
| Paramètre | Valeur |
|---|---|
| URL | https://niort-freres.hrmaps.cloud/api/AdepApi/GetJobOfferList/0 |
| Méthode | POST |
| Format retour | JSON (tableau d'offres) |
Déclenchement
Import automatique (WP-Cron)
L'import est planifié toutes les heures via WP-Cron :
if (!wp_next_scheduled('import_jobs_event')) {
wp_schedule_event(time(), 'hourly', 'import_jobs_event');
}
add_action('import_jobs_event', 'import_jobs_from_api');
WP-Cron ne se déclenche que lorsque le site reçoit une visite. En production avec peu de trafic, configurer un vrai cron système :
* * * * * curl -s https://groupeniort.fr/wp-cron.php?doing_wp_cron > /dev/null
Import manuel (Admin WP)
Un bouton d'import manuel est accessible dans l'administration :
WordPress Admin → Offres d'emploi → Importation API → "Importer Maintenant"
Il appelle directement import_jobs_from_api() sans passer par le cron.
Logique d'import
Étape 1 — Filtrage des offres archivées
Avant tout traitement, les offres marquées comme archivées sont ignorées :
if (!empty($job['IsArchived']) && $job['IsArchived'] === true) {
continue;
}
Étape 2 — Vérification des doublons
L'unicité est assurée par le champ _position_id (ID HRMaps). Si une offre avec le même PositionID existe déjà en base, elle est ignorée :
$existing_job = get_posts([
'post_type' => 'job_offer',
'meta_query' => [[
'key' => '_position_id',
'value' => $job['PositionID'],
]],
]);
if (empty($existing_job)) {
// Création du nouveau post
}
Étape 3 — Création du post WordPress
Les nouvelles offres sont créées comme Custom Post Type job_offer :
$post_id = wp_insert_post([
'post_title' => $job['PositionTitle'],
'post_content' => wp_kses_post($job['PositionFormattedDescription']['Content']),
'post_type' => 'job_offer',
'post_status' => 'publish',
]);
Le contenu HTML de la description est assaini via wp_kses_post() avant insertion.
Étape 4 — Cas particulier DPAN
Si l'organisation est DPAN et qu'aucune localisation n'est fournie par l'API, une adresse par défaut est appliquée :
if ($job['OrganizationName'] === 'DPAN' && empty($city) && empty($postal_code) && empty($address)) {
$city = 'Rouen';
$postal_code = '76000';
$address = '154 Avenue du mont Riboudet';
}
Suppression des offres obsolètes
Après chaque import, les offres présentes en base mais absentes de la réponse API sont supprimées définitivement :
// Construction de la liste des IDs reçus
foreach ($data as $offer) {
$new_job_ids[] = $offer['PositionID'];
}
// Suppression des offres qui ne sont plus dans l'API
foreach ($existing_jobs as $job) {
$existing_job_id = get_post_meta($job->ID, '_position_id', true);
if (!in_array($existing_job_id, $new_job_ids)) {
wp_delete_post($job->ID, true); // true = suppression définitive (sans corbeille)
}
}
Le second argument true de wp_delete_post() bypasse la corbeille. Les offres supprimées ne sont pas récupérables depuis l'admin WordPress.
Schéma récapitulatif
Requête POST → GetJobOfferList
│
▼
Pour chaque offre reçue :
│
├─ IsArchived === true ──────────────────► Ignorée
│
├─ _position_id déjà en base ───────────► Ignorée (pas de doublon)
│
└─ Nouvelle offre
├─ Org = DPAN sans localisation ─► Adresse Rouen par défaut
└─ wp_insert_post() + metas ─────► Post publié
Après la boucle :
└─ Posts WP absents de l'API ────────────► wp_delete_post() définitif