Update Composer, update everything
This commit is contained in:
parent
ea3e94409f
commit
dda5c284b6
19527 changed files with 1135420 additions and 351004 deletions
|
@ -29,8 +29,9 @@ function action_help($route_name, RouteMatchInterface $route_match) {
|
|||
$output = '<p>' . t('There are two types of actions: simple and advanced. Simple actions do not require any additional configuration and are listed here automatically. Advanced actions need to be created and configured before they can be used because they have options that need to be specified; for example, sending an email to a specified address or unpublishing content containing certain words. To create an advanced action, select the action from the drop-down list in the advanced action section below and click the <em>Create</em> button.') . '</p>';
|
||||
return $output;
|
||||
|
||||
case 'action.admin_add':
|
||||
case 'entity.action.edit_form':
|
||||
return t('An advanced action offers additional configuration options which may be filled out below. Changing the <em>Description</em> field is recommended in order to better identify the precise action taking place.');
|
||||
return t('An advanced action offers additional configuration options which may be filled out below. Changing the <em>Label</em> field is recommended in order to better identify the precise action taking place.');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,4 +29,3 @@ entity.action.delete_form:
|
|||
_title: 'Delete'
|
||||
requirements:
|
||||
_permission: 'administer actions'
|
||||
|
||||
|
|
|
@ -15,6 +15,6 @@ function action_views_form_substitutions() {
|
|||
'#attributes' => ['class' => ['action-table-select-all']],
|
||||
];
|
||||
return [
|
||||
'<!--action-bulk-form-select-all-->' => drupal_render($select_all),
|
||||
'<!--action-bulk-form-select-all-->' => \Drupal::service('renderer')->render($select_all),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -3,10 +3,12 @@ label: Action configuration
|
|||
migration_tags:
|
||||
- Drupal 6
|
||||
- Drupal 7
|
||||
- Configuration
|
||||
source:
|
||||
plugin: variable
|
||||
variables:
|
||||
- actions_max_stack
|
||||
source_module: action
|
||||
process:
|
||||
recursion_limit: actions_max_stack
|
||||
destination:
|
|
@ -2,6 +2,7 @@ id: d6_action
|
|||
label: Actions
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Configuration
|
||||
source:
|
||||
plugin: action
|
||||
process:
|
||||
|
@ -23,6 +24,12 @@ process:
|
|||
imagecache_flush_action: 0
|
||||
imagecache_generate_all_action: 0
|
||||
imagecache_generate_action: 0
|
||||
comment_publish_action: entity:publish_action:comment
|
||||
comment_unpublish_action: entity:unpublish_action:comment
|
||||
comment_save_action: entity:save_action:comment
|
||||
node_publish_action: entity:publish_action:node
|
||||
node_unpublish_action: entity:unpublish_action:node
|
||||
node_save_action: entity:save_action:node
|
||||
bypass: true
|
||||
-
|
||||
plugin: skip_on_empty
|
|
@ -2,6 +2,7 @@ id: d7_action
|
|||
label: Actions
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Configuration
|
||||
source:
|
||||
plugin: action
|
||||
process:
|
||||
|
@ -20,6 +21,12 @@ process:
|
|||
system_send_email_action: action_send_email_action
|
||||
system_message_action: action_message_action
|
||||
system_block_ip_action: 0
|
||||
comment_publish_action: entity:publish_action:comment
|
||||
comment_unpublish_action: entity:unpublish_action:comment
|
||||
comment_save_action: entity:save_action:comment
|
||||
node_publish_action: entity:publish_action:node
|
||||
node_unpublish_action: entity:unpublish_action:node
|
||||
node_save_action: entity:save_action:node
|
||||
bypass: true
|
||||
-
|
||||
plugin: skip_on_empty
|
|
@ -2,67 +2,28 @@
|
|||
|
||||
namespace Drupal\action;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\Core\Action\ActionManager;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a form for action add forms.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class ActionAddForm extends ActionFormBase {
|
||||
|
||||
/**
|
||||
* The action manager.
|
||||
*
|
||||
* @var \Drupal\Core\Action\ActionManager
|
||||
*/
|
||||
protected $actionManager;
|
||||
|
||||
/**
|
||||
* Constructs a new ActionAddForm.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityStorageInterface $storage
|
||||
* The action storage.
|
||||
* @param \Drupal\Core\Action\ActionManager $action_manager
|
||||
* The action plugin manager.
|
||||
*/
|
||||
public function __construct(EntityStorageInterface $storage, ActionManager $action_manager) {
|
||||
parent::__construct($storage);
|
||||
|
||||
$this->actionManager = $action_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container) {
|
||||
return new static(
|
||||
$container->get('entity.manager')->getStorage('action'),
|
||||
$container->get('plugin.manager.action')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @param string $action_id
|
||||
* The hashed version of the action ID.
|
||||
* The action ID.
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state, $action_id = NULL) {
|
||||
// In \Drupal\action\Form\ActionAdminManageForm::buildForm() the action
|
||||
// are hashed. Here we have to decrypt it to find the desired action ID.
|
||||
foreach ($this->actionManager->getDefinitions() as $id => $definition) {
|
||||
$key = Crypt::hashBase64($id);
|
||||
if ($key === $action_id) {
|
||||
$this->entity->setPlugin($id);
|
||||
// Derive the label and type from the action definition.
|
||||
$this->entity->set('label', $definition['label']);
|
||||
$this->entity->set('type', $definition['type']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->entity->setPlugin($action_id);
|
||||
|
||||
// Derive the label and type from the action definition.
|
||||
$definition = $this->entity->getPluginDefinition();
|
||||
$this->entity->set('label', $definition['label']);
|
||||
$this->entity->set('type', $definition['type']);
|
||||
|
||||
return parent::buildForm($form, $form_state);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ namespace Drupal\action;
|
|||
|
||||
/**
|
||||
* Provides a form for action edit forms.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class ActionEditForm extends ActionFormBase {
|
||||
|
||||
|
|
|
@ -13,13 +13,6 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
*/
|
||||
abstract class ActionFormBase extends EntityForm {
|
||||
|
||||
/**
|
||||
* The action plugin being configured.
|
||||
*
|
||||
* @var \Drupal\Core\Action\ActionInterface
|
||||
*/
|
||||
protected $plugin;
|
||||
|
||||
/**
|
||||
* The action storage.
|
||||
*
|
||||
|
@ -27,6 +20,13 @@ abstract class ActionFormBase extends EntityForm {
|
|||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* The action entity.
|
||||
*
|
||||
* @var \Drupal\system\ActionConfigEntityInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* Constructs a new action form.
|
||||
*
|
||||
|
@ -46,14 +46,6 @@ abstract class ActionFormBase extends EntityForm {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(array $form, FormStateInterface $form_state) {
|
||||
$this->plugin = $this->entity->getPlugin();
|
||||
return parent::buildForm($form, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -85,8 +77,8 @@ abstract class ActionFormBase extends EntityForm {
|
|||
'#value' => $this->entity->getType(),
|
||||
];
|
||||
|
||||
if ($this->plugin instanceof PluginFormInterface) {
|
||||
$form += $this->plugin->buildConfigurationForm($form, $form_state);
|
||||
if ($plugin = $this->getPlugin()) {
|
||||
$form += $plugin->buildConfigurationForm($form, $form_state);
|
||||
}
|
||||
|
||||
return parent::form($form, $form_state);
|
||||
|
@ -96,7 +88,7 @@ abstract class ActionFormBase extends EntityForm {
|
|||
* Determines if the action already exists.
|
||||
*
|
||||
* @param string $id
|
||||
* The action ID
|
||||
* The action ID.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if the action exists, FALSE otherwise.
|
||||
|
@ -120,9 +112,8 @@ abstract class ActionFormBase extends EntityForm {
|
|||
*/
|
||||
public function validateForm(array &$form, FormStateInterface $form_state) {
|
||||
parent::validateForm($form, $form_state);
|
||||
|
||||
if ($this->plugin instanceof PluginFormInterface) {
|
||||
$this->plugin->validateConfigurationForm($form, $form_state);
|
||||
if ($plugin = $this->getPlugin()) {
|
||||
$plugin->validateConfigurationForm($form, $form_state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,9 +122,8 @@ abstract class ActionFormBase extends EntityForm {
|
|||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
parent::submitForm($form, $form_state);
|
||||
|
||||
if ($this->plugin instanceof PluginFormInterface) {
|
||||
$this->plugin->submitConfigurationForm($form, $form_state);
|
||||
if ($plugin = $this->getPlugin()) {
|
||||
$plugin->submitConfigurationForm($form, $form_state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,9 +132,22 @@ abstract class ActionFormBase extends EntityForm {
|
|||
*/
|
||||
public function save(array $form, FormStateInterface $form_state) {
|
||||
$this->entity->save();
|
||||
drupal_set_message($this->t('The action has been successfully saved.'));
|
||||
$this->messenger()->addStatus($this->t('The action has been successfully saved.'));
|
||||
|
||||
$form_state->setRedirect('entity.action.collection');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the action plugin while ensuring it implements configuration form.
|
||||
*
|
||||
* @return \Drupal\Core\Action\ActionInterface|\Drupal\Core\Plugin\PluginFormInterface|null
|
||||
* The action plugin, or NULL if it does not implement configuration forms.
|
||||
*/
|
||||
protected function getPlugin() {
|
||||
if ($this->entity->getPlugin() instanceof PluginFormInterface) {
|
||||
return $this->entity->getPlugin();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -108,12 +108,12 @@ class ActionListBuilder extends ConfigEntityListBuilder {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function render() {
|
||||
$build['action_admin_manage_form'] = \Drupal::formBuilder()->getForm('Drupal\action\Form\ActionAdminManageForm');
|
||||
$build['action_header']['#markup'] = '<h3>' . $this->t('Available actions:') . '</h3>';
|
||||
$build['action_table'] = parent::render();
|
||||
if (!$this->hasConfigurableActions) {
|
||||
unset($build['action_table']['table']['#header']['operations']);
|
||||
}
|
||||
$build['action_admin_manage_form'] = \Drupal::formBuilder()->getForm('Drupal\action\Form\ActionAdminManageForm');
|
||||
return $build;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,13 +3,14 @@
|
|||
namespace Drupal\action\Form;
|
||||
|
||||
use Drupal\Core\Form\FormBase;
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\Core\Action\ActionManager;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Provides a configuration form for configurable actions.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class ActionAdminManageForm extends FormBase {
|
||||
|
||||
|
@ -53,10 +54,10 @@ class ActionAdminManageForm extends FormBase {
|
|||
$actions = [];
|
||||
foreach ($this->manager->getDefinitions() as $id => $definition) {
|
||||
if (is_subclass_of($definition['class'], '\Drupal\Core\Plugin\PluginFormInterface')) {
|
||||
$key = Crypt::hashBase64($id);
|
||||
$actions[$key] = $definition['label'] . '...';
|
||||
$actions[$id] = $definition['label'];
|
||||
}
|
||||
}
|
||||
asort($actions);
|
||||
$form['parent'] = [
|
||||
'#type' => 'details',
|
||||
'#title' => $this->t('Create an advanced action'),
|
||||
|
@ -68,10 +69,10 @@ class ActionAdminManageForm extends FormBase {
|
|||
'#title' => $this->t('Action'),
|
||||
'#title_display' => 'invisible',
|
||||
'#options' => $actions,
|
||||
'#empty_option' => $this->t('Choose an advanced action'),
|
||||
'#empty_option' => $this->t('- Select -'),
|
||||
];
|
||||
$form['parent']['actions'] = [
|
||||
'#type' => 'actions'
|
||||
'#type' => 'actions',
|
||||
];
|
||||
$form['parent']['actions']['submit'] = [
|
||||
'#type' => 'submit',
|
||||
|
|
|
@ -7,6 +7,8 @@ use Drupal\Core\Url;
|
|||
|
||||
/**
|
||||
* Builds a form to delete an action.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class ActionDeleteForm extends EntityDeleteForm {
|
||||
|
||||
|
|
|
@ -139,12 +139,11 @@ class EmailAction extends ConfigurableActionBase implements ContainerFactoryPlug
|
|||
}
|
||||
$params = ['context' => $this->configuration];
|
||||
|
||||
if ($this->mailManager->mail('system', 'action_send_email', $recipient, $langcode, $params)) {
|
||||
$message = $this->mailManager->mail('system', 'action_send_email', $recipient, $langcode, $params);
|
||||
// Error logging is handled by \Drupal\Core\Mail\MailManager::mail().
|
||||
if ($message['result']) {
|
||||
$this->logger->notice('Sent email to %recipient', ['%recipient' => $recipient]);
|
||||
}
|
||||
else {
|
||||
$this->logger->error('Unable to send email to %recipient', ['%recipient' => $recipient]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -40,7 +40,7 @@ class GotoAction extends ConfigurableActionBase implements ContainerFactoryPlugi
|
|||
protected $unroutedUrlAssembler;
|
||||
|
||||
/**
|
||||
* Constructs a new DeleteNode object.
|
||||
* Constructs a GotoAction object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
|
@ -92,7 +92,7 @@ class GotoAction extends ConfigurableActionBase implements ContainerFactoryPlugi
|
|||
$url = $this->unroutedUrlAssembler->assemble($uri, $options);
|
||||
}
|
||||
$response = new RedirectResponse($url);
|
||||
$listener = function($event) use ($response) {
|
||||
$listener = function ($event) use ($response) {
|
||||
$event->setResponse($response);
|
||||
};
|
||||
// Add the listener to the event dispatcher.
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace Drupal\action\Plugin\Action;
|
|||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Action\ConfigurableActionBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
@ -36,6 +37,13 @@ class MessageAction extends ConfigurableActionBase implements ContainerFactoryPl
|
|||
*/
|
||||
protected $renderer;
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Constructs a MessageAction object.
|
||||
*
|
||||
|
@ -49,19 +57,22 @@ class MessageAction extends ConfigurableActionBase implements ContainerFactoryPl
|
|||
* The token service.
|
||||
* @param \Drupal\Core\Render\RendererInterface $renderer
|
||||
* The renderer.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, Token $token, RendererInterface $renderer) {
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, Token $token, RendererInterface $renderer, MessengerInterface $messenger) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
|
||||
$this->token = $token;
|
||||
$this->renderer = $renderer;
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static($configuration, $plugin_id, $plugin_definition, $container->get('token'), $container->get('renderer'));
|
||||
return new static($configuration, $plugin_id, $plugin_definition, $container->get('token'), $container->get('renderer'), $container->get('messenger'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,7 +88,7 @@ class MessageAction extends ConfigurableActionBase implements ContainerFactoryPl
|
|||
];
|
||||
|
||||
// @todo Fix in https://www.drupal.org/node/2577827
|
||||
drupal_set_message($this->renderer->renderPlain($build));
|
||||
$this->messenger->addStatus($this->renderer->renderPlain($build));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,7 +10,7 @@ use Drupal\migrate\Row;
|
|||
*
|
||||
* @MigrateSource(
|
||||
* id = "action",
|
||||
* source_provider = "system"
|
||||
* source_module = "system"
|
||||
* )
|
||||
*/
|
||||
class Action extends DrupalSqlBase {
|
||||
|
|
|
@ -5,6 +5,6 @@ package: Testing
|
|||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- action
|
||||
- views
|
||||
- node
|
||||
- drupal:action
|
||||
- drupal:views
|
||||
- drupal:node
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
name: action_form_ajax_test
|
||||
type: module
|
||||
description: 'module used for testing ajax in action config entity forms.'
|
||||
package: Core
|
||||
version: VERSION
|
||||
core: 8.x
|
||||
hidden: true
|
|
@ -0,0 +1,7 @@
|
|||
action.configuration.action_form_ajax_test:
|
||||
type: action_configuration_default
|
||||
label: 'action_form_ajax_test action'
|
||||
mapping:
|
||||
party_time:
|
||||
type: string
|
||||
label: 'The time of the party.'
|
|
@ -0,0 +1,89 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\action_form_ajax_test\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Action\ConfigurableActionBase;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
|
||||
/**
|
||||
* Plugin used for testing AJAX in action config entity forms.
|
||||
*
|
||||
* @Action(
|
||||
* id = "action_form_ajax_test",
|
||||
* label = @Translation("action_form_ajax_test"),
|
||||
* type = "system"
|
||||
* )
|
||||
*/
|
||||
class ActionAjaxTest extends ConfigurableActionBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function defaultConfiguration() {
|
||||
return [
|
||||
'party_time' => '',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
||||
$result = AccessResult::allowed();
|
||||
return $return_as_object ? $result : $result->isAllowed();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function execute() {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
||||
$having_a_party = $form_state->getValue('having_a_party', !empty($this->configuration['party_time']));
|
||||
$form['having_a_party'] = [
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $this->t('Are we having a party?'),
|
||||
'#ajax' => [
|
||||
'wrapper' => 'party-container',
|
||||
'callback' => [$this, 'partyCallback'],
|
||||
],
|
||||
'#default_value' => $having_a_party,
|
||||
];
|
||||
$form['container'] = [
|
||||
'#type' => 'container',
|
||||
'#prefix' => '<div id="party-container">',
|
||||
'#suffix' => '</div>',
|
||||
];
|
||||
|
||||
if ($having_a_party) {
|
||||
$form['container']['party_time'] = [
|
||||
'#type' => 'textfield',
|
||||
'#title' => $this->t('Party time'),
|
||||
'#default_value' => $this->configuration['party_time'],
|
||||
];
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for party checkbox.
|
||||
*/
|
||||
public function partyCallback(array $form, FormStateInterface $form_state) {
|
||||
return $form['container'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
|
||||
$this->configuration['party_time'] = $form_state->getValue('party_time');
|
||||
}
|
||||
|
||||
}
|
|
@ -28,10 +28,10 @@ class ActionListTest extends BrowserTestBase {
|
|||
// Ensure the empty text appears on the action list page.
|
||||
/** @var $storage \Drupal\Core\Entity\EntityStorageInterface */
|
||||
$storage = $this->container->get('entity.manager')->getStorage('action');
|
||||
$actions = $storage->loadMultiple();
|
||||
$actions = $storage->loadMultiple();
|
||||
$storage->delete($actions);
|
||||
$this->drupalGet('/admin/config/system/actions');
|
||||
$this->assertRaw('There is no Action yet.');
|
||||
$this->assertRaw('There are no actions yet.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ class ActionUninstallTest extends BrowserTestBase {
|
|||
|
||||
$storage = $this->container->get('entity_type.manager')->getStorage('action');
|
||||
$storage->resetCache(['user_block_user_action']);
|
||||
$this->assertTrue($storage->load('user_block_user_action'), 'Configuration entity \'user_block_user_action\' still exists after uninstalling action module.' );
|
||||
$this->assertTrue($storage->load('user_block_user_action'), 'Configuration entity \'user_block_user_action\' still exists after uninstalling action module.');
|
||||
|
||||
$admin_user = $this->drupalCreateUser(['administer users']);
|
||||
$this->drupalLogin($admin_user);
|
||||
|
|
|
@ -148,7 +148,7 @@ class BulkFormTest extends BrowserTestBase {
|
|||
$errors = $this->xpath('//div[contains(@class, "messages--status")]');
|
||||
$this->assertFalse($errors, 'No action message shown.');
|
||||
$this->drupalPostForm(NULL, [], t('Delete'));
|
||||
$this->assertText(t('Deleted 5 posts.'));
|
||||
$this->assertText(t('Deleted 5 content items.'));
|
||||
// Check if we got redirected to the original page.
|
||||
$this->assertUrl('test_bulk_form');
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Drupal\Tests\action\Functional;
|
||||
|
||||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\system\Entity\Action;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
|
@ -31,7 +30,7 @@ class ConfigurationTest extends BrowserTestBase {
|
|||
|
||||
// Make a POST request to admin/config/system/actions.
|
||||
$edit = [];
|
||||
$edit['action'] = Crypt::hashBase64('action_goto_action');
|
||||
$edit['action'] = 'action_goto_action';
|
||||
$this->drupalPostForm('admin/config/system/actions', $edit, t('Create'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
|
@ -41,17 +40,18 @@ class ConfigurationTest extends BrowserTestBase {
|
|||
$edit['label'] = $action_label;
|
||||
$edit['id'] = strtolower($action_label);
|
||||
$edit['url'] = 'admin';
|
||||
$this->drupalPostForm('admin/config/system/actions/add/' . Crypt::hashBase64('action_goto_action'), $edit, t('Save'));
|
||||
$this->drupalPostForm('admin/config/system/actions/add/action_goto_action', $edit, t('Save'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
$action_id = $edit['id'];
|
||||
|
||||
// Make sure that the new complex action was saved properly.
|
||||
$this->assertText(t('The action has been successfully saved.'), "Make sure we get a confirmation that we've successfully saved the complex action.");
|
||||
$this->assertText($action_label, "Make sure the action label appears on the configuration page after we've saved the complex action.");
|
||||
|
||||
// Make another POST request to the action edit page.
|
||||
$this->clickLink(t('Configure'));
|
||||
preg_match('|admin/config/system/actions/configure/(.+)|', $this->getUrl(), $matches);
|
||||
$aid = $matches[1];
|
||||
|
||||
$edit = [];
|
||||
$new_action_label = $this->randomMachineName();
|
||||
$edit['label'] = $new_action_label;
|
||||
|
@ -73,7 +73,7 @@ class ConfigurationTest extends BrowserTestBase {
|
|||
$this->clickLink(t('Delete'));
|
||||
$this->assertResponse(200);
|
||||
$edit = [];
|
||||
$this->drupalPostForm("admin/config/system/actions/configure/$aid/delete", $edit, t('Delete'));
|
||||
$this->drupalPostForm(NULL, $edit, t('Delete'));
|
||||
$this->assertResponse(200);
|
||||
|
||||
// Make sure that the action was actually deleted.
|
||||
|
@ -82,7 +82,7 @@ class ConfigurationTest extends BrowserTestBase {
|
|||
$this->assertResponse(200);
|
||||
$this->assertNoText($new_action_label, "Make sure the action label does not appear on the overview page after we've deleted the action.");
|
||||
|
||||
$action = Action::load($aid);
|
||||
$action = Action::load($action_id);
|
||||
$this->assertFalse($action, 'Make sure the action is gone after being deleted.');
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\action\FunctionalJavascript;
|
||||
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
|
||||
use Drupal\system\Entity\Action;
|
||||
|
||||
/**
|
||||
* Tests action plugins using Javascript.
|
||||
*
|
||||
* @group action
|
||||
*/
|
||||
class ActionFormAjaxTest extends WebDriverTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $modules = ['action', 'action_form_ajax_test'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$user = $this->drupalCreateUser(['administer actions']);
|
||||
$this->drupalLogin($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests action plugins with AJAX save their configuration.
|
||||
*/
|
||||
public function testActionConfigurationWithAjax() {
|
||||
$url = Url::fromRoute('action.admin_add', ['action_id' => 'action_form_ajax_test']);
|
||||
$this->drupalGet($url);
|
||||
$page = $this->getSession()->getPage();
|
||||
|
||||
$id = 'test_plugin';
|
||||
$this->assertSession()->waitForElementVisible('named', ['button', 'Edit'])->press();
|
||||
$this->assertSession()->waitForElementVisible('css', '[name="id"]')->setValue($id);
|
||||
|
||||
$page->find('css', '[name="having_a_party"]')
|
||||
->check();
|
||||
$this->assertSession()->waitForElementVisible('css', '[name="party_time"]');
|
||||
|
||||
$party_time = 'Evening';
|
||||
$page->find('css', '[name="party_time"]')
|
||||
->setValue($party_time);
|
||||
|
||||
$page->find('css', '[value="Save"]')
|
||||
->click();
|
||||
|
||||
$url = Url::fromRoute('entity.action.collection');
|
||||
$this->assertSession()->pageTextContains('The action has been successfully saved.');
|
||||
$this->assertSession()->addressEquals($url);
|
||||
|
||||
// Check storage.
|
||||
$instance = Action::load($id);
|
||||
$configuration = $instance->getPlugin()->getConfiguration();
|
||||
$this->assertEquals(['party_time' => $party_time], $configuration);
|
||||
|
||||
// Configuration should be shown in edit form.
|
||||
$this->drupalGet($instance->toUrl('edit-form'));
|
||||
$this->assertSession()->checkboxChecked('having_a_party');
|
||||
$this->assertSession()->fieldValueEquals('party_time', $party_time);
|
||||
}
|
||||
|
||||
}
|
|
@ -40,7 +40,7 @@ class MigrateActionsTest extends MigrateDrupal6TestBase {
|
|||
$this->assertEntity('send_e_mail', 'Send e-mail', 'system', [
|
||||
"recipient" => "test@example.com",
|
||||
"subject" => "Drupal migration test",
|
||||
"message" => "Drupal migration test"
|
||||
"message" => "Drupal migration test",
|
||||
]);
|
||||
$this->assertEntity('redirect_to_url', 'Redirect to URL', 'system', ["url" => "https://www.drupal.org"]);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ class MigrateActionsTest extends MigrateDrupal7TestBase {
|
|||
$this->assertEntity('send_e_mail', 'Send e-mail', 'system', [
|
||||
"recipient" => "test@example.com",
|
||||
"subject" => "Drupal migration test",
|
||||
"message" => "Drupal migration test"
|
||||
"message" => "Drupal migration test",
|
||||
]);
|
||||
$this->assertEntity('redirect_to_url', 'Redirect to URL', 'system', ["url" => "https://www.drupal.org"]);
|
||||
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\action\Kernel\Plugin\Action;
|
||||
|
||||
use Drupal\Core\Test\AssertMailTrait;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
/**
|
||||
* Tests for the EmailAction plugin.
|
||||
*
|
||||
* @group action
|
||||
*/
|
||||
class EmailActionTest extends KernelTestBase {
|
||||
use AssertMailTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['system', 'user', 'action', 'dblog'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->installEntitySchema('user');
|
||||
$this->installSchema('dblog', ['watchdog']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the email action plugin.
|
||||
*/
|
||||
public function testEmailAction() {
|
||||
/** @var \Drupal\Core\Action\ActionManager $plugin_manager */
|
||||
$plugin_manager = $this->container->get('plugin.manager.action');
|
||||
$configuration = [
|
||||
'recipient' => 'test@example.com',
|
||||
'subject' => 'Test subject',
|
||||
'message' => 'Test message',
|
||||
];
|
||||
$plugin_manager
|
||||
->createInstance('action_send_email_action', $configuration)
|
||||
->execute();
|
||||
|
||||
$mails = $this->getMails();
|
||||
$this->assertCount(1, $this->getMails());
|
||||
$this->assertEquals('test@example.com', $mails[0]['to']);
|
||||
$this->assertEquals('Test subject', $mails[0]['subject']);
|
||||
$this->assertEquals("Test message\n", $mails[0]['body']);
|
||||
|
||||
// Ensure that the email sending is logged.
|
||||
$log = \Drupal::database()
|
||||
->select('watchdog', 'w')
|
||||
->fields('w', ['message', 'variables'])
|
||||
->orderBy('wid', 'DESC')
|
||||
->range(0, 1)
|
||||
->execute()
|
||||
->fetch();
|
||||
|
||||
$this->assertEquals($log->message, 'Sent email to %recipient');
|
||||
$variables = unserialize($log->variables);
|
||||
$this->assertEquals($variables['%recipient'], 'test@example.com');
|
||||
}
|
||||
|
||||
}
|
|
@ -15,7 +15,7 @@ class ActionTest extends MigrateSqlSourceTestBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['action', 'migrate_drupal'];
|
||||
public static $modules = ['action', 'migrate_drupal', 'system'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
|
|
@ -6,5 +6,5 @@ version: VERSION
|
|||
core: 8.x
|
||||
configure: aggregator.admin_settings
|
||||
dependencies:
|
||||
- file
|
||||
- options
|
||||
- drupal:file
|
||||
- drupal:options
|
||||
|
|
|
@ -40,3 +40,13 @@ function aggregator_update_8200() {
|
|||
$field_definition->setRequired(TRUE);
|
||||
$definition_update_manager->updateFieldStorageDefinition($field_definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a default value for the 'Refresh' field for aggregator feed entities.
|
||||
*/
|
||||
function aggregator_update_8501() {
|
||||
$definition_update_manager = \Drupal::entityDefinitionUpdateManager();
|
||||
$field_definition = $definition_update_manager->getFieldStorageDefinition('refresh', 'aggregator_feed');
|
||||
$field_definition->setDefaultValue(3600);
|
||||
$definition_update_manager->updateFieldStorageDefinition($field_definition);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ use Drupal\Core\Routing\RouteMatchInterface;
|
|||
*
|
||||
* @deprecated in Drupal 8.3.x and will be removed before Drupal 9.0.0.
|
||||
* Use \Drupal\aggregator\FeedStorageInterface::CLEAR_NEVER instead.
|
||||
*
|
||||
* @see https://www.drupal.org/node/2831620
|
||||
*/
|
||||
const AGGREGATOR_CLEAR_NEVER = 0;
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
id: d6_aggregator_feed
|
||||
label: Aggregator feeds
|
||||
audit: true
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Content
|
||||
source:
|
||||
plugin: aggregator_feed
|
||||
process:
|
|
@ -1,7 +1,9 @@
|
|||
id: d6_aggregator_item
|
||||
label: Aggregator items
|
||||
audit: true
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Content
|
||||
source:
|
||||
plugin: aggregator_item
|
||||
process:
|
|
@ -2,6 +2,7 @@ id: d6_aggregator_settings
|
|||
label: Aggregator configuration
|
||||
migration_tags:
|
||||
- Drupal 6
|
||||
- Configuration
|
||||
source:
|
||||
plugin: variable
|
||||
variables:
|
||||
|
@ -12,6 +13,7 @@ source:
|
|||
- aggregator_teaser_length
|
||||
- aggregator_clear
|
||||
- aggregator_summary_items
|
||||
source_module: aggregator
|
||||
process:
|
||||
fetcher: aggregator_fetcher
|
||||
parser: aggregator_parser
|
|
@ -1,7 +1,9 @@
|
|||
id: d7_aggregator_feed
|
||||
label: Aggregator feeds
|
||||
audit: true
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Content
|
||||
source:
|
||||
plugin: aggregator_feed
|
||||
process:
|
|
@ -1,7 +1,9 @@
|
|||
id: d7_aggregator_item
|
||||
label: Aggregator items
|
||||
audit: true
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Content
|
||||
source:
|
||||
plugin: aggregator_item
|
||||
process:
|
|
@ -2,6 +2,7 @@ id: d7_aggregator_settings
|
|||
label: Aggregator configuration
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Configuration
|
||||
source:
|
||||
plugin: variable
|
||||
variables:
|
||||
|
@ -12,6 +13,7 @@ source:
|
|||
- aggregator_teaser_length
|
||||
- aggregator_clear
|
||||
- aggregator_summary_items
|
||||
source_module: aggregator
|
||||
process:
|
||||
fetcher: aggregator_fetcher
|
||||
parser: aggregator_parser
|
|
@ -25,7 +25,7 @@ class AggregatorController extends ControllerBase {
|
|||
* Constructs a \Drupal\aggregator\Controller\AggregatorController object.
|
||||
*
|
||||
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
|
||||
* The date formatter service.
|
||||
* The date formatter service.
|
||||
*/
|
||||
public function __construct(DateFormatterInterface $date_formatter) {
|
||||
$this->dateFormatter = $date_formatter;
|
||||
|
@ -44,13 +44,11 @@ class AggregatorController extends ControllerBase {
|
|||
* Presents the aggregator feed creation form.
|
||||
*
|
||||
* @return array
|
||||
* A form array as expected by drupal_render().
|
||||
* A form array as expected by
|
||||
* \Drupal\Core\Render\RendererInterface::render().
|
||||
*/
|
||||
public function feedAdd() {
|
||||
$feed = $this->entityManager()->getStorage('aggregator_feed')
|
||||
->create([
|
||||
'refresh' => 3600,
|
||||
]);
|
||||
$feed = $this->entityManager()->getStorage('aggregator_feed')->create();
|
||||
return $this->entityFormBuilder()->getForm($feed);
|
||||
}
|
||||
|
||||
|
@ -96,7 +94,7 @@ class AggregatorController extends ControllerBase {
|
|||
$message = $aggregator_feed->refreshItems()
|
||||
? $this->t('There is new syndicated content from %site.', ['%site' => $aggregator_feed->label()])
|
||||
: $this->t('There is no new syndicated content from %site.', ['%site' => $aggregator_feed->label()]);
|
||||
drupal_set_message($message);
|
||||
$this->messenger()->addStatus($message);
|
||||
return $this->redirect('aggregator.admin_overview');
|
||||
}
|
||||
|
||||
|
@ -104,7 +102,8 @@ class AggregatorController extends ControllerBase {
|
|||
* Displays the aggregator administration page.
|
||||
*
|
||||
* @return array
|
||||
* A render array as expected by drupal_render().
|
||||
* A render array as expected by
|
||||
* \Drupal\Core\Render\RendererInterface::render().
|
||||
*/
|
||||
public function adminOverview() {
|
||||
$entity_manager = $this->entityManager();
|
||||
|
|
|
@ -14,6 +14,13 @@ use Drupal\aggregator\FeedInterface;
|
|||
* @ContentEntityType(
|
||||
* id = "aggregator_feed",
|
||||
* label = @Translation("Aggregator feed"),
|
||||
* label_collection = @Translation("Aggregator feeds"),
|
||||
* label_singular = @Translation("aggregator feed"),
|
||||
* label_plural = @Translation("aggregator feeds"),
|
||||
* label_count = @PluralTranslation(
|
||||
* singular = "@count aggregator feed",
|
||||
* plural = "@count aggregator feeds",
|
||||
* ),
|
||||
* handlers = {
|
||||
* "storage" = "Drupal\aggregator\FeedStorage",
|
||||
* "storage_schema" = "Drupal\aggregator\FeedStorageSchema",
|
||||
|
@ -168,6 +175,7 @@ class Feed extends ContentEntityBase implements FeedInterface {
|
|||
$fields['refresh'] = BaseFieldDefinition::create('list_integer')
|
||||
->setLabel(t('Update interval'))
|
||||
->setDescription(t('The length of time between feed updates. Requires a correctly configured cron maintenance task.'))
|
||||
->setDefaultValue(3600)
|
||||
->setSetting('unsigned', TRUE)
|
||||
->setRequired(TRUE)
|
||||
->setSetting('allowed_values', $period)
|
||||
|
|
|
@ -16,6 +16,13 @@ use Drupal\Core\Url;
|
|||
* @ContentEntityType(
|
||||
* id = "aggregator_item",
|
||||
* label = @Translation("Aggregator feed item"),
|
||||
* label_collection = @Translation("Aggregator feed items"),
|
||||
* label_singular = @Translation("aggregator feed item"),
|
||||
* label_plural = @Translation("aggregator feed items"),
|
||||
* label_count = @PluralTranslation(
|
||||
* singular = "@count aggregator feed item",
|
||||
* plural = "@count aggregator feed items",
|
||||
* ),
|
||||
* handlers = {
|
||||
* "storage" = "Drupal\aggregator\ItemStorage",
|
||||
* "storage_schema" = "Drupal\aggregator\ItemStorageSchema",
|
||||
|
@ -232,7 +239,6 @@ class Item extends ContentEntityBase implements ItemInterface {
|
|||
return Feed::load($this->getFeedId())->getCacheTags();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Entity URI callback.
|
||||
*/
|
||||
|
|
|
@ -8,6 +8,8 @@ use Drupal\Core\Url;
|
|||
|
||||
/**
|
||||
* Form handler for the aggregator feed edit forms.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class FeedForm extends ContentEntityForm {
|
||||
|
||||
|
@ -20,12 +22,12 @@ class FeedForm extends ContentEntityForm {
|
|||
$label = $feed->label();
|
||||
$view_link = $feed->link($label, 'canonical');
|
||||
if ($status == SAVED_UPDATED) {
|
||||
drupal_set_message($this->t('The feed %feed has been updated.', ['%feed' => $view_link]));
|
||||
$this->messenger()->addStatus($this->t('The feed %feed has been updated.', ['%feed' => $view_link]));
|
||||
$form_state->setRedirectUrl($feed->urlInfo('canonical'));
|
||||
}
|
||||
else {
|
||||
$this->logger('aggregator')->notice('Feed %feed added.', ['%feed' => $feed->label(), 'link' => $this->l($this->t('View'), new Url('aggregator.admin_overview'))]);
|
||||
drupal_set_message($this->t('The feed %feed has been added.', ['%feed' => $view_link]));
|
||||
$this->messenger()->addStatus($this->t('The feed %feed has been added.', ['%feed' => $view_link]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ class FeedStorage extends SqlContentEntityStorage implements FeedStorageInterfac
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFeedIdsToRefresh() {
|
||||
return $this->database->query('SELECT fid FROM {aggregator_feed} WHERE queued = 0 AND checked + refresh < :time AND refresh <> :never', [
|
||||
return $this->database->query('SELECT fid FROM {' . $this->getBaseTable() . '} WHERE queued = 0 AND checked + refresh < :time AND refresh <> :never', [
|
||||
':time' => REQUEST_TIME,
|
||||
':never' => AGGREGATOR_CLEAR_NEVER,
|
||||
])->fetchCol();
|
||||
|
|
|
@ -17,7 +17,7 @@ class FeedStorageSchema extends SqlContentEntityStorageSchema {
|
|||
$schema = parent::getSharedTableFieldSchema($storage_definition, $table_name, $column_mapping);
|
||||
$field_name = $storage_definition->getName();
|
||||
|
||||
if ($table_name == 'aggregator_feed') {
|
||||
if ($table_name == $this->storage->getBaseTable()) {
|
||||
switch ($field_name) {
|
||||
case 'url':
|
||||
$this->addSharedTableFieldIndex($storage_definition, $schema, TRUE, 255);
|
||||
|
|
|
@ -7,6 +7,8 @@ use Drupal\Core\Url;
|
|||
|
||||
/**
|
||||
* Provides a form for deleting a feed.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class FeedDeleteForm extends ContentEntityDeleteForm {
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ use Drupal\Core\Url;
|
|||
|
||||
/**
|
||||
* Provides a deletion confirmation form for items that belong to a feed.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class FeedItemsDeleteForm extends ContentEntityConfirmFormBase {
|
||||
|
||||
|
|
|
@ -12,6 +12,8 @@ use GuzzleHttp\ClientInterface;
|
|||
|
||||
/**
|
||||
* Imports feeds from OPML.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class OpmlFeedAdd extends FormBase {
|
||||
|
||||
|
@ -121,14 +123,14 @@ class OpmlFeedAdd extends FormBase {
|
|||
}
|
||||
catch (RequestException $e) {
|
||||
$this->logger('aggregator')->warning('Failed to download OPML file due to "%error".', ['%error' => $e->getMessage()]);
|
||||
drupal_set_message($this->t('Failed to download OPML file due to "%error".', ['%error' => $e->getMessage()]));
|
||||
$this->messenger()->addStatus($this->t('Failed to download OPML file due to "%error".', ['%error' => $e->getMessage()]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$feeds = $this->parseOpml($data);
|
||||
if (empty($feeds)) {
|
||||
drupal_set_message($this->t('No new feed has been added.'));
|
||||
$this->messenger()->addStatus($this->t('No new feed has been added.'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -136,7 +138,7 @@ class OpmlFeedAdd extends FormBase {
|
|||
foreach ($feeds as $feed) {
|
||||
// Ensure URL is valid.
|
||||
if (!UrlHelper::isValid($feed['url'], TRUE)) {
|
||||
drupal_set_message($this->t('The URL %url is invalid.', ['%url' => $feed['url']]), 'warning');
|
||||
$this->messenger()->addWarning($this->t('The URL %url is invalid.', ['%url' => $feed['url']]));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -151,11 +153,11 @@ class OpmlFeedAdd extends FormBase {
|
|||
$result = $this->feedStorage->loadMultiple($ids);
|
||||
foreach ($result as $old) {
|
||||
if (strcasecmp($old->label(), $feed['title']) == 0) {
|
||||
drupal_set_message($this->t('A feed named %title already exists.', ['%title' => $old->label()]), 'warning');
|
||||
$this->messenger()->addWarning($this->t('A feed named %title already exists.', ['%title' => $old->label()]));
|
||||
continue 2;
|
||||
}
|
||||
if (strcasecmp($old->getUrl(), $feed['url']) == 0) {
|
||||
drupal_set_message($this->t('A feed with the URL %url already exists.', ['%url' => $old->getUrl()]), 'warning');
|
||||
$this->messenger()->addWarning($this->t('A feed with the URL %url already exists.', ['%url' => $old->getUrl()]));
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
namespace Drupal\aggregator\Form;
|
||||
|
||||
use Drupal\aggregator\Plugin\AggregatorPluginManager;
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Plugin\PluginFormInterface;
|
||||
|
@ -13,6 +13,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
|
||||
/**
|
||||
* Configures aggregator settings for this site.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class SettingsForm extends ConfigFormBase {
|
||||
|
||||
|
@ -66,7 +68,7 @@ class SettingsForm extends ConfigFormBase {
|
|||
// Get all available fetcher, parser and processor definitions.
|
||||
foreach (['fetcher', 'parser', 'processor'] as $type) {
|
||||
foreach ($this->managers[$type]->getDefinitions() as $id => $definition) {
|
||||
$this->definitions[$type][$id] = SafeMarkup::format('@title <span class="description">@description</span>', ['@title' => $definition['title'], '@description' => $definition['description']]);
|
||||
$this->definitions[$type][$id] = new FormattableMarkup('@title <span class="description">@description</span>', ['@title' => $definition['title'], '@description' => $definition['description']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ class ItemStorageSchema extends SqlContentEntityStorageSchema {
|
|||
$schema = parent::getSharedTableFieldSchema($storage_definition, $table_name, $column_mapping);
|
||||
$field_name = $storage_definition->getName();
|
||||
|
||||
if ($table_name == 'aggregator_item') {
|
||||
if ($table_name == $this->storage->getBaseTable()) {
|
||||
switch ($field_name) {
|
||||
case 'timestamp':
|
||||
$this->addSharedTableFieldIndex($storage_definition, $schema, TRUE);
|
||||
|
|
|
@ -94,7 +94,7 @@ class ItemsImporter implements ItemsImporterInterface {
|
|||
watchdog_exception('aggregator', $e);
|
||||
}
|
||||
|
||||
// Store instances in an array so we dont have to instantiate new objects.
|
||||
// Store instances in an array so we don't have to instantiate new objects.
|
||||
$processor_instances = [];
|
||||
foreach ($this->config->get('processors') as $processor) {
|
||||
try {
|
||||
|
|
|
@ -57,7 +57,6 @@ class AggregatorFeedBlock extends BlockBase implements ContainerFactoryPluginInt
|
|||
$this->itemStorage = $item_storage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -71,7 +70,6 @@ class AggregatorFeedBlock extends BlockBase implements ContainerFactoryPluginInt
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -167,8 +165,10 @@ class AggregatorFeedBlock extends BlockBase implements ContainerFactoryPluginInt
|
|||
*/
|
||||
public function getCacheTags() {
|
||||
$cache_tags = parent::getCacheTags();
|
||||
$feed = $this->feedStorage->load($this->configuration['feed']);
|
||||
return Cache::mergeTags($cache_tags, $feed->getCacheTags());
|
||||
if ($feed = $this->feedStorage->load($this->configuration['feed'])) {
|
||||
$cache_tags = Cache::mergeTags($cache_tags, $feed->getCacheTags());
|
||||
}
|
||||
return $cache_tags;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ use Drupal\Core\Url;
|
|||
* )
|
||||
*/
|
||||
class AggregatorTitleFormatter extends FormatterBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -6,6 +6,7 @@ use Drupal\aggregator\Plugin\FetcherInterface;
|
|||
use Drupal\aggregator\FeedInterface;
|
||||
use Drupal\Component\Datetime\DateTimePlus;
|
||||
use Drupal\Core\Http\ClientFactory;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
|
@ -42,6 +43,13 @@ class DefaultFetcher implements FetcherInterface, ContainerFactoryPluginInterfac
|
|||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Constructs a DefaultFetcher object.
|
||||
*
|
||||
|
@ -49,10 +57,13 @@ class DefaultFetcher implements FetcherInterface, ContainerFactoryPluginInterfac
|
|||
* A Guzzle client object.
|
||||
* @param \Psr\Log\LoggerInterface $logger
|
||||
* A logger instance.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(ClientFactory $http_client_factory, LoggerInterface $logger) {
|
||||
public function __construct(ClientFactory $http_client_factory, LoggerInterface $logger, MessengerInterface $messenger) {
|
||||
$this->httpClientFactory = $http_client_factory;
|
||||
$this->logger = $logger;
|
||||
$this->messenger = $messenger;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,7 +72,8 @@ class DefaultFetcher implements FetcherInterface, ContainerFactoryPluginInterfac
|
|||
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
||||
return new static(
|
||||
$container->get('http_client_factory'),
|
||||
$container->get('logger.factory')->get('aggregator')
|
||||
$container->get('logger.factory')->get('aggregator'),
|
||||
$container->get('messenger')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -84,11 +96,13 @@ class DefaultFetcher implements FetcherInterface, ContainerFactoryPluginInterfac
|
|||
|
||||
/** @var \Psr\Http\Message\UriInterface $actual_uri */
|
||||
$actual_uri = NULL;
|
||||
$response = $this->httpClientFactory->fromOptions(['allow_redirects' => [
|
||||
'on_redirect' => function(RequestInterface $request, ResponseInterface $response, UriInterface $uri) use (&$actual_uri) {
|
||||
$actual_uri = (string) $uri;
|
||||
}
|
||||
]])->send($request);
|
||||
$response = $this->httpClientFactory->fromOptions([
|
||||
'allow_redirects' => [
|
||||
'on_redirect' => function (RequestInterface $request, ResponseInterface $response, UriInterface $uri) use (&$actual_uri) {
|
||||
$actual_uri = (string) $uri;
|
||||
},
|
||||
],
|
||||
])->send($request);
|
||||
|
||||
// In case of a 304 Not Modified, there is no new content, so return
|
||||
// FALSE.
|
||||
|
@ -113,7 +127,7 @@ class DefaultFetcher implements FetcherInterface, ContainerFactoryPluginInterfac
|
|||
}
|
||||
catch (RequestException $e) {
|
||||
$this->logger->warning('The feed from %site seems to be broken because of error "%error".', ['%site' => $feed->label(), '%error' => $e->getMessage()]);
|
||||
drupal_set_message(t('The feed from %site seems to be broken because of error "%error".', ['%site' => $feed->label(), '%error' => $e->getMessage()]), 'warning');
|
||||
$this->messenger->addWarning(t('The feed from %site seems to be broken because of error "%error".', ['%site' => $feed->label(), '%error' => $e->getMessage()]));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Drupal\aggregator\Plugin\aggregator\parser;
|
|||
|
||||
use Drupal\aggregator\Plugin\ParserInterface;
|
||||
use Drupal\aggregator\FeedInterface;
|
||||
use Drupal\Core\Messenger\MessengerTrait;
|
||||
use Zend\Feed\Reader\Reader;
|
||||
use Zend\Feed\Reader\Exception\ExceptionInterface;
|
||||
|
||||
|
@ -20,6 +21,8 @@ use Zend\Feed\Reader\Exception\ExceptionInterface;
|
|||
*/
|
||||
class DefaultParser implements ParserInterface {
|
||||
|
||||
use MessengerTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -31,7 +34,7 @@ class DefaultParser implements ParserInterface {
|
|||
}
|
||||
catch (ExceptionInterface $e) {
|
||||
watchdog_exception('aggregator', $e);
|
||||
drupal_set_message(t('The feed from %site seems to be broken because of error "%error".', ['%site' => $feed->label(), '%error' => $e->getMessage()]), 'error');
|
||||
$this->messenger()->addError(t('The feed from %site seems to be broken because of error "%error".', ['%site' => $feed->label(), '%error' => $e->getMessage()]));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -3,15 +3,16 @@
|
|||
namespace Drupal\aggregator\Plugin\aggregator\processor;
|
||||
|
||||
use Drupal\aggregator\Entity\Item;
|
||||
use Drupal\aggregator\FeedInterface;
|
||||
use Drupal\aggregator\ItemStorageInterface;
|
||||
use Drupal\aggregator\Plugin\AggregatorPluginSettingsBase;
|
||||
use Drupal\aggregator\Plugin\ProcessorInterface;
|
||||
use Drupal\aggregator\FeedInterface;
|
||||
use Drupal\Component\Utility\Unicode;
|
||||
use Drupal\Core\Config\ConfigFactoryInterface;
|
||||
use Drupal\Core\Datetime\DateFormatterInterface;
|
||||
use Drupal\Core\Form\ConfigFormBaseTrait;
|
||||
use Drupal\Core\Form\FormStateInterface;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\Core\Routing\UrlGeneratorTrait;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
@ -28,6 +29,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
* )
|
||||
*/
|
||||
class DefaultProcessor extends AggregatorPluginSettingsBase implements ProcessorInterface, ContainerFactoryPluginInterface {
|
||||
|
||||
use ConfigFormBaseTrait;
|
||||
use UrlGeneratorTrait;
|
||||
|
||||
|
@ -52,6 +54,13 @@ class DefaultProcessor extends AggregatorPluginSettingsBase implements Processor
|
|||
*/
|
||||
protected $dateFormatter;
|
||||
|
||||
/**
|
||||
* The messenger.
|
||||
*
|
||||
* @var \Drupal\Core\Messenger\MessengerInterface
|
||||
*/
|
||||
protected $messenger;
|
||||
|
||||
/**
|
||||
* Constructs a DefaultProcessor object.
|
||||
*
|
||||
|
@ -67,11 +76,14 @@ class DefaultProcessor extends AggregatorPluginSettingsBase implements Processor
|
|||
* The entity storage for feed items.
|
||||
* @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
|
||||
* The date formatter service.
|
||||
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
|
||||
* The messenger.
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config, ItemStorageInterface $item_storage, DateFormatterInterface $date_formatter) {
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config, ItemStorageInterface $item_storage, DateFormatterInterface $date_formatter, MessengerInterface $messenger) {
|
||||
$this->configFactory = $config;
|
||||
$this->itemStorage = $item_storage;
|
||||
$this->dateFormatter = $date_formatter;
|
||||
$this->messenger = $messenger;
|
||||
// @todo Refactor aggregator plugins to ConfigEntity so merging
|
||||
// the configuration here is not needed.
|
||||
parent::__construct($configuration + $this->getConfiguration(), $plugin_id, $plugin_definition);
|
||||
|
@ -87,7 +99,8 @@ class DefaultProcessor extends AggregatorPluginSettingsBase implements Processor
|
|||
$plugin_definition,
|
||||
$container->get('config.factory'),
|
||||
$container->get('entity_type.manager')->getStorage('aggregator_item'),
|
||||
$container->get('date.formatter')
|
||||
$container->get('date.formatter'),
|
||||
$container->get('messenger')
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -141,7 +154,7 @@ class DefaultProcessor extends AggregatorPluginSettingsBase implements Processor
|
|||
];
|
||||
|
||||
$lengths = [0, 200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000];
|
||||
$options = array_map(function($length) {
|
||||
$options = array_map(function ($length) {
|
||||
return ($length == 0) ? t('Unlimited') : $this->formatPlural($length, '1 character', '@count characters');
|
||||
}, array_combine($lengths, $lengths));
|
||||
|
||||
|
@ -231,7 +244,7 @@ class DefaultProcessor extends AggregatorPluginSettingsBase implements Processor
|
|||
$this->itemStorage->delete($items);
|
||||
}
|
||||
// @todo This should be moved out to caller with a different message maybe.
|
||||
drupal_set_message(t('The news items from %site have been deleted.', ['%site' => $feed->label()]));
|
||||
$this->messenger->addStatus(t('The news items from %site have been deleted.', ['%site' => $feed->label()]));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,7 +9,7 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
|||
*
|
||||
* @MigrateSource(
|
||||
* id = "aggregator_feed",
|
||||
* source_provider = "aggregator"
|
||||
* source_module = "aggregator"
|
||||
* )
|
||||
*/
|
||||
class AggregatorFeed extends DrupalSqlBase {
|
||||
|
|
|
@ -9,7 +9,7 @@ use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
|
|||
*
|
||||
* @MigrateSource(
|
||||
* id = "aggregator_item",
|
||||
* source_provider = "aggregator"
|
||||
* source_module = "aggregator"
|
||||
* )
|
||||
*/
|
||||
class AggregatorItem extends DrupalSqlBase {
|
||||
|
|
|
@ -23,7 +23,7 @@ class Fid extends NumericArgument {
|
|||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
* Constructs a \Drupal\aggregator\Plugin\views\argument\Fid object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
|
|
|
@ -23,7 +23,7 @@ class Iid extends NumericArgument {
|
|||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* Constructs a Drupal\Component\Plugin\PluginBase object.
|
||||
* Constructs a \Drupal\aggregator\Plugin\views\argument\Iid object.
|
||||
*
|
||||
* @param array $configuration
|
||||
* A configuration array containing information about the plugin instance.
|
||||
|
|
|
@ -5,5 +5,5 @@ package: Testing
|
|||
version: VERSION
|
||||
core: 8.x
|
||||
dependencies:
|
||||
- aggregator
|
||||
- views
|
||||
- drupal:aggregator
|
||||
- drupal:views
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\aggregator\Tests;
|
||||
namespace Drupal\Tests\aggregator\Functional;
|
||||
|
||||
/**
|
||||
* Add feed test.
|
||||
|
@ -60,7 +60,7 @@ class AddFeedTest extends AggregatorTestBase {
|
|||
$this->assertNoRaw('Test feed title <script>alert(123);</script>');
|
||||
|
||||
// Ensure the feed icon title is escaped.
|
||||
$this->assertTrue(strpos(str_replace(["\n", "\r"], '', $this->getRawContent()), 'class="feed-icon"> Subscribe to Test feed title <script>alert(123);</script> feed</a>') !== FALSE);
|
||||
$this->assertTrue(strpos(str_replace(["\n", "\r"], '', $this->getSession()->getPage()->getContent()), 'class="feed-icon"> Subscribe to Test feed title <script>alert(123);</script> feed</a>') !== FALSE);
|
||||
}
|
||||
|
||||
/**
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\aggregator\Tests;
|
||||
namespace Drupal\Tests\aggregator\Functional;
|
||||
|
||||
/**
|
||||
* Tests aggregator admin pages.
|
||||
|
@ -67,18 +67,22 @@ class AggregatorAdminTest extends AggregatorTestBase {
|
|||
// Check if the amount of feeds in the overview matches the amount created.
|
||||
$this->assertEqual(1, count($result), 'Created feed is found in the overview');
|
||||
// Check if the fields in the table match with what's expected.
|
||||
$this->assertEqual($feed->label(), (string) $result[0]->td[0]->a);
|
||||
$link = $this->xpath('//table/tbody/tr//td[1]/a');
|
||||
$this->assertEquals($feed->label(), $link[0]->getText());
|
||||
$count = $this->container->get('entity.manager')->getStorage('aggregator_item')->getItemCount($feed);
|
||||
$this->assertEqual(\Drupal::translation()->formatPlural($count, '1 item', '@count items'), (string) $result[0]->td[1]);
|
||||
$td = $this->xpath('//table/tbody/tr//td[2]');
|
||||
$this->assertEquals(\Drupal::translation()->formatPlural($count, '1 item', '@count items'), $td[0]->getText());
|
||||
|
||||
// Update the items of the first feed.
|
||||
$feed->refreshItems();
|
||||
$this->drupalGet('admin/config/services/aggregator');
|
||||
$result = $this->xpath('//table/tbody/tr');
|
||||
// Check if the fields in the table match with what's expected.
|
||||
$this->assertEqual($feed->label(), (string) $result[0]->td[0]->a);
|
||||
$link = $this->xpath('//table/tbody/tr//td[1]/a');
|
||||
$this->assertEquals($feed->label(), $link[0]->getText());
|
||||
$count = $this->container->get('entity.manager')->getStorage('aggregator_item')->getItemCount($feed);
|
||||
$this->assertEqual(\Drupal::translation()->formatPlural($count, '1 item', '@count items'), (string) $result[0]->td[1]);
|
||||
$td = $this->xpath('//table/tbody/tr//td[2]');
|
||||
$this->assertEquals(\Drupal::translation()->formatPlural($count, '1 item', '@count items'), $td[0]->getText());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\aggregator\Tests;
|
||||
namespace Drupal\Tests\aggregator\Functional;
|
||||
|
||||
use Drupal\Tests\Traits\Core\CronRunTrait;
|
||||
|
||||
/**
|
||||
* Update feeds on cron.
|
||||
|
@ -8,6 +10,9 @@ namespace Drupal\aggregator\Tests;
|
|||
* @group aggregator
|
||||
*/
|
||||
class AggregatorCronTest extends AggregatorTestBase {
|
||||
|
||||
use CronRunTrait;
|
||||
|
||||
/**
|
||||
* Adds feeds and updates them via cron process.
|
||||
*/
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\aggregator\Tests;
|
||||
namespace Drupal\Tests\aggregator\Functional;
|
||||
|
||||
use Drupal\Component\Utility\SafeMarkup;
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\views\Entity\View;
|
||||
|
||||
/**
|
||||
|
@ -114,7 +114,7 @@ class AggregatorRenderingTest extends AggregatorTestBase {
|
|||
// Find the expected read_more link on the sources page.
|
||||
$href = $feed->url();
|
||||
$links = $this->xpath('//a[@href = :href]', [':href' => $href]);
|
||||
$this->assertTrue(isset($links[0]), SafeMarkup::format('Link to href %href found.', ['%href' => $href]));
|
||||
$this->assertTrue(isset($links[0]), new FormattableMarkup('Link to href %href found.', ['%href' => $href]));
|
||||
$cache_tags_header = $this->drupalGetHeader('X-Drupal-Cache-Tags');
|
||||
$cache_tags = explode(' ', $cache_tags_header);
|
||||
$this->assertTrue(in_array('aggregator_feed:' . $feed->id(), $cache_tags));
|
||||
|
@ -132,10 +132,14 @@ class AggregatorRenderingTest extends AggregatorTestBase {
|
|||
|
||||
// Check the opml aggregator page.
|
||||
$this->drupalGet('aggregator/opml');
|
||||
$outline = $this->xpath('//outline[1]');
|
||||
$this->assertEqual($outline[0]['type'], 'rss', 'The correct type attribute is used for rss OPML.');
|
||||
$this->assertEqual($outline[0]['text'], $feed->label(), 'The correct text attribute is used for rss OPML.');
|
||||
$this->assertEqual($outline[0]['xmlurl'], $feed->getUrl(), 'The correct xmlUrl attribute is used for rss OPML.');
|
||||
$content = $this->getSession()->getPage()->getContent();
|
||||
// We can't use Mink xpath queries here because it only supports HTML pages,
|
||||
// but we are dealing with XML here.
|
||||
$xml = simplexml_load_string($content);
|
||||
$attributes = $xml->xpath('//outline[1]')[0]->attributes();
|
||||
$this->assertEquals('rss', $attributes->type);
|
||||
$this->assertEquals($feed->label(), $attributes->text);
|
||||
$this->assertEquals($feed->getUrl(), $attributes->xmlUrl);
|
||||
|
||||
// Check for the presence of a pager.
|
||||
$this->drupalGet('aggregator/sources/' . $feed->id());
|
|
@ -8,6 +8,7 @@ namespace Drupal\Tests\aggregator\Functional;
|
|||
* @group aggregator
|
||||
*/
|
||||
class DeleteFeedItemTest extends AggregatorTestBase {
|
||||
|
||||
/**
|
||||
* Tests running "delete items" from 'admin/config/services/aggregator' page.
|
||||
*/
|
||||
|
|
|
@ -40,7 +40,7 @@ class DeleteFeedTest extends AggregatorTestBase {
|
|||
|
||||
// Check feed source.
|
||||
$this->drupalGet('aggregator/sources/' . $feed1->id());
|
||||
$this->assertResponse(404, 'Deleted feed source does not exists.');
|
||||
$this->assertResponse(404, 'Deleted feed source does not exist.');
|
||||
|
||||
// Check database for feed.
|
||||
$result = db_query("SELECT COUNT(*) FROM {aggregator_feed} WHERE title = :title AND url = :url", [':title' => $feed1->label(), ':url' => $feed1->getUrl()])->fetchField();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\aggregator\Tests;
|
||||
namespace Drupal\Tests\aggregator\Functional;
|
||||
|
||||
/**
|
||||
* Tests the display of a feed on the Aggregator list page.
|
|
@ -3,7 +3,7 @@
|
|||
namespace Drupal\Tests\aggregator\Functional;
|
||||
|
||||
use Drupal\aggregator\Entity\Feed;
|
||||
use Drupal\system\Tests\Entity\EntityWithUriCacheTagsTestBase;
|
||||
use Drupal\Tests\system\Functional\Entity\EntityWithUriCacheTagsTestBase;
|
||||
use Drupal\user\Entity\Role;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\aggregator\Tests;
|
||||
namespace Drupal\Tests\aggregator\Functional;
|
||||
|
||||
use Drupal\language\Entity\ConfigurableLanguage;
|
||||
use Drupal\Tests\Traits\Core\CronRunTrait;
|
||||
|
||||
/**
|
||||
* Tests aggregator feeds in multiple languages.
|
||||
|
@ -11,6 +12,8 @@ use Drupal\language\Entity\ConfigurableLanguage;
|
|||
*/
|
||||
class FeedLanguageTest extends AggregatorTestBase {
|
||||
|
||||
use CronRunTrait;
|
||||
|
||||
/**
|
||||
* Modules to install.
|
||||
*
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\hal\Functional\EntityResource\Feed;
|
||||
namespace Drupal\Tests\aggregator\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\hal\Functional\EntityResource\Feed;
|
||||
namespace Drupal\Tests\aggregator\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\hal\Functional\EntityResource\Feed;
|
||||
namespace Drupal\Tests\aggregator\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
|
@ -1,18 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\hal\Functional\EntityResource\Term;
|
||||
namespace Drupal\Tests\aggregator\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\aggregator\Functional\Rest\FeedResourceTestBase;
|
||||
use Drupal\Tests\hal\Functional\EntityResource\HalEntityNormalizationTrait;
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\Term\TermResourceTestBase;
|
||||
|
||||
/**
|
||||
* @group hal
|
||||
*/
|
||||
class TermHalJsonAnonTest extends TermResourceTestBase {
|
||||
abstract class FeedHalJsonTestBase extends FeedResourceTestBase {
|
||||
|
||||
use HalEntityNormalizationTrait;
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -40,10 +35,10 @@ class TermHalJsonAnonTest extends TermResourceTestBase {
|
|||
return $normalization + [
|
||||
'_links' => [
|
||||
'self' => [
|
||||
'href' => $this->baseUrl . '/taxonomy/term/1?_format=hal_json',
|
||||
'href' => $this->baseUrl . '/aggregator/sources/1?_format=hal_json',
|
||||
],
|
||||
'type' => [
|
||||
'href' => $this->baseUrl . '/rest/type/taxonomy_term/camelids',
|
||||
'href' => $this->baseUrl . '/rest/type/aggregator_feed/aggregator_feed',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
@ -56,7 +51,7 @@ class TermHalJsonAnonTest extends TermResourceTestBase {
|
|||
return parent::getNormalizedPostEntity() + [
|
||||
'_links' => [
|
||||
'type' => [
|
||||
'href' => $this->baseUrl . '/rest/type/taxonomy_term/camelids',
|
||||
'href' => $this->baseUrl . '/rest/type/aggregator_feed/aggregator_feed',
|
||||
],
|
||||
],
|
||||
];
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\hal\Functional\EntityResource\Item;
|
||||
namespace Drupal\Tests\aggregator\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\hal\Functional\EntityResource\Item;
|
||||
namespace Drupal\Tests\aggregator\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\hal\Functional\EntityResource\Item;
|
||||
namespace Drupal\Tests\aggregator\Functional\Hal;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\aggregator\Functional\Hal;
|
||||
|
||||
use Drupal\aggregator\Entity\Feed;
|
||||
use Drupal\Tests\aggregator\Functional\Rest\ItemResourceTestBase;
|
||||
use Drupal\Tests\hal\Functional\EntityResource\HalEntityNormalizationTrait;
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* ResourceTestBase for Item entity.
|
||||
*/
|
||||
abstract class ItemHalJsonTestBase extends ItemResourceTestBase {
|
||||
|
||||
use HalEntityNormalizationTrait;
|
||||
use AnonResourceTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['hal'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'hal_json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'application/hal+json';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedNormalizedEntity() {
|
||||
$default_normalization = parent::getExpectedNormalizedEntity();
|
||||
$normalization = $this->applyHalFieldNormalization($default_normalization);
|
||||
$feed = Feed::load($this->entity->getFeedId());
|
||||
|
||||
return $normalization + [
|
||||
'_embedded' => [
|
||||
$this->baseUrl . '/rest/relation/aggregator_item/aggregator_item/fid' => [
|
||||
[
|
||||
'_links' => [
|
||||
'self' => [
|
||||
'href' => $this->baseUrl . '/aggregator/sources/1?_format=hal_json',
|
||||
],
|
||||
'type' => [
|
||||
'href' => $this->baseUrl . '/rest/type/aggregator_feed/aggregator_feed',
|
||||
],
|
||||
],
|
||||
'uuid' => [
|
||||
[
|
||||
'value' => $feed->uuid(),
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'_links' => [
|
||||
'self' => [
|
||||
'href' => '',
|
||||
],
|
||||
'type' => [
|
||||
'href' => $this->baseUrl . '/rest/type/aggregator_item/aggregator_item',
|
||||
],
|
||||
$this->baseUrl . '/rest/relation/aggregator_item/aggregator_item/fid' => [
|
||||
[
|
||||
'href' => $this->baseUrl . '/aggregator/sources/' . $feed->id() . '?_format=hal_json',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNormalizedPostEntity() {
|
||||
return parent::getNormalizedPostEntity() + [
|
||||
'_links' => [
|
||||
'type' => [
|
||||
'href' => $this->baseUrl . '/rest/type/aggregator_item/aggregator_item',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedCacheContexts() {
|
||||
return [
|
||||
'url.site',
|
||||
'user.permissions',
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -5,7 +5,7 @@ namespace Drupal\Tests\aggregator\Functional;
|
|||
use Drupal\aggregator\Entity\Feed;
|
||||
use Drupal\aggregator\Entity\Item;
|
||||
use Drupal\Core\Cache\CacheBackendInterface;
|
||||
use Drupal\system\Tests\Entity\EntityCacheTagsTestBase;
|
||||
use Drupal\Tests\system\Functional\Entity\EntityCacheTagsTestBase;
|
||||
use Drupal\user\Entity\Role;
|
||||
use Drupal\user\RoleInterface;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\rest\Functional\EntityResource\Feed;
|
||||
namespace Drupal\Tests\aggregator\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\rest\Functional\EntityResource\Feed;
|
||||
namespace Drupal\Tests\aggregator\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\rest\Functional\EntityResource\Feed;
|
||||
namespace Drupal\Tests\aggregator\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\aggregator\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
|
||||
use Drupal\aggregator\Entity\Feed;
|
||||
|
||||
abstract class FeedResourceTestBase extends EntityResourceTestBase {
|
||||
|
||||
use BcTimestampNormalizerUnixTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['aggregator'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $entityTypeId = 'aggregator_feed';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $patchProtectedFieldNames = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $uniqueFieldNames = ['url'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpAuthorization($method) {
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
$this->grantPermissionsToTestedRole(['access news feeds']);
|
||||
break;
|
||||
case 'POST':
|
||||
case 'PATCH':
|
||||
case 'DELETE':
|
||||
$this->grantPermissionsToTestedRole(['administer news feeds']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createEntity() {
|
||||
$feed = Feed::create();
|
||||
$feed->set('fid', 1)
|
||||
->set('uuid', 'abcdefg')
|
||||
->setTitle('Feed')
|
||||
->setUrl('http://example.com/rss.xml')
|
||||
->setDescription('Feed Resource Test 1')
|
||||
->setRefreshRate(900)
|
||||
->setLastCheckedTime(123456789)
|
||||
->setQueuedTime(123456789)
|
||||
->setWebsiteUrl('http://example.com')
|
||||
->setImage('http://example.com/feed_logo')
|
||||
->setHash('abcdefg')
|
||||
->setEtag('hijklmn')
|
||||
->setLastModified(123456789)
|
||||
->save();
|
||||
|
||||
return $feed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedNormalizedEntity() {
|
||||
return [
|
||||
'uuid' => [
|
||||
[
|
||||
'value' => 'abcdefg',
|
||||
],
|
||||
],
|
||||
'fid' => [
|
||||
[
|
||||
'value' => 1,
|
||||
],
|
||||
],
|
||||
'langcode' => [
|
||||
[
|
||||
'value' => 'en',
|
||||
],
|
||||
],
|
||||
'url' => [
|
||||
[
|
||||
'value' => 'http://example.com/rss.xml',
|
||||
],
|
||||
],
|
||||
'title' => [
|
||||
[
|
||||
'value' => 'Feed',
|
||||
],
|
||||
],
|
||||
'refresh' => [
|
||||
[
|
||||
'value' => 900,
|
||||
],
|
||||
],
|
||||
'checked' => [
|
||||
$this->formatExpectedTimestampItemValues(123456789),
|
||||
],
|
||||
'queued' => [
|
||||
$this->formatExpectedTimestampItemValues(123456789),
|
||||
],
|
||||
'link' => [
|
||||
[
|
||||
'value' => 'http://example.com',
|
||||
],
|
||||
],
|
||||
'description' => [
|
||||
[
|
||||
'value' => 'Feed Resource Test 1',
|
||||
],
|
||||
],
|
||||
'image' => [
|
||||
[
|
||||
'value' => 'http://example.com/feed_logo',
|
||||
],
|
||||
],
|
||||
'hash' => [
|
||||
[
|
||||
'value' => 'abcdefg',
|
||||
],
|
||||
],
|
||||
'etag' => [
|
||||
[
|
||||
'value' => 'hijklmn',
|
||||
],
|
||||
],
|
||||
'modified' => [
|
||||
$this->formatExpectedTimestampItemValues(123456789),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNormalizedPostEntity() {
|
||||
return [
|
||||
'title' => [
|
||||
[
|
||||
'value' => 'Feed Resource Post Test',
|
||||
],
|
||||
],
|
||||
'url' => [
|
||||
[
|
||||
'value' => 'http://example.com/feed',
|
||||
],
|
||||
],
|
||||
'refresh' => [
|
||||
[
|
||||
'value' => 900,
|
||||
],
|
||||
],
|
||||
'description' => [
|
||||
[
|
||||
'value' => 'Feed Resource Post Test Description',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedUnauthorizedAccessMessage($method) {
|
||||
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
|
||||
return parent::getExpectedUnauthorizedAccessMessage($method);
|
||||
}
|
||||
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
return "The 'access news feeds' permission is required.";
|
||||
case 'POST':
|
||||
case 'PATCH':
|
||||
case 'DELETE':
|
||||
return "The 'administer news feeds' permission is required.";
|
||||
default:
|
||||
return parent::getExpectedUnauthorizedAccessMessage($method);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\aggregator\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class FeedXmlAnonTest extends FeedResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\aggregator\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class FeedXmlBasicAuthTest extends FeedResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\aggregator\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class FeedXmlCookieTest extends FeedResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\rest\Functional\EntityResource\Item;
|
||||
namespace Drupal\Tests\aggregator\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\rest\Functional\EntityResource\Item;
|
||||
namespace Drupal\Tests\aggregator\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\rest\Functional\EntityResource\Item;
|
||||
namespace Drupal\Tests\aggregator\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\aggregator\Functional\Rest;
|
||||
|
||||
use Drupal\aggregator\Entity\Feed;
|
||||
use Drupal\aggregator\Entity\Item;
|
||||
use Drupal\Tests\rest\Functional\BcTimestampNormalizerUnixTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
|
||||
|
||||
/**
|
||||
* ResourceTestBase for Item entity.
|
||||
*/
|
||||
abstract class ItemResourceTestBase extends EntityResourceTestBase {
|
||||
|
||||
use BcTimestampNormalizerUnixTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['aggregator'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $entityTypeId = 'aggregator_item';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $patchProtectedFieldNames = [];
|
||||
|
||||
/**
|
||||
* The Item entity.
|
||||
*
|
||||
* @var \Drupal\aggregator\ItemInterface
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUpAuthorization($method) {
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
$this->grantPermissionsToTestedRole(['access news feeds']);
|
||||
break;
|
||||
|
||||
case 'POST':
|
||||
case 'PATCH':
|
||||
case 'DELETE':
|
||||
$this->grantPermissionsToTestedRole(['administer news feeds']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createEntity() {
|
||||
// Create a "Camelids" feed.
|
||||
$feed = Feed::create([
|
||||
'title' => 'Camelids',
|
||||
'url' => 'https://groups.drupal.org/not_used/167169',
|
||||
'refresh' => 900,
|
||||
'checked' => 1389919932,
|
||||
'description' => 'Drupal Core Group feed',
|
||||
]);
|
||||
$feed->save();
|
||||
|
||||
// Create a "Llama" item.
|
||||
$item = Item::create();
|
||||
$item->setTitle('Llama')
|
||||
->setFeedId($feed->id())
|
||||
->setLink('https://www.drupal.org/')
|
||||
->setPostedTime(123456789)
|
||||
->save();
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function createAnotherEntity() {
|
||||
$entity = $this->entity->createDuplicate();
|
||||
$entity->setLink('https://www.example.org/');
|
||||
$label_key = $entity->getEntityType()->getKey('label');
|
||||
if ($label_key) {
|
||||
$entity->set($label_key, $entity->label() . '_dupe');
|
||||
}
|
||||
$entity->save();
|
||||
return $entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedNormalizedEntity() {
|
||||
$feed = Feed::load($this->entity->getFeedId());
|
||||
|
||||
return [
|
||||
'iid' => [
|
||||
[
|
||||
'value' => 1,
|
||||
],
|
||||
],
|
||||
'langcode' => [
|
||||
[
|
||||
'value' => 'en',
|
||||
],
|
||||
],
|
||||
'fid' => [
|
||||
[
|
||||
'target_id' => 1,
|
||||
'target_type' => 'aggregator_feed',
|
||||
'target_uuid' => $feed->uuid(),
|
||||
'url' => base_path() . 'aggregator/sources/1',
|
||||
],
|
||||
],
|
||||
'title' => [
|
||||
[
|
||||
'value' => 'Llama',
|
||||
],
|
||||
],
|
||||
'link' => [
|
||||
[
|
||||
'value' => 'https://www.drupal.org/',
|
||||
],
|
||||
],
|
||||
'author' => [],
|
||||
'description' => [],
|
||||
'timestamp' => [
|
||||
$this->formatExpectedTimestampItemValues(123456789),
|
||||
],
|
||||
'guid' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getNormalizedPostEntity() {
|
||||
return [
|
||||
'fid' => [
|
||||
[
|
||||
'target_id' => 1,
|
||||
],
|
||||
],
|
||||
'title' => [
|
||||
[
|
||||
'value' => 'Llama',
|
||||
],
|
||||
],
|
||||
'link' => [
|
||||
[
|
||||
'value' => 'https://www.drupal.org/',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedCacheContexts() {
|
||||
// @see ::createEntity()
|
||||
return ['user.permissions'];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getExpectedUnauthorizedAccessMessage($method) {
|
||||
if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
|
||||
return parent::getExpectedUnauthorizedAccessMessage($method);
|
||||
}
|
||||
|
||||
switch ($method) {
|
||||
case 'GET':
|
||||
return "The 'access news feeds' permission is required.";
|
||||
|
||||
case 'POST':
|
||||
case 'PATCH':
|
||||
case 'DELETE':
|
||||
return "The 'administer news feeds' permission is required.";
|
||||
|
||||
default:
|
||||
return parent::getExpectedUnauthorizedAccessMessage($method);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\aggregator\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class ItemXmlAnonTest extends ItemResourceTestBase {
|
||||
|
||||
use AnonResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\aggregator\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class ItemXmlBasicAuthTest extends ItemResourceTestBase {
|
||||
|
||||
use BasicAuthResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = ['basic_auth'];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'basic_auth';
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\aggregator\Functional\Rest;
|
||||
|
||||
use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
|
||||
use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* @group rest
|
||||
*/
|
||||
class ItemXmlCookieTest extends ItemResourceTestBase {
|
||||
|
||||
use CookieResourceTestTrait;
|
||||
use XmlEntityNormalizationQuirksTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $format = 'xml';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $mimeType = 'text/xml; charset=UTF-8';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected static $auth = 'cookie';
|
||||
|
||||
}
|
|
@ -1,13 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\aggregator\Tests\Update;
|
||||
namespace Drupal\Tests\aggregator\Functional\Update;
|
||||
|
||||
use Drupal\system\Tests\Update\UpdatePathTestBase;
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
|
||||
/**
|
||||
* Tests that node settings are properly updated during database updates.
|
||||
*
|
||||
* @group aggregator
|
||||
* @group legacy
|
||||
*/
|
||||
class AggregatorUpdateTest extends UpdatePathTestBase {
|
||||
|
||||
|
@ -16,7 +17,7 @@ class AggregatorUpdateTest extends UpdatePathTestBase {
|
|||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.filled.standard.php.gz',
|
||||
__DIR__ . '/../../../../../system/tests/fixtures/update/drupal-8.filled.standard.php.gz',
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -38,4 +39,21 @@ class AggregatorUpdateTest extends UpdatePathTestBase {
|
|||
$this->assertTrue($field_definition->isRequired());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the 'Update interval' field has a default value.
|
||||
*/
|
||||
public function testUpdateIntervalDefaultValue() {
|
||||
// Check that the 'refresh' field does not have a default value prior to the
|
||||
// update.
|
||||
$field_definition = \Drupal::entityDefinitionUpdateManager()->getFieldStorageDefinition('refresh', 'aggregator_feed');
|
||||
$this->assertSame([], $field_definition->getDefaultValueLiteral());
|
||||
|
||||
// Run updates.
|
||||
$this->runUpdates();
|
||||
|
||||
// Check that the 'refresh' has a default value now.
|
||||
$field_definition = \Drupal::entityDefinitionUpdateManager()->getFieldStorageDefinition('refresh', 'aggregator_feed');
|
||||
$this->assertSame([['value' => 3600]], $field_definition->getDefaultValueLiteral());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\aggregator\Tests;
|
||||
namespace Drupal\Tests\aggregator\Functional;
|
||||
|
||||
use Drupal\aggregator\Entity\Feed;
|
||||
|
||||
/**
|
||||
|
@ -9,6 +10,7 @@ use Drupal\aggregator\Entity\Feed;
|
|||
* @group aggregator
|
||||
*/
|
||||
class UpdateFeedItemTest extends AggregatorTestBase {
|
||||
|
||||
/**
|
||||
* Tests running "update items" from 'admin/config/services/aggregator' page.
|
||||
*/
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\aggregator\Tests;
|
||||
namespace Drupal\Tests\aggregator\Functional;
|
||||
|
||||
/**
|
||||
* Update feed test.
|
||||
|
@ -8,6 +8,7 @@ namespace Drupal\aggregator\Tests;
|
|||
* @group aggregator
|
||||
*/
|
||||
class UpdateFeedTest extends AggregatorTestBase {
|
||||
|
||||
/**
|
||||
* Creates a feed and attempts to update it.
|
||||
*/
|
|
@ -6,7 +6,6 @@ use Drupal\aggregator\Entity\Feed;
|
|||
use Drupal\aggregator\Entity\Item;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
|
||||
|
||||
/**
|
||||
* Tests the aggregator_title formatter.
|
||||
*
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Drupal\Tests\aggregator\Kernel\Migrate;
|
||||
|
||||
use Drupal\migrate\MigrateException;
|
||||
use Drupal\Tests\migrate_drupal\Kernel\MigrateDrupalTestBase;
|
||||
use Drupal\migrate_drupal\Tests\StubTestTrait;
|
||||
|
||||
|
@ -40,18 +39,6 @@ class MigrateAggregatorStubTest extends MigrateDrupalTestBase {
|
|||
* Tests creation of aggregator feed items.
|
||||
*/
|
||||
public function testItemStub() {
|
||||
try {
|
||||
// We expect an exception, because there's no feed to reference.
|
||||
$this->performStubTest('aggregator_item');
|
||||
$this->fail('Expected exception has not been thrown.');
|
||||
}
|
||||
catch (MigrateException $e) {
|
||||
$this->assertIdentical($e->getMessage(),
|
||||
'Stubbing failed, unable to generate value for field fid');
|
||||
}
|
||||
|
||||
// The stub should pass when there's a feed to point to.
|
||||
$this->createStub('aggregator_feed');
|
||||
$this->performStubTest('aggregator_item');
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Drupal\Tests\aggregator\Unit\Plugin;
|
|||
|
||||
use Drupal\aggregator\Form\SettingsForm;
|
||||
use Drupal\Core\Form\FormState;
|
||||
use Drupal\Core\Messenger\MessengerInterface;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
|
@ -55,6 +56,10 @@ class AggregatorPluginSettingsBaseTest extends UnitTestCase {
|
|||
->will($this->returnValue(['aggregator_test' => ['title' => '', 'description' => '']]));
|
||||
}
|
||||
|
||||
/** @var \Drupal\Core\Messenger\MessengerInterface|\PHPUnit_Framework_MockObject_MockBuilder $messenger */
|
||||
$messenger = $this->createMock(MessengerInterface::class);
|
||||
$messenger->expects($this->any())->method('addMessage');
|
||||
|
||||
$this->settingsForm = new SettingsForm(
|
||||
$this->configFactory,
|
||||
$this->managers['fetcher'],
|
||||
|
@ -62,6 +67,7 @@ class AggregatorPluginSettingsBaseTest extends UnitTestCase {
|
|||
$this->managers['processor'],
|
||||
$this->getStringTranslationStub()
|
||||
);
|
||||
$this->settingsForm->setMessenger($messenger);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,10 +110,3 @@ class AggregatorPluginSettingsBaseTest extends UnitTestCase {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
// @todo Delete after https://www.drupal.org/node/2278383 is in.
|
||||
namespace Drupal\Core\Form;
|
||||
|
||||
if (!function_exists('drupal_set_message')) {
|
||||
function drupal_set_message() {}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ class AutomatedCron implements EventSubscriberInterface {
|
|||
/**
|
||||
* The state key value store.
|
||||
*
|
||||
* @var \Drupal\Core\State\StateInterface;
|
||||
* @var \Drupal\Core\State\StateInterface
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ id: d7_blocked_ips
|
|||
label: Blocked IPs
|
||||
migration_tags:
|
||||
- Drupal 7
|
||||
- Content
|
||||
source:
|
||||
plugin: d7_blocked_ips
|
||||
process:
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue