Importer CSV dans des nœuds / entités dans Drupal 8, y compris une interface utilisateur

7

Quelle est la meilleure solution pour importer des fichiers CSV dans des nœuds ou des entités dans Drupal 8 qui offre une interface utilisateur afin que les éditeurs de contenu puissent importer régulièrement?

J'ai entendu dire que D8 Migrate fonctionnait bien, mais je comprends qu'il n'y a actuellement aucune interface utilisateur pour le processus d'importation.

L'importation CSV via les flux ne semble pas encore prête.

Scott Anderson
la source
3
J'ai essayé un test de base en utilisant la dernière version de Feeds D8 et en appliquant le correctif # 4 à partir de ce fil drupal.org/node/2443471#comment-9723715 et il semble fonctionner correctement. Découvrez comment cela se passe pour des domaines plus complexes.
Scott Anderson
Je devrais penser que Drupal enregistre tout le temps wordpress ou Drupal est toujours en développement.
Vishal Kumar Sahu

Réponses:

10

Je le fais tout le temps, en utilisant des entités de configuration de migration (fournies par le module migrate_plus ). Définissez un plugin de migration dans le répertoire config / install de votre module de migration, en utilisant le plugin source CSV du module migrate_source_csv - en omettant la configuration source 'path', qui sera remplie à partir du formulaire. Supposons que l'ID de cette migration soit example_csv. Créez un formulaire avec un élément de téléchargement de fichier (nommé 'csv_file' dans ce cas), et dans la méthode submitForm ():

  public function submitForm(array &$form, FormStateInterface $form_state) {
    $all_files = $this->getRequest()->files->get('files', []);
    if (!empty($all_files['csv_file'])) {
      $validators = ['file_validate_extensions' => ['csv']];
      if ($file = file_save_upload('csv_file', $validators, 'public://', 0)) {
        $csv_migration = Migration::load('example_csv');
        $source = $csv_migration->get('source');
        $source['path'] = $file->getFileUri();
        $csv_migration->set('source', $source);
        $csv_migration->save();
        drupal_set_message($this->t('File uploaded as @uri.', ['@uri' => $file->getFileUri()]));
      }
      else {
        drupal_set_message($this->t('File upload failed.'));
      }
    }
  }

Cela met à jour les paramètres de migration avec le nouveau fichier. Vous devez toujours exécuter la migration en utilisant drush mi example_csvpour importer réellement le contenu.

Ou ajoutez du code à la fonction pour exécuter réellement l'importation:

      $migration_instance = \Drupal::service('plugin.manager.migration')->createInstance('example_csv');

      $executable = new MigrateExecutable($migration_instance, new MigrateMessage());

      try {
        $migration_status = $executable->import();
      }
      catch (\Exception $e) {
        \Drupal::logger('migrate_drupal_ui')->error($e->getMessage());
        $migration_status = MigrationInterface::RESULT_FAILED;
      }
      if ($migration_status) {
        drupal_set_message($this->t('Import Successful'));
      }
      else {
        drupal_set_message($migration_status, 'error');
      }
Mike Ryan
la source
1

Il est probablement meilleur et plus rapide d'utiliser les flux , mais puisque la version D8 est toujours en cours de développement; vous pouvez également utiliser Excel + VBA ( Visual Basic pour Applications , fourni avec Excel) + Internet Explorer 11.

Voici un exemple de la façon dont vous pouvez importer votre contenu CSV à l'aide de VBA.

Par exemple, supposons que vous souhaitiez l'importer et créer de nouveaux nœuds avec les informations de votre CSV:

entrez la description de l'image ici

Voici un exemple de code VBA:

Sub Drupal_Import()

Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")

Dim x As Integer

For x = 2 To 4 'this controls which rows get added, so only 2 to 4

myURL = "https://rgr79.ply.st/node/add/article"

With IE
.Visible = True 'makes your Internet Explorer window visible.
.navigate myURL
End With

