Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save otarza/c2139034917e8e75f188 to your computer and use it in GitHub Desktop.
Save otarza/c2139034917e8e75f188 to your computer and use it in GitHub Desktop.
Reroll for Regression: category selector missing on site wide contact form: https://www.drupal.org/node/1997692#comment-10146010
diff --git a/core/modules/contact/src/Plugin/Block/ContactNavigationBlock.php b/core/modules/contact/src/Plugin/Block/ContactNavigationBlock.php
index 6b79758..d4ad47d 100644
--- a/core/modules/contact/src/Plugin/Block/ContactNavigationBlock.php
+++ b/core/modules/contact/src/Plugin/Block/ContactNavigationBlock.php
@@ -7,14 +7,14 @@
namespace Drupal\contact\Plugin\Block;
-use Drupal\Component\Utility\String;
+use Drupal\Component\Utility\Html;
+use Drupal\Core\Access\AccessResult;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\Entity\ConfigEntityStorageInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
-use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -79,6 +79,7 @@ public function defaultConfiguration() {
* {@inheritdoc}
*/
public function getCacheTags() {
+
$cache_tags = parent::getCacheTags();
if ($forms = array_keys($this->configuration['forms'])) {
foreach ($this->storage->loadMultiple($forms) as $form) {
@@ -103,7 +104,11 @@ protected function getRequiredCacheContexts() {
protected function blockAccess(AccountInterface $account) {
// Only grant access to users with the 'access site-wide contact form'
// permission.
- return $account->hasPermission('access site-wide contact form');
+ if ($account->hasPermission('access site-wide contact form')) {
+ return AccessResult::allowed();
+ }
+
+ return AccessResult::forbidden();
}
/**
@@ -149,7 +154,7 @@ public function blockForm($form, FormStateInterface $form_state) {
$min_weight = min($min_weight, $row_weight);
}
$row = [
- 'label' => ['#markup' => String::checkPlain($row_label)],
+ 'label' => ['#markup' => Html::escape($row_label)],
'display' => [
'#type' => 'checkbox',
'#default_value' => $row_display,
@@ -214,10 +219,11 @@ public function blockSubmit($form, FormStateInterface $form_state) {
* {@inheritdoc}
*/
public function build() {
+
$links = [];
/** @var \Drupal\contact\ContactFormInterface $contact_form */
foreach ($this->storage->loadMultiple(array_keys($this->configuration['forms'])) as $id => $contact_form) {
- $links[$id] = $contact_form->link($contact_form->label(), 'submit-form', [
+ $links[$id] = $contact_form->link($contact_form->label(), 'canonical', [
'set_active_class' => TRUE,
]);
}
diff --git a/core/modules/contact/contact.module b/core/modules/contact/contact.module
index 46b131d..ea4e747 100644
--- a/core/modules/contact/contact.module
+++ b/core/modules/contact/contact.module
@@ -7,6 +7,7 @@
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Url;
use Drupal\user\Entity\User;
/**
@@ -35,6 +36,14 @@ function contact_help($route_name, RouteMatchInterface $route_match) {
$output .= '</dl>';
return $output;
+ case 'contact.form_list':
+ $output = '<p>' . t('Create seperate contact forms for different purposes.') . '</p>';
+ $output .= '<p>' . t('If you would like additional text to appear on the site-wide contact page, use a block. You can create and edit blocks on the <a href="@blocks">Blocks administration page</a>.', array('@blocks' => \Drupal::url('block.admin_display'))) . '</p>';
+ if (\Drupal::moduleHandler()->moduleExists('block')) {
+ $output .= '<p>' . t('Each form gets a link in the Contact forms block. You can enable this block on the <a href="@block">Block layout</a> page.', array(
+ '@block' => Url::fromRoute('block.admin_display')->toString(),
+ ));
+ }
case 'entity.contact_form.collection':
$menu_page = \Drupal::moduleHandler()->moduleExists('menu_ui') ? \Drupal::url('entity.menu.collection') : '#';
$block_page = \Drupal::moduleHandler()->moduleExists('block') ? \Drupal::url('block.admin_display') : '#';
diff --git a/core/modules/contact/src/ContactFormListBuilder.php b/core/modules/contact/src/ContactFormListBuilder.php
index 29ace77..34c2ee3 100644
--- a/core/modules/contact/src/ContactFormListBuilder.php
+++ b/core/modules/contact/src/ContactFormListBuilder.php
@@ -23,7 +23,7 @@ class ContactFormListBuilder extends ConfigEntityListBuilder {
public function buildHeader() {
$header['form'] = t('Form');
$header['recipients'] = t('Recipients');
- $header['selected'] = t('Selected');
+ $header['default'] = t('Default');
return $header + parent::buildHeader();
}
@@ -35,7 +35,7 @@ public function buildRow(EntityInterface $entity) {
if ($entity->id() == 'personal') {
$row['form'] = $entity->label();
$row['recipients'] = t('Selected user');
- $row['selected'] = t('No');
+ $row['default'] = t('No');
}
else {
$row['form'] = $entity->link(NULL, 'canonical');
@@ -45,7 +45,7 @@ public function buildRow(EntityInterface $entity) {
'#context' => ['list_style' => 'comma-list'],
];
$default_form = \Drupal::config('contact.settings')->get('default_form');
- $row['selected'] = ($default_form == $entity->id() ? t('Yes') : t('No'));
+ $row['default'] = ($default_form == $entity->id() ? t('Yes') : t('No'));
}
return $row + parent::buildRow($entity);
}
diff --git a/core/modules/contact/src/Entity/ContactForm.php b/core/modules/contact/src/Entity/ContactForm.php
index 1a9f73a..86eabbe 100644
--- a/core/modules/contact/src/Entity/ContactForm.php
+++ b/core/modules/contact/src/Entity/ContactForm.php
@@ -7,8 +7,11 @@
namespace Drupal\contact\Entity;
+use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
use Drupal\contact\ContactFormInterface;
+use Drupal\Core\Config\Entity\ThirdPartySettingsTrait;
+use Drupal\Core\Entity\EntityStorageInterface;
/**
* Defines the contact form entity.
diff --git a/core/modules/contact/src/Plugin/Block/ContactNavigationBlock.php b/core/modules/contact/src/Plugin/Block/ContactNavigationBlock.php
new file mode 100644
index 0000000..6b79758
--- /dev/null
+++ b/core/modules/contact/src/Plugin/Block/ContactNavigationBlock.php
@@ -0,0 +1,233 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\contact\Plugin\Block\ContactNavigationBlock.
+ */
+
+namespace Drupal\contact\Plugin\Block;
+
+use Drupal\Component\Utility\String;
+use Drupal\Core\Block\BlockBase;
+use Drupal\Core\Cache\Cache;
+use Drupal\Core\Config\Entity\ConfigEntityStorageInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Url;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a 'Contact forms' block.
+ *
+ * @Block(
+ * id = "contact_navigation",
+ * admin_label = @Translation("Contact forms"),
+ * category = @Translation("Menus")
+ * )
+ */
+class ContactNavigationBlock extends BlockBase implements ContainerFactoryPluginInterface {
+
+ /**
+ * The contact form storage.
+ *
+ * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
+ */
+ protected $storage;
+
+ /**
+ * Constructs a new ContactNavigationBlock instance.
+ *
+ * @param array $configuration
+ * A configuration array containing information about the plugin instance.
+ * @param string $plugin_id
+ * The plugin_id for the plugin instance.
+ * @param mixed $plugin_definition
+ * The plugin implementation definition.
+ * @param \Drupal\Core\Config\Entity\ConfigEntityStorageInterface $storage
+ * The contact category storage.
+ */
+ public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigEntityStorageInterface $storage) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+ $this->storage = $storage;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+ return new static(
+ $configuration,
+ $plugin_id,
+ $plugin_definition,
+ $container->get('entity.manager')->getStorage('contact_form')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function defaultConfiguration() {
+ return [
+ 'forms' => [],
+ 'cache' => ['max_age' => Cache::PERMANENT],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCacheTags() {
+ $cache_tags = parent::getCacheTags();
+ if ($forms = array_keys($this->configuration['forms'])) {
+ foreach ($this->storage->loadMultiple($forms) as $form) {
+ $cache_tags = Cache::mergeTags($cache_tags, $form->getCacheTags());
+ }
+ }
+ return $cache_tags;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function getRequiredCacheContexts() {
+ // This blocks must be cached per role: different roles may have access to
+ // contact forms.
+ return ['cache_context.user.roles'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function blockAccess(AccountInterface $account) {
+ // Only grant access to users with the 'access site-wide contact form'
+ // permission.
+ return $account->hasPermission('access site-wide contact form');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function blockForm($form, FormStateInterface $form_state) {
+ $form['forms'] = [
+ '#type' => 'table',
+ '#header' => [
+ 'label' => $this->t('Form'),
+ 'display' => $this->t('Display'),
+ 'weight' => $this->t('Weight'),
+ ],
+ '#empty' => $this->t('There is no contact forms yet. Create one.'),
+ '#tabledrag' => [
+ [
+ 'action' => 'order',
+ 'relationship' => 'sibling',
+ 'group' => 'weight',
+ ],
+ ],
+ ];
+
+ $contact_forms = $this->configuration['forms'];
+ $rows = [];
+ $min_weight = 0;
+
+ /** @var \Drupal\contact\ContactFormInterface $contact_form */
+ foreach ($this->storage->loadMultiple() as $id => $contact_form) {
+ // Do not list personal contact form.
+ if ($id == 'personal') {
+ continue;
+ }
+
+ $row_label = $contact_form->label();
+ $row_weight = $contact_form->getWeight();
+ $row_display = TRUE;
+
+ if ($contact_forms) {
+ // Display only selected forms by default if there are any.
+ $row_display = isset($contact_forms[$id]);
+ // Find lowest weight to display selected forms first.
+ $min_weight = min($min_weight, $row_weight);
+ }
+ $row = [
+ 'label' => ['#markup' => String::checkPlain($row_label)],
+ 'display' => [
+ '#type' => 'checkbox',
+ '#default_value' => $row_display,
+ '#title' => t('Display the @title', ['@title' => $row_label]),
+ '#title_display' => 'invisible',
+ ],
+ // Add weight column.
+ 'weight' => [
+ '#type' => 'weight',
+ '#title' => $this->t('Weight for @title', ['@title' => $row_label]),
+ '#title_display' => 'invisible',
+ '#default_value' => $row_weight,
+ '#attributes' => ['class' => ['weight']],
+ ],
+ ];
+ $row['#attributes']['class'][] = 'draggable';
+ $row['#weight'] = $row_weight;
+ $rows[$contact_form->id()] = $row;
+ }
+
+ if ($contact_forms) {
+ // Move selected categories to the top of the list.
+ $min_weight = $min_weight - count($contact_forms);
+ foreach ($contact_forms as $id => $data) {
+ if (isset($rows[$id])) {
+ $rows[$id]['#weight'] = $min_weight;
+ $rows[$id]['weight']['#default_value'] = $min_weight++;
+ }
+ }
+ }
+
+ uasort($rows, '\Drupal\Component\Utility\SortArray::sortByWeightProperty');
+ $form['forms'] += $rows;
+
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function blockValidate($form, FormStateInterface $form_state) {
+ $contact_forms = [];
+ foreach ($form_state->getValue('forms') as $id => $value) {
+ if ($value['display']) {
+ $contact_forms[$id] = $value['weight'];
+ }
+ }
+ if (empty($contact_forms)) {
+ $form_state->setErrorByName('forms', $this->t('At least one category should be selected.'));
+ }
+ $form_state->setValue('forms', $contact_forms);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function blockSubmit($form, FormStateInterface $form_state) {
+ $this->configuration['forms'] = $form_state->getValue('forms');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function build() {
+ $links = [];
+ /** @var \Drupal\contact\ContactFormInterface $contact_form */
+ foreach ($this->storage->loadMultiple(array_keys($this->configuration['forms'])) as $id => $contact_form) {
+ $links[$id] = $contact_form->link($contact_form->label(), 'submit-form', [
+ 'set_active_class' => TRUE,
+ ]);
+ }
+ return [
+ '#theme' => 'item_list__contact',
+ '#items' => $links,
+ '#attributes' => [
+ 'class' => ['menu'],
+ ]
+ ];
+ }
+
+}
diff --git a/core/modules/contact/src/Plugin/Block/ContactNavigationBlock.php b/core/modules/contact/src/Plugin/Block/ContactNavigationBlock.php
index 6b79758..d4ad47d 100644
--- a/core/modules/contact/src/Plugin/Block/ContactNavigationBlock.php
+++ b/core/modules/contact/src/Plugin/Block/ContactNavigationBlock.php
@@ -7,14 +7,14 @@
namespace Drupal\contact\Plugin\Block;
-use Drupal\Component\Utility\String;
+use Drupal\Component\Utility\Html;
+use Drupal\Core\Access\AccessResult;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Config\Entity\ConfigEntityStorageInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
-use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -79,6 +79,7 @@ public function defaultConfiguration() {
* {@inheritdoc}
*/
public function getCacheTags() {
+
$cache_tags = parent::getCacheTags();
if ($forms = array_keys($this->configuration['forms'])) {
foreach ($this->storage->loadMultiple($forms) as $form) {
@@ -103,7 +104,11 @@ protected function getRequiredCacheContexts() {
protected function blockAccess(AccountInterface $account) {
// Only grant access to users with the 'access site-wide contact form'
// permission.
- return $account->hasPermission('access site-wide contact form');
+ if ($account->hasPermission('access site-wide contact form')) {
+ return AccessResult::allowed();
+ }
+
+ return AccessResult::forbidden();
}
/**
@@ -149,7 +154,7 @@ public function blockForm($form, FormStateInterface $form_state) {
$min_weight = min($min_weight, $row_weight);
}
$row = [
- 'label' => ['#markup' => String::checkPlain($row_label)],
+ 'label' => ['#markup' => Html::escape($row_label)],
'display' => [
'#type' => 'checkbox',
'#default_value' => $row_display,
@@ -214,10 +219,11 @@ public function blockSubmit($form, FormStateInterface $form_state) {
* {@inheritdoc}
*/
public function build() {
+
$links = [];
/** @var \Drupal\contact\ContactFormInterface $contact_form */
foreach ($this->storage->loadMultiple(array_keys($this->configuration['forms'])) as $id => $contact_form) {
- $links[$id] = $contact_form->link($contact_form->label(), 'submit-form', [
+ $links[$id] = $contact_form->link($contact_form->label(), 'canonical', [
'set_active_class' => TRUE,
]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment