This was an experiment, but was later (before Tiki19) removed and reports are much better done via PluginList and PluginTrackerList.

New feature in Tiki9

Tiki Report is a new way of creating and extracting data from Tiki in version 9 (trunk at time of writing). They consist of an abstract way of assembling each phase needed to create reports.

You create a Report Definition in which you define an input method, that returns what is possible in your report, and then an output method, that is your desired report criteria based on user input. The report user interface is automatically generated based off of the input method.

The aim with Reports is to eventually have saveable, reusable reports, that generate live data for use in a dashboard or spreadsheet.

Bugs & Wishes

Open and Pending



Things to keep in mind

  • Files in lib/core/Report folder are used for report building
  • Files in /lib/core/Report/Definition/ are those used to define first what reports can be generated and then their output, unless further developing how reports are generated
    • These files are automatically listed, they probably need feature detection

How to create a definition

  • Definitions are an abstract on what can be created from your report

Basic Generic Definition (copy to /lib/core/Report/Definition or name "Generic.php"):

class Report_Definition_Generic
	function input()
	{//here we tell report what we can build with out report
		return array("values"=>array(),"options"=>array());

	function output($values = array())
	{//here we assemble report based off of
		return $myGenericReportObject->assemble($values);

Example for Tracker Definition:

class Report_Definition_Tracker
	function input() {
		global $tikilib;
		$trackers = array();
		foreach($tikilib->table('tiki_trackers')->fetchAll(array('trackerId','name')) as $column) {
			$trackers[] = array(
				"name"=> $column['name'] . ' - ' . $column['trackerId'],
				"value"=> $column['trackerId'],
		$trackerFields = array();
		foreach($tikilib->table('tiki_tracker_fields')->fetchAll(array('trackerId', 'fieldId', 'name')) as $column) {
			$trackerFields[] = array(
				"name"=> $column['name'] . ' - ' . $column['fieldId'],
				"value"=> $column['fieldId'],
				"dependancy"=> $column['trackerId'],

				single (if value, turns into list, if no value, is textbox)
				multi (needs value, is checkbox)
				date	(simple date range)
				singeOneToOne (
		return array(
			"values"=> array(
				"trackers"=>		$trackers,
				"trackerFields"=>	$trackerFields,
				"trackerItemStatus"=>array("o", "p", "c"),
			"options"=> array(
					"label"=> 		tr("Tracker"),
					"name"=> 		"tracker",
					"type"=> 		"single",
					"values"=> 		"trackers",
					"repeats"=>		false,
					"required"=>	true,
					"options" =>	array(
							"label"=> 		tr("Start"),
							"name"=> 		"start",
							"type"=> 		"date",
							"repeats"=>		false,
							"required"=>	false,
							"label"=> 		tr("End"),
							"name"=> 		"end",
							"type"=> 		"date",
							"repeats"=>		false,
							"required"=>	false,
							"label"=> 		tr("Item Id"),
							"name"=> 		"itemId",
							"type"=> 		"single",
							"repeats"=>		false,
							"required"=>	false,
							"label"=> 		tr("Status"),
							"name"=> 		"status",
							"type"=> 		"multi",
							"values"=> 		"trackerItemStatus",
							"repeats"=>		false,
							"required"=>	false,
							"label"=> 		tr("Search"),
							"relationLabel"=>tr(" for "),
							"name"=> 		"search",
							"type"=> 		"singleOneToOne",
							"dependancy"=>	array("tracker"),
							"values"=> 		array("trackerFields"),
							"repeats"=>		true,
							"required"=>	false,
							"label"=> 		tr("Fields"),
							"name"=> 		"fields",
							"type"=> 		"multi",
							"dependancy"=>	"tracker",
							"values"=> 		"trackerFields",
							"repeats"=>		false,
							"required"=>	false,
	function output($values = array())
		global $tikilib;
		$tracker = $values['tracker'];
		$qry = TikiLib::lib('trkqry')->tracker($tracker['value'])
		if (!empty($tracker['status'])) {
			$allStatus = '';
			foreach($tracker['status'] as $status) {
				if (!empty($status['value'])) $allStatus .= $status['value'];
		if (!empty($tracker['search'])) {
			$fieldIds = array();
			$search = array();
			for($i = 0; $i < count($tracker['search']); $i++) {
				if (!empty($tracker['search'][$i]) && $tracker['search'][$i + 1]) {
					$fieldIds[] = $tracker['search']['value'][$i];
					$search[] = $tracker['search']['value'][$i + 1];
				$i++			; //searches are in groups of 2
			if (!empty($fieldIds) && !empty($search)) {
		$result = $qry->query(); 
		if (!empty($tracker['fields'])) {
			$newResult = array();
			foreach($result as $itemKey => $item) {
				$newResult[$itemKey] = array();
				foreach($tracker['fields'] as $field) {
					$newResult[$itemKey][$field['value']] = $result[$itemKey][$field['value']]; 
			$result = $newResult;
		return $result;

Array value from input has 2 possible keys values(optional) & options(required)

Creating report values

each key in values is a sub-array with the following keys:
name - User Interface Name, please use tr() when possible
value - selectable and returned value
dependancy - parent value dependancy (optional)

Creating reportable options

Options consist of the following variables and are nestable:

  • label - What it will be called on the user interface, please use tr() when possible
  • name - The array name what it will be returned as
  • type - How it is going to be treated on the user interface
    • Acceptable types: single, date, multi, singleOneToOne
  • values - will link with values key at user interface
    • If type set to single, will give select (drop down list of options)
  • repeats - not yet working
  • required - not yet working
  • options - nested option(s)

Example 1

  • Create a new wiki page, for example, wikiReport
  • Paste this simple text into it:
  • Save the wiki page.
  • Click the pencil edit icon to edit the page you just saved.
  • A report plugin configuration panel will pop up.
  • Perhaps select the Report Type "Tracker". Select one of your trackers and a couple of fields from that tracker.
  • Complete that panel and save it.
  • On your wikiReport page, you should now see a table, non-editable, of your tracker data.

Example 2

  • This process is still under construction...
  • Create a file on your webserver:
  • Paste into that file the ~150+ lines of code from the "Example for Tracker Definition" above.
  • Save that file.
  • Follow Example 1 immediately above, but instead of selecting Report Type "Tracker", you will see your new report design "TestReport" in the Report Type drop down list.


Show PHP error messages