You are here

public function FilterResponsiveTablesFilter::runFilter in Responsive Tables Filter 8

Business logic for adding classes & attributes to <table> tags.

1 call to FilterResponsiveTablesFilter::runFilter()
FilterResponsiveTablesFilter::process in src/Plugin/Filter/FilterResponsiveTablesFilter.php
Performs the filter processing.

File

src/Plugin/Filter/FilterResponsiveTablesFilter.php, line 77

Class

FilterResponsiveTablesFilter
Responsive Tables Filter class. Implements process() method only.

Namespace

Drupal\responsive_tables_filter\Plugin\Filter

Code

public function runFilter($text) {

  // Older versions of libxml always add DOCTYPE, <html>, and <body> tags.
  // See http://www.php.net/manual/en/libxml.constants.php.
  // Sometimes, PHP is >= 5.4, but libxml is old enough that the constants are
  // not defined.
  static $new_libxml;
  if (!isset($new_libxml)) {
    $new_libxml = version_compare(PHP_VERSION, '5.4', '>=') && defined('LIBXML_HTML_NOIMPLIED') && defined('LIBXML_HTML_NODEFDTD');
  }
  if ($text != '') {
    $tables = [];
    libxml_use_internal_errors(TRUE);

    // LibXML requires that the html is wrapped in a root node.
    $text = '<root>' . $text . '</root>';
    $dom = new \DOMDocument();
    if ($new_libxml) {
      $dom
        ->loadHTML(mb_convert_encoding($text, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
    }
    else {
      $dom
        ->loadHTML(mb_convert_encoding($text, 'HTML-ENTITIES', 'UTF-8'));
    }
    $tables = $dom
      ->getElementsByTagName('table');

    // Find all tables in text.
    if ($tables->length !== 0) {
      foreach ($tables as $table) {

        // Find existing class attributes, if any, and append tablesaw class.
        $existing_classes = $table
          ->getAttribute('class');
        if (strpos($existing_classes, 'no-tablesaw') === FALSE) {
          $mode = $this->settings['tablesaw_type'] ?? 'stack';

          // Allow for class-based override of default.
          foreach (array_keys(self::$modes) as $mode_option) {
            if (strpos($existing_classes, "tablesaw-" . $mode_option) !== FALSE) {
              $mode = $mode_option;
              break;
            }
          }
          $new_classes = !empty($existing_classes) ? $existing_classes . ' tablesaw tablesaw-' . $mode : 'tablesaw tablesaw-' . $mode;
          $table
            ->setAttribute('class', $new_classes);

          // Set data-tablesaw-mode & minimap.
          $table
            ->setAttribute('data-tablesaw-mode', $mode);
          $table
            ->setAttribute('data-tablesaw-minimap', NULL);
          $persist = $this->settings['tablesaw_persist'] ?? TRUE;
          $ths = $table
            ->getElementsByTagName('th');
          $inc = 1;
          foreach ($ths as $delta => $th) {

            // Add required columntoggle- & swipe- specific attributes.
            if (in_array($mode, [
              'columntoggle',
              'swipe',
            ])) {
              $th
                ->setAttribute('data-tablesaw-sortable-col', '');
              if (!$th
                ->getAttribute('data-tablesaw-priority')) {
                $th
                  ->setAttribute('data-tablesaw-priority', $inc);
                $inc++;
              }
            }

            // Add persistent first column if no priority has been specified.
            if ($persist && $delta === 0 && !$th
              ->getAttribute('data-tablesaw-priority')) {
              $th
                ->setAttribute('data-tablesaw-priority', 'persist');
            }
          }
        }
      }

      // Get innerHTML of root node.
      $html = "";
      foreach ($dom
        ->getElementsByTagName('root')
        ->item(0)->childNodes as $child) {

        // Re-serialize the HTML.
        $html .= $dom
          ->saveHTML($child);
      }

      // For lower older libxml, use preg_replace to clean up DOCTYPE.
      if (!$new_libxml) {
        $html_start = strpos($html, '<html><body>') + 12;
        $html_length = strpos($html, '</body></html>') - $html_start;
        $html = substr($html, $html_start, $html_length);
      }
      return $html;
    }
  }
  return FALSE;
}