added 'invité/accompagné/curaté par' field to migration, with CT personne node creation

This commit is contained in:
2026-07-11 16:06:12 +02:00
parent ec5b13be3c
commit a2a0e423a3
4 changed files with 158 additions and 3 deletions
@@ -0,0 +1,123 @@
<?php
declare(strict_types=1);
namespace Drupal\migrate_leshed\Plugin\migrate\process;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\migrate\Attribute\MigrateProcess;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Finds or creates 'personne' nodes from a list of names.
*
* Input: a string such as "Julie Faitot et Jonathan Loppin" or
* "Sonja Beaudouin, Alexandre Delabrière". Names are split on "et" and
* commas. For each name, the first word is used as 'field_prenom' and the
* rest as the node title. An existing node with the same title and prenom
* is reused, otherwise it is created. Returns an array of node IDs.
*/
#[MigrateProcess(id: 'personne_generate', handle_multiples: TRUE)]
final class PersonneGenerate extends ProcessPluginBase implements ContainerFactoryPluginInterface {
/**
* Placeholder values that must not create a personne node.
*/
private const IGNORED_VALUES = ['/', '?', '-'];
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
private readonly EntityTypeManagerInterface $entityTypeManager,
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): self {
return new self(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('entity_type.manager'),
);
}
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property): array {
if (!is_string($value) || trim($value) === '') {
return [];
}
// Ignore everything after "avec" (e.g. "Camille Bondon avec les élèves
// de l'école André Marie" only keeps "Camille Bondon").
$value = preg_replace('/\s+avec\s+.*$/us', '', $value);
// Normalize separators: " et " becomes a comma.
$value = preg_replace('/\s+et\s+/u', ',', $value);
$names = array_filter(array_map('trim', explode(',', $value)));
$nids = [];
foreach ($names as $name) {
if (in_array($name, self::IGNORED_VALUES, TRUE)) {
continue;
}
// First word is the first name, the rest is the last name.
$parts = preg_split('/\s+/u', $name, 2);
$prenom = $parts[0];
$nom = $parts[1] ?? '';
// Single-word name: use it as the title, without a first name.
if ($nom === '') {
$nom = $prenom;
$prenom = '';
}
$nids[] = $this->getOrCreatePersonne($nom, $prenom);
}
return $nids;
}
/**
* Returns the nid of the matching personne node, creating it if needed.
*/
private function getOrCreatePersonne(string $nom, string $prenom): int {
$storage = $this->entityTypeManager->getStorage('node');
$query = $storage->getQuery()
->condition('type', 'personne')
->condition('title', $nom)
->accessCheck(FALSE)
->range(0, 1);
if ($prenom !== '') {
$query->condition('field_prenom', $prenom);
}
else {
$query->notExists('field_prenom');
}
$ids = $query->execute();
if ($ids) {
return (int) reset($ids);
}
$node = $storage->create([
'type' => 'personne',
'title' => $nom,
'field_prenom' => $prenom === '' ? NULL : $prenom,
'status' => 1,
'uid' => $this->configuration['author_uid'] ?? 3,
]);
$node->save();
return (int) $node->id();
}
}
@@ -25,7 +25,9 @@ final class ProjetNode extends Url {
'id' => $this->t('Project ID'),
'title' => $this->t('Project Title'),
'date_start' => $this->t('Project date start'),
'date_end' => $this->t('Project date end')
'date_end' => $this->t('Project date end'),
'projet_type' => $this->t('Type de projet'),
'curator' => $this->t('Commissaria')
];
}