From: Ben Klang Date: Tue, 12 Jan 2010 23:00:20 +0000 (-0500) Subject: Operator: Create ability to export CDR to CSV/TSV X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=630c2761e2f1bfe59313baa5c20ae1c325b303e2;p=horde.git Operator: Create ability to export CDR to CSV/TSV --- diff --git a/operator/config/conf.xml b/operator/config/conf.xml index 3990892ef..54de86f8c 100644 --- a/operator/config/conf.xml +++ b/operator/config/conf.xml @@ -1,5 +1,4 @@ - Storage System Settings @@ -20,10 +19,12 @@ Menu Settings + true - + diff --git a/operator/export.php b/operator/export.php new file mode 100644 index 000000000..2b67572ae --- /dev/null +++ b/operator/export.php @@ -0,0 +1,70 @@ + + */ + +require_once dirname(__FILE__) . '/lib/Application.php'; + +$operator = new Operator_Application(array('init' => true)); +$cache = &$GLOBALS['cache']; + +require_once OPERATOR_BASE . '/lib/Form/SearchCDR.php'; + +$renderer = new Horde_Form_Renderer(); +$vars = Horde_Variables::getDefaultVariables(); +$data = array(); + +if (!$vars->exists('rowstart')) { + $rowstart = 0; +} elseif (!is_numeric($rowstart = $vars->get('rowstart'))) { + $notification->push(_("Invalid number for row start. Using 0.")); + $rowstart = 0; +} + +if (isset($_SESSION['operator']['lastdata'])) { + $data = $_SESSION['operator']['lastdata']; +} + +$form = new ExportCDRForm(_("Export Call Detail Records"), $vars); +if ($form->isSubmitted() && $form->validate($vars, true)) { + try { + $_SESSION['operator']['lastsearch']['params'] = array( + 'accountcode' => $vars->get('accountcode'), + 'dcontext' => $vars->get('dcontext'), + 'startdate' => $vars->get('startdate'), + 'enddate' => $vars->get('enddate')); + $_SESSION['operator']['lastdata'] = $data; + + $form->execute(); + + } catch (Exception $e) { + //$notification->push(_("Invalid date requested.")); + $notification->push($e); + $data = array(); + } +} else { + if (isset($_SESSION['operator']['lastsearch']['params'])) { + foreach($_SESSION['operator']['lastsearch']['params'] as $var => $val) { + $vars->set($var, $val); + } + } +} + +$title = _("Export Call Detail Records"); + +require OPERATOR_TEMPLATES . '/common-header.inc'; +require OPERATOR_TEMPLATES . '/menu.inc'; +$notification->notify(); +$form->renderActive($renderer, $vars); + +$columns = unserialize($prefs->getValue('columns')); +if (!empty($data)) { + require OPERATOR_TEMPLATES . '/search.inc'; +} + +require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/operator/lib/Driver/asterisksql.php b/operator/lib/Driver/asterisksql.php index 80d50c5db..d9e771740 100644 --- a/operator/lib/Driver/asterisksql.php +++ b/operator/lib/Driver/asterisksql.php @@ -79,7 +79,7 @@ class Operator_Driver_asterisksql extends Operator_Driver { * @throws Operator_Exception|Horde_Date_Exception */ protected function _getRecords($start, $end, $accountcode = null, $dcontext = null, - $rowstart = 0, $rowlimit = 100) + $rowstart = 0, $rowlimit = null) { // Use the query to make the MySQL driver look like the CDR-CSV driver @@ -95,7 +95,7 @@ class Operator_Driver_asterisksql extends Operator_Driver { Horde::logMessage('Invalid start row requested.', __FILE__, __LINE__, PEAR_LOG_ERR); throw new Operator_Exception(_("Internal error. Details have been logged for the administrator.")); } - if (!is_numeric($rowlimit)) { + if (!is_null($rowlimit) && !is_numeric($rowlimit)) { Horde::logMessage('Invalid row limit requested.', __FILE__, __LINE__, PEAR_LOG_ERR); throw new Operator_Exception(_("Internal error. Details have been logged for the administrator.")); } @@ -130,7 +130,11 @@ class Operator_Driver_asterisksql extends Operator_Driver { Horde::logMessage(sprintf('Operator_Driver_asterisksql::getData(): %s', $sql), __FILE__, __LINE__, PEAR_LOG_DEBUG); /* Execute the query. */ - $res = $this->_db->limitQuery($sql, $rowstart, $rowlimit, $values); + if (is_null($rowlimit)) { + $res = $this->_db->query($sql, $values); + } else { + $res = $this->_db->limitQuery($sql, $rowstart, $rowlimit, $values); + } if (is_a($res, 'PEAR_Error')) { Horde::logMessage($res, __FILE__, __LINE__, PEAR_LOG_ERR); throw new Operator_Exception(_("Internal error. Details have been logged for the administrator.")); diff --git a/operator/lib/Form/SearchCDR.php b/operator/lib/Form/SearchCDR.php index 261c73ec3..0899b54a3 100644 --- a/operator/lib/Form/SearchCDR.php +++ b/operator/lib/Form/SearchCDR.php @@ -17,7 +17,7 @@ class SearchCDRForm extends Horde_Form { public function __construct($title, &$vars) { - parent::Horde_Form($vars, $title); + parent::__construct($vars, $title); // FIXME: Generate a list of clients from Turba? //$clients = @@ -66,9 +66,68 @@ class SearchCDRForm extends Horde_Form { $params = array($start_year, $end_year, $picker, $format_in, $format_out, $show_seconds); - $this->addVariable(_("Account Code"), 'accountcode', 'enum', false, false, null, array($accountcodes)); - $this->addVariable(_("Destination Context"), 'dcontext', 'text', false, false, _("An empty destination context will match all destination contexts.")); - $this->addVariable(_("Start Date & Time"), 'startdate', 'datetime', true, false, null, $params); - $this->addVariable(_("End Date & Time"), 'enddate', 'datetime', true, false, null, $params); + $this->addVariable(_("Account Code"), 'accountcode', 'enum', false, + false, null, array($accountcodes)); + $this->addVariable(_("Destination Context"), 'dcontext', 'text', false, + false, _("An empty destination context will match all destination contexts.")); + $this->addVariable(_("Start Date & Time"), 'startdate', 'datetime', + true, false, null, $params); + $this->addVariable(_("End Date & Time"), 'enddate', 'datetime', true, + false, null, $params); + } +} + +class ExportCDRForm extends SearchCDRForm +{ + public function __construct($title, &$vars) + { + parent::__construct($title, $vars); + + $formats = array( + Horde_Data::EXPORT_CSV => 'Comma-Delimited (CSV)', + Horde_Data::EXPORT_TSV => 'Tab-Delimited', + ); + + $this->addVariable(_("Data Format"), 'format', 'enum', true, false, + null, array($formats)); + } + + public function execute() + { + global $operator; + if (empty($operator) || empty($operator->driver)) { + $operator = new Operator_Application(array('init' => true)); + } + + $start = new Horde_Date($this->_vars->get('startdate')); + $end = new Horde_Date($this->_vars->get('enddate')); + $accountcode = $this->_vars->get('accountcode'); + $dcontects = $this->_vars->get('dcontext'); + if (empty($dcontext)) { + $dcontext = '%'; + } + list($stats, $data) = $operator->driver->getRecords($start, $end, + $accountcode, + $dcontext, 0, + null); + switch($this->_vars->get('format')) { + case Horde_Data::EXPORT_CSV: + $ext = 'csv'; + $fmt = Horde_Data::singleton('csv'); + break; + + case Horde_Data::EXPORT_TSV: + $ext = 'tsv'; + $fmt = Horde_Data::singleton('tsv'); + break; + + default: + throw new Operator_Exception(_("Invalid data format requested.")); + break; + } + + $filename = 'export-' . uniqid() . '.' . $ext; + $fmt->exportFile($filename, $data, true); + exit; } } diff --git a/operator/lib/Operator.php b/operator/lib/Operator.php index 951cc4f45..26e0ba120 100644 --- a/operator/lib/Operator.php +++ b/operator/lib/Operator.php @@ -2,8 +2,6 @@ /** * Operator Base Class. * - * $Horde: incubator/operator/lib/Operator.php,v 1.18 2009/12/01 12:52:49 jan Exp $ - * * Copyright 2008-2010 The Horde Project (http://www.horde.org/) * * See the enclosed file COPYING for license information (GPL). If you @@ -17,13 +15,18 @@ class Operator { /** * Build Operator's list of menu items. */ - function getMenu($returnType = 'object') + public static function getMenu($returnType = 'object') { global $conf, $registry, $browser, $print_link; $menu = new Horde_Menu(Horde_Menu::MASK_ALL); - $menu->add(Horde::applicationUrl('viewgraph.php'), _("View Graphs"), 'graphs.png', null, null, null, basename($_SERVER['PHP_SELF']) == 'index.php' ? 'current' : null); - $menu->add(Horde::applicationUrl('search.php'), _("Search"), 'search.png', $registry->getImageDir('horde')); + $menu->add(Horde::applicationUrl('viewgraph.php'), _("_View Graphs"), 'graphs.png', null, null, null, basename($_SERVER['PHP_SELF']) == 'index.php' ? 'current' : null); + $menu->add(Horde::applicationUrl('search.php'), _("_Search"), 'search.png', $registry->getImageDir('horde')); + + /* Export */ + if ($GLOBALS['conf']['menu']['export']) { + $menu->add(Horde::applicationUrl('export.php'), _("_Export"), 'data.png', $GLOBALS['registry']->getImageDir('horde')); + } if ($returnType == 'object') { return $menu; @@ -32,7 +35,7 @@ class Operator { } } - function getColumns() + public static function getColumns() { #static $columns = array( $columns = array( @@ -59,13 +62,13 @@ class Operator { } - function getColumnName($column) + public static function getColumnName($column) { $columns = Operator::getColumns(); return $columns[$column]; } - function getAMAFlagName($flagid) + public static function getAMAFlagName($flagid) { // See for definitions switch($flagid) { @@ -86,13 +89,13 @@ class Operator { * * @return array List of valid account codes. */ - function getAccountCodes($permfilter = false) + public static function getAccountCodes($permfilter = false) { global $operator; if (empty($operator) || empty($operator->driver)) { $operator = new Operator_Application(array('init' => true)); } - + // Set up arrays for filtering $keys = $values = $operator->driver->getAccountCodes(); @@ -146,32 +149,41 @@ class Operator { return $accountcodes; } - function getGraphInfo($graphid) + public static function getGraphInfo($graphid = null) { - switch($graphid) { - case 'numcalls': - return array( - 'title' => _("Number of Calls by Month"), - 'axisX' => _("Month"), - 'axisY' => _("Number of Calls"), - ); - break; - case 'minutes': - return array( - 'title' => _("Total Minutes Used by Month"), - 'axisX' => _("Month"), - 'axisY' => _("Minute"), - 'numberformat' => '%0.1f', - ); - break; - case 'failed': - return array( - 'title' => _("Number of Failed Calls by Month"), - 'axisX' => _("Month"), - 'axisY' => _("Failed Calls"), - ); - break; - } + static $graphs; + + if (empty($graphs)) { + $graphs = array( + 'numcalls' => array( + 'title' => _("Number of Calls by Month"), + 'axisX' => _("Month"), + 'axisY' => _("Number of Calls"), + ), + 'minutes' => array( + 'title' => _("Total Minutes Used by Month"), + 'axisX' => _("Month"), + 'axisY' => _("Minute"), + 'numberformat' => '%0.1f', + ), + + 'failed' => array( + 'title' => _("Number of Failed Calls by Month"), + 'axisX' => _("Month"), + 'axisY' => _("Failed Calls"), + ), + ); + } + + if ($graphid === null) { + return $graphs; + } + + if (isset($graphs[$graphid])) { + return $graphs[$graphid]; + } else { + throw new Operator_Exception(_("Invalid graph type.")); + } } }