You are here

public function FrxReport::render_section in Forena Reports 6.2

Same name and namespace in other branches
  1. 6 FrxReport.inc \FrxReport::render_section()
  2. 7 FrxReport.inc \FrxReport::render_section()
  3. 7.2 FrxReport.inc \FrxReport::render_section()
  4. 7.3 FrxReport.inc \FrxReport::render_section()

Recursive report renderer Walks the nodes rendering the report.

1 call to FrxReport::render_section()
FrxReport::render in ./FrxReport.inc
Render the report

File

./FrxReport.inc, line 133
Basic report provider. Controls the rendering of the report.

Class

FrxReport

Code

public function render_section(DOMNode $dom_node) {
  $continue = TRUE;
  $is_data_block = FALSE;
  $node_type = $dom_node->nodeType;
  $o = '';

  // Shortcut process a text node
  if ($node_type == XML_TEXT_NODE || $node_type == XML_ENTITY_REF_NODE || $node_type == XML_ENTITY_NODE) {
    $text = $dom_node->textContent;
    $o .= $this->teng
      ->replace($text);
    return $o;
  }

  //Ignore certain node types
  if ($node_type == XML_COMMENT_NODE) {
    return '';
  }

  // Continue processing non text nodes
  $node = simplexml_import_dom($dom_node);

  // Special catch to make sure we don't process bad nodes
  if (!is_object($node)) {
    return '';
  }
  $frx = $node
    ->attributes(FRX_NS);
  $elements = $dom_node->childNodes->length;

  // Test to see if we have any nodes that contain data url
  if ($node
    ->xpath('*//@frx:*') || $frx) {
    $attrs = $node
      ->attributes();
    $id = (string) $attrs['id'];
    $frx = $node
      ->attributes(FRX_NS);
    $tag = $node
      ->getName();
    if ((string) $frx['block']) {
      $is_data_block = TRUE;
      $xml = $this
        ->get_data((string) $frx['block'], (string) $frx['clause'], $id, (string) $frx['parameters']);
      if ($xml) {
        $this->frx_data
          ->push($xml, $id);
      }
      else {
        return '';
      }
    }

    //Implment if then logic
    if ((string) $frx['if']) {
      $cond = (string) $frx['if'];
      if (!$this->teng
        ->test($cond)) {
        return '';
      }
    }

    // Preserve non frx attributes
    $attr_text = '';
    $tmp_attrs = array();
    if ($attrs) {
      foreach ($attrs as $key => $value) {
        $attr_text .= ' ' . $key . '="' . (string) $value . '"';
        $tmp_attrs[$key] = (string) $value;
      }
    }

    // Determine if we have a custom renderer
    $renderer = (string) $frx['renderer'];

    // if we have a foreach in this node, we need to iterate the children
    if ((string) $frx['foreach']) {

      // Save xml
      $path = $this->teng
        ->replace((string) $frx['foreach'], TRUE);
      $data = $this->frx_data
        ->currentContext();
      if (is_object($data)) {
        if (method_exists($data, 'xpath')) {
          $nodes = $data
            ->xpath($path);
        }
        else {
          $nodes = $data;
        }
      }
      else {
        $nodes = (array) $data;
      }
      if (is_object($data)) {
        $nodes = $data
          ->xpath($path);
      }
      $i = 0;

      //$tmp_attrs = (array)$attrs;
      if ($nodes) {
        foreach ($nodes as $x) {
          $this->frx_data
            ->push($x, $id);
          $i++;
          $odd = $i & 1;
          $row_class = $odd ? 'odd' : 'even';
          $tmp_attrs['class'] = trim($attrs['class'] . ' ' . $row_class);
          $r_attr_text = '';
          unset($tmp_attrs['id']);
          foreach ($tmp_attrs as $key => $value) {
            $r_attr_text .= ' ' . $key . '="' . (string) $value . '"';
          }
          $o .= $this->teng
            ->replace('<' . $tag . $r_attr_text . '>');
          foreach ($dom_node->childNodes as $child) {
            $o .= $this
              ->render_section($child);
          }
          $o .= '</' . $tag . '>';
          $this->frx_data
            ->pop();
        }
      }
    }
    elseif ($continue) {
      if ($renderer) {

        // Implement custom renderer.
        $co = FrxReportGenerator::instance()
          ->define_controls($renderer);
        if ($co) {
          $co
            ->initReportNode($dom_node, $this);
          $o = $co
            ->render();
        }
      }
      else {
        $o .= $this->teng
          ->replace('<' . $tag . $attr_text . '>');

        // None found, so render children
        foreach ($dom_node->childNodes as $child) {
          $o .= $this
            ->render_section($child);
        }
        $o .= '</' . $tag . '>';
      }
    }
    if ($is_data_block && $continue) {
      $this->frx_data
        ->pop();
    }
  }
  else {

    // We can render so lets do it.
    $text = $node
      ->asXML();
    $o .= $this->teng
      ->replace($text);
  }
  return $o;
}