You are here

forena.common.inc in Forena Reports 7

Common functions used throughout the project but loaded in this file to keep the module file lean.

File

forena.common.inc
View source
<?php

// $Id$

/**
 * @file
 * Common functions used throughout the project but loaded in this
 * file to keep the module file lean.
 */

// Include Report renderer.
require_once 'FrxReport.inc';
require_once 'FrxDataProvider.inc';

/**
 * Get name from argument 1 or alterntaively from a file name
 *
 * @param unknown_type $name
 */
function forena_report_desc($name = '') {
  if (!$name) {
    $name = arg(1);
  }

  // Get defined document types
  $doctypes = forena_supported_doctypes();
  $parts = explode('.', $name);
  $name = '';
  if ($parts) {
    foreach ($parts as $part) {
      if (!isset($doctypes[$part])) {
        $name .= '/' . $part;
      }
      else {
        $desc['format'] = $part;
      }
    }
  }
  $desc['name'] = trim($name, '/');
  $report_path = variable_get('forena_report_repos', 'reports');
  @(list($dir, $name_part) = explode('/', $name_part, -2));
  if (!$name_part) {
    $dir = '';
  }
  $desc['directory'] = $report_path . '/' . $dir;
  $desc['filename'] = $report_path . '/' . trim($name, ' /') . '.frx';
  $desc['link'] = 'reports/' . trim(str_replace('/', '.', $name), '.');
  if (file_exists($desc['filename'])) {
    $desc['exists'] = TRUE;
  }
  return $desc;
}

/**
 * Determines which css files need to be loaded.
 *
 * @param array $desc Report descriptor from forena_rport_desc
 * @param string $form The report "form" to be used.  From the report
 * @param string $format Document format that will be used for the report.
 * @return array A list of css files that should be applied to the report.
 */
function forena_report_css($desc, $form, $format = '') {
  $css_files = array();

  // First check for the form file
  $path = forena_report_path();
  if (file_exists($path . '/' . $form . '.css')) {
    $css_files[] = $path . '/' . $form . '.css';
  }
  if ($format && file_exists($path . '/' . $form . '-' . $format . '.css')) {
    $css_files[] = $path . '/' . $form . '-' . $format . '.css';
  }

  // Now check for a report specific file
  $base_file = $path . '/' . $desc['name'];
  if ($format && file_exists($base_file . '-' . $format . '.css')) {
    $css_files[] = $base_file . '-' . $format . '.css';
  }
  elseif (file_exists($base_file . '.css')) {
    $css_files[] = $base_file . '.css';
  }
  return $css_files;
}

/**
 * Check access control using the block in a data block.  In this case
 * public assess returns true.
 * @param $block  Repository block used to test access
 * @param $path   xpath to user right within xml data.
 * @param $access Access to test
 * @return unknown_type
 */
function forena_block_access($block, $path, $access, $cache = TRUE) {
  if ($access == 'PUBLIC') {
    return TRUE;
  }
  if (!isset($_SESSION['forena_access'])) {
    $_SESSION['forena_access'] = array();
  }
  if ($cache && isset($_SESSION['forena_access'][$block])) {
    $rights = $_SESSION['forena_access'][$block];
  }
  else {
    $rights = array();

    // Get the block from the repository
    $data = forena_invoke_data_provider($block, array(), NULL);
    if ($data) {
      if (!$path) {
        $path = '*/*';
      }
      $nodes = $data
        ->xpath($path);
      if ($nodes) {
        foreach ($nodes as $node) {
          $rights[] = (string) $node;
        }
      }
      $_SESSION['forena_access'][$block] = $rights;
    }
  }
  foreach ($rights as $right) {
    if ($access == $right) {
      return TRUE;
    }
  }
  return FALSE;
}

// Putting this in a function to sandbox the repository settings
function __forena_load_repository(&$repo) {

  // First determine if the class file exisits
  $path = $repo['path'];
  $conf = array();
  if (file_exists($path . '/settings.php')) {

    // Override with repository specific data
    include $path . '/settings.php';
  }
  $repo = array_merge($conf, $repo);

  // $repo['user callback'] = $conf['user callback'];
  if (!isset($repos['data']) || !is_object($repo['data'])) {
    $repo['data'] = __forena_load_provider($repo, $repo['path']);
  }

  //$repo['auth'] = __forena_load_auth($security_provider);
}

