'', 'unfiltered' => ':not(.filtered)', 'all' => '*', 'hidden' => ':hidden', ]; /** * Creates parameters that can be appended to a plugin's native parameters so the user can * set tablesorter functionality */ public function createParams() { $this->params = [ 'server' => [ 'required' => false, 'name' => tra('Server-side Processing'), 'description' => tr( 'Enter %0y%1 to have the server do the sorting and filtering through Ajax and %0n%1 to have the browser do it (n is the default). Set to %0y%1 (and also set the Paginate parameter (%0tspaginate%1)) if you do not want all rows fetched at once, but rather fetch rows as you paginate, filter or sort.', '', '' ), 'since' => '12.0', 'doctype' => 'tablesorter', 'default' => 'n', 'filter' => 'striptags', ], 'sortable' => [ 'required' => false, 'name' => tra('Overall Sort Settings'), 'description' => tr( 'Serves as the overall switch for turning jQuery Tablesorter on (also for filtering) as well as overall sort settings. Enter %0y%1 to allow sorting and %0n%1 to disallow (n is the default). Enter %0type:save%1 to allow sorts to be saved between page refreshes. Enter %0type:%2reset%3;text:*****%1 to allow sorting and show an unsort button with custom text. Enter %0type:%2savereset%3;text:buttontext%1 to allow the same for saved sorts.', '', '', '', '' ), 'since' => '12.0', 'doctype' => 'tablesorter', 'default' => 'n', 'filter' => 'striptags', ], 'sortList' => [ 'required' => false, 'name' => tra('Pre-sorted Columns'), 'description' => tr( 'Bracketed numbers for column number (first column = 0) and sort direction (%20%3 = ascending, %21%3 = descending, %2n%3 = no sort, %2y%3 = allow sorting but no pre-sort), for example: %0. If the first pre-sorted or no filter column is not the first column, then you should use the %2y%3 parameter (as in %1) to assign all previous columns.', '~np~[0,y],[1,0],[2,n]~/np~', '~np~[0,y]~/np~', '', '' ), 'since' => '12.0', 'doctype' => 'tablesorter', 'default' => '', 'filter' => 'striptags', 'advanced' => true, ], 'tsortcolumns' => [ 'required' => false, 'name' => tra('Sort Settings by Column'), 'description' => tr( 'Set %0 and %1 settings for each column, using %2 to separate columns. To show group headings upon page load, the Pre-sorted Columns parameter (%3) will need to be set for a column with a group setting. Group will not work in plugins where the Server Side Processing parameter (%4) is set to %5.', 'type', 'group', '|', '0sortList', 'server', 'y' ) . '
' . tr('Set %0 to one of the following:', 'type') . ' text, digit, currency, percent, usLongDate, shortDate, isoDate, dateFormat-ddmmyyyy, ipAddress, url, time', 'nosort' . '
' . tr('Also handle strings in numeric columns with:') . ' string-min, string-max' . tr('Handle empty cells with:') . ' empty-top, empty-bottom, empty-zero.
' . tr( '%0 creates automatic row headings upon sort with the heading text determined by the setting as follows: %1 (first letter), %2 (first word)', 'group', 'letter', 'word' ) . ', number, date, date-year, date-month, date-day, date-week, date-time.' . tr( '%0 and %1 can be extended, e.g., %2 shows the first 2 words. %3 will group rows in blocks of ten. Group will not work in plugins where the Server Side Processing parameter (%4) is set to %5.', 'letter', 'word', 'word-2', 'number-10', 'server', 'y' ), 'since' => '12.0', 'doctype' => 'tablesorter', 'default' => '', 'filter' => 'striptags', 'advanced' => true, ], 'tsfilters' => [ 'required' => false, 'name' => tra('Column Filters'), 'description' => tr( 'Enter %0 for a blank text filter on all columns, or %1 for no filters. Or set custom column filters separated by %2 for each column for the following filter choices and parameters:', 'y', 'n', '|' ) . '
Text - type:text;placeholder:xxxx
' . tra( '(For PluginTrackerlist this will be an exact search, for other plugins partial values will work.)' ) . '
' . tra( 'From Tiki 18, you can add initial:t option to allow prefix search for text filter. E.g. type:text;initial:t' ) . '
Dropdown - type:dropdown;placeholder:****;empty:****;option:****;option:****;option:****
' . tr( 'Options generated automatically if not set and the %0server%1 parameter is not %0y%1.', '', '' ) . '
' . tr( 'Use %0value=Display label%1 to have the option value be different than the displayed label in the dropdown.', '', '' ) . '
' . tr( 'Use %0empty:Display label%1 to include an option with the specified label that will filter only empty rows. Only used if other options are not specified manually.', '', '' ) . '
' . tra( 'Date range - ' ) . 'type:date;format:yy-mm-dd;from:2013-06-30;to:2020-12-31
' . tra('(from and to values set defaults for these fields when user clicks on the input field)') . tra( 'Beware that items with empty date values will not be shown when default date range filters are applied.' ) . '
' . tra('Numeric range - ') . 'type:range;from:0;to:50
' . tra('No filter - ') . 'type:nofilter
' . tr( 'For example: %0tsfilters="type:dropdown;placeholder:Type to filter..."%1 would result in a dropdown filter on the first column with all unique values in that column in the dropdown list.', '', '' ), 'since' => '12.0', 'doctype' => 'tablesorter', 'default' => '', 'filter' => 'striptags', 'advanced' => true, ], 'tsfilteroptions' => [ 'required' => false, 'name' => tra('Filter Options'), 'description' => tr( 'The following options are available: %0reset%1 (adds button to take off filters), and %0hide%1 (Filters are revealed upon mouseover. Hide doesn\'t work when date and range filters are used.). To use both, set %0tsfilteroptions="type:reset;text:button text;style:hide"%1', '', '' ), 'since' => '12.0', 'doctype' => 'tablesorter', 'default' => '', 'filter' => 'striptags', 'advanced' => true, ], 'tspaginate' => [ 'required' => false, 'name' => tra('Paginate'), 'description' => tr( 'Enter %0y%1 to set default values based on the site setting for maximum records in listings (on the pagination table of the Look & Feel admin panel). Set to %0n%1 (and %0server%1 cannot be set to %0y%1) for no pagination. Set custom values as in the following example: ', '', '' ) . 'max:40;expand:60;expand:100;expand:140', 'since' => '12.0', 'doctype' => 'tablesorter', 'default' => '', 'filter' => 'striptags', 'advanced' => true, ], 'tscolselect' => [ 'required' => false, 'name' => tra('Column Select'), 'description' => tr( 'Add a button for hiding and re-showing columns. Also sets priority for dropping columns when browser is too narrow. Set each column to a number between 1 and 6 (1 is highest priority and last to be dropped) or to %0critical%1 to never hide or drop. An example with 4 columns:', '', '' ) . 'tscolselect="critical|4|5|6"', 'since' => '14.0', 'doctype' => 'tablesorter', 'default' => '', 'filter' => 'striptags', 'advanced' => true, ], 'tstotals' => [ 'required' => false, 'name' => tra('Totals'), 'description' => tr( 'Generate table, column or row totals and set labels, using either %0 or the following syntax for each total: %1.', 'y', 'type:value;formula:value;filter:value;label:value' ) . '
' . tr( 'Setting to %0 will add one column total row set as follows: %1.', '(y)', 'type:col;formula:sum;filter:visible;label:Totals' ) . '
' . tr( 'Separate multiple total row or column settings with a pipe %0. Set %1 only to generate sums of visible values. In all cases, cells in columns set to be ignored in the %2 parameter will not be included in calculations.', '(|)', 'type', 'tstotaloptions' ) . '
' . tr('Instructions for each total option follows:') . '
type - ' . tr( 'Choices are %0, for a row of columns totals, %1, for a column of row totals, and %2 to include amounts from all cells in the table body in a row total.', 'col', 'row', 'all', 'tstotaloptions' ) . '
formula - ' . tr('set what the calculation is. Choices are:') . ' sum, count, max, min, mean, median, mode, range, varp, vars, stdevp, stdevs. ' . tr( 'Click %0 for a description of these options.', 'here' ) . '
filter - ' . tr( 'Determines the rows that will be included in the calculations (so no impact if %0). Also, when %1, only visible cells are included regardless of this setting. Choices are %2 (rows visible on the page), %3 (all rows not filtered out, even if not visible because of pagination), %4 (all rows, even if filtered or hidden), and %5 (rows filtered out and rows hidden due to pagination).', 'type:row', 'server="y"', 'visible', 'unfiltered', 'all', 'hidden' ) . '
label - ' . tr( 'set the label for the total, which will appear in the header for row totals and in the first column for column totals.' ), 'since' => '15.0', 'doctype' => 'tablesorter', 'default' => '', 'filter' => 'striptags', 'advanced' => true, ], 'tstotalformat' => [ 'required' => false, 'name' => tra('Total Format'), 'description' => tr( 'Format for table totals (click %0 for patterns). Example:', 'here' ) . ' #,###.
', ], 'tstotaloptions' => [ 'required' => false, 'name' => tra('Total Options'), 'description' => tr( 'Pipe-separated options for totals for each column which are set in the %0 parameter:', 'tstotals' ) . '
format - ' . tr('overrides the default number format set in %0', 'tstotalformat') . '
' . 'ignore - ' . tr( 'column will be excluded from total calculations set in the %0 parameter. Remember to include any columns that will be added for row totals set in the %0 parameter.', 'tstotals' ) . '
' . tr('Example:') . 'ignore|ignore|#,###.', 'since' => '15.0', 'doctype' => 'tablesorter', 'default' => '', 'filter' => 'striptags', 'advanced' => true, ], ]; } /** * To be used within plugin program to convert user parameter settings into the settings array * that can be used by Table_Factory to generate the necessary jQuery * * @param null $id //html element id for table and surrounding div * @param string $server //see params above * @param string $sortable //see params above * @param null $sortList //see params above * @param null $tsortcolumns //see params above * @param null $tsfilters //see params above * @param null $tsfilteroptions //see params above * @param null $tspaginate //see params above * @param null $tscolselect //see params above * @param null $ajaxurl //only needed if ajax will be used to pull partial record sets * @param null $totalrows //only needed if ajax will be used to pull partial record sets * @param null $tstotals //see params above * @param null $tstotaloptions //see params above */ public function setSettings( $id = null, $server = 'n', $sortable = 'n', $sortList = null, $tsortcolumns = null, $tsfilters = null, $tsfilteroptions = null, $tspaginate = null, $tscolselect = null, $ajaxurl = null, $totalrows = null, $tstotals = null, $tstotalformat = null, $tstotaloptions = null, $showProcessing = 'y', $ignoreCase = 'y', $sortLocaleCompare = 'y' ) { $s = []; //id if (! empty($id)) { $s['id'] = $id; } //sortable switch ($sortable) { case 'y': case 'server': $s['sorts']['type'] = true; break; case 'n': $s['sorts']['type'] = false; break; default: $sp = Table_Check::parseParam($sortable); if (isset($sp[0]['type'])) { $s['sorts']['type'] = $sp[0]['type']; } } //sortlist if (! empty($sortList) && (! isset($s['sorts']['type']) || $s['sorts']['type'] !== false)) { $crop = substr($sortList, 1); $crop = substr($crop, 0, -1); $slarray = explode('],[', $crop); if (is_array($slarray)) { foreach ($slarray as $l) { $lpieces = explode(',', $l); if (isset($lpieces[1])) { switch ($lpieces[1]) { case '0': $dir = 'asc'; break; case '1': $dir = 'desc'; break; case 'y': $dir = true; break; case 'n': $dir = false; break; default: if ($s['sorts']['type'] !== false) { $dir = true; } else { $dir = false; } } if ($dir === false || $dir === true) { $s['columns'][$lpieces[0]]['sort']['type'] = $dir; } else { $s['columns'][$lpieces[0]]['sort']['dir'] = $dir; } } } } } //tsortcolumns if (! empty($tsortcolumns)) { $tsc = Table_Check::parseParam($tsortcolumns); if (is_array($tsc)) { foreach ($tsc as $col => $sortinfo) { if (isset($sortinfo['type']) && $sortinfo['type'] == 'nosort') { $sortinfo['type'] = false; } if (isset($s['columns'][$col]['sort'])) { $s['columns'][$col]['sort'] = $s['columns'][$col]['sort'] + $sortinfo; } else { $s['columns'][$col]['sort'] = $sortinfo; } } ksort($s['columns']); } if ($server === 'y') { $s['sorts']['group'] = false; } } else { $s['sorts']['group'] = false; } //tsfilters if (! empty($tsfilters)) { switch ($tsfilters) { case 'y': $s['filters']['type'] = 'text'; break; case 'n': $s['filters']['type'] = false; break; default: $tsf = Table_Check::parseParam($tsfilters); if (is_array($tsf)) { foreach ($tsf as $col => $filterinfo) { if ( isset($filterinfo['type']) && $filterinfo['type'] === 'dropdown' && ! empty($filterinfo['options']) ) { foreach ($filterinfo['options'] as $key => $value) { $filterinfo['options'][$key] = str_replace('=', '|', $value); } } if (isset($s['columns'][$col]['filter'])) { $s['columns'][$col]['filter'] = $s['columns'][$col]['filter'] + $filterinfo; } else { $s['columns'][$col]['filter'] = $filterinfo; } } } } } //tsfilteroptions if (! empty($tsfilteroptions) && ! empty($s['filters']['type'])) { $tsfo = Table_Check::parseParam($tsfilteroptions); switch ($tsfo[0]['type']) { case 'reset': $s['filters']['type'] = 'reset'; break; case 'hide': $s['filters']['hide'] = true; break; } } //tspaginate if (empty($tspaginate)) { $tspaginate = $server === 'y' ? 'y' : ''; } if (! empty($tspaginate)) { $tsp = Table_Check::parseParam($tspaginate); //pagination must be on if server side processing is on ($server == 'y') if (is_array($tsp[0]) || $tsp[0] !== 'n' || ($tsp[0] === 'n' && $server === 'y')) { if (is_array($tsp[0])) { $s['pager'] = $tsp[0]; if (isset($s['pager']['expand']) && is_array($s['pager']['expand'])) { if (isset($s['pager']['max']) && $s['pager']['max'] > 0) { $s['pager']['expand'] = array_merge([$s['pager']['max']], $s['pager']['expand']); } else { $s['pager']['max'] = min($s['pager']['expand']); } $s['pager']['expand'] = array_unique($s['pager']['expand']); sort($s['pager']['expand']); } } $s['pager']['type'] = true; } elseif ($tsp[0] === 'n' && $server === 'n') { $s['pager']['type'] = false; } } //tscolselect if (! empty($tscolselect)) { $tscs = Table_Check::parseParam($tscolselect); if (is_array($tscs)) { $s['colselect']['type'] = true; foreach ($tscs as $col => $priority) { $s['columns'][$col]['priority'] = $priority; } } } //ajaxurl if (! empty($ajaxurl) && $server === 'y') { $url = $this->getAjaxurl($ajaxurl); $s['ajax']['url']['file'] = $url['path']; $s['ajax']['url']['query'] = $url['query']; $s['ajax']['type'] = true; } else { $s['ajax']['type'] = false; } //totalrows if (! empty($totalrows)) { $s['total'] = $totalrows; } //tstotals if (! empty($tstotals)) { if (trim($tstotals) === 'y') { $tstotals = 'type:col;formula:sum;label:' . tr('Page totals'); } $tst = Table_Check::parseParam($tstotals); if (is_array($tst)) { foreach ($tst as $key => $tinfo) { if (! empty($tinfo['type'] && in_array($tinfo['type'], ['col', 'row', 'all']))) { $s['math']['totals'][$tinfo['type']][$key]['formula'] = ! empty($tinfo['formula']) && in_array($tinfo['formula'], $this->mathtypes) ? $tinfo['formula'] : 'sum'; if (! empty($tinfo['filter']) && isset($this->totalfilters[$tinfo['filter']])) { if ($server === 'y') { $s['math']['totals'][$tinfo['type']][$key]['filter'] = ''; $labelfilter = ''; } else { $s['math']['totals'][$tinfo['type']][$key]['filter'] = $this->totalfilters[$tinfo['filter']]; $labelfilter = $tinfo['filter']; } } else { $s['math']['totals'][$tinfo['type']][$key]['filter'] = ''; $labelfilter = ''; } if (isset($tinfo['label'])) { $s['math']['totals'][$tinfo['type']][$key]['label'] = $tinfo['label']; } else { $map = ['col' => 'Column', 'row' => 'Row', 'all' => 'Table']; $label = $map[$tinfo['type']] . ' ' . $s['math']['totals'][$tinfo['type']][$key]['formula'] . ' ' . $labelfilter; $s['math']['totals'][$tinfo['type']][$key]['label'] = tr($label); } } } } } //tstotalformat if (! empty($tstotalformat)) { $s['math']['format'] = $tstotalformat; } //tstotaloptions if (! empty($tstotaloptions)) { $tsto = Table_Check::parseParam($tstotaloptions); if (is_array($tsto)) { foreach ($tsto as $col => $option) { if ($option === 'ignore') { $s['columns'][$col]['math']['ignore'] = true; //only other option is format } elseif (! empty($option['format'])) { $s['columns'][$col]['math']['format'] = $option['format']; } } } } // misc options $s['showProcessing'] = $showProcessing ?? 'y'; $s['ignoreCase'] = $ignoreCase ?? 'y'; $s['sortLocaleCompare'] = $sortLocaleCompare ?? 'y'; $this->settings = $s; } /** * Utility to add ajax parameters to URL * * @param $ajaxurl * * @return string */ private function getAjaxurl($ajaxurl) { $str = '{sort:sort}&{filter:filter}'; $url = parse_url($ajaxurl); if (isset($url['query'])) { $url['query'] = '?' . $url['query'] . '&' . $str; } else { $url['query'] = '?' . $str; } return $url; } }