Commit 93533acf authored by Youri van Koppen's avatar Youri van Koppen
Browse files

Issue #3263399 by MegaChriz, loopy1492: Fixed "New Source" option gone when...

Issue #3263399 by MegaChriz, loopy1492: Fixed "New Source" option gone when using a parser that does not extend ParserBase.
parent 9c61031d
Loading
Loading
Loading
Loading
+7 −0
Changes for feeds.install: 7 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -97,3 +97,10 @@ function feeds_update_8003() {
    $schema->addPrimaryKey('feeds_clean_list', ['feed_id', 'entity_id']);
  }
}

/**
 * Flush all caches to make plugin type "FeedsCustomSource" available.
 */
function feeds_update_8004() {
  drupal_flush_all_caches();
}
+2 −89
Changes for src/Feeds/Parser/ParserBase.php: 2 added lines, 89 removed lines.
Original line number Diff line number Diff line
@@ -2,55 +2,15 @@

namespace Drupal\feeds\Feeds\Parser;

use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\Element;
use Drupal\feeds\Plugin\Type\MappingPluginFormInterface;
use Drupal\feeds\Plugin\Type\Parser\ParserInterface;
use Drupal\feeds\Plugin\Type\PluginBase;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Base class for Feeds parsers.
 */
abstract class ParserBase extends PluginBase implements ParserInterface, MappingPluginFormInterface, ContainerFactoryPluginInterface {

  /**
   * The custom source plugin manager.
   *
   * @var \Drupal\Component\Plugin\PluginManagerInterface
   */
  protected $customSourcePluginManager;

  /**
   * Constructs a new ParserBase object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param array $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Component\Plugin\PluginManagerInterface $custom_source_plugin_manager
   *   The custom source plugin manager.
   */
  public function __construct(array $configuration, $plugin_id, array $plugin_definition, PluginManagerInterface $custom_source_plugin_manager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->customSourcePluginManager = $custom_source_plugin_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('plugin.manager.feeds.custom_source')
    );
  }
abstract class ParserBase extends PluginBase implements ParserInterface, MappingPluginFormInterface {

  /**
   * Returns the label for single source.
@@ -75,22 +35,7 @@ abstract class ParserBase extends PluginBase implements ParserInterface, Mapping
  /**
   * {@inheritdoc}
   */
  public function mappingFormAlter(array &$form, FormStateInterface $form_state) {
    // Add the appropriate new custom source options to the select source
    // dropdown.
    foreach (Element::children($form['mappings']) as $i) {
      if (!isset($form['mappings'][$i]['map'])) {
        continue;
      }
      foreach (Element::children($form['mappings'][$i]['map']) as $subtarget) {
        $options = [];
        if (isset($form['mappings'][$i]['map'][$subtarget]['select']['#options'])) {
          $options = $form['mappings'][$i]['map'][$subtarget]['select']['#options'];
        }
        $form['mappings'][$i]['map'][$subtarget]['select']['#options'] = $this->getCustomSourceOptions() + $options;
      }
    }
  }
  public function mappingFormAlter(array &$form, FormStateInterface $form_state) {}

