You are here

FrxControls.inc in Forena Reports 6.2

contains various methods for extending report formating, layout, transformation and design.

File

plugins/FrxControls.inc
View source
<?php

// $Id$

/**
 * @file contains various methods for extending report
 * formating, layout, transformation and design.
 *
 */
class FrxControls {

  /**
   * @section
   * Below here are advertising methods
   */

  //date formats
  public function formats() {
    $formats = array(
      'drupal_date_format' => 'Drupal Date',
      'iso_date' => 'ISO Date',
      'xhtml' => 'XHTML Decode of data',
      'sprintf' => 'PHP sprintf()',
      'number' => 'Number',
      'drupal_translation' => 'Translatable Text',
    );
    return $formats;
  }

  //document transformations
  public function doc_types() {
    $doc_types = array(
      'doc' => 'htmlDocument',
      'html' => 'htmlDocument',
      'csv' => 'csvDocument',
      'xls' => 'xlsDocument',
      'email' => 'emailDocument',
      'svg' => 'svgDocument',
    );
    return $doc_types;
  }

  // Custom formats based on translation string
  public function drupal_translation($value, $format_str, $teng) {
    $field = '';
    if ($format_str) {
      $field = '{' . $format_str . '}';
    }
    $field = $teng
      ->replace($field, null, TRUE);
    $vars = array();
    if ($field) {
      $vars = (array) @unserialize($field);
    }
    return t($value, $vars);
  }

  //Date format methods
  public function drupal_date_format($value, $format_str, $teng) {
    if (!$format_str) {
      $format_str = 'small';
    }
    switch ($format_str) {
      case 'medium':
        $type = $format_str;
        $format = '';
        break;
      case 'small':
        $type = $format_str;
        $format = '';
        break;
      case 'large':
        $type = $format_str;
        $format = '';
        break;
      default:
        $type = 'custom';
        $format = $format_str;
    }
    if ($value) {
      $value = function_exists('format_date') ? format_date($value, $type, $format) : date($format, $value);
    }
    return $value;
  }
  public function iso_date($value, $format_str, $teng) {
    if ($value) {
      $date = strtotime($value);
    }
    return $this
      ->drupal_date_format($date, $format_str, $teng);
  }
  public function xhtml($value, $format_str, $teng) {
    if ($value) {
      $value = html_entity_decode($value, ENT_QUOTES, 'UTF-8');
    }
    return $value;
  }
  public function sprintf($value, $format_str, $teng) {
    if ($value) {
      $value = sprintf($format_str, $value);
    }
    return $value;
  }
  public function number($value, $format_str, $data = '') {
    $dec = 2;
    $dec_sep = '.';
    $th_sep = ',';
    if ($format_str && !trim($format_str, '9.,$')) {

      //Determine the decimal places.
      $dec_pos = strrpos($format_str, $dec_sep);
      if ($dec_pos) {
        $dec = strlen($format_str) - $dec_pos - 1;
      }
      else {
        $dec = 0;
        $dec_sep = '';
      }
    }
    if ($value && $this
      ->is_number($value)) {
      $value = number_format($value, $dec, $dec_sep, $th_sep);
    }
    return $value;
  }
  private function is_number($value) {
    $non_numeric_chars = trim($value, ' +-.,0123456789');

    // Determine if it contains +- in the interior
    // Zero is ok here bu
    $inner_symbols = FALSE;
    if (strpos($value, '+') || strpos($value, '-') || strpos($value, ' ')) {
      $inner_symbols = TRUE;
    }
    return empty($non_numeric_chars) && trim($value) !== '' && !$inner_symbols ? TRUE : FALSE;
  }

  //Document transformation methods
  public function htmlDocument($body, $options) {
    $output = '<html><head>';
    $output .= '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>';
    if ($options['css']) {
      $output .= '<style type="text/css">';
      $output .= $options['css'];
      $output .= '</style>';
    }
    $output .= '<title>' . $options['title'] . '</title></head><body class="forena-report">' . $body . '</body></html>';
    return $output;
  }

