Skip to main content

Importation des Offres d'Emploi via HRMaps

Ce document décrit la logique d'importation automatique des offres d'emploi depuis l'API HRMaps vers le site WordPress du Groupe Niort.

Fonctionnement global

Les ressources humaines gèrent les offres sur la plateforme HRMaps. Une fonction PHP sur le site WordPress interroge périodiquement l'API pour synchroniser les données.

Les offres sont stockées dans un Custom Post Type (CPT) nommé job_offer.

Logique de Synchronisation

La fonction import_jobs_from_api() effectue les opérations suivantes :

  1. Récupération : Appel POST sur l'API HRMaps.
  2. Filtrage : Exclusion des offres archivées.
  3. Réconciliation :
    • Si l'offre n'existe pas (basé sur _position_id), elle est créée.
    • Si l'offre existe déjà, ses informations (titre, contenu) sont mises à jour.
  4. Métadonnées : Mise à jour de tous les champs personnalisés (ville, contrat, salaire, etc.).
  5. Nettoyage : Suppression des offres présentes sur WordPress mais disparues de l'API.

Code Source (functions.php)

function import_jobs_from_api()
{
$api_url = 'https://niort-freres.hrmaps.cloud/api/AdepApi/GetJobOfferList/0';

$response = wp_remote_post($api_url);

if (is_wp_error($response)) {
error_log('Erreur API: ' . $response->get_error_message());
return;
}

$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);

if (!empty($data)) {
foreach ($data as $job) {

if (!empty($job['IsArchived']) && $job['IsArchived'] === true) {
continue;
}

$existing_job = get_posts(array(
'post_type' => 'job_offer',
'meta_query' => array(
array(
'key' => '_position_id',
'value' => $job['PositionID'],
),
),
));

if (empty($existing_job)) {
// ── CRÉATION ──────────────────────────────────────────────
$post_id = wp_insert_post(array(
'post_title' => $job['PositionTitle'],
'post_content' => wp_kses_post($job['PositionFormattedDescription']['Content']),
'post_type' => 'job_offer',
'post_status' => 'publish',
));

error_log('Offre créée : ' . $post_id . ' (' . $job['PositionTitle'] . ')');
} else {
// ── MISE À JOUR ───────────────────────────────────────────
$post_id = $existing_job[0]->ID;

wp_update_post(array(
'ID' => $post_id,
'post_title' => $job['PositionTitle'],
'post_content' => wp_kses_post($job['PositionFormattedDescription']['Content']),
));

error_log('Offre mise à jour : ' . $post_id . ' (' . $job['PositionTitle'] . ')');
}

// ── METAS (communes création + mise à jour) ───────────────────
update_post_meta($post_id, '_position_id', $job['PositionID']);
update_post_meta($post_id, '_apply_uri', $job['ApplyURI']);
update_post_meta($post_id, '_organization_name', $job['OrganizationName']);
update_post_meta($post_id, '_industry', $job['PositionIndustry']['Name']);
update_post_meta($post_id, '_job_grade', $job['JobGrade']['Name']);
update_post_meta($post_id, '_career_level', $job['CareerLevel']['Name']);
update_post_meta($post_id, '_schedule', $job['PositionSchedule']['Name']);
update_post_meta($post_id, '_contract_type', $job['PositionOfferingType']['Name']);
update_post_meta($post_id, '_start_date', substr($job['PositionStartDate'], 0, 9));
update_post_meta($post_id, '_end_date', $job['PositionEndDate']);
update_post_meta($post_id, '_publication_date', $job['PublicationStartDate']);
update_post_meta($post_id, '_close_date', $job['ApplicationCloseDate']);
update_post_meta($post_id, '_parent_organization_name', $job['ParentOrganizationName']);
update_post_meta($post_id, '_schedule_work', $job['PositionSchedule']['WeeklyWorkDuration']);
update_post_meta($post_id, '_contenu', substr(strip_tags($job['PositionFormattedDescription']['Content']), 0, 80));

$city = $job['PositionLocation']['CityName'] ?? '';
$postal_code = $job['PositionLocation']['PostalCode'] ?? '';
$address = $job['PositionLocation']['AddressLine'] ?? '';

if ($job['OrganizationName'] === 'DPAN' && empty($city) && empty($postal_code) && empty($address)) {
$city = 'Rouen';
$postal_code = '76000';
$address = '154 Avenue du mont Riboudet';
}

update_post_meta($post_id, '_city', $city);
update_post_meta($post_id, '_postal_code', $postal_code);
update_post_meta($post_id, '_adress', $address);
}
}

// ── SUPPRESSION DES OFFRES OBSOLÈTES ─────────────────────────────────
$existing_jobs = get_posts([
'post_type' => 'job_offer',
'posts_per_page' => -1,
]);

$new_job_ids = array_filter(array_column($data, 'PositionID'));

foreach ($existing_jobs as $job) {
$existing_job_id = get_post_meta($job->ID, '_position_id', true);

if (empty($existing_job_id)) {
continue;
}

if (!in_array($existing_job_id, $new_job_ids)) {
wp_delete_post($job->ID, true);
error_log("Post supprimé : " . $job->ID);
}
}
}
Actualisation Automatique

Cette modification permet désormais de mettre à jour le contenu et le titre des offres si elles sont modifiées par les RH dans l'outil HRMaps, au lieu de simplement créer les nouvelles offres.