Importieren Sie CSV in Knoten / Entitäten in Drupal 8, einschließlich einer Benutzeroberfläche

7

Was ist die beste Lösung zum Importieren von CSV-Dateien in Knoten oder Entitäten in Drupal 8, die eine Benutzeroberfläche bietet, damit Inhaltseditoren regelmäßig importieren können?

Ich habe gehört, dass D8 Migrate gut funktioniert, aber ich verstehe, dass es derzeit keine Benutzeroberfläche für den Importvorgang gibt.

Der CSV-Import über Feeds scheint noch nicht fertig zu sein.

Scott Anderson
quelle
3
Ich habe einen Basistest mit der neuesten Feeds D8-Version versucht und den Patch auf # 4 von diesem Thread drupal.org/node/2443471#comment-9723715 angewendet, und er scheint korrekt zu funktionieren. Sehen Sie, wie es für komplexere Felder geht.
Scott Anderson
Ich sollte denken, dass Drupal die ganze Zeit WordPress spart oder Drupal sich noch entwickelt.
Vishal Kumar Sahu

Antworten:

10

Ich mache dies die ganze Zeit unter Verwendung von Migrationskonfigurationsentitäten (bereitgestellt vom Modul migrate_plus ). Definieren Sie ein Migrations-Plugin im Konfigurations- / Installationsverzeichnis Ihres Migrationsmoduls mithilfe des CSV-Quell-Plugins aus dem Modul migrate_source_csv. Lassen Sie dabei die Quellkonfiguration 'path' weg , die im Formular ausgefüllt wird. Angenommen, die ID dieser Migration lautet example_csv. Erstellen Sie ein Formular mit einem Datei-Upload-Element (in diesem Fall 'csv_file' genannt) und in der Methode 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.'));
      }
    }
  }

Dadurch werden die Migrationseinstellungen mit der neuen Datei aktualisiert. Sie müssen die Migration noch ausführen drush mi example_csv, um den Inhalt tatsächlich zu importieren.

Oder fügen Sie der Funktion Code hinzu, um den Import tatsächlich auszuführen:

      $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
quelle
1

Es ist wahrscheinlich besser und schneller, Feeds zu verwenden , aber da sich die D8-Version noch in der Entwicklung befindet; Alternativ können Sie Excel + VBA ( Visual Basic für Applikationen , wird mit Excel geliefert) + Internet Explorer 11 verwenden.

Hier ein Beispiel, wie Sie Ihren CSV-Inhalt mit VBA importieren können.

Angenommen, Sie möchten dies importieren und neue Knoten mit den Informationen aus Ihrer CSV erstellen:

Geben Sie hier die Bildbeschreibung ein

Hier ist ein Beispiel für einen VBA-Code:

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

Stellen Sie sicher, dass Sie den Domainnamen myURL = "https://rgr79.ply.st/node/add/article"entsprechend Ihrer Domain ändern . Ich verwende eine simplytest.me- Domain, wenn Sie nicht bereits sagen können.

Wie füge ich den VBA-Code hinzu?

Klicken Sie auf die Registerkarte Entwickler und dann auf das Visual Basic-Symbol (oder ALT + F11).

Geben Sie hier die Bildbeschreibung ein

und fügen Sie den Code in Sheet1 ein (Sheet1)

Geben Sie hier die Bildbeschreibung ein

Klicken Sie nun in der Symbolleiste auf toolund dannReferences

Geben Sie hier die Bildbeschreibung ein

Sie müssen scrollen, suchen und markieren

  • Microsoft HTML-Objektbibliothek
  • Microsoft Internet Controls

Geben Sie hier die Bildbeschreibung ein

Hinweis: Ich weiß, dass es mit Internet Explorer 11 funktioniert, nicht sicher, ob es mit dem neuen Microsoft Edge-Browser funktioniert.

Jetzt können Sie das Skript ausführen. Sie können dies tun, indem Sie auf die Schaltfläche Wiedergabe klicken

Geben Sie hier die Bildbeschreibung ein

Sie können es auch ausführen, indem Sie auf das Makrosymbol klicken (siehe Abbildung 2). Ich bevorzuge es jedoch über das VBA-Fenster.

Sie drücken also die Wiedergabetaste und ein IE-Fenster wird automatisch geöffnet und Sie sehen Folgendes:

Geben Sie hier die Bildbeschreibung ein

Oh ja, du hast vergessen dich einzuloggen, lol.

Sie melden sich also bei Drupal an und schließen dann den Explorer (da der Cookie-Verlauf Ihr Login speichert) und planen, erneut auf die Wiedergabetaste zu klicken. Aber Sie sind nicht in der Lage ... Sie sehen die Wiedergabetaste ausgegraut und können keine Änderungen am VBA-Code vornehmen ... Was ist los?

Nun, Ihr Code läuft noch, also müssen Sie die Stopp-Taste (Zurücksetzen) drücken.

Geben Sie hier die Bildbeschreibung ein

Jetzt können Sie erneut auf die Wiedergabetaste klicken und die Welt der Automatisierung genießen.

Wichtig

Wenn Sie vorhaben, Inhalte in das Body-Feld einzufügen (wie in diesem Beispiel), können wir keine div-Klasse oder ID als Ziel festlegen, da Drupal 8 CKEditor für dieses Feld verwendet und CKEditor JS ist. Daher können wir keine Inhalte in CKEditor hinzufügen.

Zum Glück gibt es eine Lösung. Stellen Sie sicher, dass Ihre IE 11-Sicherheitseinstellungen auf Hoch eingestellt sind. Dadurch werden automatisch alle JS blockiert. Daher wird CKeditor nicht geladen und das Body-Feld ist genau wie die anderen Felder.

Geben Sie hier die Bildbeschreibung ein


Wenn Sie Knoten bearbeiten müssen Beispiel:

Geben Sie hier die Bildbeschreibung ein

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
Kein Sssweat
quelle
Danke ... das ist eine interessante Option. Ich denke, ich brauche eine einfachere Lösung aus Sicht der Benutzeroberfläche.
Scott Anderson
2
Funktioniert nicht, wenn Benutzer keinen IE haben und unnötig komplex erscheinen. Ich denke, der richtige Weg wäre ein benutzerdefiniertes Bestätigungsformular für Administratoren, ein Batch-Op und ein Migrationsprozess ... @mikeryan wäre die Person, die gefragt werden muss.
Kevin
Du bist ein Mörder.
Vishal Kumar Sahu
0

Das obige funktioniert gut für mich, aber Migratin::Load()und save()Methode ist in Drupal 8 3.x nicht verfügbar. Ich habe einige Änderungen an dem von @Mike Ryan vorgeschlagenen Code vorgenommen. Hier ist der Arbeitscode für den Formular-Sumbit-Handler.

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
quelle