Importa CSV in nodi / entità in Drupal 8 inclusa un'interfaccia utente


7

Qual è la soluzione migliore per importare file CSV in nodi o entità in Drupal 8 che offre un'interfaccia utente in modo che gli editor di contenuti possano importare regolarmente?

Ho sentito che D8 Migrate funziona bene ma capisco che al momento non esiste un'interfaccia utente per il processo di importazione.

L'importazione CSV tramite feed non sembra essere ancora pronta.


3
Ho provato un test di base usando l'ultima versione di Feeds D8 e applicando la patch al numero 4 da questa discussione drupal.org/node/2443471#comment-9723715 e sembra funzionare correttamente. Guarda come va per i campi più complessi.
Scott Anderson,

Dovrei pensare che Drupal stia sempre salvando wordpress o che Drupal stia ancora sviluppando.
Vishal Kumar Sahu,

Risposte:


10

Lo faccio sempre, facendo uso di entità di configurazione della migrazione (fornite dal modulo migrate_plus ). Definire un plug-in di migrazione nella directory config / install del modulo di migrazione, utilizzando il plug-in di origine CSV dal modulo migrate_source_csv , omettendo la configurazione di origine "percorso", che verrà compilata dal modulo. Supponiamo che l'ID di questa migrazione sia example_csv. Creare un modulo con un elemento di caricamento file (in questo caso denominato "csv_file") e nel metodo 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.'));
      }
    }
  }

Ciò aggiorna le impostazioni di migrazione con il nuovo file. Devi ancora eseguire la migrazione usando drush mi example_csvper importare effettivamente il contenuto.

Oppure aggiungi del codice alla funzione per eseguire effettivamente l'importazione:

      $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');
      }

1

Probabilmente è meglio e più veloce usare Feed , ma poiché la versione D8 è ancora in fase di sviluppo; in alternativa, è possibile utilizzare Excel + VBA ( Visual Basic , Applications Edition , viene fornito con Excel) + Internet Explorer 11.

Ecco un esempio di come importare i tuoi contenuti CSV usando VBA.

Ad esempio, supponiamo che tu voglia importare questo e creare nuovi nodi con le informazioni dal tuo CSV:

inserisci qui la descrizione dell'immagine

Ecco un esempio di codice 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

Assicurati di cambiare il nome di dominio in myURL = "https://rgr79.ply.st/node/add/article"linea con il tuo dominio. Sto usando un dominio simplytest.me , se non puoi già dirlo.

Come aggiungere il codice VBA?

Fare clic sulla scheda Sviluppatore e quindi sull'icona Visual Basic (o ALT + F11)

inserisci qui la descrizione dell'immagine

e incolla il codice all'interno di Sheet1 (Sheet1)

inserisci qui la descrizione dell'immagine

Ora nella barra degli strumenti, fai clic su toole quindiReferences

inserisci qui la descrizione dell'immagine

Dovrai scorrere, trovare e selezionare

  • Libreria di oggetti HTML Microsoft
  • Controlli Internet di Microsoft

inserisci qui la descrizione dell'immagine

Nota: so che funziona con Internet Explorer 11, non sono sicuro che funzioni con il nuovo browser Microsoft Edge.

Ora sei pronto per eseguire lo script. Puoi farlo facendo clic sul pulsante Riproduci

inserisci qui la descrizione dell'immagine

Puoi anche eseguirlo facendo clic sull'icona Macro (vedi immagine2), ma preferisco farlo dalla finestra VBA.

Quindi premi il pulsante di riproduzione e una finestra di IE si apre automaticamente e vedi questo:

inserisci qui la descrizione dell'immagine

Oh sì, hai dimenticato di accedere, lol.

Quindi procedi al login su Drupal e poi chiudi explorer (poiché la cronologia dei cookie salva il tuo login) e pensi di premere nuovamente il pulsante di riproduzione. Ma non sei in grado di ... vedi il pulsante di riproduzione disattivato e non puoi apportare modifiche al codice VBA ... Cosa sta succedendo?

Bene, il tuo codice è ancora in esecuzione, quindi devi premere il pulsante Stop (reset).

inserisci qui la descrizione dell'immagine

Ora puoi fare nuovamente clic sul pulsante di riproduzione e rallegrare il mondo dell'automazione.

Importante

Se hai intenzione di inserire elementi nel campo Body (come stiamo facendo in questo esempio), poiché Drupal 8 utilizza CKEditor per questo campo e CKEditor è JS, non possiamo scegliere come target una classe div o un ID; pertanto, non possiamo aggiungere contenuti all'interno di CKEditor.

Fortunatamente, c'è un lavoro in giro. Assicurati che le impostazioni di sicurezza di IE 11 siano impostate su Alta, questo bloccherà automaticamente tutto JS. Pertanto, CKeditor non verrà caricato e il campo del corpo sarà proprio come gli altri campi.

inserisci qui la descrizione dell'immagine


Se è necessario modificare un esempio di nodi:

inserisci qui la descrizione dell'immagine

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

Grazie ... è un'opzione interessante. Penso che avrò bisogno di una soluzione più semplice dal punto di vista dell'interfaccia utente.
Scott Anderson,

2
Non funzionerà se gli utenti non hanno IE e sembrano inutilmente complessi. Penso che la strada da percorrere sarebbe un modulo di conferma dell'amministratore personalizzato, un batch op e il processo di migrazione ... @mikeryan sarebbe la persona a cui chiedere.
Kevin,

Sei un assassino.
Vishal Kumar Sahu,

0

Quanto sopra funziona bene per me ma Migratin::Load()e il save()metodo non è disponibile in Drupal 8 3.x. Ho apportato alcune modifiche al codice suggerito sopra @Mike Ryan. Ecco il codice di lavoro sul gestore del modulo sumbit.

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.'));
  }
}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.