Commit e2292f2a authored by David Metzler's avatar David Metzler
Browse files

Mid rework of editor.

parent 553af247
......@@ -170,13 +170,10 @@ class Frx {
/**
* Returns an object of the template class
* that has a method named templates.
* @return FrxTemplate
* @return FrxRenderer
*/
public static function Template($class) {
FrxReportGenerator::instance()->supported_templates();
if (class_exists($class)) {
return new $class();
}
return Frx::Controls($class);
}
/**
......
......@@ -30,13 +30,11 @@ class FrxEditor {
* @param unknown_type $xml_string
*/
public function __construct($report_name) {
$this->dom = new DOMDocument('1.0', 'UTF-8');
$dom = $this->dom;
$this->load($report_name);
$this->frxReport = new FrxReport();
$this->frxReport->setReport($this->dom);
}
/**
......@@ -89,6 +87,7 @@ class FrxEditor {
$r_text = Frx::File()->contents($filename);
}
}
if (!$r_text) {
$m_path = drupal_get_path('module', 'forena');
$r_text = file_get_contents($m_path . '/default.frx');
......@@ -635,4 +634,17 @@ class FrxEditor {
}
public function addTemplate( $class, $conf, $data, $id='') {
if ($id) {
$node = $this->dom->getElementById($id);
}
else {
$nodes = $this->dom->getElementsByTagName('body');
$node = $nodes->item(0);
}
$c = Frx::Template($class);
$c->initReportNode($node, $this->frxReport);
$c->generate($data, $config);
}
}
\ No newline at end of file
......@@ -38,13 +38,13 @@ class FrxReport {
public $link_mode = '';
public function __construct($xhtml, $data=array()) {
public function __construct($xhtml='', $data=array()) {
$this->access = array();
$this->parameters = array();
$this->options = array();
$this->parms = $data;
if ($data) $this->data_passed = TRUE;
$this->teng = new FrxSyntaxEngine(FRX_TOKEN_EXP, '{}', $this);
$this->setParameters($data);
if ($xhtml) {
$dom = $this->dom = new DOMDocument('1.0', 'UTF-8');
// Old assumption is an ojbect is a simplexml one
......@@ -58,70 +58,10 @@ class FrxReport {
return;
}
if (!$success) return;
$this->setReport($dom);
}
$dom->formatOutput = TRUE;
$rpt_xml = $this->rpt_xml = simplexml_import_dom($dom);
// Load header data
$this->body = $rpt_xml->body;
if ($rpt_xml->head) {
$this->title = (string)$rpt_xml->head->title;
$nodes = $rpt_xml->xpath('//frx:docgen/frx:doc');
$this->formats = array();
if ($nodes) foreach ($nodes as $value) {
$arr = $value->attributes();
$this->formats[] = (string)$arr['type'];
}
foreach ($rpt_xml->head->children(FRX_NS) as $name => $node) {
switch ($name) {
case 'fields':
$this->fields = $node;
break;
case 'category':
$this->category = (string)$node;
break;
case 'descriptor':
$this->descriptor = (string)$node;
break;
case 'options':
foreach ($node->attributes() as $key => $value) {
$this->options[$key] = (string)$value;
}
break;
case 'cache':
foreach ($node->attributes() as $key => $value) {
$this->cache[$key] = (string)$value;
}
case 'title':
$this->frx_title = (string)$node;
break;
case 'form':
$this->form = (string) $value;
break;
case 'parameters':
foreach ($node->children(FRX_NS) as $key => $node) {
$parm = array();
foreach ($node->attributes() as $akey => $attr) {
$parm[$akey] = (string)$attr;
}
$id = $parm['id'];
$val = isset($parm['value']) ? $parm['value'] : '';
$parm['value']= ((string)$node) ? (string)$node : $val;
$this->parameters[$id] = $parm;
}
break;
case 'doctypes':
$this->doctypes = $value;
break;
}
}
$this->skin = isset($this->options['skin']) ? $this->options['skin'] : @$this->options['form'];
}
}
}
function __destruct() {
......@@ -130,6 +70,79 @@ class FrxReport {
}
}
public function setParameters($parms) {
$this->data = $parms;
if ($parms) $this->data_passed = TRUE;
}
/**
* Sets the report.
* @param DOMDocument $dom
*/
public function setReport(DOMDocument $dom) {
$this->dom = $dom;
$dom->formatOutput = TRUE;
$rpt_xml = $this->rpt_xml = simplexml_import_dom($dom);
// Load header data
$this->body = $rpt_xml->body;
if ($rpt_xml->head) {
$this->title = (string)$rpt_xml->head->title;
$nodes = $rpt_xml->xpath('//frx:docgen/frx:doc');
$this->formats = array();
if ($nodes) foreach ($nodes as $value) {
$arr = $value->attributes();
$this->formats[] = (string)$arr['type'];
}
foreach ($rpt_xml->head->children(FRX_NS) as $name => $node) {
switch ($name) {
case 'fields':
$this->fields = $node;
break;
case 'category':
$this->category = (string)$node;
break;
case 'descriptor':
$this->descriptor = (string)$node;
break;
case 'options':
foreach ($node->attributes() as $key => $value) {
$this->options[$key] = (string)$value;
}
break;
case 'cache':
foreach ($node->attributes() as $key => $value) {
$this->cache[$key] = (string)$value;
}
case 'title':
$this->frx_title = (string)$node;
break;
case 'form':
$this->form = (string) $value;
break;
case 'parameters':
foreach ($node->children(FRX_NS) as $key => $node) {
$parm = array();
foreach ($node->attributes() as $akey => $attr) {
$parm[$akey] = (string)$attr;
}
$id = $parm['id'];
$val = isset($parm['value']) ? $parm['value'] : '';
$parm['value']= ((string)$node) ? (string)$node : $val;
$this->parameters[$id] = $parm;
}
break;
case 'doctypes':
$this->doctypes = $value;
break;
}
}
$this->skin = isset($this->options['skin']) ? $this->options['skin'] : @$this->options['form'];
}
}
/**
* Get the data block
......
......@@ -175,19 +175,8 @@ class FrxReportGenerator {
*
*/
function supported_templates() {
require_once('templates/FrxTemplate.inc');
require_once('templates/FrxTable.inc');
require_once('templates/FrxFieldTable.inc');
require_once('templates/FrxEmailMerge.inc');
require_once('templates/FrxGraphTemplate.inc');
require_once('templates/FrxRptInclude.inc');
$templates = array(
'FrxTable' => 'Table',
'FrxTemplate' => 'Document',
'FrxEmailMerge' => 'Email Merge',
'FrxFieldTable' => 'Fields',
'FrxGraphTemplate' => 'Graph or Chart',
);
return $templates;
}
......
......@@ -1529,10 +1529,16 @@ function forena_add_data_block_form($formid, &$form_state, $report_name) {
// General report data variables;
drupal_set_title($form_state['storage']['title']);
$form = array();
$template_array = FrxReportGenerator::instance()->supported_templates();
$template_array = array(
'FrxTable' => 'Table',
'FrxTemplate' => 'Document',
'FrxEmailMerge' => 'Email Merge',
'FrxFieldTable' => 'Fields',
'FrxGraphTemplate' => 'Graph or Chart',
);
@$default_template = (isset($form_state['values']['templates'])) ? $form_state['values']['templates'] : $form_state['storage']['template'];
$template = ($default_template) ? $default_template : 'FrxTable';
$template_obj = FrxReportGenerator::instance()->get_templates($template);
$template_obj = Frx::Controls($template);
$params = @$form_state['storage']['parameters'];
$param_values = @$form_state['storage']['parms'];
$form = array();
......
......@@ -2,7 +2,6 @@
class FrxCrossTab extends FrxRenderer {
private $headers = array();
private $columns = array();
private $dim_columns = array();
private $group_columns = array();
private $dim_headers = array();
......
......@@ -3,8 +3,7 @@
* @file FrxEmailMerge
* Email merge template.
*/
require_once('FrxTemplate.inc');
class FrxEmailMerge extends FrxTemplate {
class FrxEmailMerge extends FrxRenderer {
public function configForm($config, $xml='') {
$form_ctl['from'] = array(
......
......@@ -3,7 +3,6 @@
* @file FrxFieldTable
* Template that displays a table of column/value vertically.
*/
require_once('FrxTemplate.inc');
class FrxFieldTable extends FrxTemplate {
public function generate($xml, $config) {
$config['foreach'] = '*';
......
<?php
/**
* @file FrxGraphTemplate.inc
* Graphing Template,
* Generates graphs using phpSVG.
* @author davidmetzler
*
*/
require_once (drupal_get_path('module','forena') . '/renderers/FrxSVGGraph.inc');
class FrxGraphTemplate extends FrxTemplate {
}
\ No newline at end of file
......@@ -73,5 +73,15 @@ class FrxInclude extends FrxRenderer {
return $x->asXML();
}
/**
* Implement template generator.
* @see FrxRenderer::generate()
*/
public function generate($xml, $config) {
$src = $this->extract('src', $key);
$div = $this->blockDiv($config);
$frx = array('src' => $src, 'renderer' => 'FrxInclude');
$this->addNode($div, 4, 'div', NULL, $config, $frx);
}
}
\ No newline at end of file
......@@ -16,8 +16,11 @@ class FrxRenderer {
public $id;
public $format;
public $frxReport; // The report object being used.
public $columns;
public $numeric_columns;
public function initReportNode(DOMNode $domNode, FrxReport $frxReport) {
$this->dom = $frxReport->dom;
$this->reportDocDomNode = $domNode;
$this->dataProvider = Frx::Data();
$this->reportDocNode = $node = simplexml_import_dom($domNode);
......@@ -376,5 +379,232 @@ class FrxRenderer {
return $output;
}
/**
* Returns the section
* Enter description here ...
*/
public function configForm($config, $xml='') {
$form_ctl = array();
$form_ctl['heading'] = array(
'#type' => 'textfield',
'#title' => t('Heading'),
'#default_value' => @$config['heading'],
);
$form_ctl['description'] = array(
'#type' => 'textarea',
'#title' => t('Description'),
'#rows' => 2,
'#default_value' => @$config['description'],
);
$form_ctl['include'] = array(
'#type' => 'textfield',
'#title' => 'Include Report (graph/image)',
'#autocomplete_path' => 'forena/reports/autocomplete',
'#default_value' => @$config['include']
);
return $form_ctl;
}
function addNode($cur_node, $indent=0, $tag='div', $value='', $attributes=array(), $frx_attributes=array()) {
$dom = $this->dom;
if (!$cur_node) {
return;
}
if ($indent!==FALSE) {
$tnode = $dom->createTextNode("\n" . str_repeat(' ', $indent));
$cur_node->appendChild($tnode);
}
$pnode = $dom->createElement($tag, $value);
if ($attributes) foreach ($attributes as $key => $value) {
if ($value) {
$attr = $dom->createAttribute($key);
$attr->value = $value;
$pnode->appendChild($attr);
}
}
if ($frx_attributes) foreach ($frx_attributes as $key => $value) {
if ($value) {
// If the value is an array create multiple attributes
// that are of the form key_1, key_2 .... etc.
if (is_array($value)) {
$i=0;
foreach ($value as $v) {
$i++;
$k = $key . '_' . trim((string)$i);
$attr = $dom->createAttributeNS($this->xmlns, $k);
$attr->value = htmlentities($v);
$pnode->appendChild($attr);
}
}
// A normal value.
else {
$attr = $dom->createAttributeNS($this->xmlns, $key);
$attr->value = htmlentities($value);
$pnode->appendChild($attr);
}
}
}
$cur_node->appendChild($pnode);
return $pnode;
}
public function columns($xml, $path='/*/*') {
//create an array of columns
if (!is_object($xml)) return array();
$rows = $xml->xpath($path);
$column_array = array();
$numeric_columns = array();
foreach ($rows as $columns) {
foreach ($columns as $name => $value) {
$label = str_replace('_', ' ', $name);
$column_array[$name] = $label;
if (is_numeric((string)$value)) {
$numeric_columns[$name] = $label;
}
else {
if (isset($numeric_columns[$name])) unset($numeric_columns[$name]);
}
}
if (is_object($xml) && method_exists($xml, 'attributes')) {
foreach ($xml->attributes() as $name => $value) {
$column_array['@' . $name] = '@' . $name;
}
}
}
$this->columns = $column_array;
$this->numeric_columns = $numeric_columns;
return $column_array;
}
function addText($cur_node, $text) {
$dom = $this->dom;
$tnode = $dom->createTextNode($text);
$cur_node->appendChild($tnode);
return $tnode;
}
/**
*
* Extract a configuration var removing it from the array
* @param string $key attribute key for the data being extracted.
* @param array $config
*/
public function extract($key, &$config) {
$value = '';
if (isset($config[$key])) {
$value = $config[$key];
unset($config[$key]);
}
return $value;
}
/**
*
* Generate generic div tag.
* @param unknown_type $config
* @param unknown_type $text
*/
public function blockDiv(&$config, $text='') {
$body = $this->reportDocDomNode;
$heading = $this->extract('heading', $config);
$descr = $this->extract('description', $config);
$include = $this->extract('include', $config);
$block = $this->extract('block', $config);
$foreach = $this->extract('foreach', $config);
$id = $this->extract('id', $config);
if (!$id) {
$id = $this->idFromBlock($block);
}
$class = $this->extract('class', $config);
$frx_attributes = array(
'block' => $block,
'foreach' => $foreach,
);
$attributes = array(
'id' => $id,
'class' => $class,
);
$node = $this->addNode($body, 2, 'div', $text, $attributes, $frx_attributes);
if ($heading) {
$this->addNode($node, 4, 'h2', $heading);
}
if ($descr) {
$this->addNode($node, 4, 'p', $descr);
}
if ($include) {
$src = 'reports/' . str_replace('/', '.', $include);
$this->addNode($node, 4, 'div', NULL, NULL, array('renderer' => 'FrxInclude', 'src' => $src));
}
return $node;
}
/**
*
* Enter description here ...
* @param string $data_block
* @param SimpleXMLElement $xml
* @param array $config
*/
public function generate($xml , $config) {
if (!@$config['foreach']) $config['foreach']='*';
$columns = $this->columns($xml);
$text = '';
if ($columns) foreach ($columns as $col => $label) {
$text .= ' {' . $col . '}';
}
$this->blockDiv($config, $text);
}
public function template() {
$body = $this->body;
$output = '';
foreach ($body->childNodes as $node) {
$output .= $this->dom->saveXML($node);
}
return $output;
}
public function asXML() {
return $this->dom->saveXML();
}
/**
* Simple function to get id from node.
* @param unknown $block
* @return mixed
*/
public function idFromBlock($block) {
$parts = explode('/', $block);
$id = str_replace('.', '_', array_pop($parts));
return $id;
}
public function verifyElement(DOMNode $node, $tag, $indent) {
$e = '';
foreach ($domNode->childNodes as $child) {
if (is_object($child) && $child->getName()==$tag) {
$e = $child;
break;
}
}
if (!$e) {
$e = $this->addNode($node, $indent, $tag );
}
return $e;
}
}
\ No newline at end of file
......@@ -112,5 +112,147 @@ class FrxSVGGraph extends FrxChart {
return $output;
}
public function configForm($config, $xml='') {
$form_ctl = array();
$graph_types = array(
'bargraph' => 'Bar Graph',
'linegraph' => 'Line Graph',
'multilinegraph' => 'Line Graph (Multi Series)',
'piechart' => 'Pie Chart',
'radargraph' => 'Radar Graph',
'multiradargraph' => 'Radar Graph (Multi Series)',
'scatterplot' => 'Scatter Plot',
);
$type = isset($config['type']) ? $config['type'] : 'Bar Graph';
$style = isset($config['style']) ? $config['style'] : 'BarGraph';
$graph_options = FrxSVGGraph::graphOptions();
$graph_types = FrxSVGGraph::graphTypes();
$styles = $graph_options['styles'][$type];
$xvalues = @$graph_types[$type]['xaxis'];
$num_series = isset($graph_types[$style]['series']) ? $graph_types[$style]['series'] : 1;
$types = $graph_options['types'];
$form_ctl['type'] = array(
'#type' => 'select',
'#title' => t('Graph Type'),
'#options' => $graph_options['types'],
'#default_value' => $type,
);
forena_template_ajax($form_ctl['type']);
$form_ctl['style'] = array(
'#type' => 'select',
'#title' => t('Style'),
'#options' => $styles,
'#default_value' => $style,
);
forena_template_ajax($form_ctl['style']);