CMS  Version 3.9
ReportManager Class Reference

ReportManager provides a generic mechanism for implementing user configurable reports based on DataItem classes. More...

Public Member Functions

 ReportManager ()
 Creates a new ReportManager instance. More...
 
 __sleep ()
 Tidy up the request data and limit the fields returned when serializing a ReportManager. More...
 
 table ($class, $title="", $useOutputFilter=false)
 Add a table to the report. More...
 
 drawForm ()
 Draw the configuration/search form. More...
 
 getTable ($class)
 Retrieve the ReportTable object for the specified DataItem class. More...
 
 populateSelected ()
 
 setSelected ($table, $checkRequest=true)
 Set the given table as selected. More...
 
 generateConstraint ()
 Generate the search constraint for the current report configuration. More...
 
 generateReport ($inlineScript=false)
 
 isColumnSelected ($column)
 
 writeResultsFormButtons ($excel)
 
 preSaveReport ()
 Alternative implementation - presave version of report is stored in session with a. More...
 
 save ()
 
 fromRequest ()
 

Static Public Member Functions

static deleteUser ($user)
 Respond to fired event DeleteUser. More...
 
static load ($report_id, $mode="")
 

Public Attributes

 $report_id
 ID of the saved report as persisted in the database. More...
 
 $title
 Title of the report. More...
 
 $description
 Longer description of the report. More...
 
 $resultsPage = "custom_report_results"
 The page used to display the search results. More...
 
 $editorPage = "custom_report"
 The page used to display the report editor. More...
 
 $target
 The target window for the form results. More...
 
 $columnOrder
 Override the default column order. More...
 
 $tables
 
 $join
 
 $report
 
 $request
 
 $interstitialMessage = ""
 Optional interstitial message to display while report is being generated. More...
 
 $limit
 Optional limit to number of records retrieved, depending on acceptable load times for results. More...
 

Detailed Description

ReportManager provides a generic mechanism for implementing user configurable reports based on DataItem classes.

To use ReportManager:

1) create a component "report" in your application's components and create its manifest.inc file

2) create folder "pages" with a file for each type of report needed in the application with names such as "custom_xx_report" (e.g., custom_program_report)

3) The page or pages should contain this code:

Fakoli::using("report");

$report = new XXReportManager();

if ($method == "POST" || isset($_REQUEST["__excel"])) { $report->generateReport(); } else { $report->drawForm(); }

4) On the top level in the report component, add a php file xx_report_manager.inc with the code:

class XXReportManager extends ReportManager { function XXReportManager() { $this->ReportManager();

$this->table(MyDataItemClass, "MyTitle")
->column("My Field Label", "{my_field}", true, "") ... ; } }

the same way you would create a DataListView Before closing the column list with the semicolon, you can also add search fields with the search mode (equal if not provided):

->searchFields("contact_id", "name:like")

For fields that have values in a related table, create a RelatedItemSelectFieldRenderer for the search filter Example:

new RelatedItemSelectFieldRenderer($this->getTable(Program)->form, "affiliation_id", "Primary Program Type", Affiliation, "ORDER BY sort_order, affiliation", "affiliation", "affiliation_id");

If the field has a set of options defined in the DataItem class, create SelectFieldRenderer. Example:

new SelectFieldRenderer($this->getTable(Program)->form, "residency_requirement", "Residency Requirement", Program::$residencyTypes);

If you need to search on a field that is not in the table but is instead in an xref table, such as the obj is linked to a set of states through a item_state_xref table, then create the RelatedItemSelectFieldRenderer but set an additional or custom callback parameter handler:

new RelatedItemSelectFieldRenderer($this->getTable(Program)->form, "state", "State", State, "ORDER BY name", "name", "state_id");

$this->getTable(Program)->params->setParam("state", "equal", $_REQUEST["state:equal"]); $this->getTable(Program)->params->setHandler("state", array(ProgramReportManager, getStateConstraint));

Author
andy

Definition at line 118 of file report_manager.inc.

Member Function Documentation

◆ __sleep()

ReportManager::__sleep ( )

Tidy up the request data and limit the fields returned when serializing a ReportManager.

Returns
array

Definition at line 156 of file report_manager.inc.

157  {
158  $this->request = array_remove_keys($this->request, "custom_report_mode", "PHPSESSID", "__utma", "__utmb", "__utmc", "__utmz");
159  return array('report_id', 'title', 'description', 'request');
160  }

◆ deleteUser()

static ReportManager::deleteUser (   $user)
static

Respond to fired event DeleteUser.

Delete any records in this component that have dependencies on user object.

Parameters
obj$user- class SiteUser or custom user class

