You are here

public function Freelinking::process in Freelinking 4.0.x

Same name and namespace in other branches
  1. 8.3 src/Plugin/Filter/Freelinking.php \Drupal\freelinking\Plugin\Filter\Freelinking::process()

Performs the filter processing.

Parameters

string $text: The text string to be filtered.

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

Return value

\Drupal\filter\FilterProcessResult The filtered text, wrapped in a FilterProcessResult object, and possibly with associated assets, cacheability metadata and placeholders.

Overrides FilterInterface::process

See also

\Drupal\filter\FilterProcessResult

File

src/Plugin/Filter/Freelinking.php, line 193

Class

Freelinking
Freelinking input filter plugin.

Namespace

Drupal\freelinking\Plugin\Filter

Code

public function process($text, $langcode) {
  $defaultplugin = $this->settings['default'];

  // Ignore the node language if the current user's preferred language is
  // different so that links can be generated in the user's native language.
  $user_langcode = $langcode != $this->currentUser
    ->getPreferredLangcode() ? $this->currentUser
    ->getPreferredLangcode() : $langcode;
  $result = new FilterProcessResult($text);

  // $pattern = '/(\[\[([a-z0-9\_]+):([^\]]+)\]\])/';.
  // @todo why not go back to preg_match_all for double square bracket syntax?
  // @see https://www.drupal.org/node/647940
  $start = 0;
  $remain = $text;
  $newtext = '';

  // Begin an indefinite loop until it is manually broken.
  while (TRUE) {
    $offset = 0;

    // Break when there is no remaining text to process.
    if (empty($remain)) {
      break;
    }

    // Begin freelinking parse or reset.
    if ('[' === $remain[0] && '[' === $remain[1]) {
      $infreelinkp = TRUE;
      $delim = ']]';
    }
    else {
      $infreelinkp = FALSE;
      $delim = '[[';
    }

    // Break out of loop if cannot find anything in remaining text.
    $pos = strpos($remain, $delim);
    if (FALSE === $pos) {
      break;
    }

    // Get the next chunk of text until the position of the delimiter above,
    // and if in freelinking, start processing, otherwise set remaining text
    // to the next chunk from the beginning delimiter.
    $chunk_all = substr($remain, $start, $pos);
    if ($infreelinkp) {
      $chunk_stripped = substr($chunk_all, 2);

      // Find the indicator (plugin) from the first set of characters up until
      // the colon, or use the default plugin.
      $indicatorPosition = strpos($chunk_stripped, ':');
      if (FALSE === $indicatorPosition) {
        $indicator = $defaultplugin;
        $target = $chunk_stripped;
      }
      else {
        $indicator = substr($chunk_stripped, 0, $indicatorPosition);
        $target = substr($chunk_stripped, $indicatorPosition + 1);
      }

      // Load the current plugin from the indicator and available plugins.
      $current_plugin = $this->freelinkingManager
        ->getPluginFromIndicator($indicator, $this
        ->extractAllowedPlugins($this->settings['plugins']), $this->settings);
      if (!$this->settings['global_options']['ignore_upi'] || $current_plugin) {

        // Lazy Builder callback and context must be scalar.
        if (!$current_plugin) {
          $link = $result
            ->createPlaceholder('freelinking.manager:createErrorElement', [
            $indicator,
          ]);
        }
        else {

          // Serialize plugin settings as a string.
          $plugin_settings = self::extractPluginSettings($current_plugin
            ->getPluginId(), $this->settings['plugins']);

          // Failover plugin settings need to be extracted here and passed in
          // to the placeholder as well.
          if ($current_plugin
            ->getFailoverPluginId()) {
            $failover_settings = self::extractPluginSettings($current_plugin
              ->getFailoverPluginId(), $this->settings['plugins']);
          }
          else {
            $failover_settings = [];
          }
          $link = $result
            ->createPlaceholder('freelinking.manager:createFreelinkElement', [
            $current_plugin
              ->getPluginId(),
            $target,
            $indicator,
            $user_langcode,
            serialize($plugin_settings),
            serialize($failover_settings),
          ]);
        }
        if ($link) {
          $chunk_all = $link;
          $offset = 2;
        }
      }
      $remain = substr($remain, $pos + $offset);
    }
    else {
      $remain = substr($remain, $pos);
    }
    $newtext .= $chunk_all;
  }
  $newtext .= $remain;
  $result
    ->setProcessedText($newtext);
  return $result;
}