web-dev-qa-db-ja.com

Drupal 8のノード/エンティティにCSVをインポートし、UIを含む)

コンテンツエディターが定期的にインポートできるようにUIを提供するDrupal 8のノードまたはエンティティにCSVファイルをインポートするための最良のソリューションは何ですか?

D8 Migrateが適切に機能すると聞きましたが、現時点ではインポートプロセス用のUIがないことを理解しています。

フィードによるCSVインポートはまだ準備ができていないようです。

7
Scott Anderson

私はこれを常に行い、( migrate_plus module によって提供される)移行構成エンティティを利用します。 migrate_source_csv module のCSVソースプラグインを使用して、移行モジュールのconfig/installディレクトリに移行プラグインを定義します。フォームから入力される「パス」ソース設定を省略します。この移行のIDがexample_csvであるとしましょう。ファイルアップロード要素(この場合は「csv_file」という名前)と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.'));
      }
    }
  }

これにより、移行設定が新しいファイルで更新されます。コンテンツを実際にインポートするには、drush mi example_csvを使用して移行を実行する必要があります。

または、実際にインポートを実行するために 関数にコード を追加します。

      $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

おそらく Feeds を使用する方がより速く、より高速ですが、D8バージョンはまだ開発中です。または、Excel + VBA(Visual Basic for Applications、Excelに付属)+ Internet Explorer 11を使用することもできます。

ここでは、VBAを使用してCSVコンテンツをインポートする方法の例を示します。

たとえば、これをインポートして、CSVからの情報で新しいノードを作成するとします。

enter image description here

次に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

myURL = "https://rgr79.ply.st/node/add/article"行のドメイン名を自分のドメインに変更してください。 simplytest.me ドメインを使用しています。

VBAコードを追加する方法

(開発)タブをクリックしてから、Visual Basicアイコン(またはAlt + F11)をクリックします

enter image description here

そしてSheet1(Sheet1)の中にコードを貼り付けます

enter image description here

次に、ツールバーでtoolをクリックし、次にReferencesをクリックします。

enter image description here

スクロール、検索、チェックマークを付ける必要があります

  • Microsoft HTMLオブジェクトライブラリ
  • Microsoftインターネットコントロール

enter image description here

注:Internet Explorer 11で動作することはわかっていますが、新しいMicrosoft Edgeブラウザで動作するかどうかはわかりません。

これで、スクリプトを実行する準備ができました。再生ボタンをクリックすることでそれを行うことができます

enter image description here

マクロアイコン(画像2を参照)をクリックして実行することもできますが、VBAウィンドウから実行することをお勧めします。

再生ボタンを押すと、IEウィンドウが自動的に開き、次のように表示されます。

enter image description here

ああ、あなたはログインするのを忘れました、笑。

Drupalへのログインに進み、次にCookieの履歴によりログインが保存されるため)Explorerを閉じ、もう一度再生ボタンを押すことを計画します。ただし、次のことはできません...再生ボタンがグレー表示になり、VBAコードに変更を加えることができません...何が起こっているのですか?

さて、コードはまだ実行中であるため、停止(リセット)ボタンを押す必要があります。

enter image description here

これで、もう一度再生ボタンをクリックして、自動化の世界を楽しむことができます。

重要

(この例で行っているように)Bodyフィールドにデータを挿入する予定の場合、Drupal 8はこのフィールドにCKEditorを使用し、CKEditorはJSであるため、divクラスまたはIDをターゲットにすることはできません。 ;したがって、CKEditor内にコンテンツを追加することはできません。

幸い、回避策があります。 IE 11セキュリティ設定が高に設定されていることを確認してください。これにより、すべてのJSが自動的にブロックされます。そのため、CKeditorは読み込まれず、本文フィールドは他のフィールドと同じになります。

enter image description here


ノードの例を編集する必要がある場合:

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

これで、コンテンツインポートモジュール( https://www.drupal.org/project/contentimport )を使用できます。それを使用する方法についての投稿はこちらです: https://www.ostraining.com/blog/drupal/content-import-module/

0

上記は私にとってはうまく機能していますが、Migratin::Load()およびsave()メソッドはDrupal 8 3.xでは使用できません。上記でいくつかの変更を行いました@Mike Ryanが提案したコード。これは、フォームサビットハンドラーの作業コードです。

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