Definition at line 181 of file report_manager.inc.

182  {
183  $pk = $user->getPrimaryKey();
184  $user_id = $user->$pk;
185 
186  trace("Component report_manager is deleting objects dependent on user_id {$user_id}", 3);
187 
188  $report = new CustomReport();
189  $report->delete("WHERE user_id={$user_id}");
190 
191  return $user;
192  }
$user_id
global $user

◆ drawForm()

ReportManager::drawForm ( )

Draw the configuration/search form.

Definition at line 197 of file report_manager.inc.

198  {
199  global $script;
200 
201  $tableNavigator = new ReportTableNavigator($this->tables);
202  $filterNavigator = new ReportFilterNavigator($this->tables);
203 
204  $script .= $tableNavigator->writeScript();
205  $script .= $filterNavigator->writeScript();
206 
207  $action = $this->resultsPage ? $this->resultsPage : Fakoli::scriptName();
208  $target = $this->target ? " target='{$this->target}'" : "";
209 
210  $interstitial = $this->interstitialMessage ? " onsubmit='interstitial(\"".jsSafe($this->interstitialMessage).".\"); return true;'" : "";
211  $targetClass = CustomReportManager::getTarget($this);
212 
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();
220 
221 
222  $incomplete = ($this->request["__include_incomplete"] || $this->report_id == 0) ? " checked='checked'" : "";
223  $excel = $this->request["__excel"] ? " checked='checked'": "";
224 
225  echo "<div style='clear: left'><br/><input type='checkbox' name='__include_incomplete' value='1'$incomplete/> <strong>Include Incomplete Records in Results</strong>";
226  //echo "<br/><input type='checkbox' name='__excel' value='custom_report'$excel/> <strong>Output as Excel</strong>";
227  echo "<br/><br/><input type='submit' class='button' value='Generate Report'/>";
228  //echo "&nbsp;&nbsp;<button class='button' onclick='ReportManager.saveReport($this->report_id); return false;'>Save Report</button>";
229  echo "</div></form>";
230  }
$siteTree target
Definition: site_map.inc:56
static getTarget($manager)
static scriptName()
Returns the name of the currently executing script.
Definition: core.inc:1446
$target
The target window for the form results.
$action
Definition: run.php:41

◆ fromRequest()

ReportManager::fromRequest ( )

Definition at line 521 of file report_manager.inc.

522  {
523  $this->request = $_REQUEST;
524  $this->populateSelected();
525  }

◆ generateConstraint()

ReportManager::generateConstraint ( )

Generate the search constraint for the current report configuration.

Returns
string the SQL constraint for the search

Definition at line 307 of file report_manager.inc.

308  {
309  $first = true;
310  foreach($this->tables as $table)
311  if ($this->selected["table_{$table->class}"])
312  {
313  $this->constraint .= $table->getConstraint($first, $this->request);
314  $first = false;
315  }
316 
317  if($this->limit && is_numeric($this->limit))
318  {
319  $this->constraint .= " LIMIT {$this->limit}";
320  }
321 
322  //var_dump($this->request);
323  }

◆ generateReport()

ReportManager::generateReport (   $inlineScript = false)

Definition at line 325 of file report_manager.inc.

