Écritures Pods centralisées (class-pods-storage), catégories par slug et IDs Pods par nom, tests
This commit is contained in:
@@ -9,38 +9,42 @@ if (!defined('ABSPATH')) {
|
||||
|
||||
class Thalim_HAL_Importer_Logic {
|
||||
|
||||
// HAL doc type -> WordPress category ID
|
||||
private const DOC_TYPE_MAP = [
|
||||
'ART' => 16, // Article
|
||||
'COUV' => 16, // Chapitre -> Articles
|
||||
'OUV' => 15, // Ouvrage -> Ouvrages
|
||||
'COMM' => 13, // Communication -> Communications
|
||||
'ISSUE' => 16, // Direction de numéro -> Articles
|
||||
'PROCEEDINGS' => 15, // Direction d'ouvrage/Proceedings -> Ouvrages
|
||||
'THESE' => 14, // Thèse -> Soutenances
|
||||
'HDR' => 14, // HDR -> Soutenances
|
||||
'SON' => 19, // Son -> Captations audio/vidéo
|
||||
'VIDEO' => 19, // Vidéo -> Captations audio/vidéo
|
||||
'NOTICE' => 16, // Notice/recension -> Articles
|
||||
'BLOG' => 19, // Blog/tribune -> Médias
|
||||
'TRAD' => 15, // Traduction -> Ouvrages (fonction auteur "Traduction")
|
||||
'REPORT' => 4, // Rapport -> Publications et productions
|
||||
'UNDEFINED' => 4, // Non défini -> Publications et productions
|
||||
'POSTER' => 4, // Poster -> Publications et productions
|
||||
'OTHER' => 4, // Autre -> Publications et productions
|
||||
// HAL doc type -> slug de catégorie WP (résolu en term_id au runtime —
|
||||
// les IDs auto-incrémentés ne survivent pas à une réimportation de base)
|
||||
private const DOC_TYPE_SLUGS = [
|
||||
'ART' => 'articles', // Article
|
||||
'COUV' => 'articles', // Chapitre -> Articles
|
||||
'OUV' => 'ouvrages', // Ouvrage -> Ouvrages
|
||||
'COMM' => 'communications', // Communication -> Communications
|
||||
'ISSUE' => 'articles', // Direction de numéro -> Articles
|
||||
'PROCEEDINGS' => 'ouvrages', // Direction d'ouvrage/Proceedings -> Ouvrages
|
||||
'THESE' => 'soutenances', // Thèse -> Soutenances
|
||||
'HDR' => 'soutenances', // HDR -> Soutenances
|
||||
'SON' => 'medias', // Son -> Médias
|
||||
'VIDEO' => 'medias', // Vidéo -> Médias
|
||||
'NOTICE' => 'articles', // Notice/recension -> Articles
|
||||
'BLOG' => 'medias', // Blog/tribune -> Médias
|
||||
'TRAD' => 'ouvrages', // Traduction -> Ouvrages (fonction auteur "Traduction")
|
||||
'REPORT' => 'publications-et-productions', // Rapport -> Publications et productions
|
||||
'UNDEFINED' => 'publications-et-productions', // Non défini -> Publications et productions
|
||||
'POSTER' => 'publications-et-productions', // Poster -> Publications et productions
|
||||
'OTHER' => 'publications-et-productions', // Autre -> Publications et productions
|
||||
];
|
||||
|
||||
// Doc types that use date_de_debut instead of datetime
|
||||
private const EVENT_DOC_TYPES = ['COMM', 'THESE', 'HDR', 'SON', 'VIDEO'];
|
||||
|
||||
// Pods IDs — queried from the DB, stable per installation
|
||||
private const POD_ID_POST = 8;
|
||||
private const FIELD_ID_CATEGORIE = 16; // "Type d'annonce" (picks from WP category)
|
||||
private const FIELD_ID_MEMBRES = 178;
|
||||
private const FIELD_ID_AUTRE_MBRES = 195; // autre_membres (unused in import, for reference)
|
||||
private const FIELD_ID_AXES = 270; // axes_thematiques (picks from axe_thematique)
|
||||
private const FIELD_ID_PROGRAMMES = 271; // programmes_de_recherche (picks from programme_de_recherche)
|
||||
private const FIELD_ID_ETIQUETTES = 652; // étiquettes (picks from post_tag)
|
||||
/**
|
||||
* Résout un slug de catégorie en term_id (cache statique par requête).
|
||||
*/
|
||||
private function cat_id_by_slug(string $slug): ?int {
|
||||
static $cache = [];
|
||||
if (!array_key_exists($slug, $cache)) {
|
||||
$term = get_term_by('slug', $slug, 'category');
|
||||
$cache[$slug] = $term ? (int) $term->term_id : null;
|
||||
}
|
||||
return $cache[$slug];
|
||||
}
|
||||
|
||||
/** Source of the axes applied on the last import(): 'spip' | 'coauthors' | 'owner' | 'none'. */
|
||||
public $last_axes_source = 'none';
|
||||
@@ -77,14 +81,19 @@ class Thalim_HAL_Importer_Logic {
|
||||
* Get category ID for HAL doc type
|
||||
*/
|
||||
public function get_category_id($doc_type) {
|
||||
return self::DOC_TYPE_MAP[$doc_type] ?? null;
|
||||
$slug = self::DOC_TYPE_SLUGS[$doc_type] ?? null;
|
||||
return $slug ? $this->cat_id_by_slug($slug) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get doc type mappings
|
||||
* Get doc type mappings (doc type => category term_id)
|
||||
*/
|
||||
public function get_doc_type_map() {
|
||||
return self::DOC_TYPE_MAP;
|
||||
$map = [];
|
||||
foreach (self::DOC_TYPE_SLUGS as $type => $slug) {
|
||||
$map[$type] = $this->cat_id_by_slug($slug);
|
||||
}
|
||||
return $map;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,34 +159,10 @@ class Thalim_HAL_Importer_Logic {
|
||||
$post_id = wp_insert_post($post_args, true);
|
||||
if (is_wp_error($post_id)) return $post_id;
|
||||
|
||||
// --- Category — Pods triple-storage pattern ---
|
||||
$cat_id = self::DOC_TYPE_MAP[$doc_type] ?? null;
|
||||
// --- Category — stockage Pods centralisé (cf. class-pods-storage.php) ---
|
||||
$cat_id = $this->get_category_id($doc_type);
|
||||
if ($cat_id) {
|
||||
global $wpdb;
|
||||
|
||||
// 1. Native WP category assignment
|
||||
wp_set_post_categories($post_id, [$cat_id]);
|
||||
|
||||
// 2. Pods postmeta: single integer value
|
||||
update_post_meta($post_id, 'categorie', $cat_id);
|
||||
|
||||
// 3. Pods _pods_ meta: serialized array of one integer
|
||||
update_post_meta($post_id, '_pods_categorie', [$cat_id]);
|
||||
|
||||
// 4. wp_podsrel row
|
||||
$wpdb->insert(
|
||||
$wpdb->prefix . 'podsrel',
|
||||
[
|
||||
'pod_id' => self::POD_ID_POST,
|
||||
'field_id' => self::FIELD_ID_CATEGORIE,
|
||||
'item_id' => $post_id,
|
||||
'related_pod_id' => 0,
|
||||
'related_field_id'=> 0,
|
||||
'related_item_id' => $cat_id,
|
||||
'weight' => 0,
|
||||
],
|
||||
['%d', '%d', '%d', '%d', '%d', '%d', '%d']
|
||||
);
|
||||
Thalim_HAL_Pods_Storage::set_categorie($post_id, $cat_id);
|
||||
}
|
||||
|
||||
// --- Core meta ---
|
||||
@@ -220,41 +205,13 @@ class Thalim_HAL_Importer_Logic {
|
||||
update_post_meta($post_id, 'fonction_auteur', 'Traduction // Translation');
|
||||
}
|
||||
|
||||
// --- Keywords -> étiquettes (Pods triple-storage, picks from post_tag) ---
|
||||
$hal_keywords = $hal_doc['keyword_s'] ?? [];
|
||||
if (!empty($hal_keywords)) {
|
||||
$matched_term_ids = $this->match_keywords_to_tags($hal_keywords);
|
||||
if (!empty($matched_term_ids)) {
|
||||
global $wpdb;
|
||||
|
||||
// 1. Native WP term relationship
|
||||
wp_set_object_terms($post_id, $matched_term_ids, 'post_tag', true);
|
||||
|
||||
// 2. Individual postmeta rows (one per term ID)
|
||||
foreach ($matched_term_ids as $tid) {
|
||||
add_post_meta($post_id, 'etiquettes', (string) $tid);
|
||||
}
|
||||
|
||||
// 3. _pods_etiquettes: serialized array of term IDs as integers
|
||||
update_post_meta($post_id, '_pods_etiquettes', array_map('intval', $matched_term_ids));
|
||||
|
||||
// 4. wp_podsrel rows
|
||||
foreach ($matched_term_ids as $weight => $tid) {
|
||||
$wpdb->insert(
|
||||
$wpdb->prefix . 'podsrel',
|
||||
[
|
||||
'pod_id' => self::POD_ID_POST,
|
||||
'field_id' => self::FIELD_ID_ETIQUETTES,
|
||||
'item_id' => $post_id,
|
||||
'related_pod_id' => 0,
|
||||
'related_field_id' => 0,
|
||||
'related_item_id' => (int) $tid,
|
||||
'weight' => $weight,
|
||||
],
|
||||
['%d', '%d', '%d', '%d', '%d', '%d', '%d']
|
||||
);
|
||||
}
|
||||
}
|
||||
// --- Keywords HAL + tags SPIP -> étiquettes (une seule écriture Pods) ---
|
||||
$etiquette_ids = $this->match_keywords_to_tags($hal_doc['keyword_s'] ?? []);
|
||||
if (!empty($spip_context['tags'])) {
|
||||
$etiquette_ids = array_merge($etiquette_ids, array_map('intval', $spip_context['tags']));
|
||||
}
|
||||
if (!empty($etiquette_ids)) {
|
||||
Thalim_HAL_Pods_Storage::set_relation($post_id, 'etiquettes', $etiquette_ids, 'post_tag');
|
||||
}
|
||||
|
||||
// --- Date meta ---
|
||||
@@ -303,50 +260,27 @@ class Thalim_HAL_Importer_Logic {
|
||||
}
|
||||
}
|
||||
|
||||
// --- Reference bibliographique from citationFull_s (cats 4, 15, 16) ---
|
||||
// --- Reference bibliographique from citationFull_s (publications/ouvrages/articles) ---
|
||||
$citation_cats = array_filter([
|
||||
$this->cat_id_by_slug('publications-et-productions'),
|
||||
$this->cat_id_by_slug('ouvrages'),
|
||||
$this->cat_id_by_slug('articles'),
|
||||
]);
|
||||
$citation = $hal_doc['citationFull_s'] ?? '';
|
||||
if ($citation && in_array($cat_id, [4, 15, 16])) {
|
||||
if ($citation && in_array($cat_id, $citation_cats, true)) {
|
||||
update_post_meta($post_id, 'reference_bibliographique', wp_kses_post($citation));
|
||||
}
|
||||
|
||||
// --- Store matched THALIM members — Pods triple-storage pattern
|
||||
// --- Store matched THALIM members ---
|
||||
if (!empty($matched_user_ids)) {
|
||||
global $wpdb;
|
||||
|
||||
// 1. Individual postmeta rows (one per user ID, as string)
|
||||
foreach ($matched_user_ids as $uid) {
|
||||
add_post_meta($post_id, 'membres', (string) $uid);
|
||||
}
|
||||
|
||||
// 2. _pods_ meta: serialized PHP array of user IDs as integers
|
||||
update_post_meta($post_id, '_pods_membres', array_map('intval', $matched_user_ids));
|
||||
|
||||
// 3. wp_podsrel rows (one per user, weight = position)
|
||||
foreach ($matched_user_ids as $weight => $uid) {
|
||||
$wpdb->insert(
|
||||
$wpdb->prefix . 'podsrel',
|
||||
[
|
||||
'pod_id' => self::POD_ID_POST,
|
||||
'field_id' => self::FIELD_ID_MEMBRES,
|
||||
'item_id' => $post_id,
|
||||
'related_pod_id' => 0,
|
||||
'related_field_id'=> 0,
|
||||
'related_item_id' => (int) $uid,
|
||||
'weight' => $weight,
|
||||
],
|
||||
['%d', '%d', '%d', '%d', '%d', '%d', '%d']
|
||||
);
|
||||
}
|
||||
Thalim_HAL_Pods_Storage::set_relation($post_id, 'membres', $matched_user_ids, null);
|
||||
}
|
||||
|
||||
// --- Axes thématiques : cascade (SPIP direct > co-auteurs > owner) ---
|
||||
$axes_resolution = $this->resolve_axes_cascade($matched_user_ids, $spip_context);
|
||||
$this->last_axes_source = $axes_resolution['source'];
|
||||
if (!empty($axes_resolution['term_ids'])) {
|
||||
$this->set_pods_taxonomy_multi(
|
||||
$post_id, 'axes_thematiques', self::FIELD_ID_AXES,
|
||||
$axes_resolution['term_ids'], 'axe_thematique'
|
||||
);
|
||||
Thalim_HAL_Pods_Storage::set_relation($post_id, 'axes_thematiques', $axes_resolution['term_ids'], 'axe_thematique');
|
||||
}
|
||||
|
||||
// --- Programmes de recherche : SPIP direct OR keyword matching ---
|
||||
@@ -354,25 +288,7 @@ class Thalim_HAL_Importer_Logic {
|
||||
? array_map('intval', $spip_context['programmes'])
|
||||
: $this->match_terms_by_keywords($hal_doc['keyword_s'] ?? [], 'programme_de_recherche');
|
||||
if (!empty($prog_ids)) {
|
||||
$this->set_pods_taxonomy_multi(
|
||||
$post_id, 'programmes_de_recherche', self::FIELD_ID_PROGRAMMES,
|
||||
$prog_ids, 'programme_de_recherche'
|
||||
);
|
||||
}
|
||||
|
||||
// --- Étiquettes SPIP directes (en plus du matching HAL déjà fait plus haut) ---
|
||||
if (!empty($spip_context['tags'])) {
|
||||
// Merge avec les tags déjà posés par le bloc étiquettes plus haut
|
||||
$existing = wp_get_object_terms($post_id, 'post_tag', ['fields' => 'ids']);
|
||||
$merged = array_values(array_unique(array_merge(
|
||||
is_array($existing) ? array_map('intval', $existing) : [],
|
||||
array_map('intval', $spip_context['tags'])
|
||||
)));
|
||||
$this->set_pods_taxonomy_multi(
|
||||
$post_id, 'etiquettes', self::FIELD_ID_ETIQUETTES,
|
||||
array_diff($merged, is_array($existing) ? $existing : []),
|
||||
'post_tag'
|
||||
);
|
||||
Thalim_HAL_Pods_Storage::set_relation($post_id, 'programmes_de_recherche', $prog_ids, 'programme_de_recherche');
|
||||
}
|
||||
|
||||
// Unmatched authors as free text — remove matched names from the full list
|
||||
@@ -389,11 +305,6 @@ class Thalim_HAL_Importer_Logic {
|
||||
update_post_meta($post_id, 'autrepersonnes', implode(', ', array_values($unmatched)));
|
||||
}
|
||||
|
||||
// --- Polylang: assign French language ---
|
||||
if (function_exists('pll_set_post_language')) {
|
||||
pll_set_post_language($post_id, 'fr');
|
||||
}
|
||||
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
@@ -510,41 +421,4 @@ class Thalim_HAL_Importer_Logic {
|
||||
return $ts ? date('Y-m-d', $ts) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic Pods triple-storage writer for multi-value taxonomy fields.
|
||||
* Writes to: wp_term_relationships, postmeta rows, _pods_ meta, wp_podsrel.
|
||||
*/
|
||||
private function set_pods_taxonomy_multi(int $post_id, string $field_name, int $field_id, array $term_ids, string $taxonomy): void {
|
||||
if (empty($term_ids)) return;
|
||||
global $wpdb;
|
||||
$term_ids = array_values(array_unique(array_map('intval', $term_ids)));
|
||||
|
||||
// 1. wp_term_relationships
|
||||
wp_set_object_terms($post_id, $term_ids, $taxonomy, true);
|
||||
|
||||
// 2. postmeta (one row per term ID, as string)
|
||||
foreach ($term_ids as $tid) {
|
||||
add_post_meta($post_id, $field_name, (string) $tid);
|
||||
}
|
||||
|
||||
// 3. _pods_ meta: serialized array of ints
|
||||
update_post_meta($post_id, '_pods_' . $field_name, $term_ids);
|
||||
|
||||
// 4. wp_podsrel rows (weight = position)
|
||||
foreach ($term_ids as $weight => $tid) {
|
||||
$wpdb->insert(
|
||||
$wpdb->prefix . 'podsrel',
|
||||
[
|
||||
'pod_id' => self::POD_ID_POST,
|
||||
'field_id' => $field_id,
|
||||
'item_id' => $post_id,
|
||||
'related_pod_id' => 0,
|
||||
'related_field_id' => 0,
|
||||
'related_item_id' => (int) $tid,
|
||||
'weight' => $weight,
|
||||
],
|
||||
['%d', '%d', '%d', '%d', '%d', '%d', '%d']
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
165
includes/class-pods-storage.php
Normal file
165
includes/class-pods-storage.php
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
/**
|
||||
* Écriture des champs relationnels Pods — point d'entrée unique.
|
||||
*
|
||||
* ⚠ DÉPENDANCE DURE à Pods 3.x : Pods stocke ses relations en quadruple
|
||||
* (lignes postmeta multiples + meta `_pods_*` sérialisée + table wp_podsrel
|
||||
* + wp_term_relationships pour les taxonomies). Cette classe reproduit ce
|
||||
* stockage interne car l'import se fait hors du formulaire Pods. Toute
|
||||
* montée de version majeure de Pods doit revalider ce mécanisme.
|
||||
*
|
||||
* Les IDs de pod et de champs sont résolus PAR NOM dans wp_posts
|
||||
* (post_type _pods_pod / _pods_field) — ils ne survivraient pas en dur à
|
||||
* une réimportation de base.
|
||||
*/
|
||||
|
||||
if (!defined('ABSPATH')) {
|
||||
exit;
|
||||
}
|
||||
|
||||
class Thalim_HAL_Pods_Storage {
|
||||
|
||||
/** @var array<string,int> cache par requête */
|
||||
private static $ids = [];
|
||||
|
||||
/**
|
||||
* ID du pod `post` (post_type _pods_pod), 0 si introuvable.
|
||||
*/
|
||||
public static function pod_id(): int {
|
||||
if (!isset(self::$ids['__pod'])) {
|
||||
global $wpdb;
|
||||
self::$ids['__pod'] = (int) $wpdb->get_var(
|
||||
"SELECT ID FROM {$wpdb->posts}
|
||||
WHERE post_type = '_pods_pod' AND post_name = 'post' LIMIT 1"
|
||||
);
|
||||
}
|
||||
return self::$ids['__pod'];
|
||||
}
|
||||
|
||||
/**
|
||||
* ID d'un champ du pod `post` résolu par nom, 0 si introuvable.
|
||||
*/
|
||||
public static function field_id(string $field_name): int {
|
||||
if (!isset(self::$ids[$field_name])) {
|
||||
global $wpdb;
|
||||
self::$ids[$field_name] = (int) $wpdb->get_var($wpdb->prepare(
|
||||
"SELECT ID FROM {$wpdb->posts}
|
||||
WHERE post_type = '_pods_field' AND post_name = %s AND post_parent = %d
|
||||
LIMIT 1",
|
||||
$field_name,
|
||||
self::pod_id()
|
||||
));
|
||||
}
|
||||
return self::$ids[$field_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Écrit une relation multi-valeurs (terms ou users) façon Pods :
|
||||
* 1. wp_term_relationships (si $taxonomy fournie)
|
||||
* 2. lignes postmeta individuelles
|
||||
* 3. meta `_pods_{field}` sérialisée
|
||||
* 4. lignes wp_podsrel (weight = position), précédées d'un delete
|
||||
* pour ne jamais créer de doublons.
|
||||
*
|
||||
* @param int[] $related_ids IDs liés (term_ids ou user_ids)
|
||||
* @param string|null $taxonomy Taxonomy WP si le champ pointe des termes
|
||||
*/
|
||||
public static function set_relation(int $post_id, string $field_name, array $related_ids, ?string $taxonomy = null): void {
|
||||
$related_ids = array_values(array_unique(array_map('intval', $related_ids)));
|
||||
if (empty($related_ids)) {
|
||||
return;
|
||||
}
|
||||
global $wpdb;
|
||||
|
||||
// 1. Relation native WP pour les taxonomies (append)
|
||||
if ($taxonomy !== null) {
|
||||
wp_set_object_terms($post_id, $related_ids, $taxonomy, true);
|
||||
}
|
||||
|
||||
// 2. postmeta : une ligne par valeur (string, comme Pods)
|
||||
// Re-écrit l'ensemble pour rester cohérent avec _pods_* et podsrel.
|
||||
delete_post_meta($post_id, $field_name);
|
||||
foreach ($related_ids as $rid) {
|
||||
add_post_meta($post_id, $field_name, (string) $rid);
|
||||
}
|
||||
|
||||
// 3. _pods_{field} : tableau d'entiers sérialisé
|
||||
update_post_meta($post_id, '_pods_' . $field_name, $related_ids);
|
||||
|
||||
// 4. wp_podsrel
|
||||
$pod_id = self::pod_id();
|
||||
$field_id = self::field_id($field_name);
|
||||
if (!$pod_id || !$field_id) {
|
||||
// Configuration Pods absente/inattendue : on n'écrit pas podsrel
|
||||
// (les meta posées ci-dessus suffisent au front), mais on trace.
|
||||
error_log(sprintf(
|
||||
'[thalim-hal-importer] Pods field "%s" introuvable (pod_id=%d) — wp_podsrel non écrit pour le post %d',
|
||||
$field_name, $pod_id, $post_id
|
||||
));
|
||||
return;
|
||||
}
|
||||
$wpdb->delete(
|
||||
$wpdb->prefix . 'podsrel',
|
||||
['pod_id' => $pod_id, 'field_id' => $field_id, 'item_id' => $post_id],
|
||||
['%d', '%d', '%d']
|
||||
);
|
||||
foreach ($related_ids as $weight => $rid) {
|
||||
$wpdb->insert(
|
||||
$wpdb->prefix . 'podsrel',
|
||||
[
|
||||
'pod_id' => $pod_id,
|
||||
'field_id' => $field_id,
|
||||
'item_id' => $post_id,
|
||||
'related_pod_id' => 0,
|
||||
'related_field_id' => 0,
|
||||
'related_item_id' => $rid,
|
||||
'weight' => $weight,
|
||||
],
|
||||
['%d', '%d', '%d', '%d', '%d', '%d', '%d']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigne LA catégorie d'un post (champ pick `categorie`) : catégorie WP
|
||||
* native (remplace) + stockage Pods.
|
||||
*/
|
||||
public static function set_categorie(int $post_id, int $cat_id): void {
|
||||
if (!$cat_id) {
|
||||
return;
|
||||
}
|
||||
wp_set_post_categories($post_id, [$cat_id]);
|
||||
global $wpdb;
|
||||
|
||||
update_post_meta($post_id, 'categorie', $cat_id);
|
||||
update_post_meta($post_id, '_pods_categorie', [$cat_id]);
|
||||
|
||||
$pod_id = self::pod_id();
|
||||
$field_id = self::field_id('categorie');
|
||||
if (!$pod_id || !$field_id) {
|
||||
error_log(sprintf(
|
||||
'[thalim-hal-importer] Pods field "categorie" introuvable — wp_podsrel non écrit pour le post %d',
|
||||
$post_id
|
||||
));
|
||||
return;
|
||||
}
|
||||
$wpdb->delete(
|
||||
$wpdb->prefix . 'podsrel',
|
||||
['pod_id' => $pod_id, 'field_id' => $field_id, 'item_id' => $post_id],
|
||||
['%d', '%d', '%d']
|
||||
);
|
||||
$wpdb->insert(
|
||||
$wpdb->prefix . 'podsrel',
|
||||
[
|
||||
'pod_id' => $pod_id,
|
||||
'field_id' => $field_id,
|
||||
'item_id' => $post_id,
|
||||
'related_pod_id' => 0,
|
||||
'related_field_id' => 0,
|
||||
'related_item_id' => $cat_id,
|
||||
'weight' => 0,
|
||||
],
|
||||
['%d', '%d', '%d', '%d', '%d', '%d', '%d']
|
||||
);
|
||||
}
|
||||
}
|
||||
17
phpcs.xml.dist
Normal file
17
phpcs.xml.dist
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset name="THALIM thalim-hal-importer">
|
||||
<description>WordPress Coding Standards pour thalim-hal-importer.</description>
|
||||
<!-- Installation : composer global require wp-coding-standards/wpcs dealerdirect/phpcodesniffer-composer-installer
|
||||
Exécution depuis ce dossier : phpcs -->
|
||||
<file>.</file>
|
||||
<exclude-pattern>tests/*</exclude-pattern>
|
||||
<arg name="extensions" value="php"/>
|
||||
<arg value="sp"/>
|
||||
<rule ref="WordPress-Core">
|
||||
<exclude name="Universal.Arrays.DisallowShortArraySyntax"/>
|
||||
<exclude name="WordPress.WhiteSpace.PrecisionAlignment"/>
|
||||
<exclude name="Generic.WhiteSpace.DisallowSpaceIndent"/>
|
||||
</rule>
|
||||
<rule ref="WordPress.Security"/>
|
||||
<rule ref="WordPress.DB.PreparedSQL"/>
|
||||
</ruleset>
|
||||
65
tests/run-tests.php
Normal file
65
tests/run-tests.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* Tests du plugin THALIM HAL Importer.
|
||||
*
|
||||
* Exécution (environnement Docker de dev) :
|
||||
* docker exec wordpress php /var/www/html/wp-content/plugins/thalim-hal-importer/tests/run-tests.php
|
||||
*/
|
||||
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
exit("CLI only\n");
|
||||
}
|
||||
|
||||
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_HOST'] ?? 'localhost';
|
||||
$_SERVER['REQUEST_URI'] = $_SERVER['REQUEST_URI'] ?? '/';
|
||||
|
||||
require dirname(__DIR__, 4) . '/wp-load.php';
|
||||
|
||||
$failures = 0;
|
||||
$count = 0;
|
||||
|
||||
function check(string $name, $actual, $expected): void {
|
||||
global $failures, $count;
|
||||
$count++;
|
||||
if ($actual === $expected) {
|
||||
echo " ok $name\n";
|
||||
} else {
|
||||
$failures++;
|
||||
echo " FAIL $name\n attendu: " . var_export($expected, true)
|
||||
. "\n obtenu : " . var_export($actual, true) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$importer = new Thalim_HAL_Importer_Logic();
|
||||
|
||||
echo "== parse_hal_date (méthode privée, via Reflection) ==\n";
|
||||
$parse = new ReflectionMethod(Thalim_HAL_Importer_Logic::class, 'parse_hal_date');
|
||||
$parse->setAccessible(true);
|
||||
$d = fn(string $raw): string => $parse->invoke($importer, $raw);
|
||||
|
||||
check('date complète', $d('2022-06-15'), '2022-06-15');
|
||||
check('datetime ISO', $d('2022-06-15T10:30:00Z'), '2022-06-15');
|
||||
check('année-mois', $d('2022-06'), '2022-06-01');
|
||||
check('année seule', $d('2022'), '2022-01-01'); // strtotime("2022") = heure, pas année
|
||||
check('chaîne vide', $d(''), '');
|
||||
check('espaces', $d(' 2021 '), '2021-01-01');
|
||||
check('invalide', $d('not-a-date'), '');
|
||||
|
||||
echo "== get_category_id (résolution par slug) ==\n";
|
||||
check('ART → articles (16)', $importer->get_category_id('ART'), 16);
|
||||
check('OUV → ouvrages (15)', $importer->get_category_id('OUV'), 15);
|
||||
check('THESE → soutenances (14)', $importer->get_category_id('THESE'), 14);
|
||||
check('SON → medias (19)', $importer->get_category_id('SON'), 19);
|
||||
check('REPORT → publications (4)',$importer->get_category_id('REPORT'), 4);
|
||||
check('type inconnu → null', $importer->get_category_id('XYZ'), null);
|
||||
|
||||
echo "== Thalim_HAL_Pods_Storage (résolution par nom) ==\n";
|
||||
check('pod post = 8', Thalim_HAL_Pods_Storage::pod_id(), 8);
|
||||
check('champ categorie = 16', Thalim_HAL_Pods_Storage::field_id('categorie'), 16);
|
||||
check('champ membres = 178', Thalim_HAL_Pods_Storage::field_id('membres'), 178);
|
||||
check('champ etiquettes = 652',Thalim_HAL_Pods_Storage::field_id('etiquettes'), 652);
|
||||
check('champ axes = 270', Thalim_HAL_Pods_Storage::field_id('axes_thematiques'), 270);
|
||||
check('champ inconnu = 0', Thalim_HAL_Pods_Storage::field_id('champ_bidon'), 0);
|
||||
|
||||
echo "\n$count tests, $failures échec(s)\n";
|
||||
exit($failures ? 1 : 0);
|
||||
@@ -50,6 +50,7 @@ class Thalim_HAL_Importer {
|
||||
require_once THALIM_HAL_PLUGIN_DIR . 'includes/trait-admin-page-config.php';
|
||||
require_once THALIM_HAL_PLUGIN_DIR . 'includes/trait-admin-page-csv-legacy.php';
|
||||
require_once THALIM_HAL_PLUGIN_DIR . 'includes/class-admin-page.php';
|
||||
require_once THALIM_HAL_PLUGIN_DIR . 'includes/class-pods-storage.php';
|
||||
require_once THALIM_HAL_PLUGIN_DIR . 'includes/class-importer.php';
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user