Commit 37db8b5f authored by metzlerd's avatar metzlerd
Browse files

Working document creation including csv and export to word doc.

parent 1237c560
......@@ -4,7 +4,7 @@
* @file
* Basic report engine. Controls the rendering of the report.
*/
define('FRX_NS','urn:FrxReports');
define('FRX_NS', 'urn:FrxReports');
require_once('FrxSyntaxEngine.inc');
class FrxReport {
......@@ -28,7 +28,7 @@ class FrxReport {
if (!is_object($xhtml)) {
$this->rpt_xml = new SimpleXMLElement($xhtml);
}
else {
else {
$this->rpt_xml = $xhtml;
}
$this->cur_data = $data;
......@@ -78,11 +78,11 @@ class FrxReport {
$this->cur_data = forena_invoke_data_engine($block, $this->cur_data);
}
private function process_frx_attributes(SimpleXMLElement $node) {
private function process_frx_attributes(SimpleXMLElement $node) {
$attrs = $node->attributes(FRX_NS);
if ($attrs) foreach ($attrs as $key => $value) {
switch ($key) {
case "block":
case "block":
$this->get_data((string)$value);
break;
}
......@@ -93,13 +93,12 @@ class FrxReport {
* Recursive report renderer
* Walks the nodes rendering the report.
*/
public function render_section(SimpleXMLElement $node) {
//drupal_set_message('Rendering Section '. $node->getName());
public function render_section(SimpleXMLElement $node) {
$cur_data = $this->cur_data;
$elements = count($node->xpath('*'));
$frx = $node->attributes(FRX_NS);
// Test to see if we have any nodes that are contains data url
if ($node->xpath('*//@frx:*') || $frx) {
// Test to see if we have any nodes that are contains data url
if ($node->xpath('*//@frx:*') || $frx) {
$attrs = $node->attributes();
$tag = $node->getName();
$this->process_frx_attributes($node);
......@@ -151,7 +150,7 @@ class FrxReport {
* Render the report
* @return unknown_type
*/
public function render($format) {
public function render($format) {
$rpt_xml = $this->rpt_xml;
drupal_set_title($this->title);
......@@ -161,6 +160,7 @@ class FrxReport {
foreach ($body_xml->children() as $node) {
$o .= $this->render_section($node);
}
return $o ;
}
/*
......@@ -172,22 +172,20 @@ class FrxReport {
if ($this->fields) {
$path = 'frx:field[@id="'. $key .'"]';
$formatters = $this->fields->xpath($path);
if ($formatters) foreach ($formatters as $formatter) {
if ($formatters) foreach ($formatters as $formatter) {
if (((string)$formatter['block'] == $this->block) || (!(string)$formatter['block'])) {
//@TODO: Replace the default extraction with something that will get sub elements of the string
$default = (string)$formatter;
$link = (string) $formatter['link'];
$format = (string) $formatter['format'];
$format_str = (string) $formatter['format-string'];
}
$format_str = (string) $formatter['format-string'];
}
}
}
if ($format) {
$value = forena_format_data($value,$format,$format_str);
$value = forena_format_data($value, $format, $format_str);
}
......
......@@ -62,7 +62,9 @@ class FrxSyntaxEngine {
}
// Call the formatter object if neccessary
$f = $this->formatter;
if (!$raw && is_object($f) && method_exists($f, 'format')) $retvar = $f->format($retvar, $key, $data);
if (!$raw && is_object($f) && method_exists($f, 'format')) {
$retvar = $f->format($retvar, $key, $data);
}
$retvar = trim($retvar);
return $retvar;
......
......@@ -52,8 +52,8 @@ function forena_save_report($report_name, $report, $save_file = FALSE) {
if (file_exists($filepath)) {
$result = db_query("SELECT report_name FROM {forena_reports} WHERE report_name='%s'", $name);
if ($rpt = db_fetch_object($result)) {
//drupal_set_message('updating '.$name. print_r($rpt,1));
db_query("UPDATE {forena_reports} SET title='%s', category='%s'".
//drupal_set_message('updating '.$name. print_r($rpt,1));
db_query("UPDATE {forena_reports} SET title='%s', category='%s'".
", hidden='%s', cache='%s' WHERE report_name='%s'",
array($data['title'],
$data['category'],
......@@ -159,7 +159,7 @@ function forena_settings() {
}
/**
* Added submit handler to create directories and clear menu cacth
* Added submit handler to create directories and clear menu cache
*
* @param unknown_type $form
* @param unknown_type $form_state
......@@ -212,42 +212,131 @@ function forena_settings_submit($form, &$form_state) {
* @param $form_state
* @return the form
*/
function forena_edit_form($form_state){
$r = forena_get_report(arg(1));
$form = array();
$title = (string)$r->title;
$category = (string)$r->category;
$body = $r->body->asXML();
$form['head'] = array(
'#type' => 'value',
'#value' => $r->rpt_xml->head,
);
$form['title'] = array(
'#type' => 'textfield',
'#title' => t('Title'),
'#default_value' => $title,
);
$form['category'] = array(
'#type' => 'textfield',
'#title' => t('Category'),
'#default_value' => $category,
);
$form['body'] = array(
'#type' => 'textarea',
'#title' => t('Body'),
'#default_value' => $body,
'#rows' => 25,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Save',
);
return $form;
function forena_edit_form($form_state) {
$report_name = arg(1);
list($name, $format) = explode('.', $report_name, 2);
if ($name) {
$report_path = forena_report_path();
$filename = $report_path .'/'. $name .'.frx';
if (file_exists($filename)) {
$r = forena_get_report($name);
$form = array();
$title = (string)$r->title;
$category = (string)$r->category;
$body = $r->body->asXML();
//array for xml attributes that are required to have a value
$required = array('id' => TRUE, 'label' => TRUE);
//list of desired document transformations
$doclist = array('doc', 'pdf', 'html', 'xls');
//passes name of the file in case there is an extension.
$form['file_name'] = array(
'#type' => 'hidden',
'#value' => $name,
);
$form['head'] = array(
'#type' => 'value',
'#value' => $r->rpt_xml->head,
);
$form['title'] = array(
'#type' => 'textfield',
'#title' => t('Title'),
'#default_value' => $title,
);
$form['category'] = array(
'#type' => 'textfield',
'#title' => t('Category'),
'#default_value' => $category,
);
$form['params'] = array('#tree' => TRUE, '#type' => 'fieldset', '#title' => 'Params', '#collapsible' => TRUE, '#collapsed' => TRUE );
$nodes = $r->rpt_xml->head->xpath('frx:parameters/frx:parm');
if ($nodes) foreach ($nodes as $node) {
//make a subtree of params
$form['params'][(string)$node['id']] = array('#tree' => TRUE, '#type' => 'fieldset', '#title' => (string)$node['label'], '#collapsible' => TRUE, '#collapsed' => TRUE );
//now walk the attributes of each node
//and make a subtree for each node
$w_count = 0; // increments the weight, so form elements show in order
foreach ($node->attributes() as $key => $value) {
if (strcmp($key, 'require') == 0) {
$form['params'][(string)$node['id']][(string)$key] = array(
'#type' => 'radios',
'#title' => $key,
'#default_value' => $value,
'#options' => array("1" => t('Yes'), "0" => t('No')),
);
}
else{
$form['params'][(string)$node['id']][(string)$key] = array(
'#type' => 'textfield',
'#title' => $key,
'#default_value' => $value,
'#required' => $required[$key],
'#weight' => ($required[$key]) ? -20 + $w_count : 0,
);
}
$w_count ++;
}
//add the default value
$form['params'][(string)$node['id']]['default'] = array(
'#type' => 'textfield',
'#title' => 'Default Value',
'#default_value' => (string)$node,
'#required' => FALSE,
);
}
//begin checking doc generation options
$nodes = $r->rpt_xml->head->xpath('frx:docgen/frx:doc');
if ($nodes) {
$form['docgen'] = array('#tree' => TRUE, '#type' => 'fieldset', '#title' => 'Document Options', '#collapsible' => TRUE, '#collapsed' => TRUE );
//build the options and default list
$options = array();
$default = array();
foreach ($doclist as $key => $value) {
if (is_object(forena_get_doctypes($value))) {
$options[$value] = strtoupper($value);
$doc = $r->rpt_xml->head->xpath('frx:docgen/frx:doc[@id="' . $value . '"]');
if ($doc) {
$default[$value] = $value;
}
}
}
//display checkboxes
$form['docgen']['docs'] = array(
'#type' => 'checkboxes',
'#description' => (t('*If no options are selected, the system will display all of the above as available for this report.')),
'#options' => $options,
'#default_value' => $default
);
}
$form['body'] = array(
'#type' => 'textarea',
'#title' => t('Body'),
'#default_value' => $body,
'#rows' => 25,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Save',
);
return $form;
}
else {
drupal_not_found();
}
}
else {
drupal_not_found();
}
}
/**
* builds a string of the xml document,
* submits it to forena_save_report.
......@@ -256,25 +345,61 @@ function forena_edit_form_submit($form, &$form_state) {
$values = $form_state['values'];
$h = $values['head'];
$xml = '<html xmlns:frx="urn:FrxReports"><head>';
$xml .= '<title>'. htmlspecialchars($values['title']). '</title>';
$xml .= '<frx:category>'. htmlspecialchars($values['category']). '</frx:category>';
$xml = '<html xmlns:frx="urn:FrxReports">'. "\n";
$xml .= ' <head>'. "\n";
$xml .= ' <title>'. htmlspecialchars($values['title']) .'</title>'. "\n";
$xml .= ' <frx:category>'. htmlspecialchars($values['category']) .'</frx:category>'. "\n";
$nodes = $h->xpath('frx:options');
if ($nodes) $xml.=$nodes[0]->asXML();
if ($nodes) $xml .= ' ' . $nodes[0]->asXML() . "\n";
$xml .= ' <frx:parameters>'. "\n";
$default_value;
foreach ($values['params'] as $key => $value) {
$name = $key;
$xml .= ' <frx:parm ';
foreach ($values['params'][$key] as $n => $v) {
//capture default value, concatenate it outside of tag.
if (! (strcmp($n, 'default') == 0)) {
$xml .= htmlspecialchars($n) . '="' . htmlspecialchars($v) . '" ';
}
else{
$default_value = htmlspecialchars($v);
}
}
$xml .= '>' . $default_value . '</frx:parm>' . "\n";
}
$xml .= ' </frx:parameters>' . "\n";
$nodes = $h->xpath('frx:parameters');
if ($nodes) $xml.=$nodes[0]->asXML();
//check if docgen is avaialable for report
if($values['docgen']){
$xml .= ' <frx:docgen>' . "\n";
//if no options were checked, default to select all of them
if($selected = array_filter($values['docgen']['docs'])) {
foreach ($selected as $key => $value) {
$xml .= ' <frx:doc id="'. $value . '">' . $value . '</frx:doc>' . "\n";
}
}
else {
foreach ($values['docgen']['docs'] as $key => $value) {
$xml .= ' <frx:doc id="'. $key . '">' . $key . '</frx:doc>' . "\n";
}
}
$xml .= ' </frx:docgen>' . "\n";
}
$nodes = $h->xpath('frx:fields');
if ($nodes) $xml.=$nodes[0]->asXML();
if ($nodes) $xml .= $nodes[0]->asXML();
$xml .= '</head>';
$xml .= "\n" . ' </head>' . "\n";
$xml .= $form_state['values']['body'];
$xml .= '</html>';
if (forena_save_report(arg(1), $xml, TRUE) == 1){
drupal_set_message('Your report, "'. $values['title']. '", has been saved');
$form_state['redirect']= 'reports/' . arg(1);
$file = $values['file_name'];
if (forena_save_report($file, $xml, TRUE) == 1) {
drupal_set_message('Your report, "' . $values['title'] . '" has been saved.');
$form_state['redirect']= 'reports/' . arg(1);
}
}
......@@ -86,7 +86,7 @@ function forena_repository($name='') {
function forena_load_cache($r_xhtml) {
$blocks = array();
if (is_object($r_xhtml)) {
if (is_object($r_xhtml)) {
$block_xml = $r_xhtml->xpath('//*[@frx:block]');
// Extract all the blocks and organize by provider
foreach ($block_xml as $key => $block_node) {
......@@ -153,10 +153,10 @@ function forena_get_formatter($fkey) {
$repos = forena_repository();
foreach ($repos as $k => $r) {
$engine = $r['data'];
if ($engine && method_exists($engine,'formats')) {
$engine = $r['data'];
if ($engine && method_exists($engine, 'formats')) {
$f = $engine->formats();
if ($f[$fkey] && method_exists($engine, $fkey)) {
if ($f[$fkey] && method_exists($engine, $fkey)) {
// We found an object with the advertised method return it
return $engine;
}
......@@ -167,9 +167,9 @@ function forena_get_formatter($fkey) {
$controls = forena_define_controls();
foreach ($controls as $k => $r) {
$engine = $r;
if ($engine && method_exists($engine,'formats')) {
if ($engine && method_exists($engine, 'formats')) {
$f = $engine->formats();
if ($f[$fkey] && method_exists($engine, $fkey)) {
if ($f[$fkey] && method_exists($engine, $fkey)) {
// We found an object with the advertised method return it
return $engine;
}
......@@ -185,9 +185,9 @@ function forena_get_formatter($fkey) {
*
*/
function forena_get_report($report_name){
function forena_get_report($report_name) {
if ($report_name) {
$report_path = forena_report_path();
$report_path = forena_report_path();
$filename = $report_path . '/'. $report_name . '.frx';
if (file_exists($filename)) {
$r_text = file_get_contents($filename);
......@@ -199,7 +199,7 @@ function forena_get_report($report_name){
forena_error('Unable to read report', $e->getMessage());
}
}
return $r;
return $r;
}
}
......@@ -209,7 +209,7 @@ function forena_get_report($report_name){
* Returns the string within the html tag name
*
*/
function forena_get_html($tag, $r_text){
function forena_get_html($tag, $r_text) {
$open = strpos($r_text, $tag);
$close = strpos($r_text, '>', $open);
$next = strpos($r_text, '<', $close + 1);
......@@ -220,10 +220,10 @@ function forena_get_html($tag, $r_text){
function forena_format_data($value, $format, $format_str) {
$fo = forena_get_formatter($format);
if ($fo) {
if ($fo) {
$ret = $fo->$format($value, $format_str);
} else {
}
else {
$ret = $value;
}
return $ret;
......@@ -322,7 +322,7 @@ function forena_define_plugins( $class='') {
$plugins = forena_plugins();
foreach ($plugins as $p) {
if (($class=='' || $class==$p['class'])) {
if ($p['file'] && $p['module']) {
if ($p['file'] && $p['module']) {
include_once( drupal_get_path('module' , $p['module']) .'/'. trim($p['file'], '/'));
}
}
......@@ -338,7 +338,7 @@ function forena_controls() {
if (!$controls) {
$controls = array();
foreach (module_list() as $module) {
$function = $module .'_forena_controls';
$function = $module . '_forena_controls';
if (function_exists($function)) {
$returned_controls = $function();
if ($returned_controls) foreach ((array)$returned_controls as $c) {
......@@ -357,56 +357,146 @@ function forena_controls() {
function forena_define_controls( $class='') {
static $instances = '';
if (!$instances) {
$classes = forena_controls();
foreach ($classes as $c) {
if (($class=='' || $class==$c['class'])) {
if ($c['file'] && $c['module']) {
include_once( drupal_get_path('module' , $c['module']) .'/'. trim($c['file'], '/'));
$instances[$c['class']] = new $c['class'];
}
}
}
$classes = forena_controls();
foreach ($classes as $c) {
if (($class=='' || $class==$c['class'])) {
if ($c['file'] && $c['module']) {
include_once( drupal_get_path('module' , $c['module']) .'/'. trim($c['file'], '/'));
$instances[$c['class']] = new $c['class'];
}
}
}
}
if($class && $instances[$class]){
return $instances[$class];
if ($class && $instances[$class]) {
return $instances[$class];
}
return $instances;
return $instances;
}
/**
* Form to edit parameters
*/
function forena_parameters_form($form_state) {
$r = forena_get_report(arg(1));
$head = $r->rpt_xml->head;
$form = array();
$form['params'] = array('#tree' => true);
$nodes = $head->xpath('frx:parameters/frx:parm');
foreach ($nodes as $node) {
(strcmp((string)$node['require'], "1") == 0) ? $bool = TRUE : $bool = FALSE;
$form['params'][(string)$node['id']] = array(
'#type' => 'textfield',
'#title' => t((string)$node['label']),
'#default_value' => $node,
'#required' => $bool,
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
);
return $form;
function forena_parameters_form($form_state) {
$report_name = arg(1);
list($name, $format) = explode('.', $report_name, 2);
if ($name) {
$report_path = forena_report_path();
$filename = $report_path . '/'. $name . '.frx';
if (file_exists($filename)) {
$r = forena_get_report($name);
$head = $r->rpt_xml->head;
$form = array();
$form['params'] = array('#tree' => TRUE);
$nodes = $head->xpath('frx:parameters/frx:parm');
foreach ($nodes as $node) {
(strcmp((string)$node['require'], "1") == 0) ? $bool = TRUE : $bool = FALSE;
$form['params'][(string)$node['id']] = array(
'#type' => 'textfield',
'#title' => t((string)$node['label']),
'#default_value' => $node,
'#required' => $bool,
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit',
);
}
else {
drupal_not_found();
}
}
else {
drupal_not_found();
}
return $form;
}
/**
*
* gets the values from the params form
* redirects to the report page with the values in
* the querystring.
*/
function forena_parameters_form_submit($form, &$form_state) {
$values = $form_state['values'];
foreach ($values['params'] as $key => $value) {
$q .= '&'.$key . '=' . urlencode($value);
$q .= '&'. $key .'='. urlencode($value);
}
$q = trim($q,'&');
$q = trim($q, '&');
$form_state['redirect']= array('reports/' . arg(1), $q);
}
/**
* Gets the correct format function
* to render the document and returns an
* object of that class.
*
* If it fails it returns a 0;
*/
$form_state['redirect']= array('reports/' . arg(1),$q);
function forena_get_doctypes($fkey) {
$controls = forena_define_controls();
foreach ($controls as $k => $r) {
$engine = $r;
if ($engine && method_exists($engine, 'doc_types')) {
$f = $engine->doc_types();
if ($f[$fkey] && method_exists($engine, $f[$fkey])) {
// We found an object with the advertised method return it
return $engine;
}
}
}
return 0;
}
/**
*
* @param unknown_type $format: The extension of the document to be rendered
* @param unknown_type $output: The string of the page to be displayed
* @return: The document in the requested format. Returns a string if not
* able to format.
*/
function forena_generate_doc($format, $output, $options = array()) {
$doc = forena_get_doctypes($format);
if ($doc) {
$all_methods = $doc->doc_types();
$method = $all_methods[$format];
$ret = $doc->$method($output, $options);
}
if ($ret) {
// If that was successful set the appropriate mime type (header doctype).
$flen = strlen($ret);
switch ($format) {
case 'doc':
header('Content-Type: application/msword');
header('Cache-Control:');
header('Pragma:');
header("Cache-Control: must-revalidate");
header("Content-Length: $flen");
break;
case 'pdf':
header('Content-Type: application/pdf');