326  {
327  $t1 = microtime(true);
328 
329  $this->preSaveReport();
330 
331  global $script;
332 
333  if (!isset($this->selected))
334  {
335  $this->populateSelected();
336  }
337 
338  $this->generateConstraint();
339 
340  if ($_REQUEST["custom_report_mode"] == "save")
341  {
342  $this->save();
343  return;
344  }
345 
346  $joinClass = ($this->request['__include_incomplete'] == "1") ? LeftOuterJoin : InnerJoin;
347 
348  $this->join = new $joinClass;
349  $this->join->unique = true;
350  $constraint .= "";
351  $first = true;
352 
353  foreach($this->tables as $table)
354  {
355  if ($this->selected["table_{$table->class}"])
356  {
357  $table->createJoin($this);
358 
359 
360  $first = false;
361  }
362  }
363 
364  //echo "constraint {$this->constraint}<br>";
365  $results = $this->join->iteratedQuery($this->constraint);
366 
367  $report = new DataListView($results, "custom_report_results");
368 
369  foreach($this->tables as $table)
370  {
371  if ($this->selected["table_{$table->class}"])
372  {
373  $table->createColumns($this, $report);
374  }
375  }
376 
377  $report->dragColumnReorder = true;
378  $report->columnReorderCallback = "ReportManager.setColumnOrder";
379 
380  if ($this->columnOrder)
381  {
382  $report->setColumnOrder(explode("|",$this->columnOrder));
383  }
384 
385  $reportTitle = ($this->title) ? codify($this->title)."_".date("Y_m_d_Hi") : "custom_report_".date("Y_m_d_Hi");
386  //if(isset($this->request["__excel"]))
387  //{
388  $report->excelFile = $reportTitle . ".xls";
389  //}
390  /* to do - pdf output
391  else
392  {
393  $identifier = $this->request["identifier"];
394  $pdf = new PDF("/$identifier", false, true, $reportTitle . ".pdf");
395  $pdf->generate();
396  }
397  */
398  if ($inlineScript)
399  {
400  echo $report->writeScript();
401  }
402  else
403  {
404  $script .= $report->writeScript();
405  }
406 
407  $report->cssClass = "list small";
408  $report->hideExcelIcon = true;
409 
410  $excel = $report->getExcelLink();
411 
412  if($this->limit && count($results))
413  {
414  echo "<p class='report_limit'>Results are limited to the first {$this->limit} records.</p>\n";
415  }
416 
418 
419  $report->drawView();
420 
421  if (count($results))
422  {
424  }
425 
426  $t2 = microtime(true);
427  $elapsed = ($t2 - $t1);
428  echo "<p><em>Report generated in ".number_format($elapsed, 2)." seconds</em></p>";
429  }
$constraint
$bookmark title
preSaveReport()
Alternative implementation - presave version of report is stored in session with a.
generateConstraint()
Generate the search constraint for the current report configuration.
writeResultsFormButtons($excel)
$title
Title of the report.

◆ getTable()

ReportManager::getTable (   $class)

Retrieve the ReportTable object for the specified DataItem class.

Parameters
string$classthe class identifying the ReportTable to be retrieved.

Definition at line 236 of file report_manager.inc.

237  {
238  foreach($this->tables as $table)
239  {
240  if ($table->class == $class) return $table;
241  }
242 
243  return null;
244  }

◆ isColumnSelected()

ReportManager::isColumnSelected (   $column)

Definition at line 431 of file report_manager.inc.

432  {
433  return $this->selected["column_".codify($column->title)];
434  }

◆ load()

static ReportManager::load (   $report_id,
  $mode = "" 
)
static

Definition at line 482 of file report_manager.inc.

483  {
484  if (is_numeric($report_id))
485  {
487 
488  $proto = unserialize($report->configuration);
489  $cl = get_class($proto);
490 
491  if ($mode != "save")
492  {
493  //$_REQUEST = $proto->request;
494  }
495 
496  $instance = new $cl;
497  $instance->request = ($mode == "save" || $mode == "post") ? $_REQUEST : $proto->request;
498 
499  $instance->populateSelected();
500  $instance->columnOrder = $report->column_order;
501  $instance->report_id = $report_id;
502  return $instance;
503  }
504  else if (startsWith($report_id, "tmp-"))
505  {
506  $proto = unserialize($_SESSION[$report_id]);
507  $cl = get_class($proto);
508  $instance = new $cl;
509  $instance->request = $proto->request;
510  $instance->populateSelected();
511  $instance->columnOrder = $report->column_order;
512  $instance->report_id = 0;
513  return $instance;
514  }
515  else
516  {
517  throw new FakoliException("Invalid report id");
518  }
519  }
FakoliException is the base exception class for all Fakoli errors.
Definition: core.inc:53
$report_id
ID of the saved report as persisted in the database.
$mode
$_SESSION["useMobile"]
Definition: override.inc:7

◆ populateSelected()

ReportManager::populateSelected ( )

Definition at line 253 of file report_manager.inc.

254  {
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"];
257 
258  foreach($this->tables as $table)
259  {
260  if ($this->request["table_{$table->class}"])
261  {
262  $this->setSelected($table);
263  }
264  $table->load($this->request);
265  }
266 
267  if(count($this->selected) == 0)
268  {
269  $this->setSelected($this->tables[0], false);
270  }
271 
272  }
setSelected($table, $checkRequest=true)
Set the given table as selected.

◆ preSaveReport()

ReportManager::preSaveReport ( )

Alternative implementation - presave version of report is stored in session with a.

Definition at line 449 of file report_manager.inc.

450  {
451  global $user;
452 
453  if (!$this->report_id)
454  {
455  $sleeper = serialize($this);
456  $mgr = new UserManager();
457 
458  $this->report_id = "tmp-" .sha1($user->get($mgr->getUsernameField()) . $sleeper . now());
459  $_SESSION[$this->report_id] = $sleeper;
460  $_SESSION[$this->report_id . "-class"] = get_class($this);
461  }
462  }
Provides the interface to the user model for the application.