Do
el = vbNullString
On Error Resume Next
Set HTML = IE.document
el = HTML.getElementsByClassName("visually-hidden")(1).innerText
DoEvents
Loop While el = vbNullString

'the above loops until the visualy-hidden class is detected, which means the edit form has been loaded

Application.Wait (Now + TimeValue("00:00:03")) 'tells the program to wait 3 secs.

Set HTML = IE.document

HTML.getElementById("edit-title-0-value").Value = Cells(x, 1).Value 'here the 1 is the Y (so 1 is Column A)

HTML.getElementById("edit-body-0-value").Value = Cells(x, 2).Value 'here the 2 is the Y (so 2 is Column B)

Cells(x, 3).Value = "Done" 'here we use the 3rd column (Column C) and mark it as Done to keep track.

HTML.getElementsByClassName("button js-form-submit form-submit")(1).Click 'clicks the submit button

Application.Wait (Now + TimeValue("00:00:00")) 'here I have a wait for 0, increase it to 2 or 3 if you see your VBA get stuck after submitting a node.

Do
el = vbNullString
On Error Resume Next
Set HTML = IE.document
el = HTML.getElementsByClassName("messages messages--status")(0).innerText
DoEvents
Loop While el = vbNullString

'all the above does is loops the code until the drupal message is detected, which means the node was loaded, after the submit.

Next x

End Sub

Assurez-vous de changer le nom de domaine en myURL = "https://rgr79.ply.st/node/add/article"ligne pour votre domaine. J'utilise un domaine Simplytest.me , si vous ne le savez pas déjà.

Comment ajouter le code VBA?

Cliquez sur l'onglet Développeur puis sur l'icône Visual Basic (ou ALT + F11)

entrez la description de l'image ici

et collez le code à l'intérieur de Sheet1 (Sheet1)

entrez la description de l'image ici

Maintenant, dans la barre d'outils, cliquez sur toolpuis surReferences

entrez la description de l'image ici

Vous devrez faire défiler, rechercher et cocher

  • Bibliothèque d'objets Microsoft HTML
  • Contrôles Internet de Microsoft

entrez la description de l'image ici

Remarque: je sais que cela fonctionne avec Internet Explorer 11, je ne sais pas s'il fonctionne avec le nouveau navigateur Microsoft Edge.

Vous êtes maintenant prêt à exécuter le script. Vous pouvez le faire en cliquant sur le bouton Lecture

entrez la description de l'image ici

Vous pouvez également l'exécuter en cliquant sur l'icône Macros (voir image2), mais je préfère le faire à partir de la fenêtre VBA.

Donc, vous appuyez sur le bouton de lecture et une fenêtre IE s'ouvre automatiquement et vous voyez ceci:

entrez la description de l'image ici

Oh oui, vous avez oublié de vous connecter, lol.

Vous vous connectez donc à Drupal, puis vous fermez l'explorateur (car l'historique des cookies enregistre votre connexion) et vous prévoyez d'appuyer à nouveau sur le bouton de lecture. Mais vous n'êtes pas en mesure de ... vous voyez le bouton de lecture grisé et vous ne pouvez pas apporter de modifications au code VBA ... Que se passe-t-il?

Eh bien, votre code est toujours en cours d'exécution, vous devez donc appuyer sur le bouton Arrêter (réinitialiser).

entrez la description de l'image ici

Vous pouvez maintenant cliquer à nouveau sur le bouton de lecture et profiter du monde de l'automatisation.

Important

Si vous prévoyez d'insérer des éléments dans le champ Body (comme nous le faisons dans cet exemple), puisque Drupal 8 utilise CKEditor pour ce champ et CKEditor est JS, nous ne pouvons pas cibler une classe div ou un ID; ainsi, nous ne pouvons pas ajouter de contenu à l'intérieur de CKEditor.

