X-Git-Url: https://yaffs.net/gitweb/?a=blobdiff_plain;f=web%2Fmodules%2Fcontrib%2Fmetatag%2Fsrc%2FMetatagManager.php;h=170f33d6b4662c789b0c78e36f08152fa91b3608;hb=93ef30d42f68e55d11d97312531118bbcd4cf318;hp=9123713c53f38a34cb49041c769981a079d4de0c;hpb=a2bd1bf0c2c1f1a17d188f4dc0726a45494cefae;p=yaffs-website diff --git a/web/modules/contrib/metatag/src/MetatagManager.php b/web/modules/contrib/metatag/src/MetatagManager.php index 9123713c5..170f33d6b 100644 --- a/web/modules/contrib/metatag/src/MetatagManager.php +++ b/web/modules/contrib/metatag/src/MetatagManager.php @@ -4,9 +4,12 @@ namespace Drupal\metatag; use Drupal\Component\Render\PlainTextOutput; use Drupal\Core\Entity\ContentEntityInterface; +use Drupal\Core\Entity\EntityTypeManager; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Logger\LoggerChannelFactoryInterface; use Drupal\field\Entity\FieldConfig; +use Drupal\metatag\Entity\MetatagDefaults; +use Drupal\views\ViewEntityInterface; /** * Class MetatagManager. @@ -17,7 +20,7 @@ class MetatagManager implements MetatagManagerInterface { protected $groupPluginManager; protected $tagPluginManager; - + protected $metatagDefaults; protected $tokenService; /** @@ -34,15 +37,18 @@ class MetatagManager implements MetatagManagerInterface { * @param MetatagTagPluginManager $tagPluginManager * @param MetatagToken $token * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $channelFactory + * @param EntityTypeManager $entityTypeManager */ public function __construct(MetatagGroupPluginManager $groupPluginManager, MetatagTagPluginManager $tagPluginManager, MetatagToken $token, - LoggerChannelFactoryInterface $channelFactory) { + LoggerChannelFactoryInterface $channelFactory, + EntityTypeManager $entityTypeManager) { $this->groupPluginManager = $groupPluginManager; $this->tagPluginManager = $tagPluginManager; $this->tokenService = $token; $this->logger = $channelFactory->get('metatag'); + $this->metatagDefaults = $entityTypeManager->getStorage('metatag_defaults'); } /** @@ -62,11 +68,40 @@ class MetatagManager implements MetatagManagerInterface { return $tags; } + /** + * {@inheritdoc} + */ + public function tagsFromEntityWithDefaults(ContentEntityInterface $entity) { + return $this->tagsFromEntity($entity) + $this->defaultTagsFromEntity($entity); + } + + /** + * {@inheritdoc} + */ + public function defaultTagsFromEntity(ContentEntityInterface $entity) { + /** @var MetatagDefaults $metatags */ + $metatags = $this->metatagDefaults->load('global'); + if (!$metatags) { + return NULL; + } + // Add/overwrite with tags set on the entity type. + $entity_type_tags = $this->metatagDefaults->load($entity->getEntityTypeId()); + if (!is_null($entity_type_tags)) { + $metatags->overwriteTags($entity_type_tags->get('tags')); + } + // Add/overwrite with tags set on the entity bundle. + $bundle_metatags = $this->metatagDefaults->load($entity->getEntityTypeId() . '__' . $entity->bundle()); + if (!is_null($bundle_metatags)) { + $metatags->overwriteTags($bundle_metatags->get('tags')); + } + return $metatags->get('tags'); + } + /** * Gets the group plugin definitions. * * @return array - * Group definitions + * Group definitions. */ protected function groupDefinitions() { return $this->groupPluginManager->getDefinitions(); @@ -91,10 +126,10 @@ class MetatagManager implements MetatagManagerInterface { // Pull the data from the definitions into a new array. $groups = []; foreach ($metatag_groups as $group_name => $group_info) { - $id = $group_info['id']; - $groups[$id]['label'] = $group_info['label']->render(); - $groups[$id]['description'] = $group_info['description']; - $groups[$id]['weight'] = $group_info['weight']; + $groups[$group_name]['id'] = $group_info['id']; + $groups[$group_name]['label'] = $group_info['label']->render(); + $groups[$group_name]['description'] = $group_info['description']; + $groups[$group_name]['weight'] = $group_info['weight']; } // Create the 'sort by' array. @@ -118,10 +153,10 @@ class MetatagManager implements MetatagManagerInterface { // Pull the data from the definitions into a new array. $tags = []; foreach ($metatag_tags as $tag_name => $tag_info) { - $id = $tag_info['id']; - $tags[$id]['label'] = $tag_info['label']->render(); - $tags[$id]['group'] = $tag_info['group']; - $tags[$id]['weight'] = $tag_info['weight']; + $tags[$tag_name]['id'] = $tag_info['id']; + $tags[$tag_name]['label'] = $tag_info['label']->render(); + $tags[$tag_name]['group'] = $tag_info['group']; + $tags[$tag_name]['weight'] = $tag_info['weight']; } // Create the 'sort by' array. @@ -144,7 +179,7 @@ class MetatagManager implements MetatagManagerInterface { $groups = $this->sortedGroups(); $tags = $this->sortedTags(); - foreach ($tags as $tag_id => $tag) { + foreach ($tags as $tag_name => $tag) { $tag_group = $tag['group']; if (!isset($groups[$tag_group])) { @@ -155,7 +190,7 @@ class MetatagManager implements MetatagManagerInterface { $tag_group = 'basic'; } - $groups[$tag_group]['tags'][$tag_id] = $tag; + $groups[$tag_group]['tags'][$tag_name] = $tag; } return $groups; @@ -165,7 +200,6 @@ class MetatagManager implements MetatagManagerInterface { * {@inheritdoc} */ public function form(array $values, array $element, array $token_types = [], array $included_groups = NULL, array $included_tags = NULL) { - // Add the outer fieldset. $element += [ '#type' => 'details', @@ -176,29 +210,29 @@ class MetatagManager implements MetatagManagerInterface { $groups_and_tags = $this->sortedGroupsWithTags(); $first = TRUE; - foreach ($groups_and_tags as $group_id => $group) { + foreach ($groups_and_tags as $group_name => $group) { // Only act on groups that have tags and are in the list of included // groups (unless that list is null). - if (isset($group['tags']) && (is_null($included_groups) || in_array($group_id, $included_groups))) { + if (isset($group['tags']) && (is_null($included_groups) || in_array($group_name, $included_groups) || in_array($group['id'], $included_groups))) { // Create the fieldset. - $element[$group_id]['#type'] = 'details'; - $element[$group_id]['#title'] = $group['label']; - $element[$group_id]['#description'] = $group['description']; - $element[$group_id]['#open'] = $first; + $element[$group_name]['#type'] = 'details'; + $element[$group_name]['#title'] = $group['label']; + $element[$group_name]['#description'] = $group['description']; + $element[$group_name]['#open'] = $first; $first = FALSE; - foreach ($group['tags'] as $tag_id => $tag) { + foreach ($group['tags'] as $tag_name => $tag) { // Only act on tags in the included tags list, unless that is null. - if (is_null($included_tags) || in_array($tag_id, $included_tags)) { + if (is_null($included_tags) || in_array($tag_name, $included_tags) || in_array($tag['id'], $included_tags)) { // Make an instance of the tag. - $tag = $this->tagPluginManager->createInstance($tag_id); + $tag = $this->tagPluginManager->createInstance($tag_name); // Set the value to the stored value, if any. - $tag_value = isset($values[$tag_id]) ? $values[$tag_id] : NULL; + $tag_value = isset($values[$tag_name]) ? $values[$tag_name] : NULL; $tag->setValue($tag_value); // Create the bit of form for this tag. - $element[$group_id][$tag_id] = $tag->form($element); + $element[$group_name][$tag_name] = $tag->form($element); } } } @@ -238,8 +272,8 @@ class MetatagManager implements MetatagManagerInterface { /** * Returns a list of the metatags with values from a field. * - * @param $entity - * @param $field_name + * @param ContentEntityInterface $entity + * @param string $field_name */ protected function getFieldTags(ContentEntityInterface $entity, $field_name) { $tags = []; @@ -254,6 +288,93 @@ class MetatagManager implements MetatagManagerInterface { return $tags; } + /** + * + * + * @param ContentEntityInterface $entity + */ + public function getDefaultMetatags(ContentEntityInterface $entity = NULL) { + // Get general global metatags + $metatags = $this->getGlobalMetatags(); + // If that is empty something went wrong. + if (!$metatags) { + return; + } + + // Check if this is a special page. + $special_metatags = $this->getSpecialMetatags(); + + // Merge with all globals defaults. + if ($special_metatags) { + $metatags->set('tags', array_merge($metatags->get('tags'), $special_metatags->get('tags'))); + } + + // Next check if there is this page is an entity that has meta tags. + // @TODO: Think about using other defaults, e.g. views. Maybe use plugins? + else { + if (is_null($entity)) { + $entity = metatag_get_route_entity(); + } + + if (!empty($entity)) { + // Get default metatags for a given entity. + $entity_defaults = $this->getEntityDefaultMetatags($entity); + if ($entity_defaults != NULL) { + $metatags->set('tags', array_merge($metatags->get('tags'), $entity_defaults)); + } + } + } + + return $metatags->get('tags'); + } + + /** + * + */ + public function getGlobalMetatags() { + return $this->metatagDefaults->load('global'); + } + + /** + * + */ + public function getSpecialMetatags() { + $metatags = NULL; + + if (\Drupal::service('path.matcher')->isFrontPage()) { + $metatags = $this->metatagDefaults->load('front'); + } + elseif (\Drupal::service('current_route_match')->getRouteName() == 'system.403') { + $metatags = $this->metatagDefaults->load('403'); + } + elseif (\Drupal::service('current_route_match')->getRouteName() == 'system.404') { + $metatags = $this->metatagDefaults->load('404'); + } + + return $metatags; + } + + /** + * + */ + public function getEntityDefaultMetatags(ContentEntityInterface $entity) { + $entity_metatags = $this->metatagDefaults->load($entity->getEntityTypeId()); + $metatags = []; + if ($entity_metatags != NULL) { + // Merge with global defaults. + $metatags = array_merge($metatags, $entity_metatags->get('tags')); + } + + // Finally, check if we should apply bundle overrides. + $bundle_metatags = $this->metatagDefaults->load($entity->getEntityTypeId() . '__' . $entity->bundle()); + if ($bundle_metatags != NULL) { + // Merge with existing defaults. + $metatags = array_merge($metatags, $bundle_metatags->get('tags')); + } + + return $metatags; + } + /** * Generate the elements that go in the attached array in * hook_page_attachments. @@ -262,12 +383,49 @@ class MetatagManager implements MetatagManagerInterface { * The array of tags as plugin_id => value. * @param object $entity * Optional entity object to use for token replacements. + * * @return array * Render array with tag elements. */ public function generateElements($tags, $entity = NULL) { - $metatag_tags = $this->tagPluginManager->getDefinitions(); $elements = []; + $tags = $this->generateRawElements($tags, $entity); + + foreach ($tags as $name => $tag) { + if (!empty($tag)) { + $elements['#attached']['html_head'][] = [ + $tag, + $name, + ]; + } + } + + return $elements; + } + + /** + * Generate the actual meta tag values. + * + * @param array $tags + * The array of tags as plugin_id => value. + * @param object $entity + * Optional entity object to use for token replacements. + * + * @return array + * Render array with tag elements. + */ + public function generateRawElements($tags, $entity = NULL) { + $rawTags = []; + + $metatag_tags = $this->tagPluginManager->getDefinitions(); + + // Order the elements by weight first, as some systems like Facebook care. + uksort($tags, function ($tag_name_a, $tag_name_b) use ($metatag_tags) { + $weight_a = isset($metatag_tags[$tag_name_a]['weight']) ? $metatag_tags[$tag_name_a]['weight'] : 0; + $weight_b = isset($metatag_tags[$tag_name_b]['weight']) ? $metatag_tags[$tag_name_b]['weight'] : 0; + + return ($weight_a < $weight_b) ? -1 : 1; + }); // Each element of the $values array is a tag with the tag plugin name // as the key. @@ -280,7 +438,15 @@ class MetatagManager implements MetatagManagerInterface { // Render any tokens in the value. $token_replacements = []; if ($entity) { - $token_replacements = [$entity->getEntityTypeId() => $entity]; + // @TODO: This needs a better way of discovering the context. + if ($entity instanceof ViewEntityInterface) { + // Views tokens require the ViewExecutable, not the config entity. + // @todo Can we move this into metatag_views somehow? + $token_replacements = ['view' => $entity->getExecutable()]; + } + else { + $token_replacements = [$entity->getEntityTypeId() => $entity]; + } } // Set the value as sometimes the data needs massaging, such as when @@ -289,6 +455,7 @@ class MetatagManager implements MetatagManagerInterface { // @see @Robots::setValue(). $tag->setValue($value); $langcode = \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId(); + if ($tag->type() === 'image') { $processed_value = $this->tokenService->replace($tag->value(), $token_replacements, ['langcode' => $langcode]); } @@ -303,15 +470,12 @@ class MetatagManager implements MetatagManagerInterface { $output = $tag->output(); if (!empty($output)) { - $elements['#attached']['html_head'][] = [ - $output, - $tag_name - ]; + $rawTags[$tag_name] = $output; } } } - return $elements; + return $rawTags; } /**