  /**
   * {@inheritdoc}
@@ -109,36 +54,4 @@ abstract class ParserBase extends PluginBase implements ParserInterface, Mapping
    return [];
  }

  /**
   * Returns a list of custom source options, used by the mapping form.
   *
   * @return array
   *   A list of custom source options using id => label.
   */
  protected function getCustomSourceOptions(): array {
    $custom_sources = [];
    $supported_custom_source_plugins = $this->getSupportedCustomSourcePlugins();
    // The blank source plugin is available for all parsers.
    $supported_custom_source_plugins[] = 'blank';

    foreach ($supported_custom_source_plugins as $custom_source_plugin_id) {
      $custom_source_plugin = $this->customSourcePluginManager->createInstance($custom_source_plugin_id, [
        'feed_type' => $this->feedType,
      ]);
      $custom_sources['custom__' . $custom_source_plugin_id] = $this->t('New @type source...', [
        '@type' => $custom_source_plugin->getLabel(),
      ]);
    }

    // In the UI, clearly separate the options for adding new sources from the
    // options for existing sources.
    if (!empty($custom_sources)) {
      $custom_sources_delimiter = ['----' => '----'];
    }
    else {
      $custom_sources_delimiter = [];
    }
    return $custom_sources + $custom_sources_delimiter;
  }

}
+37 −0
Changes for src/Form/MappingForm.php: 37 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -418,6 +418,11 @@ class MappingForm extends FormBase {
        '#weight' => -1,
      ];
    }

    // Add the appropriate new custom source options to the select source
    // dropdown.
    $options = $element['select']['#options'] ?? [];
    $element['select']['#options'] = $this->getCustomSourceOptions() + $options;
  }

  /**
@@ -585,6 +590,38 @@ class MappingForm extends FormBase {
    return FALSE;
  }

  /**
   * Returns a list of custom source options, used by the mapping form.
   *
   * @return array
   *   A list of custom source options using id => label.
   */
  protected function getCustomSourceOptions(): array {
    $custom_sources = [];
    $supported_custom_source_plugins = $this->feedType->getParser()->getSupportedCustomSourcePlugins();
    // The blank source plugin is available for all parsers.
    $supported_custom_source_plugins[] = 'blank';

    foreach ($supported_custom_source_plugins as $custom_source_plugin_id) {
      $custom_source_plugin = $this->customSourcePluginManager->createInstance($custom_source_plugin_id, [
        'feed_type' => $this->feedType,
      ]);
      $custom_sources['custom__' . $custom_source_plugin_id] = $this->t('New @type source...', [
        '@type' => $custom_source_plugin->getLabel(),
      ]);
    }

    // In the UI, clearly separate the options for adding new sources from the
    // options for existing sources.
    if (!empty($custom_sources)) {
      $custom_sources_delimiter = ['----' => '----'];
    }
    else {
      $custom_sources_delimiter = [];
    }
    return $custom_sources + $custom_sources_delimiter;
  }

  /**
   * Processes the form state, populating the mappings on the feed type.
   *
+4 −0
Changes for tests/modules/feeds_test_plugin/src/Feeds/Parser/ParserWithMappingForm.php: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -14,6 +14,10 @@ use Drupal\feeds\StateInterface;
/**
 * Dummy parser to test integration with the Feeds mapping form.
 *
 * This parser deliberately does not extend
 * \Drupal\feeds\Feeds\Parser\ParserBase, in order to have tests for parsers
 * that only implement \Drupal\feeds\Plugin\Type\Parser\ParserInterface.
 *
 * @FeedsParser(
 *   id = "parser_with_mapping_form",
 *   title = "Parser with mapping form",
+41 −0
Changes for tests/src/Functional/Form/MappingFormTest.php: 41 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -124,6 +124,47 @@ class MappingFormTest extends FeedsBrowserTestBase {
    $this->assertEquals($expected, $feed_type->getCustomSources());
  }

  /**
   * Tests adding a blank source for a parser that does not extend ParserBase.
   */
  public function testAddBlankSourceForBasicParser() {
    // Create a feed type with the parser "Parser with mapping form".
    // That parser does not extend \Drupal\feeds\Feeds\Parser\ParserBase.
    $feed_type = $this->createFeedType([
      'parser' => 'parser_with_mapping_form',
      'mappings' => [],
    ]);

    // Add a new target and set field specific for this parser.
    $edit = [
      'dummy' => 'dummyValue',
      'add_target' => 'title',
    ];
    $this->drupalGet('/admin/structure/feeds/manage/' . $feed_type->id() . '/mapping');
    $this->submitForm($edit, 'Save');

    // Create a new blank source and map that.
    $edit = [
      'mappings[0][map][value][select]' => 'custom__blank',
      'mappings[0][map][value][custom__blank][value]' => 'title',
      'mappings[0][map][value][custom__blank][machine_name]' => 'title',
    ];
    $this->submitForm($edit, 'Save');

    // Reload feed type and assert that a custom source of type "blank" was
    // added.
    $feed_type = $this->reloadEntity($feed_type);
    $expected = [
      'title' => [
        'value' => 'title',
        'label' => 'title',
        'type' => 'blank',
        'machine_name' => 'title',
      ],
    ];
    $this->assertEquals($expected, $feed_type->getCustomSources());
  }

  /**
   * Tests that validation handlers on custom sources are ran.
   */
Loading