/**
 * Load the data provider class based on the class name.
 *
 * @param string $name
 * @return object The data provider object
 */
function __forena_load_provider($conf, $repo_path) {
  @($name = isset($conf['data provider']) ? $conf['data provider'] : $conf['data_engine']);
  forena_define_plugins();

  // Instantiate the path

  //drupal_set_message("conf: <pre>". print_r($conf, 1) ."</pre>  repo_path: <pre>". print_r($repo_path,1) ."</pre>");
  if (class_exists($name)) {
    $o = new $name($conf, $repo_path);
    return $o;
  }
  else {
    drupal_set_message(t('Data provider %s not found', array(
      '%s' => $name,
    )), 'error');
  }
}

/*
 * Get the repository data for an a repository name.
 * If no repository is specified the descriptors for all repositories are returned.
 */
function forena_repository($name = '') {
  global $_forena_repositories;
  static $repos = '';

  // Empty repository so we need to initialize
  if (!$repos) {

    // Build the default sample one
    $path = drupal_get_path('module', 'forena');
    $repos = array();

    // Load the repository list from the global settings.php file.
    if ($_forena_repositories) {
      $repos = $_forena_repositories;
    }

    // Overide difinitions of the sample and drupal repositories.
    $repos['forena_help'] = array(
      'path' => $path . '/repos/forena_help',
      'title' => 'Forena Sample Reports',
    );
    $repos['drupal'] = array(
      'path' => $path . '/repos/drupal',
      'title' => 'Drupal Reports',
    );
    $repos['sampledb'] = array(
      'path' => $path . '/repos/sample',
      'title' => 'Sample DB Repository',
    );
  }

  // Now determine if the object exists
  if ($name) {
    if (isset($repos[$name])) {
      if (!isset($repos[$name]['data']) || !is_object($repos[$name]['data']) || !isset($repos[$name]['auth']) || !is_object($repos[$name]['auth'])) {
        __forena_load_repository($repos[$name]);
      }
      return $repos[$name];
    }
    else {
      forena_error('Undefined repository' . $name, "Undefined Repository: {$name} <pre>" . print_r($repos, 1) . '</pre>');
    }
  }
  else {
    return $repos;
  }
}

/**
 * Biuld cache
 *
 * @param xhtml $r_xhtml Forena XML report.
 * @return array data to be stored in the cache field for the report in the database.
 */
function forena_load_cache($r_xhtml) {
  $conf = array();
  $cache = array();
  $blocks = array();
  $repos = array();
  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) {
      $attrs = $block_node
        ->attributes('urn:FrxReports');
      foreach ($attrs as $key => $value) {
        if ($key == 'block') {
          list($provider, $block) = explode('/', $value, 2);
          $repos[$provider][] = $block;
        }
      }
    }
    if ($repos) {
      foreach ($repos as $provider => $blocks) {
        $repos = forena_repository($provider);
        $provider = $repos['data'];
        if (isset($provider->conf)) {
          $conf = $provider->conf;
        }
        $access = array();
        foreach ($blocks as $block_name) {
          if ($provider && $block_name) {
            if (method_exists($provider, 'load_block')) {
              $conf = $provider->conf;
              $block = $provider
                ->load_block($block_name);
              if (isset($block['access']) && array_search($block['access'], $access) === FALSE) {
                $access[] = $block['access'];
              }
            }
          }
          else {

            //drupal_set_message('no provider found', 'error');
          }
        }
        if (isset($conf['access callback']) && $access) {
          $cache['access'][$conf['access callback']] = $access;
        }
      }
    }
  }
  return $cache;
}

/**
 * Extract the data by running a block
 *
 * @param unknown_type $data_block
 * @param unknown_type $parameters
 * @param string $clause order / where cause
 * @return unknown
 */