◆ ReportManager()

ReportManager::ReportManager ( )

Creates a new ReportManager instance.

Definition at line 137 of file report_manager.inc.

138  {
139  $this->selected = null;
140 
141  $this->report_id = 0;
142  $this->tables = array();
143  $this->request = $_REQUEST; // For config serialization
144  if ($this->request["custom_report_mode"] == "save")
145  {
146  $this->title = $this->request["custom_report_title"];
147  $this->description = $this->request["custom_report_description"];
148  }
149  }

◆ save()

ReportManager::save ( )

Definition at line 464 of file report_manager.inc.

465  {
466  global $user;
467 
468  $report = new CustomReport();
469  $report->report_id = $this->report_id;
470  $report->title = $this->title;
471  $report->description = $this->description;
472  $report->user_id = $user->user_id;
473  $report->configuration = serialize($this);
474  $report->manager_class = get_class($this);
475  $report->column_order = $this->columnOrder;
476 
477  $report->save();
478 
479  $this->report_id = $report->report_id;
480  }
$columnOrder
Override the default column order.
$description
Longer description of the report.

◆ setSelected()

ReportManager::setSelected (   $table,
  $checkRequest = true 
)

Set the given table as selected.

Parameters
ReportTable$tablethe table to select
boolean$checkRequestthe check request flag

Definition at line 280 of file report_manager.inc.

281  {
282  $table->selected = true;
283  $this->selected["table_{$table->class}"] = true;
284  //$this->constraint .= $table->getConstraint($first, $this->request);
285 
286  $colCount = 0;
287  foreach($table->columns as $column)
288  {
289  $col = "column_".codify($column->title);
290  if ($this->request[$col] || !$checkRequest)
291  {
292  $column->selected = true;
293  $this->selected[$col] = true;
294  $colCount ++;
295  }
296  }
297 
298  if($colCount == 0)
299  $this->setSelected($table, false);
300  }

◆ table()

ReportManager::table (   $class,
  $title = "",
  $useOutputFilter = false 
)

Add a table to the report.

Parameters
string$classthe DataItem class representing the table in the datamodel
string$title(optional) the title to present to the user in the configuration interface

Definition at line 167 of file report_manager.inc.

168  {
169  $table = new ReportTable($class, $title, $this->request, $useOutputFilter);
170  $this->tables[] = $table;
171  return $table;
172  }

◆ writeResultsFormButtons()

ReportManager::writeResultsFormButtons (   $excel)

Definition at line 436 of file report_manager.inc.

437  {
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 "&nbsp;&nbsp;<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&nbsp;&nbsp;<a class='button' href='#' onclick='ReportManager.createReportDialog();return false;'><i class='fa-fw fas fa-plus'></i> Create a New Report</a></p>\n";
443  }
$editorPage
The page used to display the report editor.
if(! $blog->published||! $blog->enable_rss_feed||!checkRole($blog->allow_read)) $url
Definition: rss.inc:58

Member Data Documentation

◆ $columnOrder

ReportManager::$columnOrder

Override the default column order.

Definition at line 126 of file report_manager.inc.

◆ $description

ReportManager::$description

Longer description of the report.

Definition at line 122 of file report_manager.inc.

◆ $editorPage

ReportManager::$editorPage = "custom_report"

The page used to display the report editor.

Definition at line 124 of file report_manager.inc.

◆ $interstitialMessage

ReportManager::$interstitialMessage = ""

Optional interstitial message to display while report is being generated.

Definition at line 131 of file report_manager.inc.

◆ $join

ReportManager::$join

Definition at line 128 of file report_manager.inc.

◆ $limit

ReportManager::$limit

Optional limit to number of records retrieved, depending on acceptable load times for results.

Definition at line 132 of file report_manager.inc.

◆ $report

ReportManager::$report

Definition at line 129 of file report_manager.inc.

◆ $report_id

ReportManager::$report_id

ID of the saved report as persisted in the database.

Definition at line 120 of file report_manager.inc.

◆ $request

ReportManager::$request

Definition at line 130 of file report_manager.inc.

◆ $resultsPage

ReportManager::$resultsPage = "custom_report_results"

The page used to display the search results.

Definition at line 123 of file report_manager.inc.

◆ $tables

ReportManager::$tables

Definition at line 127 of file report_manager.inc.

◆ $target

ReportManager::$target

The target window for the form results.

Definition at line 125 of file report_manager.inc.

◆ $title

ReportManager::$title

Title of the report.

Definition at line 121 of file report_manager.inc.


The documentation for this class was generated from the following file: