diff --git a/core/modules/contact/lib/Drupal/contact/CategoryListBuilder.php b/core/modules/contact/lib/Drupal/contact/CategoryListBuilder.php index 37169ff..dcc7889 100644 --- a/core/modules/contact/lib/Drupal/contact/CategoryListBuilder.php +++ b/core/modules/contact/lib/Drupal/contact/CategoryListBuilder.php @@ -32,7 +32,7 @@ public function buildHeader() { * {@inheritdoc} */ public function buildRow(EntityInterface $entity) { - $row['category'] = $this->getLabel($entity); + $row['category'] = $this->l($this->getLabel($entity),'contact.site_page_category', array('contact_category' => $entity->id())); // Special case the personal category. if ($entity->id() == 'personal') { $row['recipients'] = t('Selected user'); @@ -46,4 +46,30 @@ public function buildRow(EntityInterface $entity) { return $row + parent::buildRow($entity); } + /** + * Renders a link to a route given a route name and its parameters. + * + * @see \Drupal\Core\Utility\LinkGeneratorInterface::generate() for details + * on the arguments, usage, and possible exceptions. + * + * @return string + * An HTML string containing a link to the given route and parameters. + */ + protected function l($text, $route_name, array $parameters = array(), array $options = array()) { + return $this->linkGenerator()->generate($text, $route_name, $parameters, $options); + } + + /** + * Returns the link generator. + * + * @return \Drupal\Core\Utility\LinkGeneratorInterface + * The link generator + */ + protected function linkGenerator() { + if (!isset($this->linkGenerator)) { + $this->linkGenerator = \Drupal::linkGenerator(); + } + return $this->linkGenerator; + } + } diff --git a/core/modules/contact/lib/Drupal/contact/Plugin/Block/ContactNavigationBlock.php b/core/modules/contact/lib/Drupal/contact/Plugin/Block/ContactNavigationBlock.php new file mode 100644 index 0000000..8bf8bdb --- /dev/null +++ b/core/modules/contact/lib/Drupal/contact/Plugin/Block/ContactNavigationBlock.php @@ -0,0 +1,244 @@ +storage = $storage; + $this->formBuilder = $form_builder; + } + + /** + * {@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_category'), + $container->get('form_builder') + ); + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return array( + 'categories' => array(), + 'cache' => array('max_age' => Cache::PERMANENT) + ); + } + + /** + * {@inheritdoc} + */ + public function getCacheTags() { + // Even when the menu block renders to the empty string for a user, we want + // the cache tag for this menu to be set: whenever the menu is changed, this + // menu block must also be re-rendered for that user, because maybe a menu + // link that is accessible for that user has been added. + $tags = array('contact_category' => array_keys($this->configuration['categories'])); + return NestedArray::mergeDeep(parent::getCacheTags(), $tags); + } + + /** + * {@inheritdoc} + */ + protected function getRequiredCacheContexts() { + // This blocks must be cached per role: different roles may have access to + // contact forms. + return array('cache_context.user.roles'); + } + + /** + * {@inheritdoc} + */ + public function access(AccountInterface $account) { + // Only grant access to users with the 'access site-wide contact form' + // permission. + return $account->hasPermission('access site-wide contact form'); + } + + /** + * {@inheritdoc} + */ + function blockForm($form, &$form_state) { + $form['categories'] = array( + '#type' => 'table', + '#header' => array( + 'label' => $this->t('Category name'), + 'display' => $this->t('Display'), + 'weight' => $this->t('Weight'), + ), + '#empty' => $this->t('There is no contact categories yet. Create one.'), + '#tabledrag' => array( + array( + 'action' => 'order', + 'relationship' => 'sibling', + 'group' => 'weight', + ), + ), + ); + + $categories = $this->configuration['categories']; + $rows = array(); + $min_weight = 0; + /** @var $category \Drupal\contact\CategoryInterface */ + foreach ($this->storage->loadMultiple() as $id => $category) { + // Do not list personal category. + if ($id == 'personal') { + continue; + } + + $row_label = $category->label(); + $row_weight = $category->get('weight'); + $row_display = TRUE; + + if ($categories) { + // Display only selected categories by default if there are any. + $row_display = isset($categories[$id]); + // Find lowest weight to display selected categories first. + if ($min_weight > $row_weight) { + $min_weight = $row_weight; + } + } + $row = array( + 'label' => array('#markup' => String::checkPlain($row_label)), + 'display' => array( + '#type' => 'checkbox', + '#default_value' => $row_display, + '#title' => t('Display the @title', array('@title' => $row_label)), + '#title_display' => 'invisible', + ), + // Add weight column. + 'weight' => array( + '#type' => 'weight', + '#title' => $this->t('Weight for @title', array('@title' => $row_label)), + '#title_display' => 'invisible', + '#default_value' => $row_weight, + '#attributes' => array('class' => array('weight')), + ), + ); + $row['#attributes']['class'][] = 'draggable'; + $row['#weight'] = $row_weight; + $rows[$category->id()] = $row; + } + + if ($categories) { + // Move selected categories to the top of the list. + $min_weight = $min_weight - count($categories); + foreach ($categories 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['categories'] += $rows; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function blockValidate($form, &$form_state) { + $categories = array(); + foreach ($form_state['values']['categories'] as $id => $value) { + if ($value['display']) { + $categories[$id] = $value['weight']; + } + } + if (empty($categories)) { + $this->formBuilder->setErrorByName('categories', $form_state, $this->t('At least one category should be selected.')); + } + $form_state['values']['categories'] = $categories; + } + + /** + * {@inheritdoc} + */ + public function blockSubmit($form, &$form_state) { + $this->configuration['categories'] = $form_state['values']['categories']; + } + + /** + * {@inheritdoc} + */ + public function build() { + $links = array(); + /** @var $category \Drupal\contact\CategoryInterface */ + foreach ($this->storage->loadMultiple(array_keys($this->configuration['categories'])) as $id => $category) { + $links[$id] = array( + '#type' => 'link', + '#title' => $category->label(), + '#route_name' => 'contact.site_page_category', + '#route_parameters' => array('contact_category' => $id), + ); + } + return array( + '#theme' => 'item_list__contact', + '#items' => $links, + ); + } + +}