public function FrxRenderer::renderDomNode in Forena Reports 7.4
Recursive report renderer Walks the nodes rendering the report.
2 calls to FrxRenderer::renderDomNode()
- FrxRenderer::render in renderers/
FrxRenderer.inc - Default Render action, which simply does normal forena rendering. You can use renderDomNode at any time to generate the default forena rendering methods.
- FrxRenderer::renderChildren in renderers/
FrxRenderer.inc
File
- renderers/
FrxRenderer.inc, line 86 - FrxRenderer.inc Base class for Frx custom renderers @author davidmetzler
Class
- FrxRenderer
- @file FrxRenderer.inc Base class for Frx custom renderers @author davidmetzler
Code
public function renderDomNode(DOMNode $dom_node, &$o) {
// Write out buffer if we've gotten too big
if ($this->frxReport->allowDirectWrite && strlen($this->frxReport->html) > 100000) {
$this->frxReport
->writeBuffer();
}
$continue = TRUE;
$is_data_block = FALSE;
//$o = '';
$node_type = $dom_node->nodeType;
$settings = $this->settings;
$context = Frx::Data()
->currentContextArray();
$last_block = $this->blockName;
// 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;
if (!empty($settings['stripWhiteSpace'])) {
$o .= trim($this->teng
->replace(htmlspecialchars($text, ENT_NOQUOTES)));
}
else {
$o .= $this->teng
->replace(htmlspecialchars($text, ENT_NOQUOTES));
}
return;
}
//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;
}
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->frxReport->link_mode = (string) $frx['invalid_link'];
}
// Test to see if we have any nodes that contain data url
$attrs = $node
->attributes();
$id = (string) $attrs['id'];
$tag = $node
->getName();
$has_children = TRUE;
// Preprocessing for detecting blank nodes
if (@$settings['stripEmptyElements']) {
$has_children = count($node
->children()) > 0;
$has_attributes = FALSE;
foreach ($attrs as $attr) {
if (trim($this->teng
->replace((string) $attr))) {
$has_attributes = TRUE;
}
}
if (!$has_children && !$has_attributes) {
$has_text = trim($this->teng
->replace((string) $dom_node->textContent)) !== '';
if (!$has_text) {
return;
}
else {
$has_children = TRUE;
}
}
}
else {
$has_children = count($node
->children()) > 0 || trim($dom_node->textContent) !== '';
}
if ((string) $frx['block']) {
// Determine the context
$this->blockName = (string) $frx['block'];
$this->blockParms = $context;
if ($this->frxReport->preview_mode) {
$o .= Frx::Editor()
->blockLinks($this->blockName, $frx, $attrs, $id, $this->blockParms);
}
// Now get the block
$is_data_block = TRUE;
$xml = $this->frxReport
->getData((string) $frx['block'], $id, (string) $frx['parameters']);
if ($xml) {
Frx::Data()
->push($xml, $id);
}
else {
if ($id) {
Frx::Data()
->setContext($id, $xml);
}
return;
}
}
//Implment if then logic
if ((string) $frx['if']) {
$cond = (string) $frx['if'];
if (!$this->teng
->test($cond)) {
return;
}
}
// Preserve plain attributes
$attr_text = '';
$tmp_attrs = array();
if ($attrs) {
foreach ($attrs as $key => $value) {
$attr_text .= ' ' . $key . '="' . (string) $value . '"';
$tmp_attrs[$key] = (string) $value;
}
}
// Preserve other namespaced attributes
$ns_attrs = '';
foreach ($node
->getNamespaces() as $ns_key => $ns_uri) {
if ($ns_key && $ns_key != 'frx') {
foreach ($node
->attributes($ns_uri) as $key => $value) {
$ns_attrs .= ' ' . $ns_key . ':' . $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']) {
// Get proper XML for current data context.
$path = $this->teng
->replace((string) $frx['foreach'], TRUE);
if ($path && strpos($path, '.')) {
@(list($context, $path) = explode('.', $path, 2));
$data = Frx::Data()
->getContext($context);
}
else {
$data = Frx::Data()
->currentContext();
}
if (is_object($data) || $path != '*') {
if (method_exists($data, 'xpath') || is_array($data)) {
if (is_array($data)) {
$data = FrxData::arrayToXml($data);
}
$nodes = $data
->xpath($path);
}
else {
$nodes = $data;
}
}
else {
$nodes = (array) $data;
}
// Sort values
$sort = @(string) $frx['sort'];
if ($sort) {
$compare_type = @(string) $frx['compare'];
$this->frxReport
->sort($data, $sort, $compare_type);
}
// values
$group = @(string) $frx['group'];
if ($group) {
$opt = $this
->mergedAttributes($node);
$sums = (array) @$opt['sum'];
$nodes = $this->frxReport
->group($nodes, $group, $sums);
}
$i = 0;
//$tmp_attrs = (array)$attrs;
if ($nodes) {
foreach ($nodes as $x) {
if ($group) {
Frx::Data()
->setContext('group', $x[0]);
}
Frx::Data()
->push($x, $id);
$i++;
$odd = $i & 1;
$row_class = $odd ? 'odd' : 'even';
$r_attr_text = '';
if (trim($id)) {
if (strpos($attrs['id'], '{') !== FALSE) {
$id_attr = $this->teng
->replace($attrs['id']);
}
else {
if (!empty($settings['numericFrxForeachID'])) {
$id_attr = $i;
}
else {
$id_attr = $attrs['id'] . '-' . $i;
}
}
$tmp_attrs['id'] = $id_attr;
}
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 . $ns_attrs . '>', TRUE);
}
foreach ($dom_node->childNodes as $child) {
$this
->renderDomNode($child, $o);
}
if ($i == 1 && strtolower($tag) == 'div' && $this->frxReport->preview_mode) {
$o .= Frx::Editor()
->foreachLinks($this->blockName, $attrs['id']);
}
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->frxReport);
if (!empty($settings['stripWhiteSpace'])) {
$o .= trim($co
->render());
}
else {
$o .= $co
->render();
}
}
}
else {
if ($has_children) {
if ($include_root) {
$o .= $this->teng
->replace('<' . $tag . $attr_text . $ns_attrs . '>', TRUE);
}
// None found, so render children
foreach ($dom_node->childNodes as $child) {
$this
->renderDomNode($child, $o);
}
if ($include_root) {
$o .= '</' . $tag . '>';
}
}
else {
$o .= $this->teng
->replace('<' . $tag . $attr_text . $ns_attrs . '/>', TRUE);
}
}
}
if ($is_data_block && $continue) {
Frx::Data()
->pop();
}
// Restore link processing.
if (@(string) $frx['invalid_link']) {
$this->frxReport->link_mode = $old_link_mode;
}
$this->blockName = $last_block;
return;
}