Loading CHANGELOG.txt +2 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,8 @@ Metatag 8.x-1.x-dev, xxxx-xx-xx meta tag lengths. #3247678 by esolitos, DamienMcKenna: Support migration with multiple "d7_*" sources. #2914998 by JeroenT, DamienMcKenna, gngn, ytsurk: Add the mask icon "color" attribute. Metatag 8.x-1.16, 2021-03-15 Loading metatag.install +131 −0 Original line number Diff line number Diff line Loading @@ -74,3 +74,134 @@ function metatag_update_8107() { function metatag_update_8108() { return (string) new TranslatableMarkup("The sites's caches will need to be rebuild to ensure Metatag works as intended."); } /** * Update mask_icon values to the new structure. */ function metatag_update_8109(&$sandbox) { // This whole top section only needs to be done the first time. if (!isset($sandbox['records_processed'])) { $sandbox['records_processed'] = 0; $sandbox['total_records'] = 0; $sandbox['current_field'] = 0; $sandbox['current_record'] = 0; // Counter to enumerate the fields so we can access them in the array // by number rather than name. $field_counter = 0; // Get all of the field storage entities of type metatag. $field_storage_configs = \Drupal::entityTypeManager() ->getStorage('field_storage_config') ->loadByProperties(['type' => 'metatag']); foreach ($field_storage_configs as $field_storage) { $field_name = $field_storage->getName(); // Get the individual fields (field instances) associated with bundles. $fields = \Drupal::entityTypeManager() ->getStorage('field_config') ->loadByProperties(['field_name' => $field_name]); foreach ($fields as $field) { // Get the bundle this field is attached to. $bundle = $field->getTargetBundle(); // Determine the table and "value" field names. $field_table = "node__" . $field_name; $field_value_field = $field_name . "_value"; // Get all records where the field data does not match the default. $query = \Drupal::database()->select($field_table); $query->addField($field_table, 'entity_id'); $query->addField($field_table, 'revision_id'); $query->addField($field_table, 'langcode'); $query->addField($field_table, $field_value_field); $query->condition('bundle', $bundle, '='); $result = $query->execute(); $records = $result->fetchAll(); // Fill in all the sandbox information so we can batch the individual // record comparing and updating. $sandbox['fields'][$field_counter]['field_table'] = $field_table; $sandbox['fields'][$field_counter]['field_value_field'] = $field_value_field; $sandbox['fields'][$field_counter]['records'] = $records; $sandbox['total_records'] += count($sandbox['fields'][$field_counter]['records'] = $records); $field_counter++; } } } if ($sandbox['total_records'] == 0) { // No partially overridden fields so we can skip the whole batch process. $sandbox['#finished'] = 1; } else { // Begin the batch processing of individual field records. $max_per_batch = 10; $counter = 1; $current_field = $sandbox['current_field']; $current_field_records = $sandbox['fields'][$current_field]['records']; $current_record = $sandbox['current_record']; $field_table = $sandbox['fields'][$current_field]['field_table']; $field_value_field = $sandbox['fields'][$current_field]['field_value_field']; // Loop through the field(s) and update the mask_icon values if necessary. while ($counter <= $max_per_batch && $record = $current_field_records[$current_record]) { // Strip any empty tags or ones matching the field's defaults and leave // only the overridden tags in $new_tags. $tags = unserialize($record->$field_value_field); if (isset($tags['mask-icon'])) { $tags['mask_icon'] = [ 'href' => $tags['mask-icon'], ]; $tags_string = serialize($tags); \Drupal::database()->update($field_table) ->fields([ $field_value_field => $tags_string, ]) ->condition('entity_id', $record->entity_id) ->condition('revision_id', $record->revision_id) ->condition('langcode', $record->langcode) ->execute(); } $counter++; $current_record++; } // We ran out of records for the field so start the next batch out with the // next field. if (!isset($current_field_records[$current_record])) { $current_field++; $current_record = 0; } // We have finished all the fields. All done. if (!isset($sandbox['fields'][$current_field])) { $sandbox['records_processed'] += $counter - 1; $sandbox['#finished'] = 1; } // Update the sandbox values to prepare for the next round. else { $sandbox['current_field'] = $current_field; $sandbox['current_record'] = $current_record; $sandbox['records_processed'] += $counter - 1; $sandbox['#finished'] = $sandbox['records_processed'] / $sandbox['total_records']; } } if ($sandbox['total_records'] > 0) { return (string) t('Processed @processed of @total overridden Metatag records.', [ '@processed' => $sandbox['records_processed'], '@total' => $sandbox['total_records'], ]); } else { return (string) t("There were no overridden Metatag records."); } } metatag.post_update.php 0 → 100644 +28 −0 Original line number Diff line number Diff line <?php /** * @file * Post update functions for Metatag. */ use Drupal\Core\Config\Entity\ConfigEntityUpdater; use Drupal\metatag\Entity\MetatagDefaults; /** * Convert mask-icon to array values. */ function metatag_post_update_convert_mask_icon_to_array_values(&$sandbox) { $config_entity_updater = \Drupal::classResolver(ConfigEntityUpdater::class); $config_entity_updater->update($sandbox, 'metatag_defaults', function (MetatagDefaults $metatag_defaults) { if ($metatag_defaults->hasTag('mask-icon')) { $tags = $metatag_defaults->get('tags'); $tags['mask_icon'] = [ 'href' => $metatag_defaults->getTag('mask-icon'), ]; unset($tags['mask-icon']); $metatag_defaults->set('tags', $tags); return TRUE; } return FALSE; }); } metatag_favicons/config/schema/metatag_favicons.metatag_tag.schema.yml +9 −2 Original line number Diff line number Diff line Loading @@ -5,9 +5,16 @@ metatag.metatag_tag.shortcut_icon: type: label label: 'Default shortcut icon' metatag.metatag_tag.mask-icon: type: label metatag.metatag_tag.mask_icon: type: mapping label: 'Icon: SVG' mapping: href: type: label label: 'href' color: type: label label: 'Color' metatag.metatag_tag.icon_16x16: type: label label: 'Icon: 16px x 16px' Loading metatag_favicons/src/Plugin/metatag/Tag/MaskIcon.php +63 −3 Original line number Diff line number Diff line Loading @@ -8,8 +8,8 @@ use Drupal\metatag\Plugin\metatag\Tag\LinkRelBase; * The Favicons "mask-icon" meta tag. * * @MetatagTag( * id = "mask-icon", * label = @Translation("Icon: SVG"), * id = "mask_icon", * label = @Translation("Mask icon (SVG)"), * description = @Translation("A grayscale scalable vector graphic (SVG) file."), * name = "mask-icon", * group = "favicons", Loading @@ -20,5 +20,65 @@ use Drupal\metatag\Plugin\metatag\Tag\LinkRelBase; * ) */ class MaskIcon extends LinkRelBase { // Nothing here yet. Just a placeholder class for a plugin. /** * {@inheritdoc} */ public function form(array $element = []) { $form['#container'] = TRUE; $form['#tree'] = TRUE; // Backwards compatibility. $defaults = $this->value(); if (is_string($defaults)) { $defaults = [ 'href' => $defaults, 'color' => '', ]; } // The main icon value. $form['href'] = [ '#type' => 'textfield', '#title' => $this->label(), '#default_value' => isset($defaults['href']) ? $defaults['href'] : '', '#maxlength' => 255, '#required' => isset($element['#required']) ? $element['#required'] : FALSE, '#description' => $this->description(), '#element_validate' => [[get_class($this), 'validateTag']], ]; // New form element for color. $form['color'] = [ '#type' => 'textfield', '#title' => $this->t('Mask icon color'), '#default_value' => isset($defaults['color']) ? $defaults['color'] : '', '#required' => FALSE, '#description' => $this->t("Color attribute for SVG (mask) icon in hexadecimal format, e.g. '#0000ff'. Setting it will break HTML validation. If not set macOS Safari ignores the Mask Icon entirely, making the Icon: SVG completely useless."), ]; return $form; } /** * {@inheritdoc} */ public function output() { $values = $this->value; // Build the output. $element['#tag'] = 'link'; $element['#attributes'] = [ 'rel' => $this->name(), 'href' => $this->tidy($values['href']), ]; // Add the 'color' element. if (!empty($values['color'])) { $element['#attributes']['color'] = $this->tidy($values['color']); } return $element; } } Loading
CHANGELOG.txt +2 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,8 @@ Metatag 8.x-1.x-dev, xxxx-xx-xx meta tag lengths. #3247678 by esolitos, DamienMcKenna: Support migration with multiple "d7_*" sources. #2914998 by JeroenT, DamienMcKenna, gngn, ytsurk: Add the mask icon "color" attribute. Metatag 8.x-1.16, 2021-03-15 Loading
metatag.install +131 −0 Original line number Diff line number Diff line Loading @@ -74,3 +74,134 @@ function metatag_update_8107() { function metatag_update_8108() { return (string) new TranslatableMarkup("The sites's caches will need to be rebuild to ensure Metatag works as intended."); } /** * Update mask_icon values to the new structure. */ function metatag_update_8109(&$sandbox) { // This whole top section only needs to be done the first time. if (!isset($sandbox['records_processed'])) { $sandbox['records_processed'] = 0; $sandbox['total_records'] = 0; $sandbox['current_field'] = 0; $sandbox['current_record'] = 0; // Counter to enumerate the fields so we can access them in the array // by number rather than name. $field_counter = 0; // Get all of the field storage entities of type metatag. $field_storage_configs = \Drupal::entityTypeManager() ->getStorage('field_storage_config') ->loadByProperties(['type' => 'metatag']); foreach ($field_storage_configs as $field_storage) { $field_name = $field_storage->getName(); // Get the individual fields (field instances) associated with bundles. $fields = \Drupal::entityTypeManager() ->getStorage('field_config') ->loadByProperties(['field_name' => $field_name]); foreach ($fields as $field) { // Get the bundle this field is attached to. $bundle = $field->getTargetBundle(); // Determine the table and "value" field names. $field_table = "node__" . $field_name; $field_value_field = $field_name . "_value"; // Get all records where the field data does not match the default. $query = \Drupal::database()->select($field_table); $query->addField($field_table, 'entity_id'); $query->addField($field_table, 'revision_id'); $query->addField($field_table, 'langcode'); $query->addField($field_table, $field_value_field); $query->condition('bundle', $bundle, '='); $result = $query->execute(); $records = $result->fetchAll(); // Fill in all the sandbox information so we can batch the individual // record comparing and updating. $sandbox['fields'][$field_counter]['field_table'] = $field_table; $sandbox['fields'][$field_counter]['field_value_field'] = $field_value_field; $sandbox['fields'][$field_counter]['records'] = $records; $sandbox['total_records'] += count($sandbox['fields'][$field_counter]['records'] = $records); $field_counter++; } } } if ($sandbox['total_records'] == 0) { // No partially overridden fields so we can skip the whole batch process. $sandbox['#finished'] = 1; } else { // Begin the batch processing of individual field records. $max_per_batch = 10; $counter = 1; $current_field = $sandbox['current_field']; $current_field_records = $sandbox['fields'][$current_field]['records']; $current_record = $sandbox['current_record']; $field_table = $sandbox['fields'][$current_field]['field_table']; $field_value_field = $sandbox['fields'][$current_field]['field_value_field']; // Loop through the field(s) and update the mask_icon values if necessary. while ($counter <= $max_per_batch && $record = $current_field_records[$current_record]) { // Strip any empty tags or ones matching the field's defaults and leave // only the overridden tags in $new_tags. $tags = unserialize($record->$field_value_field); if (isset($tags['mask-icon'])) { $tags['mask_icon'] = [ 'href' => $tags['mask-icon'], ]; $tags_string = serialize($tags); \Drupal::database()->update($field_table) ->fields([ $field_value_field => $tags_string, ]) ->condition('entity_id', $record->entity_id) ->condition('revision_id', $record->revision_id) ->condition('langcode', $record->langcode) ->execute(); } $counter++; $current_record++; } // We ran out of records for the field so start the next batch out with the // next field. if (!isset($current_field_records[$current_record])) { $current_field++; $current_record = 0; } // We have finished all the fields. All done. if (!isset($sandbox['fields'][$current_field])) { $sandbox['records_processed'] += $counter - 1; $sandbox['#finished'] = 1; } // Update the sandbox values to prepare for the next round. else { $sandbox['current_field'] = $current_field; $sandbox['current_record'] = $current_record; $sandbox['records_processed'] += $counter - 1; $sandbox['#finished'] = $sandbox['records_processed'] / $sandbox['total_records']; } } if ($sandbox['total_records'] > 0) { return (string) t('Processed @processed of @total overridden Metatag records.', [ '@processed' => $sandbox['records_processed'], '@total' => $sandbox['total_records'], ]); } else { return (string) t("There were no overridden Metatag records."); } }
metatag.post_update.php 0 → 100644 +28 −0 Original line number Diff line number Diff line <?php /** * @file * Post update functions for Metatag. */ use Drupal\Core\Config\Entity\ConfigEntityUpdater; use Drupal\metatag\Entity\MetatagDefaults; /** * Convert mask-icon to array values. */ function metatag_post_update_convert_mask_icon_to_array_values(&$sandbox) { $config_entity_updater = \Drupal::classResolver(ConfigEntityUpdater::class); $config_entity_updater->update($sandbox, 'metatag_defaults', function (MetatagDefaults $metatag_defaults) { if ($metatag_defaults->hasTag('mask-icon')) { $tags = $metatag_defaults->get('tags'); $tags['mask_icon'] = [ 'href' => $metatag_defaults->getTag('mask-icon'), ]; unset($tags['mask-icon']); $metatag_defaults->set('tags', $tags); return TRUE; } return FALSE; }); }
metatag_favicons/config/schema/metatag_favicons.metatag_tag.schema.yml +9 −2 Original line number Diff line number Diff line Loading @@ -5,9 +5,16 @@ metatag.metatag_tag.shortcut_icon: type: label label: 'Default shortcut icon' metatag.metatag_tag.mask-icon: type: label metatag.metatag_tag.mask_icon: type: mapping label: 'Icon: SVG' mapping: href: type: label label: 'href' color: type: label label: 'Color' metatag.metatag_tag.icon_16x16: type: label label: 'Icon: 16px x 16px' Loading
metatag_favicons/src/Plugin/metatag/Tag/MaskIcon.php +63 −3 Original line number Diff line number Diff line Loading @@ -8,8 +8,8 @@ use Drupal\metatag\Plugin\metatag\Tag\LinkRelBase; * The Favicons "mask-icon" meta tag. * * @MetatagTag( * id = "mask-icon", * label = @Translation("Icon: SVG"), * id = "mask_icon", * label = @Translation("Mask icon (SVG)"), * description = @Translation("A grayscale scalable vector graphic (SVG) file."), * name = "mask-icon", * group = "favicons", Loading @@ -20,5 +20,65 @@ use Drupal\metatag\Plugin\metatag\Tag\LinkRelBase; * ) */ class MaskIcon extends LinkRelBase { // Nothing here yet. Just a placeholder class for a plugin. /** * {@inheritdoc} */ public function form(array $element = []) { $form['#container'] = TRUE; $form['#tree'] = TRUE; // Backwards compatibility. $defaults = $this->value(); if (is_string($defaults)) { $defaults = [ 'href' => $defaults, 'color' => '', ]; } // The main icon value. $form['href'] = [ '#type' => 'textfield', '#title' => $this->label(), '#default_value' => isset($defaults['href']) ? $defaults['href'] : '', '#maxlength' => 255, '#required' => isset($element['#required']) ? $element['#required'] : FALSE, '#description' => $this->description(), '#element_validate' => [[get_class($this), 'validateTag']], ]; // New form element for color. $form['color'] = [ '#type' => 'textfield', '#title' => $this->t('Mask icon color'), '#default_value' => isset($defaults['color']) ? $defaults['color'] : '', '#required' => FALSE, '#description' => $this->t("Color attribute for SVG (mask) icon in hexadecimal format, e.g. '#0000ff'. Setting it will break HTML validation. If not set macOS Safari ignores the Mask Icon entirely, making the Icon: SVG completely useless."), ]; return $form; } /** * {@inheritdoc} */ public function output() { $values = $this->value; // Build the output. $element['#tag'] = 'link'; $element['#attributes'] = [ 'rel' => $this->name(), 'href' => $this->tidy($values['href']), ]; // Add the 'color' element. if (!empty($values['color'])) { $element['#attributes']['color'] = $this->tidy($values['color']); } return $element; } }