Heureusement, il existe un travail autour. Assurez-vous que vos paramètres de sécurité IE 11 sont définis sur Élevé, cela bloquera automatiquement tous les JS. Par conséquent, CKeditor ne se chargera pas et le champ body sera comme les autres champs.

entrez la description de l'image ici


Si vous devez modifier l'exemple de nœuds:

entrez la description de l'image ici

Sub Drupal_Edit()

Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")

Dim x As Integer

For x = 2 To 4 'this controls which rows get added, so only 2 to 4

myURL = "https://rgr79.ply.st/node/" & Cells(x, 3) & "/edit"

With IE
.Visible = True 'makes your Internet Explorer window visible.
.navigate myURL
End With

Do
el = vbNullString
On Error Resume Next
Set HTML = IE.document
el = HTML.getElementsByClassName("visually-hidden")(1).innerText
DoEvents
Loop While el = vbNullString

'the above loops until the visualy-hidden class is detected, which means the edit form has been loaded

Application.Wait (Now + TimeValue("00:00:04")) 'tells the program to wait 3 secs.

Set HTML = IE.document

HTML.getElementById("edit-title-0-value").Value = Cells(x, 1).Value 'here the 1 is the Y (so 1 is Column A)

HTML.getElementById("edit-body-0-value").Value = Cells(x, 2).Value 'here the 2 is the Y (so 2 is Column B)

Cells(x, 4).Value = "Done" 'here we use the 4th column (Column D) and mark it as Done to keep track.

HTML.getElementsByClassName("button js-form-submit form-submit")(1).Click 'clicks the submit button

Application.Wait (Now + TimeValue("00:00:00")) 'here I have a wait for 0, increase it to 2 or 3 if you see your VBA get stuck after submitting a node.

Do
el = vbNullString
On Error Resume Next
Set HTML = IE.document
el = HTML.getElementsByClassName("messages messages--status")(0).innerText
DoEvents
Loop While el = vbNullString

'all the above does is loops the code until the drupal message is detected, which means the node was loaded, after the submit.

Next x

End Sub
Pas de sueur
la source
Merci ... c'est une option intéressante. Je pense que j'aurai besoin d'une solution plus simple du point de vue de l'interface utilisateur.
Scott Anderson
2
Ne fonctionnera pas si les utilisateurs ne disposent pas d'IE et semble inutilement complexe. Je pense que la voie à suivre serait un formulaire de confirmation administrateur personnalisé, une opération par lots et un processus de migration ... @mikeryan serait la personne à demander.
Kevin
Tu es un tueur.
Vishal Kumar Sahu
0

Ce qui précède fonctionne très bien pour moi , mais Migratin::Load()et save()méthode n'est pas disponible dans Drupal 8 3.x. J'ai fait quelques changements dans le code suggéré par @Mike Ryan ci-dessus. Voici le code de travail sur le gestionnaire de sumbit de formulaire.

public function submitForm(array &$form, FormStateInterface $form_state) {
$all_files = $form_state->getValue('csv_file');
if (!empty($all_files)) {
  $file = file_load($all_files[0]);
  if (!empty($file)) {
    $csv_migration = \Drupal::service('plugin.manager.migration')->createInstance('panalist_migration');
    $source = $csv_migration->get('source');
    $source['path'] = $file->getFileUri();
    $csv_migration->set('source', $source);
    drupal_set_message($this->t('File uploaded as @uri.', ['@uri' => $file->getFileUri()]));
    $executable = new MigrateExecutable($csv_migration, new MigrateMessage());

    try {
      $migration_status = $executable->import();
    }
    catch (\Exception $e) {
      \Drupal::logger('migrate_drupal_ui')->error($e->getMessage());
      $migration_status = MigrationInterface::RESULT_FAILED;
    }
    if ($migration_status) {
      drupal_set_message($this->t('Import Successful'));
    }
    else {
      drupal_set_message($migration_status, 'error');
    }
  }
  else {
    drupal_set_message($this->t('File upload failed.'));
  }
}
Manav
la source