diff --git a/core/modules/aggregator/aggregator.services.yml b/core/modules/aggregator/aggregator.services.yml
index cf74241..fe4871a 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 bb46647..df94ff5 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Form/SettingsForm.php
@@ -7,9 +7,12 @@
namespace Drupal\aggregator\Form;
-use Drupal\system\SystemConfigFormBase;
-use Drupal\Core\Config\ConfigFactory;
use Drupal\aggregator\Plugin\AggregatorPluginManager;
+use Drupal\Component\Utility\String;
+use Drupal\Core\Form\FormInterface;
+use Drupal\Core\Config\ConfigFactory;
+use Drupal\Core\StringTranslation\TranslationManager;
+use Drupal\system\SystemConfigFormBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -18,6 +21,13 @@
class SettingsForm extends SystemConfigFormBase {
/**
+ * The configuration object factory.
+ *
+ * @var \Drupal\Core\Config\ConfigFactory
+ */
+ protected $configFactory;
+
+ /**
* The aggregator plugin managers.
*
* @var array
@@ -25,6 +35,13 @@ class SettingsForm extends SystemConfigFormBase {
protected $managers = array();
/**
+ * The instantiated plugin instances.
+ *
+ * @var array
+ */
+ protected $instances = array();
+
+ /**
* The aggregator plugin definitions.
*
* @var array
@@ -57,7 +74,7 @@ public function __construct(ConfigFactory $config_factory, AggregatorPluginManag
// 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,14 +92,14 @@ public static function create(ContainerInterface $container) {
}
/**
- * 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');
@@ -136,28 +153,56 @@ public function buildForm(array $form, array &$form_state) {
$form['basic_conf'] += $basic_conf;
}
+ // Call buildForm() 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 FormInterface) {
+ $form = $instance->buildForm($form, $form_state);
+ // Store the instance for validate and submit handlers.
+ $this->instances[] = $instance;
+ }
+ }
+ }
+
// Implementing processor plugins will expect an array at $form['processors'].
$form['processors'] = array();
- // Call settingsForm() for each active processor.
+ // Call buildForm() 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 FormInterface) {
+ $form = $instance->buildForm($form, $form_state);
+ // Store the instance for validate and submit handlers.
+ $this->instances[] = $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->instances as $instance) {
+ $instance->validateForm($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->instances as $instance) {
+ $instance->submitForm($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 2aa6731..043f3fc 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("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("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..d4dcf52
--- /dev/null
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Plugin/AggregatorPluginSettingsBase.php
@@ -0,0 +1,31 @@
+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 8373fa9..8d903ea 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,14 @@
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\Plugin\Core\Entity\Feed;
-use Drupal\aggregator\Annotation\AggregatorProcessor;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Database\Database;
+use Drupal\Core\Config\ConfigFactory;
+use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a default processor implementation.
@@ -25,13 +27,44 @@
* description = @Translation("Creates lightweight records from feed items.")
* )
*/
-class DefaultProcessor extends PluginBase implements ProcessorInterface {
+class DefaultProcessor extends AggregatorPluginSettingsBase implements ProcessorInterface {
+
+ /**
+ * 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) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition);
+ $this->configFactory = $config;
+ }
+
+ /**
+ * {@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 = config('aggregator.settings');
+ public function buildForm(array $form, array &$form_state) {
+ $config = $this->configFactory->get('aggregator.settings');
$processors = $config->get('processors');
$info = $this->getPluginDefinition();
$items = drupal_map_assoc(array(3, 5, 10, 15, 20, 25), array($this, 'formatItems'));
@@ -84,10 +117,10 @@ public function settingsForm(array $form, array &$form_state) {
}
/**
- * Implements \Drupal\aggregator\Plugin\ProcessorInterface::settingsSubmit().
+ * {@inheritdoc}
*/
- public function settingsSubmit(array $form, array &$form_state) {
- $config = config('aggregator.settings');
+ public function submitForm(array &$form, array &$form_state) {
+ $config = $this->configFactory->get('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'])
@@ -96,7 +129,7 @@ public function settingsSubmit(array $form, array &$form_state) {
}
/**
- * Implements \Drupal\aggregator\Plugin\ProcessorInterface::process().
+ * {@inheritdoc}
*/
public function process(Feed $feed) {
if (!is_array($feed->items)) {
@@ -147,7 +180,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 +197,7 @@ public function remove(Feed $feed) {
* Expires items from a feed depending on expiration settings.
*/
public function postProcess(Feed $feed) {
- $aggregator_clear = config('aggregator.settings')->get('items.expire');
+ $aggregator_clear = $this->configFactory->get('aggregator.settings')->get('items.expire');
if ($aggregator_clear != AGGREGATOR_CLEAR_NEVER) {
// Remove all items that are older than flush item timer.
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..e5746ea
--- /dev/null
+++ b/core/modules/aggregator/tests/Drupal/aggregator/Tests/Plugin/AggregatorPluginSettingsBaseTest.php
@@ -0,0 +1,124 @@
+ '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->managers['fetcher'],
+ $this->managers['parser'],
+ $this->managers['processor']
+ );
+ }
+
+ /**
+ * 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('aggregator_allowed_html_tags' => ''));
+
+ $test_processor = $this->getMock(
+ 'Drupal\aggregator_test\Plugin\aggregator\processor\TestProcessor',
+ array('buildForm', 'validateForm', 'submitForm'),
+ array(array(), 'aggregator_test', array(), $this->configFactory)
+ );
+ $test_processor->expects($this->at(0))
+ ->method('buildForm')
+ ->with($this->anything(), $form_state)
+ ->will($this->returnArgument(0));
+ $test_processor->expects($this->at(1))
+ ->method('validateForm')
+ ->with($this->anything(), $form_state);
+ $test_processor->expects($this->at(2))
+ ->method('submitForm')
+ ->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() {}
+ }
+ // @todo remove in https://drupal.org/node/2018411 or after its in.
+ if (!function_exists('t')) {
+ function t($string) {
+ return $string;
+ }
+ }
+}
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 d08a272..5e5fb8c 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,13 @@
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\Plugin\Core\Entity\Feed;
use Drupal\aggregator\Annotation\AggregatorProcessor;
use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Config\ConfigFactory;
+use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a default processor implementation.
@@ -24,14 +26,44 @@
* description = @Translation("Test generic processor functionality.")
* )
*/
-class TestProcessor extends PluginBase implements ProcessorInterface {
+class TestProcessor extends AggregatorPluginSettingsBase implements ProcessorInterface {
/**
- * 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 = 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 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) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition);
+ $this->configFactory = $config;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, array &$form_state) {
+ $processors = $this->configFactory->get('aggregator.settings')->get('processors');
$info = $this->getPluginDefinition();
$form['processors'][$info['id']] = array(
@@ -46,22 +78,22 @@ public function settingsForm(array $form, array &$form_state) {
'#type' => 'number',
'#min' => 1,
'#max' => 1000,
- '#default_value' => config('aggregator_test.settings')->get('items.dummy_length'),
+ '#default_value' => $this->configFactory->get('aggregator_test.settings')->get('items.dummy_length'),
);
return $form;
}
/**
- * Implements \Drupal\aggregator\Plugin\ProcessorInterface::settingsSubmit().
+ * {@inheritdoc}
*/
- public function settingsSubmit(array $form, array &$form_state) {
- config('aggregator_test.settings')
+ public function submitForm(array &$form, array &$form_state) {
+ $this->configFactory->get('aggregator_test.settings')
->set('items.dummy_length', $form_state['values']['dummy_length'])
->save();
}
/**
- * Implements \Drupal\aggregator\Plugin\ProcessorInterface::process().
+ * {@inheritdoc}
*/
public function process(Feed $feed) {
foreach ($feed->items as &$item) {
@@ -71,7 +103,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,7 +111,7 @@ public function remove(Feed $feed) {
}
/**
- * Implements \Drupal\aggregator\Plugin\ProcessorInterface::postProcess().
+ * {@inheritdoc}
*/
public function postProcess(Feed $feed) {
// Double the refresh rate.