Verified Commit 4ec07d68 authored by Dave Long's avatar Dave Long
Browse files

Issue #3365895 by danflanagan8, benjifisher, mikelutz: When sub_process...

Issue #3365895 by danflanagan8, benjifisher, mikelutz: When sub_process encounters a row skip, it should skip its internal row, and not bubble up to the outer row
parent 91a743c1
Loading
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
namespace Drupal\migrate\Plugin\migrate\process;

use Drupal\migrate\MigrateException;
use Drupal\migrate\MigrateSkipRowException;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Row;
@@ -208,7 +209,12 @@ public function transform($value, MigrateExecutableInterface $migrate_executable
          throw new MigrateException(sprintf("Input array should hold elements of type array, instead element was of type '%s'", gettype($new_value)));
        }
        $new_row = new Row($new_value + $source);
        try {
          $migrate_executable->processRow($new_row, $this->configuration['process']);
        }
        catch (MigrateSkipRowException $e) {
          continue;
        }
        $destination = $new_row->getDestination();
        if (array_key_exists('key', $this->configuration)) {
          $key = $this->transformKey($key, $migrate_executable, $new_row);
+144 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Tests\migrate\Kernel\process;

use Drupal\KernelTests\KernelTestBase;
use Drupal\migrate\MigrateExecutable;
use Drupal\migrate\Plugin\MigrationInterface;

/**
 * Tests process pipelines when a sub_process skips a row or process.
 *
 * @group migrate
 */
class SubProcessWithSkipTest extends KernelTestBase {

  /**
   * {@inheritdoc}
   */
  protected static $modules = ['migrate'];

  /**
   * Provides the test migration definition.
   *
   * @return array
   */
  public function getDefinition() {
    return [
      'source' => [
        'plugin' => 'embedded_data',
        'data_rows' => [
          [
            'id' => 'skip_test',
            'my_array_of_arrays' => [
              [
                'key_1' => 'foo',
                'key_2' => 'bar',
              ],
              [
                'key_1' => NULL,
                'key_2' => 'baz',
              ],
            ],
          ],
        ],
        'ids' => [
          'id' => ['type' => 'string'],
        ],
      ],
      'process' => [
        'first' => [
          'plugin' => 'default_value',
          'default_value' => 'something outside of sub_process',
        ],
        'second' => [
          'plugin' => 'sub_process',
          'source' => 'my_array_of_arrays',
          'process' => [
            'prop_1' => [
              [
                'plugin' => 'skip_on_empty',
                'source' => 'key_1',
              ],
              // We put a process after skip_on_empty to better test skipping
              // a process.
              [
                'plugin' => 'get',
                'source' => 'key_2',
              ],
            ],
            'prop_2' => 'key_2',
          ],
        ],
      ],
      'destination' => [
        'plugin' => 'config',
        'config_name' => 'migrate_test.settings',
      ],
    ];
  }

  /**
   * Test use of skip_on_empty within sub_process.
   *
   * @dataProvider providerTestSubProcessSkip
   *
   * @param string $method
   *   The method to use with skip_on_empty (row or process).
   * @param array $expected_data
   *   The expected result of the migration.
   */
  public function testSubProcessSkip(string $method, array $expected_data): void {
    $definition = $this->getDefinition();
    $definition['process']['second']['process']['prop_1'][0]['method'] = $method;

    $migration = \Drupal::service('plugin.manager.migration')->createStubMigration($definition);

    $executable = new MigrateExecutable($migration);
    $result = $executable->import();

    // Migration needs to succeed before further assertions are made.
    $this->assertSame(MigrationInterface::RESULT_COMPLETED, $result);

    // Compare with expected data.
    $this->assertEquals($expected_data, \Drupal::config('migrate_test.settings')->get());
  }

  /**
   * Data provider for testNotFoundSubProcess().
   *
   * @return array
   */
  public function providerTestSubProcessSkip(): array {
    return [
      'skip row' => [
        'method' => 'row',
        'expected' => [
          'first' => 'something outside of sub_process',
          'second' => [
            [
              'prop_1' => 'bar',
              'prop_2' => 'bar',
            ],
          ],
        ],
      ],
      'skip process' => [
        'method' => 'process',
        'expected' => [
          'first' => 'something outside of sub_process',
          'second' => [
            [
              'prop_1' => 'bar',
              'prop_2' => 'bar',
            ],
            [
              'prop_2' => 'baz',
            ],
          ],
        ],
      ],
    ];
  }

}