Loading feeds.install +7 −0 Changes for feeds.install: 7 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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(); } src/Feeds/Parser/ParserBase.php +2 −89 Changes for src/Feeds/Parser/ParserBase.php: 2 added lines, 89 removed lines. Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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} Loading @@ -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; } } src/Form/MappingForm.php +37 −0 Changes for src/Form/MappingForm.php: 37 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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; } /** Loading Loading @@ -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. * Loading tests/modules/feeds_test_plugin/src/Feeds/Parser/ParserWithMappingForm.php +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 Loading @@ -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", Loading tests/src/Functional/Form/MappingFormTest.php +41 −0 Changes for tests/src/Functional/Form/MappingFormTest.php: 41 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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 Loading
feeds.install +7 −0 Changes for feeds.install: 7 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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(); }
src/Feeds/Parser/ParserBase.php +2 −89 Changes for src/Feeds/Parser/ParserBase.php: 2 added lines, 89 removed lines. Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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} Loading @@ -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; } }
src/Form/MappingForm.php +37 −0 Changes for src/Form/MappingForm.php: 37 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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; } /** Loading Loading @@ -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. * Loading
tests/modules/feeds_test_plugin/src/Feeds/Parser/ParserWithMappingForm.php +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 Loading @@ -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", Loading
tests/src/Functional/Form/MappingFormTest.php +41 −0 Changes for tests/src/Functional/Form/MappingFormTest.php: 41 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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