public function RendererBase::renderDomNode in Forena Reports 8
Recursive report renderer Walks the nodes rendering the report.
1 call to RendererBase::renderDomNode()
- RendererBase::renderChildren in src/
FrxPlugin/ Renderer/ RendererBase.php
File
- src/
FrxPlugin/ Renderer/ RendererBase.php, line 103 - FrxRenderer.php Base class for FrxAPI custom Renderer @author davidmetzler
Class
- RendererBase
- Crosstab Renderer
Namespace
Drupal\forena\FrxPlugin\RendererCode
public function renderDomNode(DOMNode $dom_node, &$o) {
// Write out buffer if we've gotten too big
$continue = TRUE;
$is_data_block = FALSE;
//$o = '';
$node_type = $dom_node->nodeType;
$settings = $this->settings;
$context = $this
->currentDataContextArray();
// 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'])) {
$this
->write(trim($this->report
->replace(htmlspecialchars($text, ENT_NOQUOTES))));
}
else {
$this
->write($this->report
->replace(htmlspecialchars($text, ENT_NOQUOTES)));
}
return NULL;
}
//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->report
->replace($text));
if ($comment_text === '') {
return '';
}
}
// comment markup is stripped so need to add it back in
$cmt = '<!--' . $this->report
->replace($text) . '-->';
$this
->write($cmt);
return NULL;
}
else {
return NULL;
}
}
// 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 NULL;
}
$frx = $node
->attributes(Report::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->report->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->report
->replace((string) $attr))) {
$has_attributes = TRUE;
}
}
if (!$has_children && !$has_attributes) {
$has_text = trim($this->report
->replace((string) $dom_node->textContent)) !== '';
if (!$has_text) {
return NULL;
}
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;
// Now get the block
$is_data_block = TRUE;
$xml = $this->report
->getData((string) $frx['block'], (string) $frx['parameters']);
if ($xml) {
$this
->pushData($xml, $id);
}
else {
if ($id) {
$this
->setDataContext($id, $xml);
}
return NULL;
}
}
//Implment if then logic
if ((string) $frx['if']) {
$cond = (string) $frx['if'];
if (!$this->report
->test($cond)) {
return NULL;
}
}
// 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 . '"';
}
}
}
// Check for include syntax
$include_file = (string) $frx['include'];
if ($include_file) {
$parms = $this->dmSvc->dataSvc
->currentContextArray();
forena_report_include($include_file, $parms);
return NULL;
}
// 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->report
->replace((string) $frx['foreach'], TRUE);
if ($path && strpos($path, '.')) {
@(list($context, $path) = explode('.', $path, 2));
$data = $this
->getDataContext($context);
}
else {
$data = $this
->currentDataContext();
}
if (is_object($data) || $path != '*') {
if (method_exists($data, 'xpath') || is_array($data)) {
if (is_array($data)) {
$data = DataContext::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->report
->sort($data, $sort, $compare_type);
}
// values
$group = @(string) $frx['group'];
if ($group) {
$opt = $this
->mergedAttributes($node);
$sums = (array) @$opt['sum'];
$nodes = $this->report
->group($nodes, $group, $sums);
}
$i = 0;
//$tmp_attrs = (array)$attrs;
if ($nodes) {
foreach ($nodes as $x) {
if ($group) {
$this
->setDataContext('group', $x[0]);
}
$this
->pushData($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->report
->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) {
$this
->write($this->report
->replace('<' . $tag . $r_attr_text . $ns_attrs . '>', TRUE));
}
foreach ($dom_node->childNodes as $child) {
$this
->renderDomNode($child, $o);
}
if ($include_root) {
$close_tag = '</' . $tag . '>';
$this
->write($close_tag);
}
$this
->popData();
}
}
}
elseif ($continue) {
if ($renderer) {
// Implement custom renderer.
/** @var \Drupal\forena\FrxPlugin\Renderer\RendererInterface $co */
$co = $this->report
->getRenderer($renderer);
if ($co) {
$co
->initReportNode($dom_node);
$output = $co
->render();
$this
->write($output);
}
}
else {
if ($has_children) {
if ($include_root) {
$this
->write($this->report
->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) {
$this
->write('</' . $tag . '>');
}
}
else {
$this
->write($this->report
->replace('<' . $tag . $attr_text . $ns_attrs . '/>', TRUE));
}
}
}
if ($is_data_block && $continue) {
$this
->popData();
}
// Restore link processing.
if (@(string) $frx['invalid_link']) {
$this->report->link_mode = $old_link_mode;
}
return NULL;
}