function forena_invoke_data_provider($data_block, $parameters = array(), $clause = '') {
  list($provider, $block) = explode('/', $data_block, 2);

  // Get the data
  $repos = forena_repository($provider);
  if (isset($repos['user callback'])) {
    $user_fn = $repos['user callback'];
    if (is_callable($user_fn)) {
      $parameters['current_user'] = $user_fn();
    }
  }
  if ($repos['data']) {
    $provider = $repos['data'];
    $access = TRUE;
    if (method_exists($provider, 'data')) {
      $xml = $provider
        ->data($block, $parameters, $clause);
    }
    return $xml;
  }
}

/**
 * Load information about a data block
 *
 * @param string $data_block provider/blockpath to use for the load.
 * @return unknown
 */

/**
 * Returns an array of information about the data block
 * @param $data_block
 * @return unknown_type
 */
function forena_load_block($data_block, $clause = '') {
  @(list($provider, $block) = explode('/', $data_block, 2));

  // Get the data
  $repos = forena_repository($provider);
  if (isset($repos['data'])) {
    $provider = $repos['data'];
    if (method_exists($provider, 'load_block')) {
      $block_info = $provider
        ->load_block($block, $clause);
    }
    return $block_info;
  }
}

/**
 * Load the formatters for all initialized repositories.
 *
 */
function forena_get_formatter($fkey) {

  // Get all repositories
  $repos = forena_repository();
  $formats = array();
  foreach ($repos as $k => $r) {
    $provider = isset($r['data']) ? $r['data'] : NULL;
    if ($provider && method_exists($provider, 'formats')) {
      $f = $provider
        ->formats();
      if (isset($f[$fkey]) && method_exists($provider, $fkey)) {

        // We found an object with the advertised method return it
        return $provider;
      }
    }
  }

  //Did not find the formater in the data provider

  //Look to see if it's in a control class
  $controls = forena_define_controls();
  foreach ($controls as $k => $r) {
    $provider = $r;
    if ($provider && method_exists($provider, 'formats')) {
      $f = $provider
        ->formats();
      if (isset($f[$fkey]) && method_exists($provider, $fkey)) {

        // We found an object with the advertised method return it
        return $provider;
      }
    }
  }
  return $formats;
}

/**
 * Accepts the name of a file
 *
 * Returns a xml object of the file.
 *
*/
function forena_get_report($report_name, $data = array()) {
  $r = null;
  if ($report_name) {
    $report_path = forena_report_path();
    $filename = $report_path . '/' . $report_name . '.frx';
    if (file_exists($filename)) {
      $r_text = file_get_contents($filename);
      $modified = filemtime($filename);
      $result = db_query("SELECT report_name, modified FROM {forena_reports} WHERE report_name=:report_name", array(
        ':report_name' => $report_name,
      ));
      $save = FALSE;

      // If the file modification time has changed then save.
      if ($rpt = $result
        ->fetchObject()) {
        if ($rpt->modified != $modified) {
          $save = TRUE;
        }
      }
      else {
        $save = TRUE;
      }
      try {
        $r = forena_report_object($r_text, $data);
      } catch (Exception $e) {
        forena_error('Unable to read report', $e
          ->getMessage());
      }
      if ($save) {
        require_once 'forena.admin.inc';
        forena_save_report($report_name, $r_text, FALSE);
      }
    }
    return $r;
  }
}

/**
 * Object factory for forena report
 * When called without a report name, it returns the last created report.
 * This static caching mechanism is used for form functions that are called
 * within a page load.
 *
 * @param unknown_type $report_name
 */
function forena_report_object($report = '', $data = '') {
  static $object = '';
  if ($report) {
    $object = new FrxReport($report, $data);
  }
  return $object;
}

/**
 * Enter description here...
 *
 * @param simplexml $xml
 * @param string $tag
 * @return string
 */
function forena_inner_xml($xml, $tag) {
  if (is_object($xml) && is_object($xml->{$tag})) {
    $xml_data = $xml->{$tag}
      ->asXML();
    $xml_data = preg_replace("/<\\/?" . $tag . "(.|\\s)*?>/", "", $xml_data);
  }
  return $xml_data;
}

