3 namespace Drupal\metatag_views\Controller;
5 use Drupal\Core\Controller\ControllerBase;
6 use Drupal\Core\Entity\EntityStorageInterface;
8 use Drupal\metatag\MetatagManagerInterface;
9 use Drupal\views\Views;
10 use Symfony\Component\DependencyInjection\ContainerInterface;
13 * Class MetatagViewsController.
15 * @package Drupal\metatag_views\Controller
17 class MetatagViewsController extends ControllerBase {
20 * The Views storage interface.
22 * @var \Drupal\Core\Entity\EntityStorageInterface
24 protected $viewStorage;
27 * The Metatag manager interface.
29 * @var \Drupal\metatag\MetatagManagerInterface
31 protected $metatagManager;
34 * Associative array of labels.
38 protected $viewLabels;
43 public function __construct(EntityStorageInterface $viewStorage, MetatagManagerInterface $metatagManager) {
44 $this->viewStorage = $viewStorage;
45 $this->metatagManager = $metatagManager;
47 // Generate the labels for views and displays.
48 $this->labels = $this->getViewsAndDisplaysLabels();
54 public static function create(ContainerInterface $container) {
56 $container->get('entity_type.manager')->getStorage('view'),
57 $container->get('metatag.manager')
62 * Get meta tags for all of the views / displays that have them set.
65 * List of tags grouped by view and display.
67 public static function getTaggedViews() {
69 foreach (Views::getEnabledViews() as $view_id => $view) {
70 $displays = $view->get('display');
71 foreach (array_keys($displays) as $display_id) {
72 if ($tags = metatag_get_view_tags($view_id, $display_id)) {
73 $tagged_views[$view_id][$display_id] = $tags;
81 * Generates the renderable array for views meta tags UI.
84 * The list of details.
86 public function listViews() {
89 $elements['header'] = [
90 '#markup' => '<p>' . $this->t("To view a list of displays with meta tags set up, click on a view name. To view a summary of meta tags configuration for a particular display, click on the display name. If you need to set meta tags for a specific view, choose Add views meta tags. Reverting the meta tags removes the specific configuration and falls back to defaults.") . '</p>',
93 // Iterate over the values and build the whole UI.
94 // 1. Top level is a collapsible fieldset with a view name (details)
95 // 2. Inside each fieldset we have 2 columns -> Display and Operations.
96 // Display contains point 3.
97 // Operations contain edit and revert.
98 // 3. In each display there is a table that has 2 columns: tag name and tag
100 $tagged_views = $this->getTaggedViews();
101 foreach ($tagged_views as $view_id => $displays) {
102 $elements[$view_id] = [
103 '#type' => 'details',
104 '#title' => $this->t($this->viewLabels[$view_id]['#label']),
105 'details' => $this->buildViewDetails($view_id, $displays),
113 * Builds the second "level" of the UI table with display fieldset and ops.
115 * @param string $view_id
116 * The view display to use.
117 * @param array $displays
118 * The displays to process.
123 protected function buildViewDetails($view_id, array $displays) {
126 '#collapsible' => TRUE,
129 $this->t('Operations'),
133 foreach ($displays as $display_id => $metatags) {
134 $metatags = array_filter($metatags);
136 $element[$display_id]['details'] = [
137 '#type' => 'details',
138 '#title' => $this->viewLabels[$view_id][$display_id],
142 'view_id' => $view_id,
143 'display_id' => $display_id,
146 // Generate the operations.
147 $element[$display_id]['ops'] = [
148 '#type' => 'operations',
151 'title' => $this->t('Edit'),
152 'url' => Url::fromRoute('metatag_views.metatags.edit', $params),
155 'title' => $this->t('Translate'),
156 'url' => Url::fromRoute('metatag_views.metatags.translate_overview', $params),
159 'title' => $this->t('Revert'),
160 'url' => Url::fromRoute('metatag_views.metatags.revert', $params),
165 // Build the rows for each of the metatag types.
166 $element[$display_id]['details']['table'] = $this->buildDisplayDetailsTable($metatags);
173 * Build the table with metatag values summary.
176 * The tags to process.
179 * The tag structure in a display element.
181 protected function buildDisplayDetailsTable(array $tags) {
187 foreach ($tags as $tag_name => $tag_value) {
188 // This is for the case where we have a subarray.
189 $tag_value = $this->prepareTagValue($tag_value);
194 $element[$i]['tag_name'] = [
196 '#markup' => $tag_name,
199 $element[$i]['tag_value'] = [
201 '#markup' => $tag_value,
210 * Massage the tag value.
212 * @param string $value
213 * The meta tag to output.
216 * An imploded string for meta tags that are nested, ex. robots.
218 protected function prepareTagValue($value) {
219 if (is_array($value)) {
220 $value = implode(', ', array_filter($value));
227 * Gets label values for the views and their displays.
229 protected function getViewsAndDisplaysLabels() {
230 /** @var \Drupal\views\ViewEntityInterface[] $views */
231 $views = $this->viewStorage->loadByProperties(['status' => 1]);
235 foreach ($views as $view_id => $view) {
236 $displays = $view->get('display');
237 $labels[$view_id]['#label'] = $view->label();
238 foreach (array_keys($displays) as $display_id) {
239 $labels[$view_id][$display_id] = $displays[$display_id]['display_title'];
243 $this->viewLabels = $labels;