Newer
Older
// First build menu items.
Frx::Menu()->addMenuItems($items);
$items['admin/structure/forena'] = array(
'type' => MENU_NORMAL_ITEM,
'title' => 'Forena Reports',
'description' => 'Build reports based on data in your sites databases.',
'page callback' => 'forena_admin_reports',
'access arguments' => array('design any report'),
'file' => 'forena.admin.inc',
);
$items['admin/structure/forena/reports'] = array(
'type' => MENU_DEFAULT_LOCAL_TASK,
'title' => 'Reports',
'description' => 'Build reports based on data in your sites databases.',
'page callback' => 'forena_admin_reports',
'access arguments' => array('design any report'),
'file' => 'forena.admin.inc',
);
'page arguments' => array('forena_settings'),
'title' => 'Forena Reports',
'description' => 'Tell Forena where to store report files and how users should access them.',
'access arguments' => array('administer forena reports'),
'type' => MENU_NORMAL_ITEM,
'file' => 'forena.admin.inc',
$items['admin/config/content/forena/general'] = array(
'title' => 'General',
'type' => MENU_DEFAULT_LOCAL_TASK,
'file' => 'forena.admin.inc',
'weight' => -10,
$items['admin/config/content/forena/data/configure'] = array(
'title' => 'Configure data source',
'page callback' => 'drupal_get_form',
'page arguments' => array('forena_data_settings_edit'),
'type' => MENU_CALLBACK,
'file' => 'forena.admin.inc',
'access arguments' => array('administer forena reports'),
);
$items['admin/config/content/forena/data/add'] = array(
'title' => 'Add data source',
'type' => MENU_CALLBACK,
'page callback' => 'drupal_get_form',
'page arguments' => array('forena_data_settings_edit'),
'file' => 'forena.admin.inc',
'access arguments' => array('administer forena reports'),
);
$items['admin/config/content/forena/data'] = array(
'title' => 'Data',
'page callback' => 'forena_data_settings',
'type' => MENU_LOCAL_TASK,
'file' => 'forena.admin.inc',
'access arguments' => array('administer forena reports'),
);
'page callback' => 'drupal_get_form',
'page arguments' => array('forena_doc_formats_settings'),
'title' => 'Document Types',
'access arguments' => array('administer forena reports'),
'type' => MENU_LOCAL_TASK,
'file' => 'forena.admin.inc',
'page arguments' => array(1),
'title' => 'Reports',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
'file' => 'forena.common.inc',
$items['report_doc/%'] = array(
'page callback' => 'forena_report',
'page arguments' => array(1),
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
'file' => 'forena.common.inc',
$items['reports/%/view'] = array(
'title' => 'View',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
'file' => 'forena.common.inc',
'access arguments' => array('design any report'),
'page callback' => 'drupal_get_form',
'page arguments' => array( 'forena_layout_form',1),
'access arguments' => array('design any report'),
'description' => 'Edit the layout of your report',
'type' => MENU_LOCAL_TASK,
'file' => 'forena.admin.inc',
if (module_exists('locale')) {
$items['reports/%/translations'] = array(
'page callback' => 'forena_report_translations',
'page arguments' => array(1),
'title' => 'Translate',
'file' => 'forena.admin.inc',
'access arguments' => array('design any report'),
'type' => MENU_LOCAL_TASK,
$items['reports/%/edit/params'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array('forena_admin_params_form', 1),
'title' => 'Parameters',
'file' => 'forena.admin.inc',
'access arguments' => array('design any report'),
'type' => MENU_LOCAL_TASK,
$items['reports/%/edit/params/add'] = array(
'page callback' => 'drupal_get_form',
'page arguments' => array('forena_add_param_form', 1),
'file' => 'forena.admin.inc',
'title' => 'Parameters',
'access arguments' => array('design any report'),
'type' => MENU_CALLBACK,
'page callback' => 'drupal_get_form',
'page arguments' => array('forena_layout_form',1),
'access arguments' => array('design any report'),
'description' => 'Edit the layout of your report',
'type' => MENU_DEFAULT_LOCAL_TASK,
'file' => 'forena.admin.inc',
'page callback' => 'drupal_get_form',
'page arguments' => array('forena_data_block_form', 1),
'access arguments' => array('design any report'),
'description' => 'Add a data block to your report',
'file' => 'forena.admin.inc',
'title' => 'Data',
'file' => 'forena.admin.inc',
'page callback' => 'drupal_get_form',
'page arguments' => array('forena_add_data_block_form', 1),
'access arguments' => array('design any report'),
'description' => 'Add a data block to your report',
'type' => MENU_CALLBACK,
'page callback' => 'drupal_get_form',
'page arguments' => array('forena_fields_form',1),
'access arguments' => array('design any report'),
'description' => 'Edit the fields of your report',
'file' => 'forena.admin.inc',
'title' => 'Format',
'page callback' => 'drupal_get_form',
'page arguments' => array('forena_format_form', 1),
'access arguments' => array('design any report'),
'file' => 'forena.admin.inc',
'description' => 'Style and document options',
'type' => MENU_LOCAL_TASK,
'title' => 'Delete Report',
'page callback' => 'drupal_get_form',
'page arguments' => array('forena_delete_form', 1),
'access arguments' => array('delete report'),
'type' => MENU_NORMAL_ITEM,
'title' => 'Create Report',
'page callback' => 'drupal_get_form',
'page arguments' => array('forena_add_report_form'),
'access arguments' => array('create any report'),
'description' => 'Create a new report',
'file' => 'forena.admin.inc',
'title' => 'Create Report',
'page callback' => 'drupal_get_form',
'page arguments' => array('forena_add_report_form', 1),
'access arguments' => array('create any report'),
'description' => 'Create a new report from a template',
'file' => 'forena.admin.inc',
'type' => MENU_CALLBACK,
'title' => 'Translate Report',
'page callback' => 'drupal_get_form',
'page arguments' => array('forena_create_trans_form',1),
'access arguments' => array('create any report'),
'description' => 'Create a new report translation',
'file' => 'forena.admin.inc',
'type' => MENU_CALLBACK,
$items['forena'] = array(
'page callback' => 'forena_user_reports',
'page arguments' => array(),
'title' => 'My Reports',
'access arguments' => array('list reports'),
'type' => MENU_NORMAL_ITEM,
'page callback' => 'forena_block_xml',
'page arguments' => array(2),
'access callback' => TRUE,
'file' => 'forena.common.inc',
'type' => MENU_CALLBACK,
'page callback' => 'forena_fields_format_autocomplete',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'page callback' => 'forena_data_block_autocomplete',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'page callback' => 'forena_reports_autocomplete',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'page callback' => 'forena_categories_autocomplete',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
/**
* Implements hook_admin_paths_alter().
*/
function forena_admin_paths_alter(&$paths) {
$paths['reports/*/*'] = TRUE;
$paths['reports/*/view'] = FALSE;
$paths['reports/add'] = TRUE;
}
/**
* Implementation of hook_block_view
*/
function forena_block_view($delta = 0) {
// Inlcude the base library
require_once('forena.common.inc');
switch ($delta) {
case 'forena_reports':
$block = array('subject' => 'My Reports',
*/
function forena_categories_autocomplete($string='') {
require_once('forena.admin.inc');
$categories = @forena_get_categories($string);
/**
* Auto complete for data blocks
* @param $string
* @return unknown_type
*/
function forena_data_block_autocomplete($string='') {
$data_blocks = forena_user_data_blocks($string);
$temp = array_values($data_blocks);
$data_blocks = array_combine($temp, $temp);
function forena_reports_autocomplete($string='', $string2='') {
$reports='';
$link = '';
// If we have two parameters.
if ($string2) {
$string = '%' .$string .'%';
$result = db_query('SELECT * FROM {forena_reports} where language=:language
AND report_name like :string
ORDER BY category,title', array(':language' => $language->language, ':string' => $string));
foreach ($result as $row) {
$access = TRUE;
$cache = $row->cache;
if ($cache) {
$cache = unserialize($cache);
// Check each callback function to see if we have an error.
if ($cache['access']) foreach ($cache['access'] as $callback => $args) {
if ($callback) foreach ($args as $arg) {
$access = FALSE;
if (function_exists($callback)) {
}
if ($a) $access = TRUE;
}
else {
$access = TRUE;
}
}
}
if ($access) {
$key = $row->report_name;
if ($mode == 'link') {
$key = 'reports/' . str_replace('/', '.', $key);
}
$reports[$key] = $key . ' - ' . $row->title;
function forena_xml($block_name, $parms=array()) {
include_once('forena.common.inc');
drupal_alter('forena_parameters', $block_name, $parms );
//now invoke the data provider with the correct params
Frx::Data()->push($parms, 'parm');
return Frx::RepoMan()->data($block_name);
/**
* Auto complete for formats
* @param $string
* @return unknown_type
*/
function forena_fields_format_autocomplete($string='') {
require_once('forena.common.inc');
$matches = array();
$formats = @FrxReportGenerator::instance()->supported_formats();
return;
}
if ($formats && $string) foreach ($formats as $name => $value) {
if (strpos(strtolower($name), strtolower($string)) !== FALSE || strpos(strtolower($value), strtolower($string))!==FALSE) {
$matches[$name] = $value;
}
}
/**
* Calls forena_parameter_form
* in forena.common.inc
*/
require_once('forena.admin.inc');
$m = Frx::Menu();
$name = $m->name;
$filename = $m->filename;
$report = forena_get_report($name);
if ($report) {
$r = forena_report_object();
$o = drupal_get_form('forena_parameters_form');
return $o;
function forena_parameter_form($formid, &$form_state, $parameters, $attributes= array()) {
$menu_parms = Frx::Data()->getContext('menu-parms');
if ($menu_parms) {
$form_state['storage']['menu-parms'] = $menu_parms;
}
if (isset($form_state['values'])) {
$collapse=FALSE;
$parms = array_merge($parms, $form_state['values']['params']);
// In the case of ahah, we need to restore menu parameters from the form state.
if (isset($form_state['storage']['menu-parms'])) {
$menu_parms = $form_state['storage']['menu-parms'];
$parms = array_merge($menu_parms,$parms);
}
$collapse = isset($attributes['collapse']) ? $attributes['collapse'] : FALSE;
$template = @$attributes['template'];
$collapsible = isset($attributes['collapsible']) ? $attributes['collapsible'] : TRUE;
$title = isset($attributes['title']) ? $attributes['title'] : t('Parameters');
$submit_value = isset($attributes['submit']) ? $attributes['submit'] : t('Submit');
$report_name = '';
drupal_alter('forena_parameters', $report_name, $parms);
if ($parameters) {
'#title' => $title,
'#collapsible' => $collapsible,
'#collapsed' => $collapse,
'#prefix' => '<div id="parameters-wrapper">',
'#suffix' => '</div>',
$disabled = FALSE;
$label = @(string)$node['label'];
$id = @(string)$node['id'];
$data_source = @(string)$node['data_source'];
$data_field = @(string)$node['data_field'];
$class = @(string)$node['class'];
$type = @(string)$node['type'];
$option_str = @(string)$node['options'];
$options = array();
if ($option_str) {
parse_str($option_str, $options);
}
if (isset($parms[$id])) {
$value = $parms[$id];
$multi_value=(array)$parms[$id];
}
else {
$value = @(string)$node['default'];
$multi_value = array();
if (strpos($value, '|')!==FALSE) $multi_value = explode('|', $value);
}
$desc = @(string)$node['desc'];
$label_field = @(string)$node['label_field'];
@(strcmp((string)$node['require'], "1") == 0) ? $required = TRUE : $required = FALSE;
$ctl_attrs = array();
//returned values filtered against data_field attr.
if ($data_source) {
$list = Frx::RepoMan()->dataBlockParams($data_source, $data_field, $label_field);
if (!$required && $add_null) $list = array('' => '') + $list;
}
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
//Determine the form element type to be displayed
//If select or radios is chosen then begin a $list array for display values.
$multiselect = FALSE;
$ajax = FALSE;
$add_null = FALSE;
switch ($type) {
case 'multiselect':
$type = 'select';
$multiselect = TRUE;
$value = $multi_value;
break;
case 'multiselectajax':
$type = 'select';
$multiselect = TRUE;
$value = $multi_value;
$ajax = TRUE;
break;
case 'checkboxes':
$value = $multi_value;
break;
case 'selectajax':
$ajax = TRUE;
$type = 'select';
$add_null = TRUE;
break;
case 'select':
$add_null = TRUE;
break;
case 'date_text':
case 'date_select':
case 'date_popup':
$options['date_format'] = @$options['date_format'] ? $options['date_format'] : 'Y-m-d';
$ctl_attrs['#date_format'] = $options['date_format'];
if ($value){
$datetime = @strtotime($value);
if ($datetime) {
$value = date('Y-m-d h:i', $datetime);
$ctl_attrs['#forena_date_format'] = @$options['date_parm_format'] ? $options['date_parm_format'] : 'Y-m-d';
if (@$options['date_year_range']) {
$ctl_attrs['#date_year_range'] = $options['date_year_range'];
}
if (@$options['date_label_position']) {
$ctl_attrs['#date_label_position'] = $options['date_label_position'];
}
break;
case 'checkbox':
if (@$option_str['return_value']) {
$ctl_attrs['#return_value'] = $options['return_value'];
}
if (isset($menu_parms[$id]) && $type=='textfield') {
$disabled = TRUE;
}
//If a data_source attr was found then create an array of
$form['params'][$id] = array(
'#type' => $type,
'#title' => ($label) ? t($label) : t($id),
'#default_value' => $value,
'#disabled' => $disabled,
'#required' => $required,
'#description' => t($desc),
$form['params'][$id] = array_merge($form['params'][$id], $ctl_attrs);
if ($type == 'item') {
$form['params'][$id]['#markup'] = $value;
// Add class to parmeter form.
if ($class) {
$form['params'][$id]['#attributes'] = array(
//if $list is not empty then push options
//onto the array. options will cause an error for
//textfield elements.
if ($list || $type == 'select' || $type =='radios') {
if ($add_null) {
$prompt = @$options['prompt'];
if (!$prompt) $prompt = $required ? '-select-' : '-none-';
$form['params'][$id]['#empty_option'] = $prompt ;
}
$form['params'][$id]['#options'] = $list;
$form['params'][$id]['#multiple'] = $multiselect;
}
if ($ajax) {
$form['params'][$id]['#ajax'] = array('callback' => 'forena_parameters_callback',
}
if ($template) {
$form['params']['#forena-template'] = $template;
$form['params']['#theme'] = 'forena_fieldset_template';
_forena_set_inline_theme($form['params']);
}
'#value' => $submit_value,
}
/**
*
* gets the values from the params form
* redirects to the report page with the values in
* the querystring.
*/
function forena_parameter_form_submit($form, &$form_state) {
$values = $form_state['values'];
unset($values['params']['submit']);
if (isset($values['params'])) foreach ($values['params'] as $key => $value) {
$ctl = $form['params'][$key];
switch($ctl['#type']) {
case 'date_popup':
case 'date_select':
case 'date_text':
$datetime = @strtotime($value);
if ($datetime) {
$value = $values['params'][$key] = date($ctl['#forena_date_format'], $datetime);
}
break;
}
$values['params'][$key] = array();
if ($val) {
$values['params'][$key][] = $val;
}
}
}
else {
if (strpos($value, '|')!==FALSE) {
$values['params'][$key] = explode('|', $value);
}
elseif ($value==='' || $value===NULL) {
unset($values['params'][$key]);
}
}
}
$form_state['redirect']= array($_GET['q'], array('query' => @$values['params']));
}
/**
* Ajax form callback function
* Enter description here ...
* @param unknown_type $form
* @param unknown_type $form_state
*/
function forena_parameters_callback($form, &$form_state) {
return $form['params'];
}
David Metzler
committed
/**
* Implementation of hook_perm
*
* @return unknown
*/
David Metzler
committed
$perms = array(
'administer forena reports' => array('title' => t('Administer Forena Reports')),
'access demo reports' => array('title' => t('Access Demo Reports')),
'list reports' => array('title' => t('List reports')),
'create any report' => array('title' => t('Create a report')),
'design any report' => array('title' => t('Design reports')),
'delete report' => array('title' => t('Delete reports')),
'perform email merge' => array('title' => t('Peform email merge')),
David Metzler
committed
}
function forena_user_reports() {
require_once('forena.common.inc');
$output='';
$reports = forena_get_user_reports();
$report_repos = variable_get('forena_path', 'reports');
if (!$reports) {
$output = 'No Reports Found';
}
$links .= '<li><a href="#' . urlencode($category) . '">' . $category . '</a></li> ';
$output .= '<h3><a name="' . urlencode($category) . '"/>' . $category . '</h3>';
$output .= '<ul>';
foreach ($reports as $r) {
$output .= '<li>' . l($r['title'], $report_repos . '/' . str_replace('/', '.', $r['report_name'])) . '</li>';
function forena_include_data_tables() {
static $init = FALSE;
if (!$init) {
$init = TRUE;
$lib = 'sites/all/libraries/dataTables/media/js/jquery.dataTables.min.js';
if (file_exists($lib)) {
drupal_add_js($lib);
}
$lib = 'sites/all/libraries/FixedColumns/media/js/FixedColumns.min.js';
if (file_exists($lib)) {
drupal_add_js($lib);
}
$lib = 'sites/all/libraries/FixedHeader/js/FixedHeader.min.js';
if (file_exists($lib)) {
drupal_add_js($lib);
}
}
/**
* Load and render a report based on a drupal path.
* In this function the arglist is used to get the full path to the report.
*
* @return unknown
*/
function forena_report($name_in, $parms = array(), $print = TRUE) {
require_once('forena.common.inc');
if (!$desc['exists']) {
FrxData::instance()->setContext('cookie', $_COOKIE);
$report_name = $desc['name'];
// Load dataTable plugin if possible.
$output = FrxReportGenerator::instance()->report($name_in, $parms, $print);
$m_path = drupal_get_path('module', 'forena');
if ($output) {
// This has been deprecated, but we'll eave it in for now.
$forena_js = array();
$forena_js['form'] = preg_replace('/[^\w\-]+/u', '_', Frx::Skin()->name);
$forena_js['report'] = preg_replace('/[^\w\-]+/u', '_', $name_in);
if ($print) drupal_add_js(array('forena' => $forena_js), 'setting');
return $output;
}
* Render report as an inlcude. Don't perform the output fuctnions for the document
* @param $report_name String
* @param $parms array of parameters to include
*/
function forena_report_include($report_name, $parms=array()) {
$output = '';
require_once 'forena.common.inc';
$desc= Frx::Menu()->parseURL($report_name);
$name = $desc['name'];
$r = @FrxReportGenerator::instance()->get_report($name, $parms);
if (!$r || !$r->rpt_xml) {
return '';
}
//check for default parameters
$r->processParameters();
$format = $desc['format'];
$r->render($format);
$o = Frx::Document($format);
if ($o) {
$output = $o->render($r, $format, array());
}
return $output;
* Menu callback for rendering the forena report.
function forena_report_menu_callback() {
$args = func_get_args();
$path = array_shift($args);
$report_name = array_shift($args);
$parms = $_GET;
unset($parms['q']);
$menu_parms = array();
$tokens = Frx::Menu()->tokens($path);
if ($args && $tokens) {
foreach ($args as $i=> $value) {
@$menu_parms[$tokens[$i]] = $value;
}
}
Frx::Data()->setContext('menu-parms', $menu_parms);
$parms = array_merge($parms, $menu_parms);
$output = forena_report($report_name, $parms);
if ($output) return $output;
* Used in hook_menu to test access to menu items.
* @param $checks array key value of callbacks and args to check.
*/
function forena_check_all_access($checks) {
// Check each callback function to see if we have an error.
$access = FALSE;
if ($checks) foreach ((array)$checks as $callback => $args) {
if (function_exists($callback)) {
$a = $callback($arg);
}
if ($a) $access = TRUE;
}
else {
$access = TRUE;
}
/**
* Callback for setting international titles
* @param $report_name string name of report
* @param $use_menu_title boolean indicate wether to use menu title attribute.
*/
function forena_report_title_callback($report_name, $use_menu_title=TRUE) {
GLOBAL $language;
$title = '';
$lang = $language->language;
$result = db_query('SELECT * FROM {forena_reports} where report_name = :name and language=:language',
$cache = $row->cache;
if ($cache) {
$cache = unserialize($cache);
// Load menu item defaults
$menu = $cache['menu'];
}
$title = $use_menu_title && @$menu['title'] ? $menu['title']: $row->title;
}
return $title;
}
* @param string $format
* @param mixed $data
function forena_render_report($report, $format='', $data='', $options= array(), $print = TRUE) {
require_once('forena.common.inc');
$o = forena_report_object($report, $data);
$output = $o->render($format);
//If a format was requested render a custom non-drupal document
if ($format && $format != 'web') {
$output = FrxReportGenerator::instance()->generate_doc($format, $output, $options, $print);
David Metzler
committed
* Self register plugins with forena.
function forena_forena_plugins() {
$plugins[] = array('file' => 'plugins/FrxPDO.inc',
'class' => 'FrxPDO',
$plugins[] = array('file' => 'plugins/FrxOracle.inc',
'class' => 'FrxOracle',
'class' => 'FrxDrupal',
'class' => 'FrxFiles',
$plugins[] = array('file' => 'plugins/FrxPostgres.inc',
'class' => 'FrxPostgres',
$plugins[] = array('file' => 'plugins/FrxMSSQL.inc',
'class' => 'FrxMSSQL',
David Metzler
committed
/**
* Self register document formats with Forena
function forena_forena_document_types() {
require_once 'docformats/FrxWebDoc.inc';
require_once 'docformats/FrxCSVDoc.inc';
require_once 'docformats/FrxHtmlDoc.inc';
require_once 'docformats/FrxSVGDoc.inc';
require_once 'docformats/FrxWordDoc.inc';
require_once 'docformats/FrxXLSDoc.inc';
require_once 'docformats/FrxEmailMergeDoc.inc';
$items['web'] = array(
'class' => 'FrxWebDoc',
'title' => t('Themed Drupal Page'),
);
'class' => 'FrxCSVDoc',
'title' => t('Comma separated values'),
);
'class' => 'FrxEmailMergeDoc',
'title' => t('Email Merge Document'),
);
'class' => 'FrxHtmlDoc',
'title' => t('Unthemed HTML'),
);
'class' => 'FrxSVGDoc',
'title' => t('SVG Document'),
);