/**
 * Accepts the name of the html tag, and the string the tag is in.
 *
 * Returns the string within the html tag name
 *
*/
function forena_get_html($tag, $r_text) {
  $open = strpos($r_text, $tag);
  $close = strpos($r_text, '>', $open);
  $next = strpos($r_text, '<', $close + 1);
  $str = substr($r_text, $close + 1, $next - ($close + 1));
  return $str;
}
function forena_format_data($value, $format, $format_str) {
  $fo = forena_get_formatter($format);
  if ($fo) {
    $ret = $fo
      ->{$format}($value, $format_str);
  }
  else {
    $ret = $value;
  }
  return $ret;
}

/**
 * Load a block file form disk and introspect the comments to determine security
 * Return a structured array based on this.
 *
 * @param unknown_type $filepath
 * @param unknown_type $comment
 */
function forena_load_block_file($filepath, $comment = '--', $trim) {
  if (!file_exists($filepath)) {
    return array();
  }
  $block_data = file_get_contents($filepath);
  $lines = explode("\n", $block_data);
  $cnt = count($lines);
  $access = '';
  $i = 0;
  $block = '';
  $data = '';
  while ($i < $cnt) {
    $l = trim($lines[$i], "\r");
    @(list($d, $c) = explode($comment, $l, 2));
    if ($trim) {
      $c = trim($c, $trim);
    }
    if ($c) {
      list($a, $o) = explode('=', $c, 2);
      if (trim($a) == 'ACCESS') {
        $access = trim($o);
      }
    }
    if (strpos($l, $comment) !== 0) {
      $data .= "{$l}\n";
    }
    $i++;
  }
  return array(
    'access' => $access,
    'source' => $data,
  );
}

/**
 * General wrapper procedure for reporting erros
 *
 * @param string $short_message Message that will be displayed to the users
 * @param string $log Message that will be recorded in the logs.
 */
function forena_error($short_message = '', $log = '') {
  if ($short_message) {
    drupal_set_message(check_markup($short_message), 'error');
  }
  if ($log) {
    watchdog('forena', $log, NULL, WATCHDOG_ERROR);
  }
}
function forena_debug($short_message, $log) {
  if ($log) {
    watchdog('forena debug', $log, NULL);
  }
  if ($short_message) {
    drupal_set_message(check_markup($short_message));
  }
}

/**
 * Invokes the hooks required for forena plugin registration.
 * Each module returns an array structure that defines multiple plugins
 *
 * class - Indicates the name of the class that will be used to define the plugins behaviors.
 *
 */
function forena_plugins() {
  static $plugins = '';
  if (!$plugins) {
    $plugins = array();
    foreach (module_list() as $module) {
      $function = $module . '_forena_plugins';
      if (function_exists($function)) {
        $returned_plugins = $function();
        if ($returned_plugins) {
          foreach ((array) $returned_plugins as $p) {
            $p['module'] = $module;
            $plugins[] = $p;
          }
        }
      }
    }
  }
  return $plugins;
}

/**
 * Loads all of the include files that
 */
function forena_define_plugins($class = '') {
  $plugins = forena_plugins();
  foreach ($plugins as $p) {
    if ($class == '' || $class == $p['class']) {
      if ($p['file'] && $p['module']) {
        include_once drupal_get_path('module', $p['module']) . '/' . trim($p['file'], '/');
      }
    }
  }
}

/**
 * Builds a global array of available controls
 * and returns the array.
 */
function forena_controls() {
  static $controls = '';
  if (!$controls) {
    $controls = array();
    foreach (module_list() as $module) {
      $function = $module . '_forena_controls';
      if (function_exists($function)) {
        $returned_controls = $function();
        if ($returned_controls) {
          foreach ((array) $returned_controls as $c) {
            $c['module'] = $module;
            $controls[] = $c;
          }
        }
      }
    }
  }
  return $controls;
}

/**
 * returns a list of instances of the control classes
 * if there wasn't a class, returns an empty string.
 */
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'], '/');
          if (class_exists($c['class'])) {
            $instances[$c['class']] = new $c['class']();
          }
        }
      }
    }
  }
  if ($class && $instances[$class]) {
    return $instances[$class];
  }
  return $instances;
}

