Импорт CSV в узлы / объекты в Drupal 8, включая пользовательский интерфейс

7

Какое лучшее решение для импорта файлов CSV в узлы или объекты в Drupal 8, которое предлагает пользовательский интерфейс, чтобы редакторы контента могли регулярно импортировать?

Я слышал, что D8 Migrate работает хорошо, но я понимаю, что в настоящее время нет интерфейса для процесса импорта.

Импорт CSV через каналы пока не готов.

Скотт Андерсон
источник
3
Я попробовал базовый тест, используя последнюю версию Feeds D8 и применив патч к # 4 из этой ветки drupal.org/node/2443471#comment-9723715, и он, кажется, работает правильно. Посмотрите, как это происходит для более сложных полей.
Скотт Андерсон
Я должен думать, что Drupal все время сохраняет WordPress или Drupal все еще развивается.
Вишал Кумар Саху

Ответы:

10

Я делаю это все время, используя объекты конфигурации миграции (предоставляемые модулем migrate_plus ). Определите подключаемый модуль миграции в каталоге config / install вашего модуля миграции, используя исходный подключаемый модуль CSV из модуля migrate_source_csv, не указав исходную конфигурацию path, которая будет заполнена в форме. Допустим, идентификатор этой миграции - 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');
      }
Майк Райан
источник
1

Возможно, лучше и быстрее использовать Feeds , но так как версия D8 все еще находится в разработке; В качестве альтернативы вы можете использовать Excel + VBA ( Visual Basic для приложений , поставляется с Excel) + Internet Explorer 11.

Вот пример того, как вы можете импортировать ваш CSV-контент, используя VBA.

Например, предположим, что вы хотите импортировать это и создать новые узлы с информацией из вашего CSV:

введите описание изображения здесь

Вот пример кода 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"соответствии с вашим доменом. Я использую домен simpletest.me , если вы уже не можете сказать.

Как добавить код VBA?

Перейдите на вкладку «Разработчик», а затем на значок Visual Basic (или ALT + F11).

введите описание изображения здесь

и вставьте код внутри Sheet1 (Sheet1)

введите описание изображения здесь

Теперь на панели инструментов нажмите toolи затемReferences

введите описание изображения здесь

Вам нужно будет прокрутить, найти и поставить галочку

  • Microsoft HTML Object Library
  • Microsoft Internet Controls

введите описание изображения здесь

Примечание. Я знаю, что он работает с Internet Explorer 11, но не уверен, что он работает с новым браузером Microsoft Edge.

Теперь вы готовы запустить скрипт. Вы можете сделать это, нажав кнопку Play

введите описание изображения здесь

Вы также можете запустить его, щелкнув значок макроса (см. Изображение 2), но я предпочитаю делать это из окна VBA.

Итак, вы нажимаете кнопку воспроизведения, и автоматически открывается окно IE, и вы видите это:

введите описание изображения здесь

Ах, да, ты забыл войти, лол.

Итак, вы переходите к входу в Drupal, а затем закрываете проводник (поскольку история файлов cookie сохраняет ваш логин) и планируете снова нажать кнопку воспроизведения. Но вы не можете ... вы видите, что кнопка воспроизведения неактивна и не можете вносить какие-либо изменения в код VBA ... Что происходит?

Ваш код все еще работает, поэтому вам нужно нажать кнопку Стоп (сброс).

введите описание изображения здесь

Теперь вы можете снова нажать кнопку воспроизведения и порадоваться миру автоматизации.

Важный

Если вы планируете вставить материал в поле Body (как мы делаем в этом примере), так как Drupal 8 использует CKEditor для этого поля, а CKEditor - JS, мы не можем нацеливаться на класс или идентификатор div; таким образом, мы не можем добавлять контент внутри CKEditor.

К счастью, есть обходной путь. Убедитесь, что в настройках IE 11 Security установлено значение High, это автоматически заблокирует все JS. Следовательно, CKeditor не будет загружаться, и поле body будет таким же, как и другие поля.

введите описание изображения здесь


Если вам нужно отредактировать пример узла:

введите описание изображения здесь

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
Нет Sssweat
источник
Спасибо ... это интересный вариант. Думаю, мне понадобится более простое решение с точки зрения пользовательского интерфейса.
Скотт Андерсон
2
Не будет работать, если пользователи не имеют IE и кажутся излишне сложными. Я думаю, что путь - это пользовательская форма подтверждения администратора, пакетная операция и процесс переноса ... @mikeryan - тот, кого можно спросить.
Кевин
Вы убийца.
Вишал Кумар Саху
0

Выше работает нормально для меня , но Migratin::Load()и save()метод не доступен в Drupal 8 3.x. Я сделал некоторые изменения в приведенном выше коде, предложенном Майком Райаном. Вот рабочий код для обработчика формы 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.'));
  }
}
Manav
источник