diff -u b/core/modules/contact/contact.routing.yml b/core/modules/contact/contact.routing.yml --- b/core/modules/contact/contact.routing.yml +++ b/core/modules/contact/contact.routing.yml @@ -1,9 +1,9 @@ contact_category_delete: pattern: 'admin/structure/contact/manage/{contact_category}/delete' defaults: - _entity_form: contact_category.delete + _entity_form: 'contact_category.delete' requirements: - _entity_access: contact_category.delete + _entity_access: 'contact_category.delete' contact_category_list: pattern: '/admin/structure/contact' @@ -15,16 +15,16 @@ contact_category_add: pattern: '/admin/structure/contact/add' defaults: - _entity_form: contact_category.add + _entity_form: 'contact_category.add' requirements: _permission: 'administer contact forms' contact_category_edit: pattern: '/admin/structure/contact/manage/{contact_category}' defaults: - _entity_form: contact_category.edit + _entity_form: 'contact_category.edit' requirements: - _entity_access: contact_category.update + _entity_access: 'contact_category.update' contact_site_page: pattern: 'contact' @@ -38,7 +38,7 @@ defaults: _content: '\Drupal\contact\Controller\ContactPageController::contactSitePage' requirements: - _permission: 'access site-wide contact form' + _entity_access: 'contact_category.page' contact_personal_page: pattern: 'user/{user}/contact' diff -u b/core/modules/contact/contact.services.yml b/core/modules/contact/contact.services.yml --- b/core/modules/contact/contact.services.yml +++ b/core/modules/contact/contact.services.yml @@ -1,5 +1,5 @@ services: - access_check.contact: + access_check.contact_personal: class: Drupal\contact\Access\ContactPageAccess tags: - { name: access_check } diff -u b/core/modules/contact/lib/Drupal/contact/Access/ContactPageAccess.php b/core/modules/contact/lib/Drupal/contact/Access/ContactPageAccess.php --- b/core/modules/contact/lib/Drupal/contact/Access/ContactPageAccess.php +++ b/core/modules/contact/lib/Drupal/contact/Access/ContactPageAccess.php @@ -8,10 +8,10 @@ namespace Drupal\contact\Access; use Drupal\Core\Access\StaticAccessCheckInterface; +use Drupal\Core\Config\ConfigFactory; use Drupal\user\UserDataInterface; use Symfony\Component\Routing\Route; use Symfony\Component\HttpFoundation\Request; -use Drupal\Core\Config\ConfigFactory; /** * Access check for contact routes. @@ -58,13 +58,14 @@ */ public function access(Route $route, Request $request) { $contact_account = $request->attributes->get('user'); - $current_account = $request->attributes->get('_account') ?: $GLOBALS['user']; // Anonymous users cannot have contact forms. if ($contact_account->isAnonymous()) { return static::DENY; } + $current_account = $request->attributes->get('_account');; + // Users may not contact themselves. if ($current_account->id() == $contact_account->id()) { return static::DENY; diff -u b/core/modules/contact/lib/Drupal/contact/Controller/ContactPageController.php b/core/modules/contact/lib/Drupal/contact/Controller/ContactPageController.php --- b/core/modules/contact/lib/Drupal/contact/Controller/ContactPageController.php +++ b/core/modules/contact/lib/Drupal/contact/Controller/ContactPageController.php @@ -13,12 +13,12 @@ use Drupal\Core\Flood\FloodInterface; use Drupal\Core\Config\ConfigFactory; use Drupal\Core\Entity\EntityManager; +use Drupal\Core\StringTranslation\Translator\TranslatorInterface; use Drupal\contact\Plugin\Core\Entity\Category; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; - /** * Controller routines for contact routes. */ @@ -46,6 +46,13 @@ protected $entityManager; /** + * The translator service. + * + * @var \Drupal\Core\StringTranslation\Translator\TranslatorInterface + */ + protected $translator; + + /** * Constructs a ContactController object. * * @param \Drupal\Core\Flood\FloodInterface $flood @@ -54,11 +61,14 @@ * Configuration Factory. * @param \Drupal\Core\Entity\EntityManager $entity_manager * Entity Manager. + * @param \Drupal\Core\StringTranslation\Translator\TranslatorInterface $translator + * The translator service. */ - public function __construct(FloodInterface $flood, ConfigFactory $config_factory, EntityManager $entity_manager) { + public function __construct(FloodInterface $flood, ConfigFactory $config_factory, EntityManager $entity_manager, TranslatorInterface $translator) { $this->flood = $flood; $this->configFactory = $config_factory; $this->entityManager = $entity_manager; + $this->translator = $translator; } /** @@ -76,33 +86,34 @@ /** * Presents the site-wide contact form. * - * @param \Drupal\contact\Plugin\Core\Entity\Category $contact_category - * (optional) The contact category to use. * @param \Drupal\Core\Session\AccountInterface $_account * The current account. + * @param \Drupal\contact\Plugin\Core\Entity\Category $contact_category + * The contact category to use. * * @return array * The form as render array as expected by drupal_render(). * * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException - * Exception is thrown when user tries to access non existing contact - * category form and does not have permissions to set it up. + * Exception is thrown when user tries to access non existing default + * contact category form. */ - public function contactSitePage(Category $contact_category = NULL, AccountInterface $_account) { + public function contactSitePage(AccountInterface $_account, Category $contact_category = NULL) { // Check if flood control has been activated for sending e-mails. if (!$_account->hasPermission('administer contact forms')) { $this->contactFloodControl(); } + // Use the default category if no category has been passed. if (empty($contact_category)) { - $controller = $this->entityManager->getStorageController('contact_category'); $default_category = $this->configFactory->get('contact.settings')->get('default_category'); - $contact_category = $controller->load($default_category); - + $contact_category = $this->entityManager + ->getStorageController('contact_category') + ->load($default_category); // If there are no categories, do not display the form. if (empty($contact_category)) { if ($_account->hasPermission('administer contact forms')) { - drupal_set_message(t('The contact form has not been configured. Add one or more categories to the form.', array('@add' => url('admin/structure/contact/add'))), 'error'); + drupal_set_message($this->translator->translate('The contact form has not been configured. Add one or more categories to the form.', array('@add' => url('admin/structure/contact/add'))), 'error'); return array(); } else { @@ -110,9 +121,6 @@ } } } - elseif ($contact_category->id() == 'personal') { - throw new NotFoundHttpException(); - } $message = $this->entityManager ->getStorageController('contact_message') @@ -140,7 +148,7 @@ $this->contactFloodControl(); } - drupal_set_title(t('Contact @username', array('@username' => $user->getUsername())), PASS_THROUGH); + drupal_set_title($this->translator->translate('Contact @username', array('@username' => $user->getUsername())), PASS_THROUGH); $message = $this->entityManager ->getStorageController('contact_message') @@ -162,7 +170,7 @@ $limit = $contact_settings->get('flood.limit'); $interval = $contact_settings->get('flood.interval'); if (!$this->flood->isAllowed('contact', $limit, $interval)) { - drupal_set_message(t('You cannot send more than %limit messages in @interval. Try again later.', array( + drupal_set_message($this->translator->translate('You cannot send more than %limit messages in @interval. Try again later.', array( '%limit' => $limit, '@interval' => format_interval($interval), )), 'error'); only in patch2: unchanged: --- a/core/includes/menu.inc +++ b/core/includes/menu.inc @@ -970,6 +970,7 @@ function _menu_link_translate(&$item, $translate = FALSE) { function menu_item_route_access(Route $route, $href, &$map) { $request = Request::create('/' . $href); $request->attributes->set('_system_path', $href); + $request->attributes->set('_account', Drupal::request()->attributes->get('_account')); // Attempt to match this path to provide a fully built request to the // access checker. try { only in patch2: unchanged: --- a/core/modules/contact/lib/Drupal/contact/CategoryAccessController.php +++ b/core/modules/contact/lib/Drupal/contact/CategoryAccessController.php @@ -23,10 +23,14 @@ class CategoryAccessController extends EntityAccessController { public function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) { if ($operation == 'delete' || $operation == 'update') { // Do not allow delete 'personal' category used for personal contact form. - return user_access('administer contact forms', $account) && $entity->id() !== 'personal'; + return $account->hasPermission('administer contact forms') && $entity->id() !== 'personal'; + } + elseif ($operation == 'page') { + // Do not allow access personal category via site-wide route. + return $account->hasPermission('access site-wide contact form') && $entity->id() !== 'personal'; } else { - return user_access('administer contact forms', $account); + return $account->hasPermission('administer contact forms'); } } only in patch2: unchanged: --- a/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php +++ b/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php @@ -44,7 +44,8 @@ function testSiteWideContact() { $this->drupalLogin($admin_user); $flood_limit = 3; - config('contact.settings') + $this->container->get('config.factory') + ->get('contact.settings') ->set('flood.limit', $flood_limit) ->set('flood.interval', 600) ->save(); @@ -89,6 +90,9 @@ function testSiteWideContact() { $this->drupalGet('contact'); $this->assertResponse(200); $this->assertText(t('The contact form has not been configured.')); + // Test access personal category via site-wide contact page. + $this->drupalGet('contact/personal'); + $this->assertResponse(403); // Add categories. // Test invalid recipients. @@ -110,7 +114,8 @@ function testSiteWideContact() { $this->assertRaw(t('Category %label has been added.', array('%label' => $label))); // Check that the category was created in site default language. - $langcode = config('contact.category.' . $id)->get('langcode'); + $langcode = $this->container->get('config.factory') + ->get('contact.category.' . $id)->get('langcode'); $default_langcode = language_default()->id; $this->assertEqual($langcode, $default_langcode); @@ -119,7 +124,8 @@ function testSiteWideContact() { // Test update contact form category. $this->updateCategory($id, $label = $this->randomName(16), $recipients_str = implode(',', array($recipients[0], $recipients[1])), $reply = $this->randomName(30), FALSE); - $config = config('contact.category.' . $id)->get(); + $config = $this->container->get('config.factory') + ->get('contact.category.' . $id)->get(); $this->assertEqual($config['label'], $label); $this->assertEqual($config['recipients'], array($recipients[0], $recipients[1])); $this->assertEqual($config['reply'], $reply); @@ -127,7 +133,10 @@ function testSiteWideContact() { $this->assertRaw(t('Category %label has been updated.', array('%label' => $label))); // Reset the category back to be the default category. - config('contact.settings')->set('default_category', $id)->save(); + $this->container->get('config.factory') + ->get('contact.settings') + ->set('default_category', $id) + ->save(); // Ensure that the contact form is shown without a category selection input. user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access site-wide contact form')); @@ -182,7 +191,8 @@ function testSiteWideContact() { $this->assertText(t('Message field is required.')); // Test contact form with no default category selected. - config('contact.settings') + $this->container->get('config.factory') + ->get('contact.settings') ->set('default_category', '') ->save(); $this->drupalGet('contact'); @@ -202,7 +212,10 @@ function testSiteWideContact() { // Submit contact form one over limit. $this->drupalGet('contact'); $this->assertResponse(403); - $this->assertRaw(t('You cannot send more than %number messages in @interval. Try again later.', array('%number' => config('contact.settings')->get('flood.limit'), '@interval' => format_interval(600)))); + $this->assertRaw(t('You cannot send more than %number messages in @interval. Try again later.', array( + '%number' => $this->container->get('config.factory')->get('contact.settings')->get('flood.limit'), + '@interval' => format_interval(600)) + )); // Test listing controller. $this->drupalLogin($admin_user); @@ -376,7 +389,7 @@ function submitContact($name, $mail, $subject, $id, $message) { $edit['mail'] = $mail; $edit['subject'] = $subject; $edit['message'] = $message; - if ($id == config('contact.settings')->get('default_category')) { + if ($id == $this->container->get('config.factory')->get('contact.settings')->get('default_category')) { $this->drupalPost('contact', $edit, t('Send message')); } else {