/*
 * Recieves a datablock and returns an array of values from the data block.
 * @data_block: name of the data block to be invoked for values
 * @field: Specific field name within the data block. The values returned will only
 * come from this field.
 * @params: filtering for the data block
 * @where_clause: Where clause for data block to be filtered against.
 *
 */
function forena_get_data_block_params($data_block, $field, $label, $params = array(), $clause = '') {
  $xml = forena_invoke_data_provider($data_block, $params, $clause);
  $list = array();
  if ($xml) {
    $path = $field ? $field : '*[1]';
    $label_path = $label ? $label : '*[2]';
    drupal_set_message(check_markup($label));

    //walk through the $xml.
    $rows = $xml
      ->xpath('*');
    if ($rows) {
      foreach ($rows as $row) {
        $value = $row
          ->xpath($path);
        $label_field = $row
          ->xpath($label_path);
        $label_value = $label_field ? (string) $label_field[0] : (string) $value[0];
        $list[(string) $value[0]] = (string) $label_value;
      }
    }
  }
  return $list;
}

/**
 * Form to edit parameters
 * Extra features:
 * In the parameters section of the report are new attributes
 * frx:parm:
 * @data_source = data block for the parameter to values from
 * @data_field = specific field of the data block to recieve values from.
 * if no field is specified then the first column is arbitrarily chosen.
 * @type = The form element that will display the values: select, radios are supported
 * default is textfield.
 *
 * This function will evaluate each parameter, determine its type, data_source, and data_field
 * and display those values appropriately.
 *
 */
function forena_parameter_form($formid, &$form_state) {
  $parms = $_GET;
  unset($parms['q']);
  $form = array();
  $r = forena_report_object();
  if ($r) {
    drupal_set_title($r->title);
    $head = $r->rpt_xml->head;
    $form['params'] = array(
      '#tree' => TRUE,
      '#title' => 'Parameters',
      '#type' => 'fieldset',
      '#collapsible' => TRUE,
      '#collapsed' => $r->blocks_loaded,
    );
    $nodes = $head
      ->xpath('frx:parameters/frx:parm');
    foreach ($nodes as $node) {
      $label = (string) $node['label'];
      $id = (string) $node['id'];
      $data_source = (string) $node['data_source'];
      $data_field = (string) $node['data_field'];
      $type = (string) $node['type'];
      $value = isset($parms[$id]) ? $parms[$id] : (string) $node['value'];
      $desc = (string) $node['desc'];
      $label_field = (string) $node['label_field'];
      strcmp((string) $node['require'], "1") == 0 ? $required = TRUE : ($required = FALSE);

      //Determine the form element type to be displayed

      //If select or radios is chosen then begin a $list array for display values.
      switch ($type) {
        case 'select':
          $list = array(
            '--select--',
          );
          break;
        case 'radios':
          $list = array(
            '--choose--',
          );
          break;
        default:
          $type = 'textfield';
          $list = '';
      }

      //If a data_source attr was found then create an array of

      //returned values filtered against data_field attr.
      if ($data_source) {
        $list = forena_get_data_block_params($data_source, $data_field, $label_field);
      }
      $form['params'][$id] = array(
        '#type' => $type,
        '#title' => $label ? t($label) : t($id),
        '#default_value' => $value,
        '#required' => $required,
        '#description' => $desc,
      );

      //if $list is not empty then push options

      //onto the array. options will cause an error for

      //textfield elements.
      if ($type != 'textfield') {
        $form['params'][$id]['#options'] = $list;
      }
    }
    $form['params']['submit'] = array(
      '#type' => 'submit',
      '#value' => 'Submit',
    );
  }
  return $form;
}

/**
 *
 * 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'];
  $q = '';
  foreach ($values['params'] as $key => $value) {
    $q .= '&' . $key . '=' . urlencode($value);
  }
  $q = trim($q, '&');
  $form_state['redirect'] = array(
    $_GET['q'],
    array(
      'query' => $values['params'],
    ),
  );
}

/**
 * Gets the correct format function
 * to render the document and returns an
 * object of that class.
 *
 * If it fails it returns a 0;
 */