  /**
   * Fill columns with rowspan tags.
   * @param unknown_type $colspan
   */
  private function fillColumns($colspan) {
    $f = '';
    for ($i = 2; $i <= $colspan; $i++) {
      $f .= ',';
    }
    return $f;
  }

  /**
   * Generate the CSV document.
   * @param XML $body
   * @param unknown_type $options
   */
  public function csvDocument($body, $options) {
    $doc = new DOMDocument();
    $doc->strictErrorChecking = FALSE;
    $xmlBody = '<?xml version="1.0" encoding="UTF-8"?>' . $body;
    @$doc
      ->loadHTML($xmlBody);
    $xml = simplexml_import_dom($doc);
    $output = '';
    $rows = $xml
      ->xpath('//tr');
    $rowspans = array();
    if ($rows) {
      foreach ($rows as $row) {
        $c = 0;
        foreach ($row as $column) {
          $c++;
          if (@$rowspans[$c]) {
            $cont = true;
            while ($rowspans[$c] && $cont) {
              $rowspans[$c]--;
              $output .= ',';
              $c++;
            }
          }
          $value = $column
            ->asXML();
          $value = strip_tags($value);
          $value = str_replace('"', '""', $value);
          $value = str_replace(array(
            "\n",
          ), '', $value);
          $value = '"' . $value . '",';
          $output .= $value;

          // Add Column span elements
          if ((int) $column['colspan'] > 1) {
            for ($i = 2; $i <= (int) $column['colspan']; $i++) {
              $c++;
              $output .= ',';
            }
          }

          // Check to see if we have some rowspans that we need to save
          if ((int) $column['rowspan'] > 1) {
            $rowspans[$c] = (int) $column['rowspan'] - 1;
          }
        }
        $output .= "\n";
      }
    }
    return $this
      ->convertCharset($output);
  }
  public function svgDocument($body, $options) {
    $output = '';
    $doc = new DomDocument();
    $xml_body = '<html><body>' . $body . '</body></html>';
    $doc->formatOutput = FALSE;
    $doc->strictErrorChecking = FALSE;
    $doc
      ->loadXML($xml_body);

    //print($xml_body);
    $xml = simplexml_import_dom($doc);
    $xml
      ->registerXPathNamespace('__empty_ns', 'http://www.w3.org/2000/svg');
    if ($xml) {
      $svg = $xml
        ->xpath('//__empty_ns:svg');
    }
    if ($svg) {
      $output = '<?xml version="1.0" encoding="UTF-8" standalone="no" ?>';
      $output .= $svg[0]
        ->asXML();
    }
    return $output;
  }
  public function xlsDocument($body, $options) {
    $output = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
    $output .= '<?mso-application progid="Excel.Sheet"?>' . "\n";
    $output .= '<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"' . "\n";
    $output .= '  xmlns:o="urn:schemas-microsoft-com:office:office"' . "\n";
    $output .= '  xmlns:x="urn:schemas-microsoft-com:office:excel"' . "\n";
    $output .= '  xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"' . "\n";
    $output .= '  xmlns:html="http://www.w3.org/TR/REC-html40">' . "\n";
    $output .= '<Styles>' . "\n";
    $output .= '  <Style ss:ID="Default" ss:Name="Normal">' . "\n";
    $output .= '    <Alignment ss:Vertical="Bottom"/>' . "\n";
    $output .= '    <Borders/>' . "\n";
    $output .= '    <Font/>' . "\n";
    $output .= '    <Interior/>' . "\n";
    $output .= '    <NumberFormat/>' . "\n";
    $output .= '    <Protection/>' . "\n";
    $output .= '  </Style>' . "\n";
    $output .= '</Styles>' . "\n";
    $doc = new DOMDocument();
    $doc->strictErrorChecking = FALSE;
    $doc
      ->loadHTML($body);
    $xml = simplexml_import_dom($doc);
    $tables = $xml
      ->xpath('//table');
    $count = 1;
    if ($tables) {
      foreach ($tables as $table) {
        $output .= '<Worksheet ss:Name="sheet' . ' ' . $count . '">' . "\n";
        $count++;
        $output .= '  <Table>' . "\n";
        $rows = $table
          ->xpath('descendant::tr');
        if ($rows) {
          foreach ($rows as $row) {
            $output .= '    <Row>' . "\n";
            foreach ($row as $column) {
              $value = $column
                ->asXML();
              $value = strip_tags($value);
              $tval = trim($value);

              // Find if it contains invalid number characters
              $non_numeric_chars = trim($value, ' +-.,0123456789');

              // Determine if it contains +- in the interior
              // Zero is ok here bu
              $inner_symbols = FALSE;
              if (strpos($tval, '+') || strpos($tval, '-') || strpos($tval, ' ')) {
                $inner_symbols = TRUE;
              }
              if (substr_count($tval, '.') > 1) {
                $inner_symbols = TRUE;
              }
              if (empty($non_numeric_chars) && trim($value) !== '' && !$inner_symbols) {
                $output .= '      <Cell><Data ss:Type="Number">' . $tval . '</Data></Cell>' . "\n";
              }
              else {
                $output .= '      <Cell><Data ss:Type="String">' . $value . '</Data></Cell>' . "\n";
              }
            }
            $output .= '    </Row>' . "\n";
          }
        }
        $output .= '  </Table>' . "\n";
        $output .= '  <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">' . "\n";
        $output .= '    <Selected/>' . "\n";
        $output .= '    <ProtectObjects>False</ProtectObjects>' . "\n";
        $output .= '    <ProtectScenarios>False</ProtectScenarios>' . "\n";
        $output .= '  </WorksheetOptions>' . "\n";
        $output .= '</Worksheet>' . "\n";
      }
    }
    $output .= '</Workbook>';
    return $this
      ->convertCharset($output);
  }
  public function emailDocument($body, $options) {
    $doc = new DOMDocument('1.0', 'UTF-8');
    $doc->strictErrorChecking = FALSE;
    $doc
      ->loadHTML($body);
    $xml = simplexml_import_dom($doc);
    $docs = $xml
      ->xpath('.//*[@class="email-document"]');
    $prompt_subject = TRUE;
    $prompt_body = TRUE;
    foreach ($docs as $doc) {
      $from = $doc
        ->xpath('.//*[@class="email-header-from"]');
      $from = $from ? (string) $from[0] : '';
      $subject = $doc
        ->xpath('.//*[@class="email-header-subject"]');
      if ($subject) {
        $prompt_subject = FALSE;
      }
      $subject = $subject ? (string) $subject[0] : '';
      $to = $doc
        ->xpath('.//*[@class="email-header-to"]');
      $to = $to ? (string) $to[0] : '';
      $body = $doc
        ->xpath('.//*[@class="email-body"]');
      if ($body) {
        $prompt_body = FALSE;
      }
      $body = $body ? $body[0]
        ->asXML() : $body;
      $email = array(
        'to' => $to,
        'from' => $from,
        'parms' => array(
          'subject' => $subject,
          'body' => $body,
        ),
      );
      $emails[] = $email;
    }
    $count = count($docs);
    if ($count) {
      $output = drupal_get_form('forena_confirm_email', $emails, $count, $prompt_subject, $prompt_body);
    }
    else {
      $output = $body;
    }
    return $output;
  }
  public function convertCharset($data) {
    if (isset($_SERVER['HTTP_ACCEPT_CHARSET'])) {
      $parts = @explode(';', $_SERVER['HTTP_ACCEPT_CHARSET']);
      $parts = @explode(',', $parts[0]);
      $to_encoding = @$parts[0];
      if ($to_encoding) {
        $data = mb_convert_encoding($data, $to_encoding, 'UTF-8');
      }
    }
    return $data;
  }

}

Classes

Namesort descending Description
FrxControls @file contains various methods for extending report formating, layout, transformation and design.