<?php
|
|
|
|
// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
|
|
//
|
|
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
|
|
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
|
|
// $Id$
|
|
|
|
function wikiplugin_trackerlist_info()
|
|
{
|
|
$ts = new Table_Plugin();
|
|
$ts->createParams();
|
|
$tsparams = $ts->params;
|
|
$params = array_merge(
|
|
[
|
|
'trackerId' => [
|
|
'required' => true,
|
|
'name' => tra('Tracker ID'),
|
|
'description' => tra('Numeric value representing the tracker ID'),
|
|
'since' => '1',
|
|
'filter' => 'digits',
|
|
'default' => '',
|
|
'profile_reference' => 'tracker',
|
|
],
|
|
'fields' => [
|
|
'required' => false,
|
|
'name' => tra('Fields'),
|
|
'description' => tr('Colon-separated list of field IDs for the fields to be displayed.
|
|
Example: %02:4:5%1. The field order specified here determines the column order if the %0sort%1
|
|
parameter is set to %0y%1.', '<code>', '</code>'),
|
|
'since' => '1',
|
|
'filter' => 'digits',
|
|
'separator' => ':',
|
|
'default' => '',
|
|
'profile_reference' => 'tracker_field',
|
|
'parent' => 'input[name="params[trackerId]"]',
|
|
'parentkey' => 'tracker_id',
|
|
],
|
|
'sort' => [
|
|
'required' => false,
|
|
'name' => tra('Sort'),
|
|
'description' => tr('Display columns in the order listed in the %0fields%1 parameter instead of by
|
|
field ID (field ID order is used by default', '<code>', '</code>'),
|
|
'since' => '2.0',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'popup' => [
|
|
'required' => false,
|
|
'name' => tra('Popup'),
|
|
'description' => tr('Colon-separated list of fields which will display in a tooltip on mouse over.
|
|
Example: %06:7%1. Setting this parameter implies %0y%1 value for %0sort%1 param.', '<code>', '</code>'),
|
|
'since' => '2.0',
|
|
'filter' => 'digits',
|
|
'separator' => ':',
|
|
'default' => '',
|
|
],
|
|
'stickypopup' => [
|
|
'required' => false,
|
|
'name' => tra('Sticky Popup'),
|
|
'description' => tra('Choose whether the popup tooltip will stay displayed on mouse out (does not stay open by default)'),
|
|
'since' => '2.0',
|
|
'filter' => 'alpha',
|
|
'default' => '',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showtitle' => [
|
|
'required' => false,
|
|
'name' => tra('Show Title'),
|
|
'description' => tra('Display the title of the tracker (not shown by default)'),
|
|
'since' => '1',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showlinks' => [
|
|
'required' => false,
|
|
'name' => tra('Show Links'),
|
|
'description' => tra('Show links to each tracker item (not shown by default). At least one field needs
|
|
to be set as Public in order for this to work.'),
|
|
'since' => '1',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n'],
|
|
['text' => tra('Row'), 'value' => 'r']
|
|
]
|
|
],
|
|
'showdesc' => [
|
|
'required' => false,
|
|
'name' => tra('Show Description'),
|
|
'description' => tra('Show the tracker\'s description (not shown by default)'),
|
|
'since' => '1',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'shownbitems' => [
|
|
'required' => false,
|
|
'name' => tra('Show Item Count'),
|
|
'description' => tra('Show the number of items found (not shown by default)'),
|
|
'since' => '2.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showinitials' => [
|
|
'required' => false,
|
|
'name' => tra('Show Initials'),
|
|
'description' => tra('Show an alphabetical index by first letter to assist in navigation (not shown
|
|
by default)'),
|
|
'since' => '1',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showstatus' => [
|
|
'required' => false,
|
|
'name' => tra('Show Status'),
|
|
'description' => tra('Show the status of the items (not shown by default)'),
|
|
'since' => '1',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showcreated' => [
|
|
'required' => false,
|
|
'name' => tra('Show Creation Date'),
|
|
'description' => tra('Creation date display is based on tracker settings unless overridden here'),
|
|
'since' => '2.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => '',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showlastmodif' => [
|
|
'required' => false,
|
|
'name' => tra('Last Modification Date'),
|
|
'description' => tra('Last modification date display is based on tracker settings unless overridden here'),
|
|
'since' => '2.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => '',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showlastmodifby' => [
|
|
'required' => false,
|
|
'name' => tra('Last modified by'),
|
|
'description' => tra('Last modified by user display is based on tracker settings unless overridden here'),
|
|
'since' => '14.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => '',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showfieldname' => [
|
|
'required' => false,
|
|
'name' => tra('Show Field Name'),
|
|
'description' => tra('Use the field names as column titles (used by default)'),
|
|
'since' => '1',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'y',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showitemrank' => [
|
|
'required' => false,
|
|
'name' => tra('Show Item Rank'),
|
|
'description' => tra('Show item ranks (not shown by default)'),
|
|
'since' => '4.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showcomments' => [
|
|
'required' => false,
|
|
'name' => tra('Show Comments'),
|
|
'description' => tra('Show comments count or last comment date and user depending on tracker preferences'),
|
|
'since' => '16.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'y',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'status' => [
|
|
'required' => false,
|
|
'name' => tra('Status Filter'),
|
|
'description' => tra('Only show items matching certain status filters (only items with open status shown by default)'),
|
|
'since' => '1',
|
|
'doctype' => 'filter',
|
|
'filter' => 'alpha',
|
|
'default' => 'o',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Open'), 'value' => 'o'],
|
|
['text' => tra('Pending'), 'value' => 'p'],
|
|
['text' => tra('Closed'), 'value' => 'c'],
|
|
['text' => tra('Open & Pending'), 'value' => 'op'],
|
|
['text' => tra('Open & Closed'), 'value' => 'oc'],
|
|
['text' => tra('Pending & Closed'), 'value' => 'pc'],
|
|
['text' => tra('Open, Pending & Closed'), 'value' => 'opc']
|
|
]
|
|
],
|
|
'sort_mode' => [
|
|
'required' => false,
|
|
'name' => tra('Sort Mode'),
|
|
'description' => tra('Sort rows in ascending (_asc) or descending (_desc) order based on field ID,
|
|
date created or date last modified'),
|
|
'accepted' => 'created_asc, created_desc, lastModif_asc, lastModif_desc, f_fieldId_asc, f_filedId_desc '
|
|
. tr('(replacing %0fieldId%1 with the field ID number, e.g. %0f_3_asc%1)', '<code>', '</code>'),
|
|
'since' => '1',
|
|
'filter' => 'word',
|
|
'default' => '',
|
|
'profile_reference' => 'tracker_field_string',
|
|
],
|
|
'sortchoice' => [
|
|
'required' => false,
|
|
'name' => tra('Sort Choice'),
|
|
'description' => tr(
|
|
'Add a dropdown of sorting choices. Separate each choice with a %0:%1. For each
|
|
choice, use the format %0value|label%1. See %0sort_mode%1 for value choices. Example with two
|
|
sorting choices: %0sortchoice="created_desc|Newest first:lastModif_desc|Last modified first"%1',
|
|
'<code>',
|
|
'</code>'
|
|
),
|
|
'since' => '5.0',
|
|
'filter' => 'text',
|
|
'separator' => ':',
|
|
'default' => '',
|
|
],
|
|
'max' => [
|
|
'required' => false,
|
|
'name' => tra('Maximum Items'),
|
|
'description' => tra('Maximum number of items to display or -1 for all items. Defaults to max records
|
|
preference, if set. Pagination will not show if all items are shown by setting to -1.'),
|
|
'since' => '1',
|
|
'doctype' => 'filter',
|
|
'filter' => 'int',
|
|
'default' => '',
|
|
],
|
|
'offset' => [
|
|
'required' => false,
|
|
'name' => tra('Offset'),
|
|
'description' => tra('Offset of first item. Default is no offset.'),
|
|
'since' => '6.0',
|
|
'doctype' => 'filter',
|
|
'filter' => 'int',
|
|
'default' => 0,
|
|
],
|
|
'forceoffset' => [
|
|
'required' => false,
|
|
'name' => tra('Fix offset always (no pagination)'),
|
|
'description' => tra('Fix offset to that specified. This will disallow pagination.'),
|
|
'since' => '8.0',
|
|
'doctype' => 'filter',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showpagination' => [
|
|
'required' => false,
|
|
'name' => tra('Show Pagination'),
|
|
'description' => tra('Determines whether pagination will be shown (shown by default)'),
|
|
'since' => '4.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'y',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'allowtableexpansion' => [
|
|
'required' => false,
|
|
'name' => tra('Show button to make entire width of tables visible'),
|
|
'description' => tra('Show a toggle button to allow wide tables to overflow to the right of the content area rather than be scrollable in a limited-width area (not by default).'),
|
|
'since' => '18.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'filterfield' => [
|
|
'required' => false,
|
|
'name' => tra('Filter Field'),
|
|
'description' => tra('Colon-separated list of fields to allow filtering on.'),
|
|
'since' => '1',
|
|
'doctype' => 'filter',
|
|
'filter' => 'digits',
|
|
'separator' => ':',
|
|
'default' => '',
|
|
'profile_reference' => 'tracker_field',
|
|
'parent' => 'input[name="params[trackerId]"]',
|
|
'parentkey' => 'tracker_id',
|
|
],
|
|
'filtervalue' => [
|
|
'required' => false,
|
|
'name' => tra('Filter Value'),
|
|
'description' => tr('Filter value (or multiple values) that correspond to %0filterfield%1. For better performance, use %0exactvalue%1
|
|
instead. %2Special search values to match:', '<code>', '</code>', '<br>') . '<br>'
|
|
. '<code>*value</code> - ' . tra('text that ends in "value"') . '<br>'
|
|
. '<code>value*</code> - ' . tra('text that begins with "value"') . '<br>'
|
|
. '<code>#user</code> - ' . tra('the current user\'s login name') . '<br>'
|
|
. '<code>#group_default</code> - ' . tra('the current user\'s default group') . '.<br>'
|
|
. tr('To filter by empty/non-empty values, use parameter %0exactvalue%1 instead', '<code>', '</code>') . '<br>',
|
|
'since' => '1',
|
|
'doctype' => 'filter',
|
|
'accepted' => tra('any text'),
|
|
'filter' => 'text',
|
|
'separator' => ':',
|
|
'default' => '',
|
|
],
|
|
'exactvalue' => [
|
|
'required' => false,
|
|
'name' => tra('Exact Value'),
|
|
'description' => tr('Exact value (or multiple values) that correspond to %0filterfield%1. %2Special
|
|
search values to filter by:', '<code>', '</code>', '<br>') . '<br>'
|
|
. '<code>categories(x)</code> - ' . tra('tracker item is in category with ID x or one its descendants') . '<br>'
|
|
. '<code>notcategories(x)</code> - ' . tra('tracker item is not in category with ID x or one of its descendants') . '<br>'
|
|
. '<code>preference(name)</code> - ' . tra('match against the value of a Tiki preference') . '<br>'
|
|
. '<code>notpreference(name)</code> - ' . tra('match if value does not equal a Tiki preference value') . '<br>'
|
|
. '<code>not(value)</code> - ' . tra('match if the field does not equal "value"') . '<br>'
|
|
. '<code>not()</code> - ' . tr('match for non empty values (opposite with %0exactvalue%1="")', '<code>', '</code>') . '<br>'
|
|
. '<code>or(value1,value2)</code> - ' . tra('match if the field equals "value1" or "value2" (can list more than 2 alternative values)') . '<br>'
|
|
. '<code>field(x, itemid)</code> - ' . tr('match field with ID x in item with ID itemid.
|
|
%0field(x)%1 can be used if the %0itemId%1 URL parameter is set', '<code>', '</code>') . '<br>'
|
|
. '<code>notfield(x, itemid)</code> - ' . tr('match if not equal to field with ID x in item with ID itemid
|
|
%0field(x)%1 can be used if the %0itemId%1 URL parameter is set', '<code>', '</code>') . '<br>'
|
|
. tr('The following comparisons can also be applied to date fields by using date phrases that PHP recognizes
|
|
(see http://us.php.net/manual/en/function.strtotime.php ):', '<code>', '</code>') . '<br>'
|
|
. '<code>less(value)</code> - ' . tra('match if less than "value"') . '<br>'
|
|
. '<code>greater(value)</code> - ' . tra('match if greater than "value"') . '<br>'
|
|
. '<code>lessequal(value)</code> - ' . tra('match if less than or equal to "value"') . '<br>'
|
|
. '<code>greaterequal(value)</code> - ' . tra('match if greater than or equal to "value"') . '<br>',
|
|
'since' => '1',
|
|
'doctype' => 'filter',
|
|
'accepted' => tra('any text'),
|
|
'filter' => 'text',
|
|
'separator' => ':',
|
|
'default' => '',
|
|
],
|
|
'checkbox' => [
|
|
'required' => false,
|
|
'name' => tra('Checkbox'),
|
|
'description' => tr('Adds a checkbox on each line to perform an action. Required elements are separated
|
|
by %0/%1. Those elements are:', '<code>', '</code>') . '<br />'
|
|
. '<code>FieldId</code> - ' . tra('the value of this field will be posted to the action') . '<br>'
|
|
. '<code>PostName</code> - ' . tra('the name of the post') . '<br>'
|
|
. '<code>Title</code> - ' . tra('the title of the submit button') . '<br>'
|
|
. '<code>Submit</code> - ' . tra('the name of the submit button') . '<br>'
|
|
. '<code>ActionUrl</code> - ' . tra('the file that will be called upon submit') . '<br>'
|
|
. '<code>Tpl</code> - ' . tra('optional template inserted before the submit button and returned') . '<br>'
|
|
. '<code>SelectType</code> - ' . tr('Leave empty for multiple select, or use %0dropdown%1 or
|
|
%0radio%1.', '<code>', '</code>') . '<br>'
|
|
. '<code>Embed</code> - ' . tra('Set to %0y%1 if the trackerlist table is embedded inside an existing form.
|
|
ActionUrl is ignored in this case.', '<code>', '</code>') . '<br>'
|
|
. '<code>Checked</code> - ' . tra('comma-separated list of pre-checked items') . '<br>'
|
|
. tr(
|
|
'Format: %0checkbox="FieldId/PostName/Title/Submit/ActionUrl/Tpl/SelectType/Embed/Checked"%1',
|
|
'<code>',
|
|
'</code>'
|
|
) . '<br />'
|
|
. tr(
|
|
'Example: %0checkbox="6/to/Email to selected/submit/messu-compose.php//dropdown//1,2,3"%1',
|
|
'<code>',
|
|
'</code>'
|
|
) . '<br />',
|
|
'since' => '1',
|
|
'doctype' => 'show',
|
|
'advanced' => true,
|
|
'default' => '',
|
|
],
|
|
'goIfOne' => [
|
|
'required' => false,
|
|
'name' => tra('goIfOne'),
|
|
'description' => tra('Display the item rather than list if only one item is found'),
|
|
'since' => '1',
|
|
'doctype' => 'filter',
|
|
'filter' => 'alpha',
|
|
'advanced' => true,
|
|
'default' => '',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'more' => [
|
|
'required' => false,
|
|
'name' => tra('More'),
|
|
'description' => tra('Show a \'more\' button that links to the tracker item (not shown by default)'),
|
|
'since' => '2.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'moreurl' => [
|
|
'required' => false,
|
|
'name' => tra('More URL'),
|
|
'description' => tra('More link pointing to specified URL instead of default tracker item link'),
|
|
'since' => '2.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'url',
|
|
'default' => 'tiki-view_tracker.php',
|
|
],
|
|
'view' => [
|
|
'required' => false,
|
|
'name' => tra('View'),
|
|
'description' => tr('Display only the items of the following:') . '<br />'
|
|
. '<code>user</code> - ' . tra('the current user') . '<br>'
|
|
. '<code>group</code> - ' . tra('the current user\'s groups') . '<br>'
|
|
. '<code>page</code> - ' . tra('the current page name') . '<br>'
|
|
. '<code>ip</code> - ' . tra('the current IP address') . '<br>',
|
|
'since' => '2.0',
|
|
'doctype' => 'filter',
|
|
'filter' => 'alpha',
|
|
'advanced' => true,
|
|
'default' => '',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Page'), 'value' => 'page'],
|
|
['text' => tra('User'), 'value' => 'user'],
|
|
['text' => tra('Group'), 'value' => 'group'],
|
|
['text' => tra('IP address'), 'value' => 'ip']
|
|
]
|
|
],
|
|
'tpl' => [
|
|
'required' => false,
|
|
'name' => tra('Template File'),
|
|
'description' => tr('Use content of the specified tpl file as template to display the item.
|
|
Use %0{$f_fieldId}%1 to display a field with ID %0fieldId%1.', '<code>', '</code>'),
|
|
'since' => '2.0',
|
|
'advanced' => true,
|
|
'default' => '',
|
|
],
|
|
'wiki' => [
|
|
'required' => false,
|
|
'name' => tra('Wiki Page'),
|
|
'description' => tr('Use content of the wiki page as template to display the item. The page should
|
|
have the permission %0tiki_p_use_as_template%1 set, and should only be editable by trusted users
|
|
such as other site admins', '<code>', '</code>'),
|
|
'since' => '2.0',
|
|
'filter' => 'pagename',
|
|
'advanced' => true,
|
|
'default' => '',
|
|
'profile_reference' => 'wiki_page',
|
|
],
|
|
'tplwiki' => [
|
|
'required' => false,
|
|
'name' => tra('Template Wiki Page'),
|
|
'description' => tr('Use content of the wiki page as template to display the item but with as little
|
|
parsing on the content as with a tpl on disk. The page should have the permission
|
|
%0tiki_p_use_as_template%1 set, and should only be editable by trusted users such as other site
|
|
admins', '<code>', '</code>'),
|
|
'since' => '6.5 & 7.1',
|
|
'filter' => 'pagename',
|
|
'advanced' => true,
|
|
'default' => '',
|
|
'profile_reference' => 'wiki_page',
|
|
],
|
|
'view_user' => [
|
|
'required' => false,
|
|
'name' => tra('View User'),
|
|
'description' => tra('Will display the items of the specified user'),
|
|
'since' => '2.0',
|
|
'doctype' => 'filter',
|
|
'default' => '',
|
|
],
|
|
'itemId' => [
|
|
'required' => false,
|
|
'name' => tra('Item ID'),
|
|
'description' => tra('Colon-separated list of item IDs to restrict the listing to'),
|
|
'since' => '2.0, multiple since 3.0',
|
|
'doctype' => 'filter',
|
|
'filter' => 'digits',
|
|
'separator' => ':',
|
|
'default' => '',
|
|
'profile_reference' => 'tracker_item',
|
|
],
|
|
'ignoreRequestItemId' => [
|
|
'required' => false,
|
|
'name' => tra('Ignore ItemId'),
|
|
'description' => tra('Ignore the itemId url parameter when filtering list (not ignored by default)'),
|
|
'since' => '5.0',
|
|
'doctype' => 'filter',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'advanced' => true,
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'url' => [
|
|
'required' => false,
|
|
'name' => tra('URL'),
|
|
'description' => tr(
|
|
'The link that will be on each main field when %0showlinks="y"%1. Special values:',
|
|
'<code>',
|
|
'</code>'
|
|
) . '<br>'
|
|
. '<code>url="mypage?<strong>itemId</strong>"</code> - '
|
|
. tra('will link to the item based on its item ID') . '<br>'
|
|
. '<code>url="mypage?<strong>tr_offset</strong>"</code> - '
|
|
. tra('will link to the item based on its offset value') . '<br>'
|
|
. '<code>url="<strong>sefurl</strong>"</code> - '
|
|
. tr('will link to the item using %0itemX%1 (where X is the item ID) for when SEFURL is being
|
|
used', '<code>', '</code>') . '<br>'
|
|
. '<code><strong>vi_tpl</strong></code> - ' . tr('use to show the item without admin buttons and with a back button
|
|
when using a template (Display > Section Format must be set to "Configured" in the tracker
|
|
properties). Example:', '<code>', '</code>')
|
|
. ' <code>url="tiki-view_tracker_item.php?<strong>vi_tpl</strong>=wiki:PageName&itemId"</code><br>'
|
|
. '<code><strong>ei_tpl</strong></code> - ' . tr('similar to %0vi_tpl%1 except that admin buttons are shown for users
|
|
with proper permissions when "Restrict non admins to wiki page access only" is set in the
|
|
tracker properties.', '<code>', '</code>') . '<br>',
|
|
'since' => tr(
|
|
'2.0, 3.0 for %0itemId%1, 11.0 for %0tr_offset%1, 14.0 for %0sefurl%1 and %0vi_tpl%1',
|
|
'<code>',
|
|
'</code>'
|
|
),
|
|
'doctype' => 'show',
|
|
'parentparam' => ['name' => 'showlinks', 'value' => 'y'],
|
|
'filter' => 'url',
|
|
'default' => '',
|
|
],
|
|
'ldelim' => [
|
|
'required' => false,
|
|
'name' => tra('Left Delimiter'),
|
|
'description' => tra('Smarty left delimiter for Latex generation. Example:') . '<code>@{</code>',
|
|
'since' => '2.0',
|
|
'advanced' => true,
|
|
'default' => '{',
|
|
],
|
|
'rdelim' => [
|
|
'required' => false,
|
|
'name' => tra('Right Delimiter'),
|
|
'description' => tra('Smarty right delimiter for Latex generation Example:') . '<code>}@</code>',
|
|
'since' => '2.0',
|
|
'advanced' => true,
|
|
'default' => '}',
|
|
],
|
|
'list_mode' => [
|
|
'required' => false,
|
|
'name' => tra('List Mode'),
|
|
'description' => tra('Set output format. Yes (y) displays tracker list view with truncated values
|
|
(default); No (n) displays in tracker item view; Comma Separated Values (csv) outputs without any
|
|
HTML formatting.'),
|
|
'since' => '3.0',
|
|
'filter' => 'alpha',
|
|
'default' => 'y',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n'],
|
|
['text' => tra('Comma Separated Values'), 'value' => 'csv']
|
|
]
|
|
],
|
|
'export' => [
|
|
'required' => false,
|
|
'name' => tra('Export Button'),
|
|
'description' => tra('Show an export button (not shown by default)'),
|
|
'since' => '3.0',
|
|
'filter' => 'alpha',
|
|
'advanced' => true,
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'compute' => [
|
|
'required' => false,
|
|
'name' => tra('Compute'),
|
|
'description' => tra('Sum or average all the values of a field and displays it at the bottom of the
|
|
table.') . ' <code>' . tra('fieldId') . '/sum:' . tra('fieldId') . '/avg</code>',
|
|
'since' => '3.0',
|
|
'filter' => 'text',
|
|
'accepted' => tr('%0, separated by %1', '<code>fieldId/operator</code>', '<code>:</code>'),
|
|
'advanced' => true,
|
|
'default' => '',
|
|
'profile_reference' => 'tracker_field_string',
|
|
],
|
|
'silent' => [
|
|
'required' => false,
|
|
'name' => tra('Silent'),
|
|
'description' => tra('Show nothing if no items found (the table header and a \'No records found\'
|
|
message is shown by default).'),
|
|
'since' => '4.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => '',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showdelete' => [
|
|
'required' => false,
|
|
'name' => tra('Show Delete'),
|
|
'description' => tra('Show a delete icon for each item (not shown by default)'),
|
|
'since' => '4.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'urlafterdelete' => [
|
|
'required' => false,
|
|
'name' => tra('Url to redirect to after delete'),
|
|
'description' => tra('Url to redirect to after delete'),
|
|
'since' => '11.0',
|
|
'filter' => 'url',
|
|
'default' => '',
|
|
],
|
|
'showopenitem' => [
|
|
'required' => false,
|
|
'name' => tra('Show Open Item'),
|
|
'description' => tra('Show an open item option (not shown by default)'),
|
|
'since' => '8.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showcloseitem' => [
|
|
'required' => false,
|
|
'name' => tra('Show Close Item'),
|
|
'description' => tra('Show a close item option (not shown by default)'),
|
|
'since' => '8.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showpenditem' => [
|
|
'required' => false,
|
|
'name' => tra('Show Pending Item'),
|
|
'description' => tra('Show a pending item option (not shown by default)'),
|
|
'since' => '8.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showwatch' => [
|
|
'required' => false,
|
|
'name' => tra('Show Watch Button'),
|
|
'description' => tra('Show a watch button (not shown by default)'),
|
|
'since' => '5.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => '',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showrss' => [
|
|
'required' => false,
|
|
'name' => tra('Show Feed Button'),
|
|
'description' => tra('Show an RSS feed button (not shown by default)'),
|
|
'since' => '5.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'showmap' => [
|
|
'required' => false,
|
|
'name' => tra('Show Results Map'),
|
|
'description' => tra('Show Map of results (not shown by default)'),
|
|
'since' => '12.0',
|
|
'doctype' => 'show',
|
|
'filter' => 'alpha',
|
|
'default' => '',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'calendarfielddate' => [
|
|
'required' => false,
|
|
'name' => tra('Calendar Field IDs'),
|
|
'description' => tr('Used to display items in a calendar view. One fieldId if one date, or 2 fieldIds
|
|
separated with %0:%1 for %0start:end%1', '<code>', '</code>'),
|
|
'since' => '6.0',
|
|
'doctype' => 'calendar',
|
|
'separator' => ':',
|
|
'filter' => 'digits',
|
|
'default' => '',
|
|
'profile_reference' => 'tracker_field',
|
|
'parent' => 'input[name="params[trackerId]"]',
|
|
'parentkey' => 'tracker_id',
|
|
],
|
|
'calendarviewmode' => [
|
|
'required' => false,
|
|
'name' => tra('Calendar View Mode'),
|
|
'description' => tra('Calendar view type time span (default is month)'),
|
|
'since' => '6.0',
|
|
'doctype' => 'calendar',
|
|
'filter' => 'word',
|
|
'default' => 'month',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Month'), 'value' => 'month'],
|
|
['text' => tra('Two months'), 'value' => 'bimester'],
|
|
['text' => tra('Trimester'), 'value' => 'trimester'],
|
|
['text' => tra('Quarter'), 'value' => 'quarter'],
|
|
['text' => tra('Semester'), 'value' => 'semester'],
|
|
['text' => tra('Year'), 'value' => 'year']
|
|
]
|
|
],
|
|
'calendarpopup' => [
|
|
'required' => false,
|
|
'name' => tra('Calendar Popup'),
|
|
'description' => tr('Calendar items will popup, overrides the %0stickypopup%1 parameter if turned off
|
|
(default is to pop up).', '<code>', '</code>'),
|
|
'since' => '6.0',
|
|
'doctype' => 'calendar',
|
|
'filter' => 'alpha',
|
|
'default' => 'y',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
],
|
|
],
|
|
'calendarstickypopup' => [
|
|
'required' => false,
|
|
'name' => tra('Sticky Popup'),
|
|
'description' => tra('Calendar item popups will stay open if set to y (Yes). Not sticky by default'),
|
|
'since' => '6.0',
|
|
'doctype' => 'calendar',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'calendarbeginmonth' => [
|
|
'required' => false,
|
|
'name' => tra('Beginning of Month'),
|
|
'description' => tra('Set whether calendar will begin at the beginning of the month (does by default).'),
|
|
'since' => '6.0',
|
|
'doctype' => 'calendar',
|
|
'filter' => 'alpha',
|
|
'default' => 'y',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'calendarviewnavbar' => [
|
|
'required' => false,
|
|
'name' => tra('Navigation Bar'),
|
|
'description' => tra('Show calendar navigation bar (shown by default).'),
|
|
'since' => '6.0',
|
|
'doctype' => 'calendar',
|
|
'filter' => 'alpha',
|
|
'default' => 'y',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n'],
|
|
['text' => tra('Partial'), 'value' => 'partial']
|
|
]
|
|
],
|
|
'calendartitle' => [
|
|
'required' => false,
|
|
'name' => tra('Calendar Title'),
|
|
'description' => tra('Enter a title to display a calendar title (not set by default)'),
|
|
'since' => '6.0',
|
|
'doctype' => 'calendar',
|
|
'filter' => 'text',
|
|
'default' => '',
|
|
],
|
|
'calendardelta' => [
|
|
'required' => false,
|
|
'name' => tra('Calendar Delta'),
|
|
'description' => tra('Set the calendar delta that will be shown (not set by default)'),
|
|
'since' => '6.0',
|
|
'doctype' => 'calendar',
|
|
'filter' => 'text',
|
|
'default' => '',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Plus Month'), 'value' => '+month'],
|
|
['text' => tra('Minus Month'), 'value' => '-month'],
|
|
['text' => tra('Plus Two months'), 'value' => '+bimester'],
|
|
['text' => tra('Minus Two months'), 'value' => '-bimester']
|
|
]
|
|
],
|
|
'displaysheet' => [
|
|
'required' => false,
|
|
'name' => tra('Display Spreadsheet.'),
|
|
'description' => tra('Display tracker as a spreadsheet (not used by default)'),
|
|
'since' => '6.0',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'force_compile' => [
|
|
'required' => false,
|
|
'name' => tra('Force Compile.'),
|
|
'description' => tra('Force Smarty to recompile the templates for each tracker item when using a
|
|
wiki page as a template. Default=n (best performance)'),
|
|
'since' => '6.0',
|
|
'filter' => 'alpha',
|
|
'default' => 'n',
|
|
'advanced' => true,
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'periodQuantity' => [
|
|
'required' => false,
|
|
'name' => tr('Period quantity'),
|
|
'description' => tr('Numeric value to display only last tracker items created within a user defined
|
|
time-frame. Used in conjunction with the next parameter "Period unit", this parameter indicates how
|
|
many of those units are to be considered to define the time frame. Use in conjunction with
|
|
%0max=-"1"%1 to list all items (by default %0max%1 is set to %010%1).', '<code>', '</code>'),
|
|
'since' => '6.5, <s>7.x</s> & 8.0',
|
|
'doctype' => 'filter',
|
|
'filter' => 'int',
|
|
'default' => '',
|
|
],
|
|
'periodUnit' => [
|
|
'required' => false,
|
|
'name' => tr('Period unit'),
|
|
'description' => tr('Time unit used with "Period quantity"'),
|
|
'since' => '6.5, <s>7.x</s> & 8.0',
|
|
'doctype' => 'filter',
|
|
'filter' => 'word',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tr('Hour'), 'value' => 'hour'],
|
|
['text' => tr('Day'), 'value' => 'day'],
|
|
['text' => tr('Week'), 'value' => 'week'],
|
|
['text' => tr('Month'), 'value' => 'month'],
|
|
],
|
|
'default' => '',
|
|
],
|
|
'periodType' => [
|
|
'required' => false,
|
|
'name' => tr('Period type'),
|
|
'description' => tr('Time period after creation or after modification'),
|
|
'since' => '6.7, <s>7.x</s>, 8.4 & 9.0',
|
|
'doctype' => 'filter',
|
|
'filter' => 'word',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tr('Creation'), 'value' => 'c'],
|
|
['text' => tr('Modification'), 'value' => 'm'],
|
|
],
|
|
'default' => '',
|
|
],
|
|
'editable' => [
|
|
'required' => false,
|
|
'name' => tr('Inline edit'),
|
|
'description' => tr('Colon-separated list of fields for which inline editing will be enabled.'),
|
|
'since' => '11.0',
|
|
'filter' => 'digits',
|
|
'separator' => ':',
|
|
'default' => '',
|
|
'profile_reference' => 'tracker_field',
|
|
'parent' => 'input[name="params[trackerId]"]',
|
|
'parentkey' => 'tracker_id',
|
|
],
|
|
'editableall' => [
|
|
'required' => false,
|
|
'name' => tr('Inline edit All'),
|
|
'description' => tr('Allow all displayed fields to be editable'),
|
|
'since' => '11.0',
|
|
'default' => 'y',
|
|
'advanced' => true,
|
|
'filter' => 'alpha',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
'force_separate_compile' => [
|
|
'required' => false,
|
|
'name' => tra('Compile Each Item'),
|
|
'description' => tra('Compile each item separately instead of compiling the entire template.'),
|
|
'since' => '11.0',
|
|
'filter' => 'alpha',
|
|
'default' => 'y',
|
|
'options' => [
|
|
['text' => '', 'value' => ''],
|
|
['text' => tra('Yes'), 'value' => 'y'],
|
|
['text' => tra('No'), 'value' => 'n']
|
|
]
|
|
],
|
|
],
|
|
$tsparams
|
|
);
|
|
return [
|
|
'name' => tra('Tracker List'),
|
|
'documentation' => 'PluginTrackerList',
|
|
'description' => tra('List, filter and sort the items in a tracker'),
|
|
'prefs' => [ 'feature_trackers', 'wikiplugin_trackerlist' ],
|
|
'tags' => [ 'basic' ],
|
|
'body' => tra('Notice'),
|
|
'additional' => '<br>' . tr('Additional information when using tablesorter and the %0 parameter (Server Side Processing) is set to y:', '<code>server</code>') . '<ul>'
|
|
. '<li>' . tra('Filtering and sorting on some field types (e.g., items list), may behave unexpectedly') . '</li>'
|
|
. '<li>' . tra('For best results the date filter should only be applied to date field types') . '</li>'
|
|
. '<li>' . tra('To filter the category field type, the exact category name or id needs to be entered') . '</li>'
|
|
. '</ul>',
|
|
'format' => 'html',
|
|
'iconname' => 'table',
|
|
'introduced' => 1,
|
|
'filter' => 'text',
|
|
'params' => $params
|
|
];
|
|
}
|
|
|
|
function wikiplugin_trackerlist($data, $params)
|
|
{
|
|
global $tiki_p_admin_trackers, $prefs, $tiki_p_view_trackers, $user,
|
|
$page, $tiki_p_tracker_vote_ratings, $tiki_p_tracker_view_ratings,
|
|
$tiki_p_export_tracker, $tiki_p_watch_trackers, $tiki_p_edit;
|
|
|
|
$userlib = TikiLib::lib('user');
|
|
$tikilib = TikiLib::lib('tiki');
|
|
$trklib = TikiLib::lib('trk');
|
|
$smarty = TikiLib::lib('smarty');
|
|
$notificationlib = TikiLib::lib('notification');
|
|
|
|
static $iTRACKERLIST = 0;
|
|
++$iTRACKERLIST;
|
|
$smarty->assign('iTRACKERLIST', $iTRACKERLIST);
|
|
|
|
$default = [
|
|
'calendarfielddate' => '',
|
|
'wiki' => '',
|
|
'calendarviewmode' => 'month',
|
|
'calendarstickypopup' => 'n',
|
|
'calendarbeginmonth' => 'y',
|
|
'calendarviewnavbar' => 'y',
|
|
'calendartitle' => '',
|
|
'calendardelta' => '',
|
|
'calendarpopup' => 'y',
|
|
'force_compile' => 'n',
|
|
'editable' => [],
|
|
'editableall' => 'n',
|
|
];
|
|
|
|
$params = array_merge($default, $params);
|
|
|
|
extract($params, EXTR_SKIP);
|
|
|
|
$skip_status_perm_check = false;
|
|
|
|
if (isset($force_separate_compile) && $force_separate_compile == 'y') {
|
|
$smarty->assign('force_separate_compile', 'y');
|
|
}
|
|
|
|
if ($prefs['feature_trackers'] != 'y' || ! isset($trackerId) || ! ($tracker_info = $trklib->get_tracker($trackerId))) {
|
|
return $smarty->fetch("wiki-plugins/error_tracker.tpl");
|
|
} else {
|
|
global $auto_query_args;
|
|
$auto_query_args_local = ['trackerId', 'tr_initial',"tr_sort_mode$iTRACKERLIST",'tr_user', 'filterfield', 'filtervalue', 'exactvalue', 'itemId', "tr_offset$iTRACKERLIST"];
|
|
$auto_query_args = empty($auto_query_args) ? $auto_query_args_local : array_merge($auto_query_args, $auto_query_args_local);
|
|
$smarty->assign('listTrackerId', $trackerId);
|
|
$definition = Tracker_Definition::get($trackerId);
|
|
$tracker_info = $definition->getInformation();
|
|
|
|
if (! isset($sort)) {
|
|
$sort = 'n';
|
|
}
|
|
|
|
$perms = $tikilib->get_perm_object($trackerId, 'tracker', $tracker_info, false);
|
|
if ($perms['tiki_p_view_trackers'] != 'y' && ! $user) {
|
|
return;
|
|
}
|
|
$userCreatorFieldIds = $definition->getItemOwnerFields();
|
|
$groupCreatorFieldId = $definition->getWriterGroupField();
|
|
if ($perms['tiki_p_view_trackers'] != 'y' && ! $definition->isEnabled('writerCanModify') && ! $definition->isEnabled('userCanSeeOwn') && ! $definition->isEnabled('groupCanSeeOwn') && empty($userCreatorFieldIds) && empty($groupCreatorFieldId)) {
|
|
return;
|
|
}
|
|
$smarty->assign_by_ref('perms', $perms);
|
|
|
|
if (! empty($fields)) {
|
|
$limit = $fields;
|
|
} else {
|
|
$limit = '';
|
|
}
|
|
// Make sure limit is an array
|
|
if (! is_array($limit) && ! empty($limit)) {
|
|
$limit = explode(':', $limit);
|
|
}
|
|
|
|
if (! empty($filterfield) && ! empty($limit)) {
|
|
$limit = array_unique(array_merge($limit, $filterfield));
|
|
}
|
|
|
|
// for some reason if param popup is set but empty, the array contains 2 empty elements. We filter them out.
|
|
if (isset($popup)) {
|
|
$popup = array_filter($popup);
|
|
if (! empty($popup)) {
|
|
$limit = array_unique(array_merge($limit, $popup));
|
|
// popup fields implies sorting by field order - otherwise, searching and sorting won't work
|
|
$sort = 'y';
|
|
}
|
|
}
|
|
if (! empty($calendarfielddate)) {
|
|
$limit = array_unique(array_merge($limit, $calendarfielddate));
|
|
}
|
|
if (! empty($limit) && $trklib->test_field_type($limit, ['C'])) {
|
|
$limit = [];
|
|
}
|
|
|
|
$filter = [];
|
|
|
|
$allfields = $trklib->list_tracker_fields($trackerId, 0, -1, 'position_asc', '', true, '', $trklib->flaten($limit));
|
|
if (! empty($fields)) {
|
|
$listfields = $fields;
|
|
if (is_string($listfields)) {
|
|
$listfields = explode(':', $listfields);
|
|
}
|
|
|
|
//We must include the $calendarfielddate, even if they are not in the listfields
|
|
if (! empty($calendarfielddate)) {
|
|
foreach ($calendarfielddate as $f) {
|
|
if (! in_array($f, $listfields)) {
|
|
$listfields[] = $f;
|
|
}
|
|
}
|
|
}
|
|
if ($sort == 'y') {
|
|
$allfields = $trklib->sort_fields($allfields, $listfields);
|
|
}
|
|
} elseif (! empty($wiki) || ! empty($tpl) || ! empty($tplwiki)) {
|
|
if (! empty($wiki)) {
|
|
$listfields = $trklib->get_pretty_fieldIds($wiki, 'wiki', $prettyModifier, $trackerId);
|
|
} elseif (! empty($tplwiki)) {
|
|
$listfields = $trklib->get_pretty_fieldIds($tplwiki, 'wiki', $prettyModifier, $trackerId);
|
|
} else {
|
|
$listfields = $trklib->get_pretty_fieldIds($tpl, 'tpl', $prettyModifier, $trackerId);
|
|
}
|
|
} else {
|
|
$listfields = [];
|
|
}
|
|
if (! empty($compute) && ! empty($listfields)) {
|
|
if (preg_match_all('/[0-9.]+/', $compute, $matches)) {
|
|
foreach ($matches[0] as $f) {
|
|
if (! in_array($f, $listfields)) {
|
|
$listfields[] = $f;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (! isset($showstatus)) {
|
|
$showstatus = 'n';
|
|
}
|
|
$smarty->assign_by_ref('showstatus', $showstatus);
|
|
|
|
if (! isset($showcomments)) {
|
|
$showcomments = 'y';
|
|
}
|
|
$smarty->assign_by_ref('showcomments', $showcomments);
|
|
|
|
if (! isset($showcreated)) {
|
|
$showcreated = $tracker_info['showCreated'];
|
|
}
|
|
$smarty->assign_by_ref('showcreated', $showcreated);
|
|
|
|
if (! isset($showlastmodif)) {
|
|
$showlastmodif = $tracker_info['showLastModif'];
|
|
}
|
|
$smarty->assign_by_ref('showlastmodif', $showlastmodif);
|
|
|
|
if (! isset($showlastmodifby)) {
|
|
$showlastmodifby = (isset($tracker_info['showLastModifBy'])) ? $tracker_info['showLastModifBy'] : '';
|
|
}
|
|
$smarty->assign_by_ref('showlastmodifby', $showlastmodifby);
|
|
|
|
/*** tablesorter ***/
|
|
//note whether ajax is needed
|
|
$tsServer = isset($params['server']) && $params['server'] === 'y';
|
|
|
|
$tsOn =
|
|
/* The sortable parameter is not defined. It enables Tablesorter, which affects more than sorting (at least filtering).
|
|
* It is not always necessary for sorting.
|
|
* FIXME: find a better name
|
|
*/
|
|
isset($sortable) && $sortable !== 'n'
|
|
|
|
&& Table_Check::isEnabled($tsServer);
|
|
$smarty->assign('tsOn', $tsOn);
|
|
|
|
//note whether this is the initial tablesorter ajax call or a subsequent ajax call
|
|
$tsAjax = Table_Check::isAjaxCall();
|
|
$smarty->assign('tsAjax', $tsAjax);
|
|
|
|
if ($tsAjax) {
|
|
// if status is enabled, need to adjust field index by -1 - need to check both - tracker config and plugin config
|
|
$adjustCol = (isset($showstatus) && $showstatus == 'y' && $definition->isEnabled('showStatus')) ? -1 : 0;
|
|
//convert tablesorter filter syntax to tiki syntax
|
|
if (! empty($_REQUEST['filter'])) {
|
|
$i = is_array($filterfield) ? count($filterfield) : 0;
|
|
$tsfiltersArray = explode('|', $tsfilters);
|
|
foreach ($_REQUEST['filter'] as $col => $ajaxfilter) {
|
|
$fieldtype = $allfields['data'][$col + $adjustCol]['type'];
|
|
$id = $allfields['data'][$col + $adjustCol]['fieldId'];
|
|
//handle status filter
|
|
if ($adjustCol === -1 && $col === 0 && in_array($ajaxfilter, ['o','p','c'])) {
|
|
$status = $ajaxfilter;
|
|
} elseif (
|
|
$showcomments != 'n'
|
|
and $tracker_info['useComments'] == 'y'
|
|
and ($tracker_info['showComments'] == 'y' || $tracker_info['showLastComment'] == 'y')
|
|
and $perms['tiki_p_tracker_view_comments'] != 'n'
|
|
and $col == count($listfields) - $adjustCol + ($showcreated == 'y') + ($showlastmodif == 'y') + ($showlastmodifby == 'y')
|
|
) {
|
|
$filter['comment'] = $ajaxfilter;
|
|
/*
|
|
* handle date filter - these are always one filter, in the form of:
|
|
* from: >=1427389832000; to: <=1427389832000; both from and to: 1427389832000 - 1427880000000
|
|
* which is unix timestamp in milliseconds
|
|
*/
|
|
} elseif (
|
|
($isCreated = $showcreated == 'y' && $col == count($listfields) - $adjustCol)
|
|
|| ($showlastmodif == 'y' && $col == count($listfields) - $adjustCol + ($showcreated == 'y'))
|
|
) {
|
|
$filteredField = $isCreated ? 'created' : 'lastModif';
|
|
$datefilter = explode(' - ', $ajaxfilter);
|
|
//a range (from and to filters) will have 2 items in the array
|
|
if (count($datefilter) == 2) {
|
|
//use substr to leave off milliseconds since date is stored in seconds in the database
|
|
$filter[$filteredField . 'After'] = substr($datefilter[0], 0, 10);
|
|
$filter[$filteredField . 'Before'] = substr($datefilter[1], 0, 10);
|
|
} else {
|
|
//use substr to leave off milliseconds since date is stored in seconds in the database
|
|
$stamp = substr($datefilter[0], 2, 10);
|
|
$symbol = substr($datefilter[0], 0, 2);
|
|
if ($symbol === '<=') {
|
|
$filter[$filteredField . 'Before'] = $stamp;
|
|
} elseif ($symbol === '>=') {
|
|
$filter[$filteredField . 'After'] = $stamp;
|
|
}
|
|
}
|
|
} elseif (strpos($tsfiltersArray[$col], 'type:date') !== false && in_array($fieldtype, ['f', 'j'])) {
|
|
$datefilter = explode(' - ', $ajaxfilter);
|
|
$filterfield[$i] = $id;
|
|
//a range (from and to filters) will have 2 items in the array
|
|
if (count($datefilter) == 2) {
|
|
$filterfield[$i + 1] = $id;
|
|
//use substr to leave off milliseconds since date is stored in seconds in the database
|
|
$exactvalue[$i] = 'greaterequal(@' . substr($datefilter[0], 0, 10) . ')';
|
|
$exactvalue[$i + 1] = 'lessequal(@' . substr($datefilter[1], 0, 10) . ')';
|
|
$filtervalue[$i] = '';
|
|
$filtervalue[$i + 1] = '';
|
|
} else {
|
|
//use substr to leave off milliseconds since date is stored in seconds in the database
|
|
$stamp = '(@' . substr($datefilter[0], 2, 10) . ')';
|
|
$symbol = substr($datefilter[0], 0, 2);
|
|
if ($symbol === '<=') {
|
|
$compare = 'lessequal';
|
|
} elseif ($symbol === '>=') {
|
|
$compare = 'greaterequal';
|
|
}
|
|
$exactvalue[$i] = $compare . $stamp;
|
|
$filtervalue[$i] = '';
|
|
}
|
|
} else {
|
|
$filterfield[$i] = $id;
|
|
//convert category filters entered as text
|
|
if ($fieldtype === 'e' && ! is_numeric($ajaxfilter)) {
|
|
$categlib = TikiLib::lib('categ');
|
|
$ajaxfilter = $categlib->get_category_id($ajaxfilter);
|
|
}
|
|
$filtervalue[$i] = $ajaxfilter;
|
|
$exactvalue[$i] = '';
|
|
}
|
|
$i++;
|
|
}
|
|
}
|
|
//convert tablesorter sort syntax to tiki syntax
|
|
if (! empty($_REQUEST['sort'])) {
|
|
foreach ($_REQUEST['sort'] as $sortcol => $ajaxsort) {
|
|
if ($ajaxsort == '0') {
|
|
$dir = '_asc';
|
|
} elseif ($ajaxsort == '1') {
|
|
$dir = '_desc';
|
|
}
|
|
//avoid setting sort_mode based on status field - will return error. Handle later once records are retrieved
|
|
if ($adjustCol !== -1 || $sortcol !== 0) {
|
|
$sort_mode = 'f_' . $allfields['data'][$sortcol + $adjustCol]['fieldId'] . $dir;
|
|
}
|
|
}
|
|
}
|
|
//set max records
|
|
if (isset($_REQUEST['numrows'])) {
|
|
$max = $_REQUEST['numrows'];
|
|
}
|
|
}
|
|
/*** end first tablesorter section ***/
|
|
|
|
if (! empty($filterfield)) {
|
|
if (is_array($filterfield)) {
|
|
foreach ($filterfield as $ff) {
|
|
unset($filterfieldok);
|
|
if (is_array($ff)) {// already checked in trackerfilter
|
|
$filterfieldok = true;
|
|
break;
|
|
} else {
|
|
foreach ($allfields['data'] as $f) {
|
|
if ($f['fieldId'] == $ff) {
|
|
$filterfieldok = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (! isset($filterfieldok)) {
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
foreach ($allfields['data'] as $f) {
|
|
if ($f['fieldId'] == $filterfield) {
|
|
$filterfieldok = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (! isset($filterfieldok)) {
|
|
return tra('incorrect filterfield');
|
|
}
|
|
}
|
|
|
|
if (isset($periodQuantity)) {
|
|
switch ($periodUnit) {
|
|
case 'hour':
|
|
$periodUnit = 3600;
|
|
break;
|
|
case 'day':
|
|
$periodUnit = 86400;
|
|
break;
|
|
case 'week':
|
|
$periodUnit = 604800;
|
|
break;
|
|
case 'month':
|
|
$periodUnit = 2628000;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (! isset($periodType)) {
|
|
$periodType = 'c';
|
|
}
|
|
|
|
if (is_int($periodUnit) && ($periodType == 'm' )) {
|
|
$filter['lastModifAfter'] = $tikilib->now - ($periodQuantity * $periodUnit);
|
|
$filter['lastModifBefore'] = $tikilib->now;
|
|
} elseif (is_int($periodUnit)) { # case for periodType beig c or anything else (therefore, set as case for default)
|
|
$filter['createdAfter'] = $tikilib->now - ($periodQuantity * $periodUnit);
|
|
$filter['createdBefore'] = $tikilib->now;
|
|
}
|
|
}
|
|
|
|
if (isset($_REQUEST['reloff']) && empty($_REQUEST['itemId']) && ! empty($_REQUEST['trackerId'])) { //coming from a pagination
|
|
$items = $trklib->list_items(
|
|
$_REQUEST['trackerId'],
|
|
$_REQUEST['reloff'],
|
|
1,
|
|
'',
|
|
'',
|
|
isset($_REQUEST['filterfield']) ? preg_split('/\s*:\s*/', $_REQUEST['filterfield']) : '',
|
|
isset($_REQUEST['filtervalue']) ? preg_split('/\s*:\s*/', $_REQUEST['filtervalue']) : '',
|
|
isset($_REQUEST['status']) ? preg_split('/\s*:\s*/', $_REQUEST['status']) : '',
|
|
isset($_REQUEST['initial']) ? $_REQUEST['initial'] : '',
|
|
isset($_REQUEST['exactvalue']) ? preg_split('/\s*:\s*/', $_REQUEST['exactvalue']) : '',
|
|
$filter
|
|
);
|
|
if (isset($items['data'][0]['itemId'])) {
|
|
$_REQUEST['cant'] = $items['cant'];
|
|
$_REQUEST['itemId'] = $items['data'][0]['itemId'];
|
|
}
|
|
}
|
|
|
|
if (! empty($_REQUEST['itemId']) && $tiki_p_tracker_vote_ratings == 'y' && $user) {
|
|
$hasVoted = false;
|
|
foreach ($allfields['data'] as $f) {
|
|
if ($f['type'] == 's' && $definition->isEnabled('useRatings') && ($f['name'] == 'Rating' || $f['name'] = tra('Rating'))) {
|
|
$i = $f['fieldId'];
|
|
if (isset($_REQUEST["ins_$i"]) && ($_REQUEST["ins_$i"] == 'NULL' || in_array($_REQUEST["ins_$i"], explode(',', $tracker_info['ratingOptions'])))) {
|
|
$trklib->replace_rating($trackerId, $_REQUEST['itemId'], $i, $user, $_REQUEST["ins_$i"]);
|
|
$hasVoted = true;
|
|
}
|
|
} elseif ($f['type'] == '*' || $f['type'] == 'STARS') {
|
|
$i = $f['fieldId'];
|
|
if (isset($_REQUEST["ins_$i"])) {
|
|
$trklib->replace_star($_REQUEST["ins_$i"], $trackerId, $_REQUEST['itemId'], $f, $user);
|
|
$hasVoted = true;
|
|
}
|
|
}
|
|
}
|
|
if ($hasVoted) {
|
|
// Must strip NULL for remove my vote case
|
|
$url = preg_replace('/[(\?)|&]vote=y/', '$1', preg_replace('/[(\?)|&]ins_[0-9]+=-?[0-9|N|U|L]*/', '$1', $_SERVER['REQUEST_URI']));
|
|
// reduce duplicate itemIds in query string
|
|
$occurences = preg_match_all('/[(\?)|&]itemId=[0-9]+/', $url, $matches);
|
|
if ($params['list_mode'] == 'y' && $occurences > 0) {
|
|
$url = preg_replace('/[(\?)|&]itemId=[0-9]+/', '$1', $url, $occurences);
|
|
} elseif ($occurences > 1) {
|
|
$url = preg_replace('/&itemId=[0-9]+/', '', $url, $occurences - 1);
|
|
}
|
|
header("Location: $url");
|
|
die;
|
|
}
|
|
}
|
|
|
|
if (! empty($showwatch) && $showwatch == 'y' && $prefs['feature_user_watches'] == 'y' && $tiki_p_watch_trackers == 'y' && ! empty($user)) {
|
|
if (isset($_REQUEST['watch']) && isset($_REQUEST['trackerId']) && $_REQUEST['trackerId'] == $trackerId) {
|
|
if ($_REQUEST['watch'] == 'add') {
|
|
$tikilib->add_user_watch($user, 'tracker_modified', $trackerId, 'tracker', $tracker_info['name'], "tiki-view_tracker.php?trackerId=" . $trackerId);
|
|
} elseif ($_REQUEST['watch'] == 'stop') {
|
|
$tikilib->remove_user_watch($user, 'tracker_modified', $trackerId, 'tracker');
|
|
}
|
|
}
|
|
if ($tikilib->user_watches($user, 'tracker_modified', $trackerId, 'tracker')) {
|
|
$smarty->assign('user_watching_tracker', 'y');
|
|
} else {
|
|
$smarty->assign('user_watching_tracker', 'n');
|
|
}
|
|
} else {
|
|
$smarty->clear_assign('user_watching_tracker');
|
|
}
|
|
if (empty($showrss) || $showrss == 'n') {
|
|
$smarty->assign('showrss', 'n');
|
|
} else {
|
|
$smarty->assign('showrss', 'y');
|
|
}
|
|
|
|
if (empty($listfields)) {
|
|
foreach ($allfields['data'] as $f) {
|
|
$listfields[] = $f['fieldId'];
|
|
}
|
|
}
|
|
if (! empty($popup)) {
|
|
$popupfields = $popup;
|
|
} else {
|
|
$popupfields = [];
|
|
}
|
|
$smarty->assign_by_ref('tracker_info', $tracker_info);
|
|
|
|
//$query_array = array();
|
|
//$quarray = array();
|
|
//parse_str($_SERVER['QUERY_STRING'],$query_array);
|
|
|
|
if (isset($stickypopup) && $stickypopup == 'y') {
|
|
$stickypopup = true;
|
|
} else {
|
|
$stickypopup = false;
|
|
}
|
|
$smarty->assign_by_ref('stickypopup', $stickypopup);
|
|
|
|
if (! isset($showtitle)) {
|
|
$showtitle = 'n';
|
|
}
|
|
$smarty->assign_by_ref('showtitle', $showtitle);
|
|
|
|
if (! isset($showlinks)) {
|
|
$showlinks = 'n';
|
|
}
|
|
$smarty->assign_by_ref('showlinks', $showlinks);
|
|
|
|
if (! isset($showdesc)) {
|
|
$showdesc = 'n';
|
|
}
|
|
$smarty->assign_by_ref('showdesc', $showdesc);
|
|
|
|
if (! isset($showinitials)) {
|
|
$showinitials = 'n';
|
|
}
|
|
$smarty->assign_by_ref('showinitials', $showinitials);
|
|
|
|
if (! isset($shownbitems)) {
|
|
$shownbitems = 'n';
|
|
}
|
|
$smarty->assign_by_ref('shownbitems', $shownbitems);
|
|
|
|
if (! isset($showfieldname)) {
|
|
$showfieldname = 'y';
|
|
}
|
|
$smarty->assign_by_ref('showfieldname', $showfieldname);
|
|
|
|
if (! isset($showitemrank)) {
|
|
$showitemrank = 'n';
|
|
}
|
|
$smarty->assign_by_ref('showitemrank', $showitemrank);
|
|
|
|
if (! isset($showdelete)) {
|
|
$showdelete = 'n';
|
|
}
|
|
$smarty->assign_by_ref('showdelete', $showdelete);
|
|
if (! isset($showpenditem)) {
|
|
$showpenditem = 'n';
|
|
}
|
|
$smarty->assign_by_ref('showpenditem', $showpenditem);
|
|
if (! isset($showcloseitem)) {
|
|
$showcloseitem = 'n';
|
|
}
|
|
$smarty->assign_by_ref('showcloseitem', $showcloseitem);
|
|
if (! isset($showopenitem)) {
|
|
$showopenitem = 'n';
|
|
}
|
|
$smarty->assign_by_ref('showopenitem', $showopenitem);
|
|
if (! isset($showpagination)) {
|
|
$showpagination = 'y';
|
|
}
|
|
$smarty->assign_by_ref('showpagination', $showpagination);
|
|
if (! isset($allowtableexpansion)) {
|
|
$allowtableexpansion = 'n';
|
|
}
|
|
$smarty->assign_by_ref('allowtableexpansion', $allowtableexpansion);
|
|
if (! isset($sortchoice)) {
|
|
$sortchoice = '';
|
|
} else {
|
|
foreach ($sortchoice as $i => $sc) {
|
|
$sc = explode('|', $sc);
|
|
$sortchoice[$i] = ['value' => $sc[0], 'label' => empty($sc[1]) ? $sc[0] : $sc[1]];
|
|
}
|
|
}
|
|
$smarty->assign_by_ref('sortchoice', $sortchoice);
|
|
|
|
if (! isset($status)) {
|
|
$status = 'o';
|
|
}
|
|
$tr_status = $status;
|
|
$smarty->assign_by_ref('tr_status', $tr_status);
|
|
|
|
if (! isset($list_mode)) {
|
|
$list_mode = 'y';
|
|
}
|
|
$smarty->assign_by_ref('list_mode', $list_mode);
|
|
|
|
if (! isset($more)) {
|
|
$more = 'n';
|
|
}
|
|
$smarty->assign_by_ref('more', $more);
|
|
|
|
if (! isset($moreurl)) {
|
|
$moreurl = 'tiki-view_tracker.php';
|
|
}
|
|
$smarty->assign_by_ref('moreurl', $moreurl);
|
|
|
|
if (! isset($url)) {
|
|
$url = '';
|
|
}
|
|
$smarty->assign_by_ref('url', $url);
|
|
|
|
if (! isset($export)) {
|
|
$export = 'n';
|
|
}
|
|
$smarty->assign_by_ref('export', $export);
|
|
|
|
if (! empty($ldelim)) {
|
|
$smarty->left_delimiter = $ldelim;
|
|
}
|
|
if (! empty($rdelim)) {
|
|
$smarty->right_delimiter = $rdelim;
|
|
}
|
|
|
|
if (isset($checkbox)) {
|
|
$check = ['ix' => -1, 'type' => 'checkbox'];
|
|
$cb = explode('/', $checkbox);
|
|
|
|
if (isset($cb[0])) {
|
|
$check['fieldId'] = $cb[0];
|
|
}
|
|
if (isset($cb[1])) {
|
|
$check['name'] = $cb[1];
|
|
}
|
|
if (isset($cb[2])) {
|
|
$check['title'] = $cb[2];
|
|
}
|
|
if (isset($cb[3])) {
|
|
$check['submit'] = $cb[3];
|
|
}
|
|
if (isset($cb[4])) {
|
|
$check['action'] = $cb[4];
|
|
}
|
|
if (isset($cb[5])) {
|
|
$check['tpl'] = $cb[5];
|
|
}
|
|
if (isset($cb[6]) && $cb[6] == 'radio') {
|
|
$check['radio'] = 'y';
|
|
$check['type'] = 'radio';
|
|
}
|
|
if (isset($cb[6]) && $cb[6] == 'dropdown') {
|
|
$check['dropdown'] = 'y'; // is this actually used?
|
|
}
|
|
if (isset($cb[7]) && $cb[7] === 'y') {
|
|
$check['embed'] = true;
|
|
} else {
|
|
$check['embed'] = false;
|
|
}
|
|
if (! empty($cb[8])) {
|
|
$check['checked'] = preg_split('/\s*,\s*/', $cb[8]);
|
|
} else {
|
|
$check['checked'] = [];
|
|
}
|
|
|
|
$smarty->assign_by_ref('checkbox', $check);
|
|
} else {
|
|
$smarty->clear_assign('checkbox');
|
|
}
|
|
|
|
if (isset($_REQUEST["tr_sort_mode$iTRACKERLIST"])) {
|
|
$sort_mode = $_REQUEST["tr_sort_mode$iTRACKERLIST"];
|
|
} elseif (! isset($sort_mode)) {
|
|
if (! empty($tracker_info['defaultOrderKey']) && is_numeric($tracker_info['defaultOrderKey'])) {
|
|
if ($tracker_info['defaultOrderKey'] == -1) {
|
|
$sort_mode = 'lastModif';
|
|
} elseif ($tracker_info['defaultOrderKey'] == -2) {
|
|
$sort_mode = 'created';
|
|
} elseif ($tracker_info['defaultOrderKey'] == -3) {
|
|
$sort_mode = 'itemId';
|
|
} else {
|
|
$sort_mode = 'f_' . $tracker_info['defaultOrderKey'];
|
|
}
|
|
if (isset($tracker_info['defaultOrderDir'])) {
|
|
$sort_mode .= "_" . $tracker_info['defaultOrderDir'];
|
|
} else {
|
|
$sort_mode .= "_asc";
|
|
}
|
|
} else {
|
|
$sort_mode = '';
|
|
}
|
|
} elseif ($sort_mode != 'created_asc' && $sort_mode != 'lastModif_asc' && $sort_mode != 'created_desc' && $sort_mode != 'lastModif_desc' && ! preg_match('/f_[0-9]+_(asc|desc)/', $sort_mode)) {
|
|
return tra('Incorrect param') . ' sort_mode';
|
|
}
|
|
|
|
$tr_sort_mode = $sort_mode;
|
|
$smarty->assign_by_ref('tr_sort_mode', $tr_sort_mode);
|
|
|
|
if (! isset($max)) {
|
|
$max = $prefs['maxRecords'];
|
|
}
|
|
|
|
if (isset($_REQUEST["tr_offset$iTRACKERLIST"]) && (! isset($forceoffset) || $forceoffset == 'n')) {
|
|
$tr_offset = $_REQUEST["tr_offset$iTRACKERLIST"];
|
|
} elseif (isset($offset) && $offset >= 0) {
|
|
$tr_offset = $offset;
|
|
} else {
|
|
$tr_offset = 0;
|
|
}
|
|
$smarty->assign_by_ref("tr_offset$iTRACKERLIST", $tr_offset);
|
|
|
|
$tr_initial = '';
|
|
if ($showinitials == 'y') {
|
|
if (isset($_REQUEST['tr_initial'])) {
|
|
//$query_array['tr_initial'] = $_REQUEST['tr_initial'];
|
|
$tr_initial = $_REQUEST['tr_initial'];
|
|
}
|
|
$smarty->assign('initials', explode(' ', 'a b c d e f g h i j k l m n o p q r s t u v w x y z'));
|
|
}
|
|
$smarty->assign_by_ref('tr_initial', $tr_initial);
|
|
|
|
if ((isset($view) && $view == 'user') || isset($view_user) || isset($_REQUEST['tr_user'])) {
|
|
if ($f = $definition->getItemOwnerFields()) {
|
|
$filterfield[] = ['usersearch' => $f];
|
|
$filtervalue[] = '';
|
|
if (! isset($_REQUEST['tr_user'])) {
|
|
$exactvalue[] = isset($view) ? (empty($user) ? 'Anonymous' : $user) : $view_user;
|
|
} else {
|
|
$exactvalue[] = $_REQUEST['tr_user'];
|
|
$smarty->assign_by_ref('tr_user', $exactvalue);
|
|
}
|
|
if ($definition->isEnabled('writerCanModify') or $definition->isEnabled('userCanSeeOwn')) {
|
|
$skip_status_perm_check = true;
|
|
}
|
|
}
|
|
}
|
|
if ((isset($view) && $view == 'group')) {
|
|
if ($f = $definition->getItemGroupOwnerFields()) {
|
|
$filterfield[] = ['usersearch' => $f];
|
|
$filtervalue[] = '';
|
|
$exactvalue[] = $tikilib->get_user_groups(empty($user) ? 'Anonymous' : $user);
|
|
if ($definition->isEnabled('groupCanSeeOwn')) {
|
|
$skip_status_perm_check = true;
|
|
}
|
|
}
|
|
}
|
|
if (isset($view) && $view == 'page' && isset($_REQUEST['page'])) {
|
|
if (($f = $trklib->get_page_field($trackerId))) {
|
|
$filterfield[] = $f['fieldId'];
|
|
$filtervalue[] = '';
|
|
$exactvalue[] = $_REQUEST['page'];
|
|
}
|
|
}
|
|
|
|
if (isset($view) && $view == 'ip') {
|
|
if ($f = $definition->getAuthorIpField()) {
|
|
$filterfield[] = $f;
|
|
$filtervalue[] = '';
|
|
$ip = $tikilib->get_ip_address();
|
|
$exactvalue[] = $ip;
|
|
}
|
|
}
|
|
|
|
if (! isset($filtervalue)) {
|
|
$filtervalue = '';
|
|
} else {
|
|
foreach ($filtervalue as $i => $f) {
|
|
if ($f == '#user') {
|
|
$filtervalue[$i] = $user;
|
|
} elseif ($f == '#default_group') {
|
|
$filtervalue[$i] = $_SESSION['u_info']['group'];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (! isset($exactvalue)) {
|
|
$exactvalue = [];
|
|
} else {
|
|
foreach ($exactvalue as $i => $f) {
|
|
if ($f == '#user') {
|
|
$exactvalue[$i] = $user;
|
|
}
|
|
}
|
|
}
|
|
if (! empty($_REQUEST['itemId']) && (empty($ignoreRequestItemId) || $ignoreRequestItemId != 'y')) {
|
|
$itemId = $_REQUEST['itemId'];
|
|
}
|
|
|
|
if (isset($itemId)) {
|
|
if (is_string($itemId) && strstr($itemId, ':')) { // JB Tiki7: This doesn't quite make sense as itemId is an array
|
|
$itemId = explode(':', $itemId); // Probably just some redundant code TOKIL
|
|
}
|
|
$filter['tti.`itemId`'] = $itemId;
|
|
}
|
|
|
|
$newItemRateField = false;
|
|
$status_types = $trklib->status_types();
|
|
$smarty->assign('status_types', $status_types);
|
|
|
|
if (! isset($filterfield)) {
|
|
$filterfield = '';
|
|
} else {
|
|
if (! empty($filterfield)) {
|
|
if (! empty($filtervalue)) {
|
|
$fvs = $filtervalue;
|
|
unset($filtervalue);
|
|
for ($i = 0, $count_ff = count($filterfield); $i < $count_ff; ++$i) {
|
|
$filtervalue[] = isset($fvs[$i]) ? $fvs[$i] : '';
|
|
}
|
|
}
|
|
if (! empty($exactvalue)) {
|
|
$evs = $exactvalue;
|
|
unset($exactvalue);
|
|
for ($i = 0, $count_ff2 = count($filterfield); $i < $count_ff2; ++$i) {
|
|
if (isset($evs[$i])) {
|
|
if (is_array($evs[$i])) { // already processed
|
|
$exactvalue[] = $evs[$i];
|
|
} elseif (preg_match('/(not)?categories\(([0-9]+)\)/', $evs[$i], $matches)) {
|
|
$categlib = TikiLib::lib('categ');
|
|
if (ctype_digit($matches[2]) && $matches[2] > 0) {
|
|
$cfilter = ['identifier' => $matches[2], 'type' => 'descendants'];
|
|
} else {
|
|
$cfilter = null;
|
|
}
|
|
$categs = $categlib->getCategories($cfilter, true, false);
|
|
$l = [$matches[2]];
|
|
foreach ($categs as $cat) {
|
|
$l[] = $cat['categId'];
|
|
}
|
|
if (empty($matches[1])) {
|
|
$exactvalue[] = $l;
|
|
} else {
|
|
$exactvalue[] = ['not' => $l];
|
|
}
|
|
} elseif (preg_match('/(not)?preference\((.*)\)/', $evs[$i], $matches)) {
|
|
if (empty($matches[1])) {
|
|
$exactvalue[] = $prefs[$matches[2]];
|
|
} else {
|
|
$exactvalue[] = ['not' => $prefs[$matches[2]]];
|
|
}
|
|
} elseif (preg_match('/(not)?field\(([0-9]+)(,([0-9]+|user)(,([0-9]+))?)?\)/', $evs[$i], $matches)) { // syntax field(fieldId, user, trackerId) or field(fieldId)(need the REQUEST['itemId'] or field(fieldId, itemId) or field(fieldId, user)
|
|
if (empty($matches[4]) && ! empty($_REQUEST['itemId'])) { // user the itemId of the url
|
|
$matches[4] = $_REQUEST['itemId'];
|
|
}
|
|
if (! empty($matches[4]) && $matches[4] == 'user') {
|
|
if (! empty($matches[6])) { // pick the user item of this tracker
|
|
$t_i = $trklib->get_tracker($matches[6]);
|
|
$matches[4] = $trklib->get_user_item($matches[6], $t_i, $user);
|
|
} elseif ($prefs['userTracker'] == 'y') { //pick the generic user tracker
|
|
$utid = $userlib->get_tracker_usergroup($user);
|
|
$matches[4] = $trklib->get_item_id($utid['usersTrackerId'], $utid['usersFieldId'], $user);
|
|
}
|
|
}
|
|
if (! empty($matches[4])) {
|
|
$l = $trklib->get_item_value(0, $matches[4], $matches[2]);
|
|
$field = $trklib->get_tracker_field($matches[2]);
|
|
if ($field['type'] == 'r') {
|
|
$refItemId = $l;
|
|
$l = $trklib->get_item_value($field['options_array'][0], $refItemId, $field['options_array'][3]);
|
|
}
|
|
}
|
|
if (empty($matches[1])) {
|
|
$exactvalue[] = $l;
|
|
} else {
|
|
$exactvalue[] = ['not' => $l];
|
|
}
|
|
} elseif (preg_match('/(less|greater|lessequal|greaterequal)\((.+)\)/', $evs[$i], $matches)) {
|
|
$conv = ['less' => '<', 'greater' => '>', 'lessequal' => '<=', 'greaterequal' => '>='];
|
|
$field = $trklib->get_tracker_field($filterfield[$i]);
|
|
if ($field['type'] == 'f' || $field['type'] == 'j') {
|
|
if ($matches[2] == 'now') {
|
|
$matches[2] = $tikilib->now;
|
|
} elseif (($r = strtotime($matches[2])) !== false) {
|
|
$matches[2] = $r;
|
|
}
|
|
}
|
|
$exactvalue[] = [$conv[$matches[1]] => $matches[2]];
|
|
} elseif (preg_match('/not\((.*)\)/', $evs[$i], $matches)) {
|
|
$exactvalue[] = ['not' => $matches[1]];
|
|
} elseif (preg_match('/or\((.*)\)/', $evs[$i], $matches)) {
|
|
$exactvalue[] = preg_split('/\s*,\s*/', $matches[1]);
|
|
} else {
|
|
$exactvalue[] = $evs[$i];
|
|
}
|
|
} else {
|
|
$exactvalue[] = '';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ($tiki_p_admin_trackers != 'y' && $perms['tiki_p_view_trackers'] != 'y' && $user && $groupCreatorFieldId) {
|
|
if ($filterfield != $groupCreatorFieldId || (is_array($filterfield) && ! in_array($groupCreatorFieldId, $filterfield))) {
|
|
global $group;// awful trick - but the filter garantee that the group is ok
|
|
$smarty->assign_by_ref('ours', $group);
|
|
$perms = array_merge($perms, $trklib->get_special_group_tracker_perm($tracker_info));
|
|
}
|
|
}
|
|
for ($i = 0, $count_allf = count($allfields['data']); $i < $count_allf; $i++) {
|
|
if ($allfields['data'][$i]['type'] == 'C') {
|
|
$infoComputed = $trklib->get_computed_info($allfields['data'][$i]['options_array'][0], $trackerId, $allfields['data']);
|
|
if (! empty($infoComputed)) {
|
|
$allfields['data'][$i] = array_merge($infoComputed, $allfields['data'][$i]);
|
|
}
|
|
} elseif ($allfields["data"][$i]['type'] == 'w') {
|
|
/* keep track of dynamic list items referring to user selectors */
|
|
$refFieldId = $allfields["data"][$i]['options_array'][3];
|
|
$refField = $trklib->get_tracker_field($refFieldId);
|
|
if ($refField['type'] == 'u') {
|
|
$allfields["data"][$i]['type'] = $refField['type'];
|
|
}
|
|
}
|
|
// If listfields is a colon separated string, convert it to an array
|
|
if (! is_array($listfields)) {
|
|
$listfields = explode(':', $listfields);
|
|
}
|
|
if ((in_array($allfields["data"][$i]['fieldId'], $listfields) or in_array($allfields["data"][$i]['fieldId'], $popupfields)) and $allfields["data"][$i]['isPublic'] == 'y') {
|
|
$passfields["{$allfields["data"][$i]['fieldId']}"] = $allfields["data"][$i];
|
|
}
|
|
if (isset($check['fieldId']) && $allfields["data"][$i]['fieldId'] == $check['fieldId']) {
|
|
$passfields["{$allfields["data"][$i]['fieldId']}"] = $allfields["data"][$i];
|
|
if (! in_array($allfields["data"][$i]['fieldId'], $listfields)) {
|
|
$allfields["data"][$i]['isPublic'] == 'n'; //don't show it
|
|
}
|
|
$check['ix'] = count($passfields) - 1;
|
|
}
|
|
if ($allfields["data"][$i]['name'] == 'page' && empty($filterfield) && empty($displayList) && ! empty($view) && $view == 'page') {
|
|
$filterfield = $allfields["data"][$i]['fieldId'];
|
|
$filtervalue = $_REQUEST['page'];
|
|
$exactvalue = [];
|
|
}
|
|
if (
|
|
$definition->isEnabled('useRatings')
|
|
and $allfields["data"][$i]['type'] == 's' and $allfields["data"][$i]['name'] == 'Rating'
|
|
) {
|
|
$newItemRateField = $allfields["data"][$i]['fieldId'];
|
|
}
|
|
}
|
|
$nonPublicFieldsWarning = '';
|
|
if ($tiki_p_edit === 'y') {
|
|
foreach ($allfields['data'] as $field) {
|
|
if ($field['isPublic'] !== 'y' && in_array($field['fieldId'], array_merge($listfields, $popupfields))) {
|
|
$nonPublicFieldsWarning = tra('You have attempted to view data of a tracker field which is not public. You need to ask the admin to change the setting to public for this field.');
|
|
}
|
|
}
|
|
}
|
|
if ($editableall == 'y') {
|
|
$editable = $listfields;
|
|
}
|
|
$smarty->assign('nonPublicFieldsWarning', $nonPublicFieldsWarning);
|
|
$smarty->assign_by_ref('filterfield', $filterfield);
|
|
$smarty->assign_by_ref('filtervalue', $filtervalue);
|
|
$smarty->assign_by_ref('fields', $passfields);
|
|
$smarty->assign_by_ref('exactvalue', $exactvalue);
|
|
$smarty->assign_by_ref('listfields', $listfields);
|
|
$smarty->assign_by_ref('popupfields', $popupfields);
|
|
if (! empty($filterfield)) {
|
|
$filterfield_flatten = array_filter($filterfield, function ($f) {
|
|
return ! is_array($f);
|
|
});
|
|
$urlquery['filterfield'] = is_array($filtervalue) ? implode(':', $filterfield_flatten) : $filterfield_flatten;
|
|
if (! is_array($filtervalue)) {
|
|
$filtervalue = [$filtervalue];
|
|
}
|
|
$urlquery['filtervalue'] = is_array($filtervalue) ? implode(':', $filtervalue) : $filtervalue;
|
|
if (is_array($exactvalue)) {
|
|
$urlquery['exactvalue'] = implode(':', array_map(
|
|
function ($ev) {
|
|
return is_array($ev) ?
|
|
key($ev) . reset($ev)
|
|
: $ev;
|
|
},
|
|
$exactvalue
|
|
));
|
|
} else {
|
|
$urlquery['exactvalue'] = $exactvalue;
|
|
}
|
|
$urlquery['trackerId'] = $trackerId;
|
|
$smarty->assign('urlquery', $urlquery);
|
|
} else {
|
|
$smarty->assign('urlquery', '');
|
|
}
|
|
if (! empty($export) && $export != 'n' && $perms['tiki_p_export_tracker'] == 'y') {
|
|
$smarty->loadPlugin('smarty_function_service');
|
|
$exportParams = [
|
|
'controller' => 'tracker',
|
|
'action' => 'export',
|
|
'trackerId' => $trackerId,
|
|
];
|
|
if (! empty($fields)) {
|
|
$exportParams['displayedFields'] = is_array($fields) ? implode(':', $fields) : $fields;
|
|
}
|
|
if (is_array($filterfield)) {
|
|
foreach ($filterfield as $i => $fieldId) {
|
|
$exportParams["f_$fieldId"] = empty($filtervalue[$i]) ? $exactvalue[$i] : $filtervalue[$i];
|
|
if (! empty($filtervalue[$i])) {
|
|
$exportParams["x_$fieldId"] = 't'; // hint exporter that is not a exact match
|
|
}
|
|
}
|
|
} elseif (! empty($filterfield)) {
|
|
$exportParams["f_$filterfield"] = empty($filtervalue) ? $exactvalue : $filtervalue;
|
|
if (! empty($filtervalue)) {
|
|
$exportParams["x_$filterfield"] = 't'; // hint exporter that is not a exact match
|
|
}
|
|
}
|
|
$exportUrl = 'tiki-export_tracker.php?' . http_build_query($exportParams);
|
|
$smarty->assign('exportUrl', $exportUrl);
|
|
}
|
|
|
|
if (! empty($_REQUEST['delete'])) {
|
|
$itemToDelete = Tracker_Item::fromId($_REQUEST['delete']);
|
|
if ($itemToDelete->canRemove()) {
|
|
$trklib->remove_tracker_item($_REQUEST['delete']);
|
|
}
|
|
|
|
if (! empty($urlafterdelete)) {
|
|
header("Location: $urlafterdelete");
|
|
exit;
|
|
}
|
|
}
|
|
if (! empty($_REQUEST['closeitem'])) {
|
|
$itemToModify = Tracker_Item::fromId($_REQUEST['closeitem']);
|
|
if ($itemToModify->canModify()) {
|
|
$trklib->change_status([['itemId' => $_REQUEST['closeitem']]], 'c');
|
|
}
|
|
}
|
|
if (! empty($_REQUEST['penditem'])) {
|
|
$itemToModify = Tracker_Item::fromId($_REQUEST['penditem']);
|
|
if ($itemToModify->canModify()) {
|
|
$trklib->change_status([['itemId' => $_REQUEST['penditem']]], 'p');
|
|
}
|
|
}
|
|
if (! empty($_REQUEST['openitem'])) {
|
|
$itemToModify = Tracker_Item::fromId($_REQUEST['openitem']);
|
|
if ($itemToModify->canModify()) {
|
|
$trklib->change_status([['itemId' => $_REQUEST['openitem']]], 'o');
|
|
}
|
|
}
|
|
if (! empty($calendarfielddate)) {
|
|
$calendarlib = TikiLib::lib('calendar');
|
|
$focusDate = empty($_REQUEST['todate']) ? $tikilib->now : $_REQUEST['todate'];
|
|
$focus = $calendarlib->infoDate($focusDate);
|
|
if (! empty($calendardelta)) {
|
|
if ($calendardelta[0] == '-') {
|
|
$focus = $calendarlib->focusPrevious($focus, str_replace('-', '', $calendardelta));
|
|
} else {
|
|
$focus = $calendarlib->focusNext($focus, str_replace('+', '', $calendardelta));
|
|
}
|
|
}
|
|
|
|
$calendarlib->focusStartEnd($focus, $calendarviewmode, $calendarbeginmonth, $startPeriod, $startNextPeriod);
|
|
$cell = $calendarlib->getTableViewCells($startPeriod, $startNextPeriod, $calendarviewmode, $calendarlib->firstDayofWeek($user));
|
|
|
|
if (is_array($filterfield) == false) {
|
|
$filterfield = [$filterfield];
|
|
}
|
|
|
|
if (is_array($filtervalue) == false) {
|
|
$filtervalue = [$filtervalue];
|
|
}
|
|
|
|
$filterfield[] = $calendarfielddate[0];
|
|
$filtervalue[] = '';
|
|
$exactvalue[] = ['>=' => $startPeriod['date']];
|
|
$filterfield[] = empty($calendarfielddate[1]) ? $calendarfielddate[0] : $calendarfielddate[1];
|
|
$filtervalue[] = '';
|
|
$exactvalue[] = ['<' => $startNextPeriod['date']];
|
|
}
|
|
|
|
if (count($passfields)) {
|
|
// Optimization: Group category fields using AND logic indicated by sub-array
|
|
$catfilters = [];
|
|
$catfiltervalue = [];
|
|
$catfilternotvalue = [];
|
|
if (! empty($filterfield)) {
|
|
foreach ($filterfield as $k => $ff) {
|
|
if (! empty($ff['usersearch'])) {
|
|
continue;
|
|
}
|
|
$filterfieldinfo = $trklib->get_tracker_field($ff);
|
|
if ($filterfieldinfo['type'] == 'e') {
|
|
$catfilters[] = $k;
|
|
if (! empty($filtervalue[$k]) && empty($exactvalue[$k])) {
|
|
// Some people use filtervalue instead of exactvalue for category filters
|
|
$exactvalue[$k] = $filtervalue[$k];
|
|
for ($i = 0; $i < $k; $i++) {
|
|
if (! isset($exactvalue[$i])) {
|
|
$exactvalue[$i] = '';
|
|
}
|
|
}
|
|
}
|
|
if (array_key_exists('not', [$exactvalue[$k]])) {
|
|
$catfilternotfield[0] = $ff;
|
|
$catfilternotvalue[] = [$exactvalue[$k]];
|
|
} else {
|
|
$catfilterfield[0] = $ff;
|
|
$catfiltervalue[] = [$exactvalue[$k]];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ($catfilters) {
|
|
foreach ($catfilters as $cf) {
|
|
unset($filterfield[$cf]);
|
|
unset($exactvalue[$cf]);
|
|
}
|
|
if ($catfiltervalue) {
|
|
// array_merge is used because it reindexes
|
|
$filterfield = array_merge($filterfield, $catfilterfield);
|
|
$exactvalue = array_merge($exactvalue, [$catfiltervalue]);
|
|
}
|
|
if ($catfilternotvalue) {
|
|
$filterfield = array_merge($filterfield, $catfilternotfield);
|
|
$exactvalue[] = ['not' => $catfilternotvalue];
|
|
}
|
|
}
|
|
// End Optimization
|
|
//fetch tracker items
|
|
$items = $trklib->list_items(
|
|
$trackerId,
|
|
$tr_offset,
|
|
$max,
|
|
$tr_sort_mode,
|
|
$passfields,
|
|
(! empty($calendarfielddate) ? null : $filterfield),
|
|
$filtervalue,
|
|
$tr_status,
|
|
$tr_initial,
|
|
$exactvalue,
|
|
$filter,
|
|
$allfields,
|
|
$skip_status_perm_check
|
|
);
|
|
/*** tablesorter ***/
|
|
if ($tsOn && ! $tsAjax) {
|
|
// when using serverside filtering check wether a dropdown is in use
|
|
// and we must take params from tracker definition because no explicit options have been defined
|
|
if ($tsServer) {
|
|
//format from plugin: type:text|type:dropdown;option:1=Open;option:2=Closed|type:text|type:nofilter|type:nofilter|type:nofilter
|
|
if (! empty($tsfilters) && strpos($tsfilters, 'dropdown') !== false) {
|
|
$tsfiltersArray = explode('|', $tsfilters);
|
|
$adjustCol = (isset($showstatus) && $showstatus == 'y' && $definition->isEnabled('showStatus')) ? -1 : 0;
|
|
foreach ($tsfiltersArray as $col => &$tsfilterField) {
|
|
// only consider dropdown definitions without explicit option
|
|
if (strpos($tsfilterField, 'dropdown') !== false && strpos($tsfilterField, 'option') === false) {
|
|
//content from options (json object): {"options":["1=Open"," 2=Closed]} - note there can be whitespaces - it should not but there can be - yet another fix required
|
|
if ($allfields['data'][$col + $adjustCol]['type'] == 'd') {
|
|
$options = $allfields['data'][$col + $adjustCol]['options'];
|
|
$options = json_decode($options);
|
|
$options = $options->options;
|
|
// construct the new dropdown filterfield entry from the trackerfield definition
|
|
$newTsfilterField = 'type:dropdown';
|
|
foreach ($options as $option) {
|
|
$newTsfilterField .= ";option:" . trim($option);
|
|
}
|
|
// update field - note that we used a ref
|
|
$tsfilterField = $newTsfilterField;
|
|
}
|
|
}
|
|
}
|
|
// update tsfilters
|
|
$tsfilters = implode('|', $tsfiltersArray);
|
|
}
|
|
}
|
|
$ts_id = 'wptrackerlist' . $trackerId . '-' . $iTRACKERLIST;
|
|
$ts = new Table_Plugin();
|
|
$ts->setSettings(
|
|
$ts_id,
|
|
isset($server) ? $server : null,
|
|
$sortable,
|
|
isset($sortList) ? $sortList : null,
|
|
isset($tsortcolumns) ? $tsortcolumns : null,
|
|
isset($tsfilters) ? $tsfilters : null,
|
|
isset($tsfilteroptions) ? $tsfilteroptions : null,
|
|
isset($tspaginate) ? $tspaginate : null,
|
|
isset($tscolselect) ? $tscolselect : null,
|
|
$GLOBALS['requestUri'],
|
|
$items['cant'],
|
|
isset($tstotals) ? $tstotals : null,
|
|
isset($tstotalformat) ? $tstotalformat : null,
|
|
isset($tstotaloptions) ? $tstotaloptions : null
|
|
);
|
|
//loads the jquery tablesorter code
|
|
if (is_array($ts->settings)) {
|
|
$ts->settings['ajax']['offset'] = 'tr_offset' . $iTRACKERLIST;
|
|
Table_Factory::build('PluginWithAjax', $ts->settings);
|
|
}
|
|
}
|
|
//determine whether totals will be added to bottom of table
|
|
if (isset($ts->settings)) {
|
|
Table_Totals::setTotals($ts->settings);
|
|
if (isset($ts->settings['pager']['max']) && $ts->settings['pager']['max'] > 0 && $tsServer) {
|
|
$items['data'] = array_slice($items['data'], 0, $ts->settings['pager']['max']);
|
|
}
|
|
}
|
|
//handle certain tablesorter sorts
|
|
if (isset($sortcol) && $items['cant'] > 1) {
|
|
$fieldtype = $items['data'][0]['field_values'][$sortcol + $adjustCol]['type'];
|
|
//convert categoryId sort to category name sort when tablesorter server side sorting is used
|
|
if ($fieldtype === 'e') {
|
|
foreach ($items['data'] as $key => $record) {
|
|
$catfield = $record['field_values'][$sortcol + $adjustCol];
|
|
$sortarray[$key] = $catfield['list'][$catfield['value']]['name'];
|
|
}
|
|
//sort status
|
|
} elseif ($adjustCol === -1 && $sortcol === 0) {
|
|
$sortarray = array_column($items['data'], 'status');
|
|
}
|
|
array_multisort($sortarray, $dir == '_desc' ? SORT_DESC : SORT_ASC, $items['data']);
|
|
}
|
|
/*** end second tablesorter section ***/
|
|
|
|
if (isset($silent) && $silent == 'y' && empty($items['cant'])) {
|
|
return;
|
|
}
|
|
|
|
if (isset($items['cant']) && $items['cant'] == 1 && isset($goIfOne) && ($goIfOne == 'y' || $goIfOne == 1)) {
|
|
header('Location: tiki-view_tracker_item.php?itemId=' . $items['data'][0]['itemId'] . '&trackerId=' . $items['data'][0]['trackerId']);
|
|
die;
|
|
}
|
|
|
|
if ($newItemRateField && ! empty($items['data'])) {
|
|
foreach ($items['data'] as $f => $v) {
|
|
$items['data'][$f]['my_rate'] = $tikilib->get_user_vote("tracker." . $trackerId . '.' . $items['data'][$f]['itemId'], $user);
|
|
}
|
|
}
|
|
|
|
if (! empty($items['data']) && $showcomments != 'n' && ($definition->isEnabled('useComments') && $definition->isEnabled('showComments') || $definition->isEnabled('showLastComment') )) {
|
|
foreach ($items['data'] as $itkey => $oneitem) {
|
|
if ($definition->isEnabled('showComments')) {
|
|
$items['data'][$itkey]['comments'] = $trklib->get_item_nb_comments($items['data'][$itkey]['itemId']);
|
|
}
|
|
if ($definition->isEnabled('showLastComment')) {
|
|
$l = $trklib->list_last_comments($items['data'][$itkey]['trackerId'], $items['data'][$itkey]['itemId'], 0, 1);
|
|
$items['data'][$itkey]['lastComment'] = ! empty($l['cant']) ? $l['data'][0] : '';
|
|
}
|
|
}
|
|
}
|
|
|
|
if (! empty($items['data']) && ($definition->isEnabled('useAttachments') && $definition->isEnabled('showAttachments'))) {
|
|
foreach ($items["data"] as $itkey => $oneitem) {
|
|
$res = $trklib->get_item_nb_attachments($items["data"][$itkey]['itemId']);
|
|
$items["data"][$itkey]['attachments'] = $res['attachments'];
|
|
}
|
|
}
|
|
|
|
if (! empty($compute) && ! empty($items['data'])) {
|
|
$fs = preg_split('/ *: */', $compute);
|
|
foreach ($fs as $fieldId) {
|
|
if (strstr($fieldId, "/")) {
|
|
list($fieldId, $oper) = preg_split('/ *\/ */', $fieldId);
|
|
$oper = strtolower($oper);
|
|
if ($oper == 'average') {
|
|
$oper = 'avg';
|
|
} elseif ($oper != 'sum' && $oper != 'avg') {
|
|
$oper = 'sum';
|
|
}
|
|
} else {
|
|
$oper = 'sum';
|
|
}
|
|
foreach ($items['data'] as $i => $item) {
|
|
foreach ($item['field_values'] as $field) {
|
|
if ($field['fieldId'] == $fieldId) {
|
|
if (preg_match('/^ *$/', $field['value']) || ! is_numeric($field['value'])) {
|
|
$amount[$i] = '0';
|
|
} else {
|
|
$amount[$i] = $field['value'];
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
$value = array_sum($amount);
|
|
if ($oper == 'avg') {
|
|
$value = round($value / count($amount));
|
|
}
|
|
$computedFields[$fieldId][] = array_merge(['computedtype' => 'n', 'operator' => $oper, 'value' => $value], $passfields[$fieldId]);
|
|
}
|
|
$smarty->assign_by_ref('computedFields', $computedFields);
|
|
} else {
|
|
$smarty->assign('computedFields', '');
|
|
}
|
|
|
|
if (! empty($items['data'])) {
|
|
foreach ($items['data'] as &$item) {
|
|
$item['editableFields'] = [];
|
|
if (! empty($editable)) {
|
|
$itemObject = Tracker_Item::fromInfo($item);
|
|
foreach ($editable as $editableFieldId) {
|
|
if ($itemObject->canModifyField($editableFieldId)) {
|
|
$item['editableFields'][] = $editableFieldId;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (! empty($calendarfielddate)) {
|
|
foreach ($items['data'] as $i => $item) {
|
|
if (! empty($wiki)) {
|
|
$smarty->assign('fields', $item['field_values']);
|
|
$smarty->assign('item', $item);
|
|
$smarty->assign('wiki', "wiki:$wiki");
|
|
$smarty->assign('showpopup', 'n');
|
|
try {
|
|
$items['data'][$i]['over'] = $smarty->fetch('tracker_pretty_item.tpl');
|
|
} catch (SmartyException $se) {
|
|
$items['data'][$i]['over'] = $se->getMessage();
|
|
}
|
|
}
|
|
if (! empty($tplwiki)) {
|
|
$smarty->assign('fields', $item['field_values']);
|
|
$smarty->assign('item', $item);
|
|
$smarty->assign('wiki', "tplwiki:$tplwiki");
|
|
$smarty->assign('showpopup', 'n');
|
|
try {
|
|
$items['data'][$i]['over'] = $smarty->fetch('tracker_pretty_item.tpl');
|
|
} catch (SmartyException $se) {
|
|
$items['data'][$i]['over'] = $se->getMessage();
|
|
}
|
|
}
|
|
if (empty($items['data'][$i]['over'])) {
|
|
$items['data'][$i]['over'] = $trklib->get_isMain_value($trackerId, $item['itemId']);
|
|
}
|
|
$items['data'][$i]['visible'] = 'y';
|
|
}
|
|
$trklib->fillTableViewCell($items['data'], $calendarfielddate, $cell);
|
|
$smarty->assign('cell', $cell);
|
|
$smarty->assign('show_calendar_module', 'y');
|
|
$calendarlib->getDayNames($calendarlib->firstDayofWeek($user), $daysnames, $daysnames_abr);
|
|
$smarty->assign('daysnames_abr', $daysnames_abr);
|
|
$smarty->assign('focusmonth', TikiLib::date_format("%m", $focusDate));
|
|
$smarty->assign('module_params', ['viewmode' => 'n', 'showaction' => 'n', 'notitle' => empty($calendartitle) ? 'y' : 'n', 'title' => $calendartitle, 'viewnavbar' => $calendarviewnavbar, 'decorations' => empty($calendartitle) ? 'n' : 'y']);
|
|
$smarty->assign('tpl_module_title', tra($calendartitle));
|
|
$smarty->assign('now', $tikilib->now);
|
|
$smarty->assign('calendarViewMode', $calendarviewmode);
|
|
$smarty->assign('viewmodelink', $calendarviewmode);
|
|
$smarty->assign('viewmode', $calendarviewmode);
|
|
$focus_prev = $calendarlib->focusPrevious($focus, $calendarviewmode);
|
|
$smarty->assign('focus_prev', $focus_prev['date']);
|
|
$focus_next = $calendarlib->focusNext($focus, $calendarviewmode);
|
|
$smarty->assign('focus_next', $focus_next['date']);
|
|
$smarty->assign('daystart', $startPeriod['date']);
|
|
$dayend = $calendarlib->infoDate($startNextPeriod['date'] - 1);
|
|
$smarty->assign('dayend', $dayend['date']);
|
|
$smarty->assign('today', $tikilib->make_time(0, 0, 0, TikiLib::date_format('%m'), TikiLib::date_format('%d'), TikiLib::date_format('%Y')));
|
|
$smarty->assign('sticky_popup', $calendarstickypopup);
|
|
$smarty->assign('calendar_popup', $calendarpopup);
|
|
$smarty->assign('showpopup', 'n');
|
|
$headerlib = TikiLib::lib('header');
|
|
$headerlib->add_cssfile('themes/base_files/feature_css/calendar.css', 20);
|
|
return $smarty->fetch('modules/mod-calendar_new.tpl');
|
|
}
|
|
if (! empty($wiki)) {
|
|
$tpl = "wiki:$wiki";
|
|
} elseif (! empty($tplwiki)) {
|
|
$tpl = "tplwiki:$tplwiki";
|
|
} elseif (empty($tpl)) {
|
|
$tpl = '';
|
|
}
|
|
if (! empty($tpl)) {
|
|
$smarty->security = true;
|
|
}
|
|
$smarty->assign('tpl', $tpl);
|
|
|
|
if (! empty($itemId) && $showpagination == 'y' && ! empty($_REQUEST['cant'])) {
|
|
$smarty->assign('max', 1);
|
|
$smarty->assign('count_item', $_REQUEST['cant']);
|
|
$smarty->assign('offset_arg', 'reloff');
|
|
$smarty->assign("tr_offset$iTRACKERLIST", $_REQUEST['reloff']);
|
|
} else {
|
|
$smarty->assign_by_ref('max', $max);
|
|
$smarty->assign_by_ref('item_count', $items['cant']);
|
|
$smarty->assign_by_ref('count_item', $items['cant']);
|
|
$smarty->assign('offset_arg', "tr_offset$iTRACKERLIST");
|
|
}
|
|
$smarty->assign_by_ref('items', $items["data"]);
|
|
$smarty->assign('daformat', $tikilib->get_long_date_format() . " " . tra("at") . " %H:%M");
|
|
|
|
if (! empty($params['showmap']) && $params['showmap'] == 'y') {
|
|
$smarty->assign('trackerlistmapview', true);
|
|
$smarty->assign('trackerlistmapname', "trackerlistmap_$iTRACKERLIST");
|
|
} else {
|
|
$smarty->assign('trackerlistmapview', false);
|
|
}
|
|
|
|
if (isset($items['data'])) {
|
|
foreach ($items['data'] as $score_item) {
|
|
$item_info = $trklib->get_tracker_item($score_item['itemId']);
|
|
$currentItemId = $score_item['itemId'];
|
|
|
|
TikiLib::events()->trigger(
|
|
'tiki.trackeritem.view',
|
|
[
|
|
'type' => 'trackeritem',
|
|
'object' => $currentItemId,
|
|
'owner' => $item_info['createdBy'],
|
|
'user' => $GLOBALS['user'],
|
|
]
|
|
);
|
|
}
|
|
}
|
|
|
|
$tracker = $trklib->get_tracker($trackerId, 0, -1);
|
|
/*foreach ($query_array as $k=>$v) {
|
|
if (!is_array($v)) { //only to avoid an error: eliminate the params that are not simple (ex: if you have in the same page a tracker list plugin and a tracker plugin, filling the tracker plugin interfers with the tracker list. In any case this is buggy if two tracker list plugins in the same page and if one needs the query value....
|
|
$quarray[] = urlencode($k) ."=". urlencode($v);
|
|
}
|
|
}
|
|
if (is_array($quarray)) {
|
|
$query_string = implode("&",$quarray);
|
|
} else {
|
|
$quering_string = '';
|
|
}
|
|
$smarty->assign('query_string', $query_string);
|
|
*/
|
|
if (! $tracker) {
|
|
$smarty->assign('msg', tra("Error in tracker ID"));
|
|
return $smarty->fetch("error_raw.tpl");
|
|
} else {
|
|
$save_fc = null;
|
|
if (! empty($wiki) && $params['force_compile'] === 'y') { // some pretty trackers need to compile fresh for each item
|
|
$save_fc = $smarty->force_compile;
|
|
$smarty->force_compile = true;
|
|
}
|
|
|
|
|
|
//this options preloads the javascript for displaying sheets
|
|
if (! empty($displaysheet) && $displaysheet == 'y') {
|
|
$headerlib = TikiLib::lib("header");
|
|
$sheetlib = TikiLib::lib("sheet");
|
|
|
|
$sheetlib->setup_jquery_sheet();
|
|
$headerlib->add_jq_onready(
|
|
'$("div.trackercontainer").sheet($.extend($.sheet.tikiOptions,{
|
|
editable:false,
|
|
buildSheet: true,
|
|
minSize: {rows: 0, cols: 0}
|
|
}));'
|
|
);
|
|
|
|
$smarty->assign('displaysheet', 'true');
|
|
}
|
|
|
|
//this method sets up the sheet just like it would for jquery.sheet, but assumes that the javascript will be handled elsewere
|
|
if (! empty($tableassheet) && $tableassheet == 'y') {
|
|
$smarty->assign('tableassheet', 'true');
|
|
}
|
|
$smarty->assign('context', $params);
|
|
try {
|
|
$str = $smarty->fetch('wiki-plugins/wikiplugin_trackerlist.tpl');
|
|
} catch (SmartyException $e) {
|
|
$str = $e->getMessage();
|
|
}
|
|
if ($save_fc !== null) {
|
|
$smarty->force_compile = $save_fc; // presumably will be false but put it back anyway
|
|
}
|
|
|
|
return $str;
|
|
}
|
|
} else {
|
|
$smarty->assign('msg', tra("No field indicated"));
|
|
return $smarty->fetch("error_raw.tpl");
|
|
}
|
|
}
|
|
return $back;
|
|
}
|