function forena_get_doctypes($fkey) {
  $controls = forena_define_controls();
  foreach ($controls as $k => $r) {
    $provider = $r;
    if ($provider && method_exists($provider, 'doc_types')) {
      $f = $provider
        ->doc_types();
      if (isset($f[$fkey]) && method_exists($provider, $f[$fkey])) {

        // We found an object with the advertised method return it
        return $provider;
      }
    }
  }
  return 0;
}

/**
 *
 * @return returns an array of supported document format extensions
 *
 */
function forena_supported_doctypes() {
  $controls = forena_define_controls();
  $supported_doctypes = array();
  foreach ($controls as $k => $r) {
    $provider = $r;
    if ($provider && method_exists($provider, 'doc_types')) {
      $f = $provider
        ->doc_types();
      $supported_doctypes = array_merge($supported_doctypes, $f);
    }
  }
  $temp = array_keys($supported_doctypes);
  $supported_doctypes = array_combine($temp, $temp);
  return $supported_doctypes;
}

/**
 * Returns an object of the template class
 * that has a method named templates.
 *
 * If it fails it returns a 0;
 */
function forena_get_templates($fkey) {
  $controls = forena_define_controls();
  foreach ($controls as $k => $r) {
    $provider = $r;
    if ($provider && method_exists($provider, 'templates')) {
      $f = $provider
        ->templates();
      if ($f[$fkey] && method_exists($provider, $fkey)) {

        // We found an object with the advertised method, return it
        return $provider;
      }
    }
  }
  return 0;
}

/**
 *
 * @return returns an array of supported templates
 *
 */
function forena_supported_templates() {
  $controls = forena_define_controls();
  $supported_templates = array();
  foreach ($controls as $k => $r) {
    $provider = $r;
    if ($provider && method_exists($provider, 'templates')) {
      $f = $provider
        ->templates();
      $supported_templates = array_merge($supported_templates, $f);
    }
  }
  return $supported_templates;
}
function forena_supported_formats() {
  $controls = forena_define_controls();
  $supported_formats = array();
  $f = array();
  foreach ($controls as $k => $r) {
    $provider = $r;
    if ($provider && method_exists($provider, 'formats')) {
      $f = $provider
        ->formats();
      $supported_formats = array_merge($supported_formats, $f);
    }
  }
  return $supported_formats;
}

/**
 *
 * @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 an object was found, 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");
        print $ret;
        break;
      case 'pdf':
        header('Content-Type: application/pdf');
        header('Cache-Control:');
        header('Pragma:');
        header("Cache-Control: must-revalidate");
        header("Content-Disposition: attachment; filename=report.pdf");
        print $ret;
        break;
      case 'xls':
        header('Content-Type: application/msexcel');
        header('Cache-Control:');
        header('Pragma:');
        header("Cache-Control: must-revalidate");
        header("Content-Disposition: attachment; filename=report.xls");
        print $ret;
        break;
      case 'csv':
        header('Content-Type: application/csv');
        header('Cache-Control:');
        header('Pragma:');
        header("Cache-Control: must-revalidate");
        header("Content-Disposition: attachment; filename=report.csv");
        print $ret;
        break;
      default:
        return $ret;
    }

    // Print the output.
  }
  else {
    return $ret;
  }
}
function forena_get_user_reports() {
  $result = db_query('SELECT * FROM {forena_reports} where hidden=0 ORDER BY category,title asc');
  $reports = array();
  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)) {
                $a = $callback($arg);
              }
              if ($a) {
                $access = TRUE;
              }
            }
          }
          else {
            $access = TRUE;
          }
        }
      }
    }
    if ($access) {
      $reports[$row->category][] = array(
        'title' => $row->title,
        'report_name' => $row->report_name,
      );
    }
  }
  return $reports;
}

/**
 * Render the my reports category block
 *
 */
function forena_my_reports_block() {
  $reports = forena_get_user_reports();
  if (!$reports) {
    return '';
  }
  $output = '<ul>';
  foreach ($reports as $category => $reports) {
    $output .= '<li>' . l($category, 'forena', array(
      'fragment' => urlencode($category),
    )) . '</li>';
  }
  $output .= '</ul>';
  return $output;
}

