Commit 3f23bfc2 authored by Eugene Bocharov's avatar Eugene Bocharov Committed by Damien McKenna
Browse files

Issue #3258427 by Eugene Bocharov, mrshowerman, saranchuk_hys, phthlaap,...

Issue #3258427 by Eugene Bocharov, mrshowerman, saranchuk_hys, phthlaap, apaderno, Kulturmensch, DamienMcKenna, quicksketch: TypeError: preg_match_all(): Argument #2 ($subject) must be of type string, array given in preg_match_all().
parent 21093e91
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -25,6 +25,9 @@ Metatag 8.x-1.x-dev, 2022-xx-xx
#3266406 by szato, DamienMcKenna: Don't assume the 'first_row_tokens' cache key
  is defined.
#3264449 by DamienMcKenna, gilles_webstanz: Trim og:description doesn't work.
#3258427 by Eugene Bocharov, mrshowerman, saranchuk_hys, phthlaap, apaderno,
  Kulturmensch, DamienMcKenna, quicksketch: TypeError: preg_match_all():
  Arg #2 ($subject) must be of type string, array given in preg_match_all().


Metatag 8.x-1.19, 2022-01-06
+1 −1
Original line number Diff line number Diff line
@@ -227,7 +227,7 @@ function metatag_tokens($type, $tokens, array $data, array $options, BubbleableM
        }
        else {
          if (is_array($processed_tags[$tag_name])) {
            $replacements[$original] = implode(',', $processed_tags[$tag_name]);
            $replacements[$original] = implode(',', array_filter($processed_tags[$tag_name]));
          }
          else {
            $replacements[$original] = $processed_tags[$tag_name];
+51 −37
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ use Symfony\Component\HttpFoundation\RequestStack;
use Drupal\Core\Language\LanguageManagerInterface;

/**
 * Primary logic for the Metatag module..
 * Primary logic for the Metatag module.
 *
 * @package Drupal\metatag
 */
@@ -100,7 +100,7 @@ class MetatagManager implements MetatagManagerInterface {
   * @param \Drupal\metatag\MetatagGroupPluginManager $groupPluginManager
   *   The MetatagGroupPluginManager object.
   * @param \Drupal\metatag\MetatagTagPluginManager $tagPluginManager
   *   The MetatagTagPluginMπanager object.
   *   The MetatagTagPluginManager object.
   * @param \Drupal\metatag\MetatagToken $token
   *   The MetatagToken object.
   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $channelFactory
@@ -141,7 +141,7 @@ class MetatagManager implements MetatagManagerInterface {
   * Returns the list of protected defaults.
   *
   * @return array
   *   Th protected defaults.
   *   The protected defaults.
   */
  public static function protectedDefaults() {
    return [
@@ -588,14 +588,7 @@ class MetatagManager implements MetatagManagerInterface {
        $token_replacements = [$entity->getEntityTypeId() => $entity];
      }
    }

    // Get the current language code.
    $langcode = $this->languageManager
      ->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
      ->getId();

    $rawTags = [];

    $metatag_tags = $this->tagPluginManager->getDefinitions();

    // Order metatags based on the group and weight.
@@ -618,24 +611,8 @@ class MetatagManager implements MetatagManagerInterface {
        // Get an instance of the plugin.
        $tag = $this->tagPluginManager->createInstance($tag_name);

        // Set the value as sometimes the data needs massaging, such as when
        // field defaults are used for the Robots field, which come as an array
        // that needs to be filtered and converted to a string.
        // @see Robots::setValue()
        $tag->setValue($value);

        // Obtain the processed value. Some meta tags will store this as a
        // string, so support that option.
        $value = $tag->value();
        if (is_array($value)) {
          $processed_value = [];
          foreach ($value as $key => $value_item) {
            $processed_value[$key] = htmlspecialchars_decode($this->tokenService->replace($value_item, $token_replacements, ['langcode' => $langcode]));
          }
        }
        else {
          $processed_value = htmlspecialchars_decode($this->tokenService->replace($value, $token_replacements, ['langcode' => $langcode]));
        }
        // Prepare value.
        $processed_value = $this->processTagValue($tag, $value, $token_replacements);

        // Now store the value with processed tokens back into the plugin.
        $tag->setValue($processed_value);
@@ -710,15 +687,8 @@ class MetatagManager implements MetatagManagerInterface {
              $token_replacements = [$entity->getEntityTypeId() => $entity];
            }
          }

          // Set the value as sometimes the data needs massaging, such as when
          // field defaults are used for the Robots field, which come as an
          // array that needs to be filtered and converted to a string.
          // @see Robots::setValue()
          $tag->setValue($value);
          $langcode = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)->getId();
          $value = PlainTextOutput::renderFromHtml(htmlspecialchars_decode($this->tokenService->replace($value, $token_replacements, ['langcode' => $langcode])));
          $this->processedTokenCache[$entity_identifier][$tag_name] = $tag->multiple() ? explode(',', $value) : $value;
          $processed_value = $this->processTagValue($tag, $value, $token_replacements, TRUE);
          $this->processedTokenCache[$entity_identifier][$tag_name] = $tag->multiple() ? explode(',', $processed_value) : $processed_value;
        }
      }
    }
@@ -738,4 +708,48 @@ class MetatagManager implements MetatagManagerInterface {
    return ['metatag'];
  }

  /**
   * Sets tag value and returns sanitized value with token replaced.
   *
   * @param \Drupal\metatag\Plugin\metatag\Tag\MetaNameBase|object $tag
   *   Metatag object.
   * @param array|string $value
   *   Value to process.
   * @param array $token_replacements
   *   Arguments for token->replace().
   * @param bool $plain_text
   *   (optional) If TRUE, value will be formatted as a plain text. Defaults to
   *   FALSE.
   *
   * @return array|string
   *   Processed value.
   */
  protected function processTagValue($tag, $value, array $token_replacements, bool $plain_text = FALSE) {
    // Set the value as sometimes the data needs massaging, such as when
    // field defaults are used for the Robots field, which come as an array
    // that needs to be filtered and converted to a string.
    // @see Robots::setValue()
    $tag->setValue($value);

    // Obtain the processed value. Some meta tags will store this as a
    // string, so support that option.
    $value = $tag->value();

    // Get the current language code.
    $langcode = $this->languageManager
      ->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
      ->getId();

    if (!($is_array = is_array($value))) {
      $value = [$value];
    }
    foreach ($value as $key => $value_item) {
      $value[$key] = htmlspecialchars_decode($this->tokenService->replace($value_item, $token_replacements, ['langcode' => $langcode]));
      if ($plain_text) {
        $value[$key] = PlainTextOutput::renderFromHtml($value[$key]);
      }
    }
    return $is_array ? $value : reset($value);
  }

}
+4 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ class MetatagTokenTest extends BrowserTestBase {
    'token_module_test',
    'metatag',
    'metatag_open_graph',
    'metatag_favicons',
  ];

  /**
@@ -95,6 +96,7 @@ class MetatagTokenTest extends BrowserTestBase {
      'field_metatags[0][basic][abstract]' => 'My abstract',
      'field_metatags[0][open_graph][og_title]' => 'My OG Title',
      'field_metatags[0][open_graph][og_image]' => 'Image 1,Image 2',
      'field_metatags[0][favicons][mask_icon][href]' => 'mask_icon.svg',
    ], 'Save');

    $tokens = [
@@ -110,6 +112,8 @@ class MetatagTokenTest extends BrowserTestBase {
      '[user:field_metatags:og_image]' => 'Image 1,Image 2',
      '[user:field_metatags:og_image:0]' => 'Image 1',
      '[user:field_metatags:og_image:1]' => 'Image 2',
      // Test metatags that store value as an array.
      '[user:field_metatags:mask_icon]' => 'mask_icon.svg',
    ];

    $this->assertPageTokens($user->toUrl(), $tokens, ['user' => $user]);