You are here

public function CollapseText::processChildItem in Collapse Text 2.0.x

Same name and namespace in other branches
  1. 8 src/Plugin/Filter/CollapseText.php \Drupal\collapse_text\Plugin\Filter\CollapseText::processChildItem()

Helper function to process a child item.

1 call to CollapseText::processChildItem()
CollapseText::processRecurseTree in src/Plugin/Filter/CollapseText.php
Helper function to take a nested tree and turn it into a string.

File

src/Plugin/Filter/CollapseText.php, line 264

Class

CollapseText
Provides a filter to display Collapsible text blocks.

Namespace

Drupal\collapse_text\Plugin\Filter

Code

public function processChildItem($item, $options) {

  // Translate the "tag" into a proper tag,
  // and then parse it as an xml tag.
  $tag = preg_replace([
    '/^\\[/',
    '/\\]$/',
    '/&/',
  ], [
    '<',
    '/>',
    '&amp;',
  ], $item['tag']);

  // Turn HTML entities into XML entities.
  // Issue #1109792 by eronte.
  $tag = $this
    ->htmlToXmlEntities($tag);
  $xmltag = simplexml_load_string($tag);
  $collapsed = $xmltag['collapsed'] == 'collapsed';
  $class = trim($xmltag['class']);

  // Issue #1096070 by Asgardinho: issues with UTF8 text.
  $title = htmlspecialchars(trim($xmltag['title']), ENT_QUOTES, 'UTF-8');

  // Set up the styles array.
  // We need to include the 'collapsible' and 'collapsed' classes ourself,
  // because this is no longer done by the theme system.
  $classes = [];
  $classes[] = Html::cleanCssIdentifier('collapse-text-details');
  $classes[] = 'collapsible';
  if ($collapsed) {
    $classes[] = 'collapsed';
  }

  // Change the style item into an array.
  foreach (explode(' ', $class) as $c) {
    if (!empty($c)) {
      $classes[] = Html::cleanCssIdentifier($c);
    }
  }

  // If a title is not supplied, look in the first child for a header tag.
  if (empty($title)) {
    if ($item['value'][0]['type'] == 'text') {
      $h_matches = [];
      if (preg_match('/(<h\\d[^>]*>(.+?)<\\/h\\d>)/smi', $item['value'][0]['value'], $h_matches)) {
        $title = strip_tags($h_matches[2]);
      }

      // If we get the title from the first header tag,
      // we should remove it from the text so that it isn't repeated.
      if (!empty($title)) {

        // This is a hack to only replace the first instance.
        $occ = 1;
        $item['value'][0]['value'] = str_replace($h_matches[0], '', $item['value'][0]['value'], $occ);
      }
    }
  }

  // If still no title, put in the default title.
  if (empty($title)) {
    $title = $options['default_title'];
    $classes[] = Html::cleanCssIdentifier('collapse-text-default-title');
  }

  // Create a details element that can be themed.
  $details = [
    '#type' => 'details',
    '#theme' => 'collapse_text_details',
    '#title' => htmlspecialchars_decode($title),
    '#open' => !$collapsed,
    '#attributes' => [
      'class' => $classes,
    ],
    'collapse_text_contents' => $this
      ->processRecurseTree($item['value'], $options),
  ];
  return $details;
}