web-dev-qa-db-fra.com

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

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 pour 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.

7
Scott Anderson

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. Disons que l'ID de cette migration est 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 à l'aide de drush mi example_csv pour 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');
      }
10
Mike Ryan

Il est probablement meilleur et plus rapide à utiliser Feeds , mais puisque la version D8 est encore en 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:

enter image description here

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 modifier le nom de domaine dans myURL = "https://rgr79.ply.st/node/add/article" ligne vers 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)

enter image description here

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

enter image description here

Maintenant dans la barre d'outils, cliquez sur tool puis References

enter image description here

Vous devrez faire défiler, rechercher et cocher

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

enter image description here

Remarque: Je sais que cela fonctionne avec Internet Explorer 11, je ne sais pas si cela 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

enter image description here

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:

enter image description here

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 ne pouvez pas ... vous voyez le bouton de lecture grisé et incapable de modifier le 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).

enter image description here

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 du corps sera comme les autres champs.

enter image description here


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

enter image description here

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
1
No Sssweat

Vous pouvez maintenant utiliser le module d'importation de contenu ( https://www.drupal.org/project/contentimport ). Voici un article sur la façon de l'utiliser: https://www.ostraining.com/blog/drupal/content-import-module/

0

Ce qui précède fonctionne bien pour moi mais la méthode Migratin::Load() et save() n'est pas disponible dans Drupal 8 3.x. J'ai fait quelques changements ci-dessus @Mike Ryan a suggéré le code. Voici le code de travail sur le gestionnaire de somme 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.'));
  }
}
0
Manav