139 $this->selected =
null;
141 $this->report_id = 0;
142 $this->tables = array();
143 $this->request = $_REQUEST;
144 if ($this->request[
"custom_report_mode"] ==
"save")
146 $this->
title = $this->request[
"custom_report_title"];
147 $this->description = $this->request[
"custom_report_description"];
158 $this->request = array_remove_keys($this->request,
"custom_report_mode",
"PHPSESSID",
"__utma",
"__utmb",
"__utmc",
"__utmz");
159 return array(
'report_id',
'title',
'description',
'request');
186 trace(
"Component report_manager is deleting objects dependent on user_id {$user_id}", 3);
189 $report->delete(
"WHERE user_id={$user_id}");
204 $script .= $tableNavigator->writeScript();
205 $script .= $filterNavigator->writeScript();
210 $interstitial = $this->interstitialMessage ?
" onsubmit='interstitial(\"".jsSafe($this->interstitialMessage).
".\"); return true;'" :
"";
213 echo
"<form method='POST' action='$action?report_id={$_GET['report_id']}&target={$targetClass}'$target id='custom_report'$interstitial>";
214 echo
"<input type='hidden' name='report_id' value='{$this->report_id}'/>";
215 echo
"<input type='hidden' name='custom_report_mode' value='search' id='custom_report_mode'/>";
216 echo
"<input type='hidden' name='custom_report_title' value='' id='custom_report_title'/>";
217 echo
"<input type='hidden' name='custom_report_description' value='' id='custom_report_description'/>";
218 $tableNavigator->drawView();
219 $filterNavigator->drawView();
222 $incomplete = ($this->request[
"__include_incomplete"] || $this->report_id == 0) ?
" checked='checked'" :
"";
223 $excel = $this->request[
"__excel"] ?
" checked='checked'":
"";
225 echo
"<div style='clear: left'><br/><input type='checkbox' name='__include_incomplete' value='1'$incomplete/> <strong>Include Incomplete Records in Results</strong>";
227 echo
"<br/><br/><input type='submit' class='button' value='Generate Report'/>";
229 echo
"</div></form>";
238 foreach($this->tables as
$table)
255 if ($this->request[
"custom_report_title"]) $this->
title = $this->request[
"custom_report_title"];
256 if ($this->request[
"custom_report_description"]) $this->description = $this->request[
"custom_report_description"];
258 foreach($this->tables as
$table)
260 if ($this->request[
"table_{$table->class}"])
264 $table->load($this->request);
267 if(count($this->selected) == 0)
283 $this->selected[
"table_{$table->class}"] =
true;
287 foreach(
$table->columns as $column)
289 $col =
"column_".codify($column->title);
290 if ($this->request[$col] || !$checkRequest)
292 $column->selected =
true;
293 $this->selected[$col] =
true;
310 foreach($this->tables as
$table)
311 if ($this->selected[
"table_{$table->class}"])
313 $this->constraint .=
$table->getConstraint($first, $this->request);
317 if($this->limit && is_numeric($this->limit))
319 $this->constraint .=
" LIMIT {$this->limit}";
327 $t1 = microtime(
true);
333 if (!isset($this->selected))
340 if ($_REQUEST[
"custom_report_mode"] ==
"save")
346 $joinClass = ($this->request[
'__include_incomplete'] ==
"1") ? LeftOuterJoin : InnerJoin;
348 $this->join =
new $joinClass;
349 $this->join->unique =
true;
353 foreach($this->tables as
$table)
355 if ($this->selected[
"table_{$table->class}"])
357 $table->createJoin($this);
365 $results = $this->join->iteratedQuery($this->constraint);
367 $report =
new DataListView($results,
"custom_report_results");
369 foreach($this->tables as
$table)
371 if ($this->selected[
"table_{$table->class}"])
377 $report->dragColumnReorder =
true;
378 $report->columnReorderCallback =
"ReportManager.setColumnOrder";
380 if ($this->columnOrder)
382 $report->setColumnOrder(explode(
"|",$this->columnOrder));
385 $reportTitle = (
$this->title) ? codify($this->
title).
"_".date(
"Y_m_d_Hi") :
"custom_report_".date(
"Y_m_d_Hi");
388 $report->excelFile = $reportTitle .
".xls";
407 $report->cssClass =
"list small";
412 if($this->limit && count($results))
414 echo
"<p class='report_limit'>Results are limited to the first {$this->limit} records.</p>\n";
426 $t2 = microtime(
true);
427 $elapsed = ($t2 - $t1);
428 echo
"<p><em>Report generated in ".number_format($elapsed, 2).
" seconds</em></p>";
433 return $this->selected[
"column_".codify($column->title)];
439 echo
"<p><a class='button' href='#' onclick='go(\"{$url}?report_id={$this->report_id}&edit=1\"); return false;'><i class='fa-fw fas fa-pencil-alt'></i> Edit Report Settings</a></p>";
440 echo
"<p><a class='button' href='#' onclick='ReportManager.updateReport(\"{$this->report_id}\"); return false;'><i class='fa-fw far fa-save'></i> Save Report</a>\n";
441 echo
" <a class='button' href='#' onclick='ReportManager.exportToExcel(\"$excel\"); return false;'><i class='fa-fw far fa-file-excel'></i> Export to Excel</a>";
442 echo
"\n <a class='button' href='#' onclick='ReportManager.createReportDialog();return false;'><i class='fa-fw fas fa-plus'></i> Create a New Report</a></p>\n";
453 if (!$this->report_id)
455 $sleeper = serialize($this);
458 $this->report_id =
"tmp-" .sha1(
$user->get(
$mgr->getUsernameField()) . $sleeper . now());
460 $_SESSION[$this->report_id .
"-class"] = get_class($this);
473 $report->configuration = serialize($this);
474 $report->manager_class = get_class($this);
479 $this->report_id =
$report->report_id;
488 $proto = unserialize(
$report->configuration);
489 $cl = get_class($proto);
497 $instance->request = (
$mode ==
"save" ||
$mode ==
"post") ? $_REQUEST : $proto->request;
499 $instance->populateSelected();
500 $instance->columnOrder =
$report->column_order;
507 $cl = get_class($proto);
509 $instance->request = $proto->request;
510 $instance->populateSelected();
511 $instance->columnOrder =
$report->column_order;
512 $instance->report_id = 0;
523 $this->request = $_REQUEST;
546 $this->
class = $class;
547 $this->proto =
new $class;
551 $this->outputFilter =
new InclusionFilter();
552 $this->outputFilter->add($this->proto->getPrimaryKey());
555 $this->fields = array();
556 $this->
title = $title ?
$title : $this->proto->prettifyClassName();
559 if ($request) $this->proto->fromDataSet($request);
561 $this->form =
new SearchForm($this->proto);
562 $this->form->id =
"custom_report";
565 $this->params = $this->form->params;
567 $this->excludedKeys = array();
575 return array(
'class',
'fields',
'title',
'constraints',
'params',
'excludedKeys',
'columns',
'footerColumns',
'totalCallbacks');
581 $this->form =
new SearchForm($this->proto);
588 $this->proto->fromDataSet($request);
589 $this->params->fromArray($request);
590 $this->form->params->fromArray($request);
607 $this->excludedKeys[] = $key;
618 $filter =
new InclusionFilter();
619 for($i = 0; $i < func_num_args(); ++$i)
622 $fieldMode = func_get_arg($i);
623 list(
$field, $searchMode) = explode(
":", $fieldMode);
627 $this->form->setMatchingMode($searchMode,
$field);
631 $this->proto->filter =
$filter;
637 $args = func_get_args();
638 $favorites = array_combine($args, $args);
639 foreach($this->
columns as $column)
641 if (array_key_exists($column->title, $favorites))
643 $column->favorite =
true;
659 $this->params->fromArray($request);
660 $constraint = $this->params->generateConstraint($first);
662 if ($this->constraints)
670 $constraint .= ($first ?
"WHERE " :
" AND ").$this->constraints;
679 if ($configurator) $configurator($this->form);
691 $column =
new ReportFooterColumn(
$title,
$text,
"", $style);
692 $this->footerColumns[
$title] = $column;
706 $column =
new FooterValueColumn($callback, $style);
707 $this->footerColumns[
$title] = $column;
721 $column =
new FooterTotalColumn(
$field, $template =
"", $style);
722 $this->footerColumns[
$title] = $column;
729 $mgr->join->add($this->
class);
732 foreach($this->excludedKeys as $excluded)
734 $mgr->join->excludeKeyFromJoin($this->
class, $excluded);
740 if ($this->outputFilter)
742 foreach($this->
columns as $column)
744 if (
$mgr->isColumnSelected($column) && is_array($column->outputFields))
746 foreach($column->outputFields as
$field)
748 $this->outputFilter->add(
$field);
753 $mgr->join->setFilter(
$class, $this->outputFilter);
759 foreach($this->
columns as $column)
761 if (
$mgr->isColumnSelected($column))
763 $report->column($column->title, $column->format, $column->sortable, $column->style, $column->type);
765 if(array_key_exists($column->title, $this->footerColumns))
767 $footer = $this->footerColumns[$column->title];
768 $report->footerColumns[] = $footer;
769 if(get_class($footer) == FooterTotalColumn)
776 $report->footerColumns[] =
new FooterTextColumn(
" ");
static getTarget($manager)
FakoliException is the base exception class for all Fakoli errors.
static scriptName()
Returns the name of the currently executing script.
static usingFeature()
Uses the specified framework feature(s).
ReportColumn($title, $format, $sortable=true, $style="", $type=null, $outputFields=null)
ReportManager provides a generic mechanism for implementing user configurable reports based on DataIt...
$columnOrder
Override the default column order.
$resultsPage
The page used to display the search results.
setSelected($table, $checkRequest=true)
Set the given table as selected.
$interstitialMessage
Optional interstitial message to display while report is being generated.
preSaveReport()
Alternative implementation - presave version of report is stored in session with a.
generateConstraint()
Generate the search constraint for the current report configuration.
__sleep()
Tidy up the request data and limit the fields returned when serializing a ReportManager.
writeResultsFormButtons($excel)
$target
The target window for the form results.
static deleteUser($user)
Respond to fired event DeleteUser.
getTable($class)
Retrieve the ReportTable object for the specified DataItem class.
$description
Longer description of the report.
$limit
Optional limit to number of records retrieved, depending on acceptable load times for results.
$report_id
ID of the saved report as persisted in the database.
generateReport($inlineScript=false)
table($class, $title="", $useOutputFilter=false)
Add a table to the report.
$editorPage
The page used to display the report editor.
$title
Title of the report.
ReportManager()
Creates a new ReportManager instance.
static load($report_id, $mode="")
isColumnSelected($column)
drawForm()
Draw the configuration/search form.
createColumns($mgr, $report)
filterOutput($mgr, $class)
__construct($class, $title="", $request=null, $outputFilter=false)
getConstraint($first, $request)
additionalConstraints($constraint)
footerText($text="", $style="")
Adds a text column to the table footer.
footerValue($title, $callback, $style="")
Adds a value column to the table footer.
configureForm($configurator=null)
footerTotal($title, $field, $style="text-align: right")
Sums the total for a column.
column($title, $format, $sortable=true, $style="", $type=null, $outputFields=null)
Provides the interface to the user model for the application.