Commit bc602a7a authored by alexpott's avatar alexpott

Issue #1957330 by ParisLiakos, twistor: Make possible for parsers and fetchers...

Issue #1957330 by ParisLiakos, twistor: Make possible for parsers and fetchers to expose configuration through plugins.
parent c534b445
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']
......
......@@ -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;
/**
......@@ -25,6 +28,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.
*
......@@ -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 <span class="description">@description</span>', array('@title' => $definition['title'], '@description' => $definition['description']));
$this->definitions[$type][$id] = String::format('@title <span class="description">@description</span>', 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']);
......
......@@ -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");
}
}
<?php
/**
* @file
* Contains \Drupal\aggregator\Plugin\AggregatorPluginSettingsBase.
*/
namespace Drupal\aggregator\Plugin;
use Drupal\Component\Plugin\ConfigurablePluginInterface;
use Drupal\Component\Plugin\PluginBase;
use Drupal\Core\Plugin\PluginFormInterface;
/**
* Base class for aggregator plugins that implement settings forms.
*/
abstract class AggregatorPluginSettingsBase extends PluginBase implements PluginFormInterface, ConfigurablePluginInterface {
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, array &$form_state) {
}
}
......@@ -20,31 +20,6 @@
*/
interface ProcessorInterface {
/**
* Returns a form to configure settings for the processor.
*
* @param array $form
* The form definition array where the settings form is being included in.
* @param array $form_state
* An associative array containing the current state of the form.
*
* @return array
* The form elements for the processor settings.
*/
public function settingsForm(array $form, array &$form_state);
/**
* Adds processor specific submission handling for the configuration form.
*
* @param array $form
* The form definition array where the settings form is being included in.
* @param array $form_state
* An associative array containing the current state of the form.
*
* @see \Drupal\aggregator\Plugin\ProcessorInterface::settingsForm()
*/
public function settingsSubmit(array $form, array &$form_state);
/**
* Processes feed data.
*
......
......@@ -7,12 +7,15 @@
namespace Drupal\aggregator\Plugin\aggregator\fetcher;
use Drupal\aggregator\Annotation\AggregatorFetcher;
use Drupal\aggregator\Plugin\FetcherInterface;
use Drupal\aggregator\Entity\Feed;
use Drupal\aggregator\Annotation\AggregatorFetcher;
use Drupal\Core\Annotation\Translation;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Guzzle\Http\ClientInterface;
use Guzzle\Http\Exception\BadResponseException;
use Guzzle\Http\Exception\RequestException;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a default fetcher implementation.
......@@ -25,14 +28,39 @@
* description = @Translation("Downloads data from a URL using Drupal's HTTP request handler.")
* )
*/
class DefaultFetcher implements FetcherInterface {
class DefaultFetcher implements FetcherInterface, ContainerFactoryPluginInterface {
/**
* The HTTP client to fetch the feed data with.
*
* @var \Guzzle\Http\ClientInterface
*/
protected $httpClient;
/**
* Constructs a DefaultFetcher object.
*
* @param \Guzzle\Http\ClientInterface $http_client
* A Guzzle client object.
*/
public function __construct(ClientInterface $http_client) {
$this->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.
......
......@@ -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 <a href="@cron">cron maintenance task</a>.', 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.
......@@ -180,6 +220,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.
*
......@@ -207,4 +265,5 @@ protected function formatItems($count) {
protected function formatCharacters($length) {
return ($length == 0) ? t('Unlimited') : format_plural($length, '1 character', '@count characters');
}
}
<?php
/**
* @file
* Contains \Drupal\aggregator\Tests\Plugin\AggregatorPluginSettingsBaseTest
*/
namespace Drupal\aggregator\Tests\Plugin {
use Drupal\aggregator\Form\SettingsForm;
use Drupal\Tests\UnitTestCase;
/**
* Tests plugins settings on aggregator plugins.
*
* @group Drupal
* @group Aggregator
*/
class AggregatorPluginSettingsBaseTest extends UnitTestCase {
/**
* The aggregator settings form object under test.
*
* @var \Drupal\aggregator\Form\SettingsForm
*/
protected $settingsForm;
/**
* The stubbed config factory object.
*
* @var \PHPUnit_Framework_MockObject_MockBuilder
*/
protected $configFactory;
/**
* The stubbed aggregator plugin managers array.
*
* @var array
*/
protected $managers;
public static function getInfo() {
return array(
'name' => '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())