You are here

public function ShortcodeService::process in Shortcode 2.0.x

Same name and namespace in other branches
  1. 8 src/ShortcodeService.php \Drupal\shortcode\ShortcodeService::process()

Processes the Shortcodes according to the text and the text format.

Parameters

string $text: The string containing shortcodes to be processed.

string $langcode: The language code of the text to be filtered.

\Drupal\filter\Plugin\FilterInterface $filter: The text filter.

Return value

string The processed string.

File

src/ShortcodeService.php, line 224

Class

ShortcodeService
Provide the ShortCode service.

Namespace

Drupal\shortcode

Code

public function process($text, $langcode = Language::LANGCODE_NOT_SPECIFIED, FilterInterface $filter = NULL) {
  $shortcodes = $this
    ->getShortcodePlugins($filter);

  // Processing recursively, now embedding tags within other tags is
  // supported!
  $chunks = preg_split('!(\\[{1,2}.*?\\]{1,2})!', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
  $heap = [];
  $heap_index = [];
  foreach ($chunks as $c) {
    if (!$c) {
      continue;
    }
    $escaped = FALSE;
    if (substr($c, 0, 2) == '[[' && substr($c, -2, 2) == ']]') {
      $escaped = TRUE;

      // Checks media tags, eg: [[{ }]].
      if (substr($c, 0, 3) != '{' && substr($c, -3, 1) != '}') {

        // Removes the outer [].
        $c = substr($c, 1, -1);
      }
    }

    // Decide this is a Shortcode tag or not.
    if (!$escaped && $c[0] == '[' && substr($c, -1, 1) == ']') {

      // The $c maybe contains Shortcode macro.
      // This is maybe a self-closing tag.
      // Removes outer [].
      $original_text = $c;
      $c = substr($c, 1, -1);
      $c = trim($c);
      $ts = explode(' ', $c);
      $tag = array_shift($ts);
      $tag = trim($tag, '/');
      if (!$this
        ->isValidShortcodeTag($tag)) {

        // This is not a valid shortcode tag, or the tag is not enabled.
        array_unshift($heap_index, '_string_');
        array_unshift($heap, $original_text);
      }
      elseif (substr($c, -1, 1) == '/') {

        // Processes a self closing tag, - it has "/" at the end.

        /*
         * The exploded array elements meaning:
         * 0 - the full tag text?
         * 1/5 - An extra [] to allow for escaping Shortcodes with double
         * [[]].
         * 2 - The Shortcode name.
         * 3 - The Shortcode argument list.
         * 4 - The content of a Shortcode when it wraps some content.
         */
        $m = [
          $c,
          '',
          $tag,
          implode(' ', $ts),
          NULL,
          '',
        ];
        array_unshift($heap_index, '_string_');
        array_unshift($heap, $this
          ->processTag($m, $shortcodes));
      }
      elseif ($c[0] == '/') {
        $closing_tag = substr($c, 1);
        $process_heap = [];
        $process_heap_index = [];
        $found = FALSE;

        // Get elements from heap and process.
        do {
          $tag = array_shift($heap_index);
          $heap_text = array_shift($heap);
          if ($closing_tag == $tag) {

            // Process the whole tag.
            $m = [
              $tag . ' ' . $heap_text,
              '',
              $tag,
              $heap_text,
              implode('', $process_heap),
              '',
            ];
            $str = $this
              ->processTag($m, $shortcodes);
            array_unshift($heap_index, '_string_');
            array_unshift($heap, $str);
            $found = TRUE;
          }
          else {
            array_unshift($process_heap, $heap_text);
            array_unshift($process_heap_index, $tag);
          }
        } while (!$found && $heap);
        if (!$found) {
          foreach ($process_heap as $val) {
            array_unshift($heap, $val);
          }
          foreach ($process_heap_index as $val) {
            array_unshift($heap_index, $val);
          }
        }
      }
      else {
        array_unshift($heap_index, $tag);
        array_unshift($heap, implode(' ', $ts));
      }
    }
    else {

      // Maybe not found a pair?
      array_unshift($heap_index, '_string_');
      array_unshift($heap, $c);
    }

    // End of foreach.
  }
  return implode('', array_reverse($heap));
}