/**
 * Email confirmation form.   Confirms an email send based on mail merge
 * @param array $docs An array of SimpleXML email documents to send
 * @param integer $count Number of documents to send.
 */
function forena_confirm_email($form, &$form_state, $docs, $count) {
  if ($docs) {
    if (!variable_get('forena_email_override', FALSE)) {
      $form['send'] = array(
        '#type' => 'radios',
        '#title' => 'Send Email',
        '#options' => array(
          'send' => 'email to users',
          'test' => 'emails to me (test mode)',
        ),
        '#required' => TRUE,
      );
    }
    $form['max'] = array(
      '#type' => 'textfield',
      '#title' => 'Only send first',
      '#description' => 'In test mode only, limits the number of messages to send',
      '#default_value' => 1,
      '#size' => 3,
    );
    $form_state['storage']['docs'] = $docs;
    $form_state['storage']['count'] = $count;
  }
  return confirm_form($form, t('Send mail to users'), 'forena', t('Send email to %count users?', array(
    '%count' => $count,
  )));
}
function forena_confirm_email_submit($form, &$form_state) {
  global $user;
  $test_send = @$form_state['values']['send'] == 'test' ? TRUE : variable_get('forena_email_override', FALSE);
  $max = (int) $form_state['values']['max'];
  $i = 0;
  foreach ($form_state['storage']['docs'] as $doc) {
    $to = $test_send ? $user->mail : $doc['to'];
    $from = $doc['from'];
    if ($test_send) {
      $i++;
    }
    if ($i <= $max) {
      drupal_mail('forena', 'mailmerge', $to, language_default(), $doc['parms'], $from, TRUE);
    }
  }
}

/**
 * Send report block XML
 * Enter description here ...
 * @param unknown_type $block_name
 */
function forena_block_xml($block_name = '') {
  $block_name = str_replace('.', '/', $block_name);
  $parms = $_GET;
  unset($parms['q']);
  $xml = forena_invoke_data_provider($block_name, $parms);
  if (is_object($xml)) {
    header('Content-Type: text/xml');
    print $xml
      ->asXML();
  }
}

Functions

Namesort descending Description
forena_block_access Check access control using the block in a data block. In this case public assess returns true.
forena_block_xml Send report block XML Enter description here ...
forena_confirm_email Email confirmation form. Confirms an email send based on mail merge
forena_confirm_email_submit
forena_controls Builds a global array of available controls and returns the array.
forena_debug
forena_define_controls returns a list of instances of the control classes if there wasn't a class, returns an empty string.
forena_define_plugins Loads all of the include files that
forena_error General wrapper procedure for reporting erros
forena_format_data
forena_generate_doc @return: The document in the requested format. Returns a string if not able to format.
forena_get_data_block_params
forena_get_doctypes Gets the correct format function to render the document and returns an object of that class.
forena_get_formatter Load the formatters for all initialized repositories.
forena_get_html Accepts the name of the html tag, and the string the tag is in.
forena_get_report Accepts the name of a file
forena_get_templates Returns an object of the template class that has a method named templates.
forena_get_user_reports
forena_inner_xml Enter description here...
forena_invoke_data_provider Extract the data by running a block
forena_load_block Returns an array of information about the data block
forena_load_block_file Load a block file form disk and introspect the comments to determine security Return a structured array based on this.
forena_load_cache Biuld cache
forena_my_reports_block Render the my reports category block
forena_parameter_form Form to edit parameters Extra features: In the parameters section of the report are new attributes frx:parm: @data_source = data block for the parameter to values from @data_field = specific field of the data block to recieve values from. if no field…
forena_parameter_form_submit gets the values from the params form redirects to the report page with the values in the querystring.
forena_plugins Invokes the hooks required for forena plugin registration. Each module returns an array structure that defines multiple plugins
forena_report_css Determines which css files need to be loaded.
forena_report_desc Get name from argument 1 or alterntaively from a file name
forena_report_object Object factory for forena report When called without a report name, it returns the last created report. This static caching mechanism is used for form functions that are called within a page load.
forena_repository
forena_supported_doctypes
forena_supported_formats
forena_supported_templates
__forena_load_provider Load the data provider class based on the class name.
__forena_load_repository