.../contact/src/Controller/ContactController.php | 70 ---------------------- core/modules/contact/src/MessageForm.php | 38 +++++++++++- .../contact/src/Tests/ContactPersonalTest.php | 2 +- .../contact/src/Tests/ContactSitewideTest.php | 3 +- 4 files changed, 38 insertions(+), 75 deletions(-) diff --git a/core/modules/contact/src/Controller/ContactController.php b/core/modules/contact/src/Controller/ContactController.php index 8813cd9..bfc8564 100644 --- a/core/modules/contact/src/Controller/ContactController.php +++ b/core/modules/contact/src/Controller/ContactController.php @@ -9,13 +9,9 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Controller\ControllerBase; -use Drupal\Core\Datetime\DateFormatter; -use Drupal\Core\Flood\FloodInterface; use Drupal\contact\ContactFormInterface; use Drupal\user\UserInterface; use Drupal\Component\Utility\String; -use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** @@ -24,43 +20,6 @@ class ContactController extends ControllerBase { /** - * The flood service. - * - * @var \Drupal\Core\Flood\FloodInterface - */ - protected $flood; - - /** - * The date formatter service. - * - * @var \Drupal\Core\Datetime\DateFormatter - */ - protected $dateFormatter; - - /** - * Constructs a ContactController object. - * - * @param \Drupal\Core\Flood\FloodInterface $flood - * The flood service. - * @param \Drupal\Core\Datetime\DateFormatter $date_formatter - * The date service. - */ - public function __construct(FloodInterface $flood, DateFormatter $date_formatter) { - $this->flood = $flood; - $this->dateFormatter = $date_formatter; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('flood'), - $container->get('date.formatter') - ); - } - - /** * Presents the site-wide contact form. * * @param \Drupal\contact\ContactFormInterface $contact_form @@ -74,10 +33,6 @@ public static function create(ContainerInterface $container) { * contact form. */ public function contactSitePage(ContactFormInterface $contact_form = NULL) { - // Check if flood control has been activated for sending emails. - if (!$this->currentUser()->hasPermission('administer contact forms')) { - $this->contactFloodControl(); - } $config = $this->config('contact.settings'); // Use the default form if no form has been passed. @@ -130,11 +85,6 @@ public function contactPersonalPage(UserInterface $user) { throw new NotFoundHttpException(); } - // Check if flood control has been activated for sending emails. - if (!$this->currentUser()->hasPermission('administer contact forms') && !$this->currentUser()->hasPermission('administer users')) { - $this->contactFloodControl(); - } - $message = $this->entityManager()->getStorage('contact_message')->create(array( 'contact_form' => 'personal', 'recipient' => $user->id(), @@ -146,24 +96,4 @@ public function contactPersonalPage(UserInterface $user) { return $form; } - /** - * Throws an exception if the current user triggers flood control. - * - * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException - */ - protected function contactFloodControl() { - // Flood control is incompatible with page caching. - \Drupal::service('page_cache_kill_switch')->trigger(); - - $limit = $this->config('contact.settings')->get('flood.limit'); - $interval = $this->config('contact.settings')->get('flood.interval'); - if (!$this->flood->isAllowed('contact', $limit, $interval)) { - drupal_set_message($this->t('You cannot send more than %limit messages in @interval. Try again later.', array( - '%limit' => $limit, - '@interval' => $this->dateFormatter->formatInterval($interval), - )), 'error'); - throw new AccessDeniedHttpException(); - } - } - } diff --git a/core/modules/contact/src/MessageForm.php b/core/modules/contact/src/MessageForm.php index 908ed17..b721db5 100644 --- a/core/modules/contact/src/MessageForm.php +++ b/core/modules/contact/src/MessageForm.php @@ -8,6 +8,7 @@ namespace Drupal\contact; use Drupal\Component\Utility\String; +use Drupal\Core\Datetime\DateFormatter; use Drupal\Core\Entity\ContentEntityForm; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Flood\FloodInterface; @@ -50,6 +51,13 @@ class MessageForm extends ContentEntityForm { protected $mailHandler; /** + * The date formatter service. + * + * @var \Drupal\Core\Datetime\DateFormatter + */ + protected $dateFormatter; + + /** * Constructs a MessageForm object. * * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager @@ -60,12 +68,15 @@ class MessageForm extends ContentEntityForm { * The language manager service. * @param \Drupal\contact\MailHandlerInterface $mail_handler * The contact mail handler service. + * @param \Drupal\Core\Datetime\DateFormatter $date_formatter + * The date service. */ - public function __construct(EntityManagerInterface $entity_manager, FloodInterface $flood, LanguageManagerInterface $language_manager, MailHandlerInterface $mail_handler) { + public function __construct(EntityManagerInterface $entity_manager, FloodInterface $flood, LanguageManagerInterface $language_manager, MailHandlerInterface $mail_handler, DateFormatter $date_formatter) { parent::__construct($entity_manager); $this->flood = $flood; $this->languageManager = $language_manager; $this->mailHandler = $mail_handler; + $this->dateFormatter = $date_formatter; } /** @@ -76,7 +87,8 @@ public static function create(ContainerInterface $container) { $container->get('entity.manager'), $container->get('flood'), $container->get('language_manager'), - $container->get('contact.mail_handler') + $container->get('contact.mail_handler'), + $container->get('date.formatter') ); } @@ -175,6 +187,28 @@ public function preview(array $form, FormStateInterface $form_state) { /** * {@inheritdoc} */ + public function validate(array $form, FormStateInterface $form_state) { + parent::validate($form, $form_state); + + $message = $this->entity; + + // Check if flood control has been activated for sending emails. + if (!$this->currentUser()->hasPermission('administer contact forms') && (!$message->isPersonal() || !$this->currentUser()->hasPermission('administer users'))) { + $limit = $this->config('contact.settings')->get('flood.limit'); + $interval = $this->config('contact.settings')->get('flood.interval'); + + if (!$this->flood->isAllowed('contact', $limit, $interval)) { + $form_state->setErrorByName('', $this->t('You cannot send more than %limit messages in @interval. Try again later.', array( + '%limit' => $limit, + '@interval' => $this->dateFormatter->formatInterval($interval), + ))); + } + } + } + + /** + * {@inheritdoc} + */ public function save(array $form, FormStateInterface $form_state) { $message = $this->entity; $user = $this->currentUser(); diff --git a/core/modules/contact/src/Tests/ContactPersonalTest.php b/core/modules/contact/src/Tests/ContactPersonalTest.php index 3eaa709..78bcc3f 100644 --- a/core/modules/contact/src/Tests/ContactPersonalTest.php +++ b/core/modules/contact/src/Tests/ContactPersonalTest.php @@ -237,7 +237,7 @@ function testPersonalContactFlood() { } // Submit contact form one over limit. - $this->drupalGet('user/' . $this->contactUser->id(). '/contact'); + $this->submitPersonalContact($this->contactUser); $this->assertRaw(t('You cannot send more than %number messages in @interval. Try again later.', array('%number' => $flood_limit, '@interval' => \Drupal::service('date.formatter')->formatInterval($this->config('contact.settings')->get('flood.interval')))), 'Normal user denied access to flooded contact form.'); // Test that the admin user can still access the contact form even though diff --git a/core/modules/contact/src/Tests/ContactSitewideTest.php b/core/modules/contact/src/Tests/ContactSitewideTest.php index 793388a..df2816e 100644 --- a/core/modules/contact/src/Tests/ContactSitewideTest.php +++ b/core/modules/contact/src/Tests/ContactSitewideTest.php @@ -230,8 +230,7 @@ function testSiteWideContact() { $this->assertText(t('Your message has been sent.')); } // Submit contact form one over limit. - $this->drupalGet('contact'); - $this->assertResponse(403); + $this->submitContact($this->randomMachineName(16), $recipients[0], $this->randomMachineName(16), $id, $this->randomMachineName(64)); $this->assertRaw(t('You cannot send more than %number messages in @interval. Try again later.', array('%number' => $this->config('contact.settings')->get('flood.limit'), '@interval' => \Drupal::service('date.formatter')->formatInterval(600)))); // Test listing controller.