diff --git a/core/modules/contact/src/ContactFormListBuilder.php b/core/modules/contact/src/ContactFormListBuilder.php index 883ad9a..369249a 100644 --- a/core/modules/contact/src/ContactFormListBuilder.php +++ b/core/modules/contact/src/ContactFormListBuilder.php @@ -10,6 +10,8 @@ use Drupal\Component\Utility\String; use Drupal\Core\Config\Entity\ConfigEntityListBuilder; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Routing\LinkGeneratorTrait; +use Drupal\Core\Url; /** * Defines a class to build a listing of contact form entities. @@ -18,6 +20,8 @@ */ class ContactFormListBuilder extends ConfigEntityListBuilder { + use LinkGeneratorTrait; + /** * {@inheritdoc} */ @@ -32,13 +36,14 @@ public function buildHeader() { * {@inheritdoc} */ public function buildRow(EntityInterface $entity) { - $row['form'] = $this->getLabel($entity); // Special case the personal form. if ($entity->id() == 'personal') { + $row['form'] = $this->getLabel($entity); $row['recipients'] = t('Selected user'); $row['selected'] = t('No'); } else { + $row['form'] = $this->l($this->getLabel($entity), Url::fromRoute('contact.site_page_form', ['contact_form' => $entity->id()])); $row['recipients'] = String::checkPlain(implode(', ', $entity->getRecipients())); $default_form = \Drupal::config('contact.settings')->get('default_form'); $row['selected'] = ($default_form == $entity->id() ? t('Yes') : t('No')); 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..9e961f3 --- /dev/null +++ b/core/modules/contact/src/Plugin/Block/ContactNavigationBlock.php @@ -0,0 +1,231 @@ +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->getCacheTag()); + } + } + 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] = [ + '#type' => 'link', + '#title' => $contact_form->label(), + '#url' => Url::fromRoute('contact.site_page_form', ['contact_form' => $id]), + ]; + } + return [ + '#theme' => 'item_list__contact', + '#items' => $links, + ]; + } + +} diff --git a/core/modules/contact/src/Tests/ContactSitewideTest.php b/core/modules/contact/src/Tests/ContactSitewideTest.php index 7e6207f..26a39d7 100644 --- a/core/modules/contact/src/Tests/ContactSitewideTest.php +++ b/core/modules/contact/src/Tests/ContactSitewideTest.php @@ -234,7 +234,7 @@ function testSiteWideContact() { // Find out in which row the form we want to add a field to is. $i = 0; foreach($this->xpath('//table/tbody/tr') as $row) { - if (((string)$row->td[0]) == $label) { + if (((string)$row->td[0]->a) == $label) { break; } $i++;