diff --git a/core/modules/aggregator/aggregator.services.yml b/core/modules/aggregator/aggregator.services.yml index c2828c9..f622f27 100644 --- a/core/modules/aggregator/aggregator.services.yml +++ b/core/modules/aggregator/aggregator.services.yml @@ -1,13 +1,13 @@ services: plugin.manager.aggregator.fetcher: class: Drupal\aggregator\Plugin\AggregatorPluginManager - arguments: [fetcher, '@container.namespaces'] + arguments: [fetcher, '@container.namespaces', '@cache.cache', '@language_manager'] plugin.manager.aggregator.parser: class: Drupal\aggregator\Plugin\AggregatorPluginManager - arguments: [parser, '@container.namespaces'] + arguments: [parser, '@container.namespaces', '@cache.cache', '@language_manager'] plugin.manager.aggregator.processor: class: Drupal\aggregator\Plugin\AggregatorPluginManager - arguments: [processor, '@container.namespaces'] + arguments: [processor, '@container.namespaces', '@cache.cache', '@language_manager'] access_check.aggregator.categories: class: Drupal\aggregator\Access\CategoriesAccessCheck arguments: ['@database'] diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php b/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php index 0bc2e80..eb40df6 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php @@ -7,10 +7,13 @@ namespace Drupal\aggregator\Form; +use Drupal\aggregator\Plugin\AggregatorPluginManager; +use Drupal\Component\Utility\String; use Drupal\Core\Config\Context\ContextInterface; -use Drupal\system\SystemConfigFormBase; use Drupal\Core\Config\ConfigFactory; -use Drupal\aggregator\Plugin\AggregatorPluginManager; +use Drupal\Core\Plugin\PluginFormInterface; +use Drupal\Core\StringTranslation\TranslationInterface; +use Drupal\system\SystemConfigFormBase; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -26,6 +29,13 @@ class SettingsForm extends SystemConfigFormBase { protected $managers = array(); /** + * The instantiated plugin instances that have configuration forms. + * + * @var array + */ + protected $configurableInstances = array(); + + /** * The aggregator plugin definitions. * * @var array @@ -49,10 +59,12 @@ class SettingsForm extends SystemConfigFormBase { * The aggregator parser plugin manager. * @param \Drupal\aggregator\Plugin\AggregatorPluginManager $processor_manager * The aggregator processor plugin manager. + * @param \Drupal\Core\StringTranslation\TranslationInterface $translation_manager + * The string translation manager. */ - public function __construct(ConfigFactory $config_factory, ContextInterface $context, AggregatorPluginManager $fetcher_manager, AggregatorPluginManager $parser_manager, AggregatorPluginManager $processor_manager) { + public function __construct(ConfigFactory $config_factory, ContextInterface $context, AggregatorPluginManager $fetcher_manager, AggregatorPluginManager $parser_manager, AggregatorPluginManager $processor_manager, TranslationInterface $translation_manager) { parent::__construct($config_factory, $context); - + $this->translationManager = $translation_manager; $this->managers = array( 'fetcher' => $fetcher_manager, 'parser' => $parser_manager, @@ -61,7 +73,7 @@ public function __construct(ConfigFactory $config_factory, ContextInterface $con // Get all available fetcher, parser and processor definitions. foreach (array('fetcher', 'parser', 'processor') as $type) { foreach ($this->managers[$type]->getDefinitions() as $id => $definition) { - $this->definitions[$type][$id] = format_string('@title @description', array('@title' => $definition['title'], '@description' => $definition['description'])); + $this->definitions[$type][$id] = String::format('@title @description', array('@title' => $definition['title'], '@description' => $definition['description'])); } } } @@ -75,19 +87,20 @@ public static function create(ContainerInterface $container) { $container->get('config.context.free'), $container->get('plugin.manager.aggregator.fetcher'), $container->get('plugin.manager.aggregator.parser'), - $container->get('plugin.manager.aggregator.processor') + $container->get('plugin.manager.aggregator.processor'), + $container->get('string_translation') ); } /** - * Implements \Drupal\Core\Form\FormInterface::getFormID(). + * {@inheritdoc} */ public function getFormID() { return 'aggregator_admin_form'; } /** - * Implements \Drupal\Core\Form\FormInterface::buildForm(). + * {@inheritdoc} */ public function buildForm(array $form, array &$form_state) { $config = $this->configFactory->get('aggregator.settings'); @@ -95,11 +108,11 @@ public function buildForm(array $form, array &$form_state) { // Global aggregator settings. $form['aggregator_allowed_html_tags'] = array( '#type' => 'textfield', - '#title' => t('Allowed HTML tags'), + '#title' => $this->t('Allowed HTML tags'), '#size' => 80, '#maxlength' => 255, '#default_value' => $config->get('items.allowed_html'), - '#description' => t('A space-separated list of HTML tags allowed in the content of feed items. Disallowed tags are stripped from the content.'), + '#description' => $this->t('A space-separated list of HTML tags allowed in the content of feed items. Disallowed tags are stripped from the content.'), ); // Only show basic configuration if there are actually options. @@ -107,8 +120,8 @@ public function buildForm(array $form, array &$form_state) { if (count($this->definitions['fetcher']) > 1) { $basic_conf['aggregator_fetcher'] = array( '#type' => 'radios', - '#title' => t('Fetcher'), - '#description' => t('Fetchers download data from an external source. Choose a fetcher suitable for the external source you would like to download from.'), + '#title' => $this->t('Fetcher'), + '#description' => $this->t('Fetchers download data from an external source. Choose a fetcher suitable for the external source you would like to download from.'), '#options' => $this->definitions['fetcher'], '#default_value' => $config->get('fetcher'), ); @@ -116,8 +129,8 @@ public function buildForm(array $form, array &$form_state) { if (count($this->definitions['parser']) > 1) { $basic_conf['aggregator_parser'] = array( '#type' => 'radios', - '#title' => t('Parser'), - '#description' => t('Parsers transform downloaded data into standard structures. Choose a parser suitable for the type of feeds you would like to aggregate.'), + '#title' => $this->t('Parser'), + '#description' => $this->t('Parsers transform downloaded data into standard structures. Choose a parser suitable for the type of feeds you would like to aggregate.'), '#options' => $this->definitions['parser'], '#default_value' => $config->get('parser'), ); @@ -125,8 +138,8 @@ public function buildForm(array $form, array &$form_state) { if (count($this->definitions['processor']) > 1) { $basic_conf['aggregator_processors'] = array( '#type' => 'checkboxes', - '#title' => t('Processors'), - '#description' => t('Processors act on parsed feed data, for example they store feed items. Choose the processors suitable for your task.'), + '#title' => $this->t('Processors'), + '#description' => $this->t('Processors act on parsed feed data, for example they store feed items. Choose the processors suitable for your task.'), '#options' => $this->definitions['processor'], '#default_value' => $config->get('processors'), ); @@ -134,35 +147,67 @@ public function buildForm(array $form, array &$form_state) { if (count($basic_conf)) { $form['basic_conf'] = array( '#type' => 'details', - '#title' => t('Basic configuration'), - '#description' => t('For most aggregation tasks, the default settings are fine.'), + '#title' => $this->t('Basic configuration'), + '#description' => $this->t('For most aggregation tasks, the default settings are fine.'), '#collapsed' => FALSE, ); $form['basic_conf'] += $basic_conf; } + // Call buildConfigurationForm() on the active fetcher and parser. + foreach (array('fetcher', 'parser') as $type) { + $active = $config->get($type); + if (array_key_exists($active, $this->definitions[$type])) { + $instance = $this->managers[$type]->createInstance($active); + if ($instance instanceof PluginFormInterface) { + $form = $instance->buildConfigurationForm($form, $form_state); + // Store the instance for validate and submit handlers. + // Keying by ID would bring conflicts, because two instances of a + // different type could have the same ID. + $this->configurableInstances[] = $instance; + } + } + } + // Implementing processor plugins will expect an array at $form['processors']. $form['processors'] = array(); - // Call settingsForm() for each active processor. + // Call buildConfigurationForm() for each active processor. foreach ($this->definitions['processor'] as $id => $definition) { if (in_array($id, $config->get('processors'))) { - $form = $this->managers['processor']->createInstance($id)->settingsForm($form, $form_state); + $instance = $this->managers['processor']->createInstance($id); + if ($instance instanceof PluginFormInterface) { + $form = $instance->buildConfigurationForm($form, $form_state); + // Store the instance for validate and submit handlers. + // Keying by ID would bring conflicts, because two instances of a + // different type could have the same ID. + $this->configurableInstances[] = $instance; + } } } + return parent::buildForm($form, $form_state); } /** - * Implements \Drupal\Core\Form\FormInterface::submitForm(). + * {@inheritdoc} + */ + public function validateForm(array &$form, array &$form_state) { + parent::validateForm($form, $form_state); + // Let active plugins validate their settings. + foreach ($this->configurableInstances as $instance) { + $instance->validateConfigurationForm($form, $form_state); + } + } + + /** + * {@inheritdoc} */ public function submitForm(array &$form, array &$form_state) { parent::submitForm($form, $form_state); $config = $this->configFactory->get('aggregator.settings'); - // Let active processors save their settings. - foreach ($this->definitions['processor'] as $id => $definition) { - if (in_array($id, $config->get('processors'))) { - $this->managers['processor']->createInstance($id)->settingsSubmit($form, $form_state); - } + // Let active plugins save their settings. + foreach ($this->configurableInstances as $instance) { + $instance->submitConfigurationForm($form, $form_state); } $config->set('items.allowed_html', $form_state['values']['aggregator_allowed_html_tags']); diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginManager.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginManager.php index 67d8c4d..6362b51 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginManager.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginManager.php @@ -7,16 +7,14 @@ namespace Drupal\aggregator\Plugin; -use Drupal\Component\Plugin\PluginManagerBase; -use Drupal\Component\Plugin\Factory\DefaultFactory; -use Drupal\Core\Language\Language; -use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery; -use Drupal\Core\Plugin\Discovery\CacheDecorator; +use Drupal\Core\Cache\CacheBackendInterface; +use Drupal\Core\Language\LanguageManager; +use Drupal\Core\Plugin\DefaultPluginManager; /** * Manages aggregator plugins. */ -class AggregatorPluginManager extends PluginManagerBase { +class AggregatorPluginManager extends DefaultPluginManager { /** * Constructs a AggregatorPluginManager object. @@ -25,9 +23,13 @@ class AggregatorPluginManager extends PluginManagerBase { * The plugin type, for example fetcher. * @param \Traversable $namespaces * An object that implements \Traversable which contains the root paths - * keyed by the corresponding namespace to look for plugin implementations, + * keyed by the corresponding namespace to look for plugin implementations. + * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend + * Cache backend instance to use. + * @param \Drupal\Core\Language\LanguageManager $language_manager + * The language manager. */ - public function __construct($type, \Traversable $namespaces) { + public function __construct($type, \Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager) { $type_annotations = array( 'fetcher' => 'Drupal\aggregator\Annotation\AggregatorFetcher', 'parser' => 'Drupal\aggregator\Annotation\AggregatorParser', @@ -38,8 +40,8 @@ public function __construct($type, \Traversable $namespaces) { 'Drupal\aggregator\Annotation' => DRUPAL_ROOT . '/core/modules/aggregator/lib', ); - $this->discovery = new AnnotatedClassDiscovery("Plugin/aggregator/$type", $namespaces, $annotation_namespaces, $type_annotations[$type]); - $this->discovery = new CacheDecorator($this->discovery, "aggregator_$type:" . language(Language::TYPE_INTERFACE)->id); - $this->factory = new DefaultFactory($this->discovery); + parent::__construct("Plugin/aggregator/$type", $namespaces, $annotation_namespaces, $type_annotations[$type]); + $this->setCacheBackend($cache_backend, $language_manager, "aggregator_$type"); } + } diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsBase.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsBase.php new file mode 100644 index 0000000..55013e1 --- /dev/null +++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsBase.php @@ -0,0 +1,25 @@ +httpClient = $http_client; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) { + return new static( + $container->get('http_default_client') + ); + } /** - * Implements \Drupal\aggregator\Plugin\FetcherInterface::fetch(). + * {@inheritdoc} */ public function fetch(Feed $feed) { - // @todo: Inject the http client. - $request = \Drupal::httpClient()->get($feed->url->value); + $request = $this->httpClient->get($feed->url->value); $feed->source_string = FALSE; // Generate conditional GET headers. diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.php b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.php index eefadcd..ec7d193 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/aggregator/processor/DefaultProcessor.php @@ -7,12 +7,15 @@ namespace Drupal\aggregator\Plugin\aggregator\processor; -use Drupal\Component\Plugin\PluginBase; +use Drupal\aggregator\Annotation\AggregatorProcessor; +use Drupal\aggregator\Plugin\AggregatorPluginSettingsBase; use Drupal\aggregator\Plugin\ProcessorInterface; use Drupal\aggregator\Entity\Feed; -use Drupal\aggregator\Annotation\AggregatorProcessor; use Drupal\Core\Annotation\Translation; use Drupal\Core\Database\Database; +use Drupal\Core\Config\ConfigFactory; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Defines a default processor implementation. @@ -25,14 +28,51 @@ * description = @Translation("Creates lightweight records from feed items.") * ) */ -class DefaultProcessor extends PluginBase implements ProcessorInterface { +class DefaultProcessor extends AggregatorPluginSettingsBase implements ProcessorInterface, ContainerFactoryPluginInterface { + + /** + * Contains the configuration object factory. + * + * @var \Drupal\Core\Config\ConfigFactory + */ + protected $configFactory; + + /** + * Constructs a DefaultProcessor 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\Core\Config\ConfigFactory $config + * The configuration factory object. + */ + public function __construct(array $configuration, $plugin_id, array $plugin_definition, ConfigFactory $config) { + $this->configFactory = $config; + // @todo Refactor aggregator plugins to ConfigEntity so merging + // the configuration here is not needed. + parent::__construct($configuration + $this->getConfiguration(), $plugin_id, $plugin_definition); + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('config.factory') + ); + } /** - * Implements \Drupal\aggregator\Plugin\ProcessorInterface::settingsForm(). + * {@inheritdoc} */ - public function settingsForm(array $form, array &$form_state) { - $config = \Drupal::config('aggregator.settings'); - $processors = $config->get('processors'); + public function buildConfigurationForm(array $form, array &$form_state) { + $processors = $this->configuration['processors']; $info = $this->getPluginDefinition(); $items = drupal_map_assoc(array(3, 5, 10, 15, 20, 25), array($this, 'formatItems')); $period = drupal_map_assoc(array(3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 2419200, 4838400, 9676800), 'format_interval'); @@ -52,7 +92,7 @@ public function settingsForm(array $form, array &$form_state) { $form['processors'][$info['id']]['aggregator_summary_items'] = array( '#type' => 'select', '#title' => t('Number of items shown in listing pages'), - '#default_value' => $config->get('source.list_max'), + '#default_value' => $this->configuration['source']['list_max'], '#empty_value' => 0, '#options' => $items, ); @@ -60,7 +100,7 @@ public function settingsForm(array $form, array &$form_state) { $form['processors'][$info['id']]['aggregator_clear'] = array( '#type' => 'select', '#title' => t('Discard items older than'), - '#default_value' => $config->get('items.expire'), + '#default_value' => $this->configuration['items']['expire'], '#options' => $period, '#description' => t('Requires a correctly configured cron maintenance task.', array('@cron' => url('admin/reports/status'))), ); @@ -68,7 +108,7 @@ public function settingsForm(array $form, array &$form_state) { $form['processors'][$info['id']]['aggregator_category_selector'] = array( '#type' => 'radios', '#title' => t('Select categories using'), - '#default_value' => $config->get('source.category_selector'), + '#default_value' => $this->configuration['source']['category_selector'], '#options' => array('checkboxes' => t('checkboxes'), 'select' => t('multiple selector')), '#description' => t('For a small number of categories, checkboxes are easier to use, while a multiple selector works well with large numbers of categories.'), @@ -76,27 +116,27 @@ public function settingsForm(array $form, array &$form_state) { $form['processors'][$info['id']]['aggregator_teaser_length'] = array( '#type' => 'select', '#title' => t('Length of trimmed description'), - '#default_value' => $config->get('items.teaser_length'), + '#default_value' => $this->configuration['items']['teaser_length'], '#options' => drupal_map_assoc(array(0, 200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000), array($this, 'formatCharacters')), - '#description' => t("The maximum number of characters used in the trimmed version of content.") + '#description' => t('The maximum number of characters used in the trimmed version of content.'), ); return $form; } /** - * Implements \Drupal\aggregator\Plugin\ProcessorInterface::settingsSubmit(). + * {@inheritdoc} */ - public function settingsSubmit(array $form, array &$form_state) { - $config = \Drupal::config('aggregator.settings'); - $config->set('items.expire', $form_state['values']['aggregator_clear']) - ->set('items.teaser_length', $form_state['values']['aggregator_teaser_length']) - ->set('source.list_max', $form_state['values']['aggregator_summary_items']) - ->set('source.category_selector', $form_state['values']['aggregator_category_selector']) - ->save(); + public function submitConfigurationForm(array &$form, array &$form_state) { + $this->configuration['items']['expire'] = $form_state['values']['aggregator_clear']; + $this->configuration['items']['teaser_length'] = $form_state['values']['aggregator_teaser_length']; + $this->configuration['source']['list_max'] = $form_state['values']['aggregator_summary_items']; + $this->configuration['source']['category_selector'] = $form_state['values']['aggregator_category_selector']; + // @todo Refactor aggregator plugins to ConfigEntity so this is not needed. + $this->setConfiguration($this->configuration); } /** - * Implements \Drupal\aggregator\Plugin\ProcessorInterface::process(). + * {@inheritdoc} */ public function process(Feed $feed) { if (!is_array($feed->items)) { @@ -147,7 +187,7 @@ public function process(Feed $feed) { } /** - * Implements \Drupal\aggregator\Plugin\ProcessorInterface::remove(). + * {@inheritdoc} */ public function remove(Feed $feed) { $iids = Database::getConnection()->query('SELECT iid FROM {aggregator_item} WHERE fid = :fid', array(':fid' => $feed->id()))->fetchCol(); @@ -164,7 +204,7 @@ public function remove(Feed $feed) { * Expires items from a feed depending on expiration settings. */ public function postProcess(Feed $feed) { - $aggregator_clear = \Drupal::config('aggregator.settings')->get('items.expire'); + $aggregator_clear = $this->configuration['items']['expire']; if ($aggregator_clear != AGGREGATOR_CLEAR_NEVER) { // Remove all items that are older than flush item timer. @@ -181,6 +221,24 @@ public function postProcess(Feed $feed) { } /** + * {@inheritdoc} + */ + public function getConfiguration() { + return $this->configFactory->get('aggregator.settings')->get(); + } + + /** + * {@inheritdoc} + */ + public function setConfiguration(array $configuration) { + $config = $this->configFactory->get('aggregator.settings'); + foreach ($configuration as $key => $value) { + $config->set($key, $value); + } + $config->save(); + } + + /** * Helper function for drupal_map_assoc. * * @param int $count @@ -207,4 +265,5 @@ protected function formatItems($count) { protected function formatCharacters($length) { return ($length == 0) ? t('Unlimited') : format_plural($length, '1 character', '@count characters'); } + } diff --git a/core/modules/aggregator/tests/Drupal/aggregator/Tests/Plugin/AggregatorPluginSettingsBaseTest.php b/core/modules/aggregator/tests/Drupal/aggregator/Tests/Plugin/AggregatorPluginSettingsBaseTest.php new file mode 100644 index 0000000..9c120c3 --- /dev/null +++ b/core/modules/aggregator/tests/Drupal/aggregator/Tests/Plugin/AggregatorPluginSettingsBaseTest.php @@ -0,0 +1,123 @@ + 'Aggregator plugin settings tests', + 'description' => 'Test settings configuration of individual aggregator plugins.', + 'group' => 'Aggregator', + ); + } + + public function setUp() { + $this->configFactory = $this->getConfigFactoryStub( + array( + 'aggregator.settings' => array( + 'processors' => array('aggregator_test'), + ), + 'aggregator_test.settings' => array(), + ) + ); + foreach (array('fetcher', 'parser', 'processor') as $type) { + $this->managers[$type] = $this->getMockBuilder('Drupal\aggregator\Plugin\AggregatorPluginManager') + ->disableOriginalConstructor() + ->getMock(); + $this->managers[$type]->expects($this->once()) + ->method('getDefinitions') + ->will($this->returnValue(array('aggregator_test' => array('title' => '', 'description' => '')))); + } + + $this->settingsForm = new SettingsForm( + $this->configFactory, + $this->getMock('Drupal\Core\Config\Context\ContextInterface'), + $this->managers['fetcher'], + $this->managers['parser'], + $this->managers['processor'], + $this->getStringTranslationStub() + ); + } + + /** + * Test for AggregatorPluginSettingsBase. + * + * Ensure that the settings form calls build, validate and submit methods on + * plugins that extend AggregatorPluginSettingsBase. + */ + public function testSettingsForm() { + // Emulate a form state of a sumbitted form. + $form_state = array('values' => array('dummy_length' => '', 'aggregator_allowed_html_tags' => '')); + + $test_processor = $this->getMock( + 'Drupal\aggregator_test\Plugin\aggregator\processor\TestProcessor', + array('buildConfigurationForm', 'validateConfigurationForm', 'submitConfigurationForm'), + array(array(), 'aggregator_test', array('description' => ''), $this->configFactory) + ); + $test_processor->expects($this->at(0)) + ->method('buildConfigurationForm') + ->with($this->anything(), $form_state) + ->will($this->returnArgument(0)); + $test_processor->expects($this->at(1)) + ->method('validateConfigurationForm') + ->with($this->anything(), $form_state); + $test_processor->expects($this->at(2)) + ->method('submitConfigurationForm') + ->with($this->anything(), $form_state); + + $this->managers['processor']->expects($this->once()) + ->method('createInstance') + ->with($this->equalTo('aggregator_test')) + ->will($this->returnValue($test_processor)); + + $form = $this->settingsForm->buildForm(array(), $form_state); + $this->settingsForm->validateForm($form, $form_state); + $this->settingsForm->submitForm($form, $form_state); + } + +} + +} + +namespace { + // @todo Remove after https://drupal.org/node/1858196 is in. + if (!function_exists('drupal_set_message')) { + function drupal_set_message() {} + } +} diff --git a/core/modules/aggregator/tests/modules/aggregator_test/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php b/core/modules/aggregator/tests/modules/aggregator_test/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php index f6f605d..04a5c5a 100644 --- a/core/modules/aggregator/tests/modules/aggregator_test/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php +++ b/core/modules/aggregator/tests/modules/aggregator_test/lib/Drupal/aggregator_test/Plugin/aggregator/processor/TestProcessor.php @@ -7,11 +7,14 @@ namespace Drupal\aggregator_test\Plugin\aggregator\processor; -use Drupal\Component\Plugin\PluginBase; +use Drupal\aggregator\Plugin\AggregatorPluginSettingsBase; use Drupal\aggregator\Plugin\ProcessorInterface; use Drupal\aggregator\Entity\Feed; use Drupal\aggregator\Annotation\AggregatorProcessor; use Drupal\Core\Annotation\Translation; +use Drupal\Core\Config\ConfigFactory; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Defines a default processor implementation. @@ -24,14 +27,49 @@ * description = @Translation("Test generic processor functionality.") * ) */ -class TestProcessor extends PluginBase implements ProcessorInterface { +class TestProcessor extends AggregatorPluginSettingsBase implements ProcessorInterface, ContainerFactoryPluginInterface { /** - * Implements \Drupal\aggregator\Plugin\ProcessorInterface::settingsForm(). + * Contains the configuration object factory. + * + * @var \Drupal\Core\Config\ConfigFactory */ - public function settingsForm(array $form, array &$form_state) { - $config = \Drupal::config('aggregator.settings'); - $processors = $config->get('processors'); + protected $configFactory; + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('config.factory') + ); + } + + /** + * Constructs a TestProcessor 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\Core\Config\ConfigFactory $config + * The configuration factory object. + */ + public function __construct(array $configuration, $plugin_id, array $plugin_definition, ConfigFactory $config) { + $this->configFactory = $config; + parent::__construct($configuration + $this->getConfiguration(), $plugin_id, $plugin_definition); + } + + /** + * {@inheritdoc} + */ + public function buildConfigurationForm(array $form, array &$form_state) { + $processors = $this->configFactory->get('aggregator.settings')->get('processors'); $info = $this->getPluginDefinition(); $form['processors'][$info['id']] = array( @@ -46,22 +84,21 @@ public function settingsForm(array $form, array &$form_state) { '#type' => 'number', '#min' => 1, '#max' => 1000, - '#default_value' => \Drupal::config('aggregator_test.settings')->get('items.dummy_length'), + '#default_value' => $this->configuration['items']['dummy_length'], ); return $form; } /** - * Implements \Drupal\aggregator\Plugin\ProcessorInterface::settingsSubmit(). + * {@inheritdoc} */ - public function settingsSubmit(array $form, array &$form_state) { - \Drupal::config('aggregator_test.settings') - ->set('items.dummy_length', $form_state['values']['dummy_length']) - ->save(); + public function submitConfigurationForm(array &$form, array &$form_state) { + $this->configuration['items']['dummy_length'] = $form_state['values']['dummy_length']; + $this->setConfiguration($this->configuration); } /** - * Implements \Drupal\aggregator\Plugin\ProcessorInterface::process(). + * {@inheritdoc} */ public function process(Feed $feed) { foreach ($feed->items as &$item) { @@ -71,7 +108,7 @@ public function process(Feed $feed) { } /** - * Implements \Drupal\aggregator\Plugin\ProcessorInterface::remove(). + * {@inheritdoc} */ public function remove(Feed $feed) { // Append a random number, just to change the feed description. @@ -79,11 +116,30 @@ public function remove(Feed $feed) { } /** - * Implements \Drupal\aggregator\Plugin\ProcessorInterface::postProcess(). + * {@inheritdoc} */ public function postProcess(Feed $feed) { // Double the refresh rate. $feed->refresh->value *= 2; $feed->save(); } + + /** + * {@inheritdoc} + */ + public function getConfiguration() { + return $this->configFactory->get('aggregator_test.settings')->get(); + } + + /** + * {@inheritdoc} + */ + public function setConfiguration(array $configuration) { + $config = $this->configFactory->get('aggregator_test.settings'); + foreach ($configuration as $key => $value) { + $config->set($key, $value); + } + $config->save(); + } + } diff --git a/core/tests/Drupal/Tests/UnitTestCase.php b/core/tests/Drupal/Tests/UnitTestCase.php index c8f32a6..576c015 100644 --- a/core/tests/Drupal/Tests/UnitTestCase.php +++ b/core/tests/Drupal/Tests/UnitTestCase.php @@ -147,4 +147,20 @@ protected function getBlockMockWithMachineName($machine_name) { return $block; } + /** + * Returns a stub translation manager that just returns the passed string. + * + * @return \PHPUnit_Framework_MockObject_MockBuilder + * A MockBuilder of \Drupal\Core\StringTranslation\TranslationInterface + */ + public function getStringTranslationStub() { + $translation = $this->getMockBuilder('Drupal\Core\StringTranslation\TranslationManager') + ->disableOriginalConstructor() + ->getMock(); + $translation->expects($this->any()) + ->method('translate') + ->will($this->returnArgument(0)); + return $translation; + } + }