You are here

public function FrxReport::render_section in Forena Reports 7.3

Same name and namespace in other branches
  1. 6.2 FrxReport.inc \FrxReport::render_section()
  2. 6 FrxReport.inc \FrxReport::render_section()
  3. 7 FrxReport.inc \FrxReport::render_section()
  4. 7.2 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 151
Basic report provider. Controls the rendering of the report.

Class

FrxReport

Code

public function render_section(DOMNode $dom_node) {
  $skin = Frx::Data()
    ->getContext('skin');
  $settings = isset($skin['FrxReport']) ? $skin['FrxReport'] : array();
  $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;
  }

  //Handle comment nodes
  if ($node_type == XML_COMMENT_NODE) {
    if (!empty($dom_node->length) && !empty($dom_node->data)) {
      $text = $dom_node->data;

      // strip empty comments if configured to
      if (!empty($settings['stripEmptyComments'])) {
        $comment_text = trim($this->teng
          ->replace($text));
        if ($comment_text === '') {
          return '';
        }
      }

      // comment markup is stripped so need to add it back in
      $o .= '<!--' . $this->teng
        ->replace($text) . '-->';
      return $o;
    }
    else {
      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);
  $include_root = !isset($frx['skip_root']) || !$frx['skip_root'];
  $elements = $dom_node->childNodes->length;

  // Check for invalid link processing.
  if (@(string) $frx['invalid_link']) {
    $old_link_mode = $this->link_mode;
    $this->link_mode = (string) $frx['invalid_link'];
  }

  // 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) {
        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 = Frx::Data()
        ->currentContext();
      if (is_object($data)) {
        if (method_exists($data, 'xpath')) {
          $nodes = $data
            ->xpath($path);
        }
        else {
          $nodes = $data;
        }
      }
      else {
        $nodes = (array) $data;
      }
      $i = 0;

      //$tmp_attrs = (array)$attrs;
      if ($nodes) {
        foreach ($nodes as $x) {
          Frx::Data()
            ->push($x, $id);
          $i++;
          $odd = $i & 1;
          $row_class = $odd ? 'odd' : 'even';
          $r_attr_text = '';
          if (isset($attrs['id'])) {
            if (strpos($attrs['id'], '{') !== FALSE) {
              $id = $this->teng
                ->replace($attrs['id']);
            }
            else {
              if (!empty($settings['numericFrxForeachID'])) {
                $id_attr = $i;
              }
              else {
                $id_attr = $attrs['id'] . '-' . $i;
              }
            }

            // check if we should skip the id for this element
            $frx = $node
              ->attributes(FRX_NS);
            $skip_id = isset($frx['skip_id']) && $frx['skip_id'];
            if (!$skip_id) {
              $tmp_attrs['id'] = $id;
            }
            else {
              unset($tmp_attrs['id']);
            }
          }
          if (@(!$settings['noHelperClasses'])) {
            $tmp_attrs['class'] = trim($attrs['class'] . ' ' . $row_class);
          }
          foreach ($tmp_attrs as $key => $value) {
            $r_attr_text .= ' ' . $key . '="' . (string) $value . '"';
          }
          if ($include_root) {
            $o .= $this->teng
              ->replace('<' . $tag . $r_attr_text . '>');
          }
          foreach ($dom_node->childNodes as $child) {
            $o .= $this
              ->render_section($child);
          }
          if ($include_root) {
            $o .= '</' . $tag . '>';
          }
          Frx::Data()
            ->pop();
        }
      }
    }
    elseif ($continue) {
      if ($renderer) {

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

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

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

    // Strip out empty leaf nodes if report is configured to
    if (!empty($settings['stripEmptyElements'])) {
      $node_updated = new SimpleXMLElement($node_xml);
      if ($this
        ->_check_xml_node_empty($node_updated)) {
        return '';
      }
    }
    $o .= $this->teng
      ->replace($text);
  }

  // Restore link processing.
  if (@(string) $frx['invalid_link']) {
    $this->link_mode = $old_link_mode;
  }
  return $o;
}