ListTable::SetId()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 4
nop 2
dl 0
loc 25
rs 9.52
c 0
b 0
f 0
1
<?php
2
require_once(dirname(__FILE__) . '/fwolflib.php');
3
require_once(FWOLFLIB . 'func/request.php');
4
5
6
/**
7
 * Generate table list
8
 *
9
 * Table head and body are given seperately, but have some relationship,
10
 * you can give head or body contain more data, then limit disp by fit it
11
 * to another part.
12
 *
13
 * Notice: No db query feather in this, data are transferd from outerside.
14
 *
15
 * <code>
16
 * $s = '';
17
 * // Set <thead>
18
 * $art = array('col1' => 'description_col1',
19
 * 		'col2' => 'description_col2',
20
 * 		);
21
 * // Set <thead> without col name, only description given.
22
 * //$art = array('description_col1', 'description_col2');
23
 *
24
 * // Set <tbody> data, 1st dim of ar is row, 2nd dim of ar is col-val pair.
25
 * $ard = array(...);
26
 *
27
 * // Set Config, check manual to see their effect.
28
 * $ar_conf = array(
29
 * 		'fit_data_title' => 3,
30
 * 		);
31
 *
32
 * // New object
33
 * //$this->oLt = new ListTable($this->oTpl, $ard, $art, '', $ar_conf);
34
 * // Or cal SetXxx func, note that SetCfg MUST before SetData
35
 * $this->oLt->SetCfg($ar_conf);
36
 * $this->oLt->SetData($ar, $art);
37
 *
38
 * // Got output html
39
 * $s = $this->oLt->GetHtml();
40
 * </code>
41
 *
42
 * @deprecated  Use Fwlib\Html\ListTable
43
 * @package		fwolflib
44
 * @subpackage	class
45
 * @copyright	Copyright 2003-2011, Fwolf
46
 * @author		Fwolf <[email protected]>
47
 * @since		2003-05-17 12:17:14
48
 */
49
class ListTable extends Fwolflib {
0 ignored issues
show
Deprecated Code introduced by
The class Fwolflib has been deprecated with message: Use classes in Fwlib namespace, see PSR-0/1/2

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
50
	/**
51
	 * Configuration
52
	 *
53
	 * <code>
54
	 * color_bg_[th/tr_even/tr_odd]:
55
	 * 					Colors of rows.
56
	 * color_bg_tr_hover:
57
	 * 					Change to this color when mouseover of row.(Not implement)
58
	 * fit_data_title:	0=data fit title, cut data items who's index not
59
	 * 					in title
60
	 * 					1=title fit data.
61
	 * 					2=fit to fewest, only items both have allowed.
62
	 * 					3=fit to mostest, all items in title or data allowed.
63
	 * fit_empty:		If an value in data is empty, set to this value.
64
	 * 					Title will always set to field name in same situation.
65
	 * code_prefix:		Prefix auto add before $sId, use to generate html.
66
	 * page_cur:		Current page no, ONLY USED TO DISP PAGER.
67
	 * page_param:		Param name of page number in URL,
68
	 * 					Will change if $sId changed.
69
	 * page_size:		Rows per page, ONLY USED TO DISP PAGER, havn't any
70
	 * 					effect to list data.
71
	 * rows_total:		Total rows, ONLY USED TO DISP PAGER.
72
	 * tpl:				Smarty template file to use.
73
	 * </code>
74
	 * @var	array
75
	 */
76
	public $aCfg = array(
77
		// 浅蓝色配色方案
78
		// fwolflib-list-table = fl_lt
79
		'code_prefix'		=> 'fl_lt',		// Used in id/class in html and css.
80
		'color_bg_th'		=> '#d0dcff',	// 表头(第0行)
81
		'color_bg_tr_even'	=> '#fff',		// 偶数行
82
		'color_bg_tr_hover'	=> '#e3e3de',	// 鼠标指向时变色
83
		'color_bg_tr_odd'	=> '#eef2ff',	// 奇数行,tbody后从0开始算
84
		'fit_data_title'	=> 0,
85
		'fit_empty'			=> '&nbsp;',
86
		'orderby'			=> 0,			// 0=off, 1=on
87
		'orderby_dir'		=> 'asc',
88
		'orderby_idx'		=> '',			// Idx of th ar
89
		'orderby_param'		=> 'o',
90
		'orderby_text'		=> '',
91
		// &#8592 = ← &#8593 = ↑ &#8594 = → &#8595 = ↓
92
		// &#8710 = ∆ &#8711 = ∇
93
		'orderby_text_asc'	=> '↑',
94
		'orderby_text_desc'	=> '↓',
95
		'page_cur'			=> 1,
96
		'page_param'		=> 'p',
97
		'page_size'			=> 10,
98
		'pager'				=> false,		// Is or not use pager
99
		'pager_bottom'		=> true,		// Is or not use pager bottom, used when pager=true
100
		// This is a message template
101
		// When display, use key append by '_value'
102
		'pager_text_cur'	=> '共{rows_total}条记录,每页显示{page_size}条,当前为第{page_cur}/{page_max}页',
103
104
		'pager_text_first'	=> '首页',
105
		'pager_text_goto1'	=> '转到第',
106
		'pager_text_goto2'	=> '页',
107
		'pager_text_goto3'	=> '转',
108
		'pager_text_last'	=> '尾页',
109
		'pager_text_next'	=> '下一页',
110
		'pager_text_prev'	=> '上一页',
111
		'pager_text_spacer'	=> ' | ',		// To be between below texts.
112
		'pager_top'			=> true,		// Is or not use pager top, used when pager=true
113
//		'param'				=> 'p',			// Used in url to set page no.
114
		'rows_total'		=> 0,
115
		'tpl'				=> 'list-table.tpl',
116
117
		// Add custom string in td/th/tr tag, eg: nowrap="nowrap"
118
		// td/th can use index same with data array index,
119
		// tr can use int index which's value is string too.
120
		// For tr of th row, use th instead.
121
		'td_add'			=> array(),
122
		'th_add'			=> array(),
123
		'tr_add'			=> array(),
124
		);
125
126
	/**
127
	 * 数组变量,指向要显示数据存放的数组,其格式见类说明
128
	 * @var	array
129
	 */
130
	protected $aData = array();
131
132
	/**
133
	 * Page url param array.
134
	 * @var array
135
	 */
136
	protected $aParam = array();
137
138
	/**
139
	 * Title of data, used as table title.
140
	 * @var	array
141
	 */
142
	protected $aTitle = array();
143
144
	/**
145
	 * Array of url, for links to display in tpl
146
	 * <code>
147
	 * array(
148
	 * 	base	=> Original page url
149
	 * 	o_cur	=> Cur orderby link(modified)
150
	 * 	o_other	=> Other orderby link(modified)
151
	 * 	p_first	=> First page link
152
	 * 	p_last	=> Last page link
153
	 * 	p_next	=> Next page link
154
	 * 	p_prev	=> Prev page link
155
	 * )
156
	 * </code>
157
	 * @var	array
158
	 */
159
	protected $aUrl = array(
160
		'base'			=> '',
161
		'o_cur'			=> '',
162
		'o_other'		=> '',
163
		'p_first'		=> '',
164
		'p_last'		=> '',
165
		'p_next'		=> '',
166
		'p_prev'		=> '',
167
		);
168
169
	/**
170
	 * 模板变量,指向在构造函数中传入的全局模板变量
171
	 * @var	object
172
	 */
173
	protected $oTpl = null;
174
175
	/**
176
	 * Class of this list in html, used with {@see $sId}
177
	 *
178
	 * Diff between $sClass and $sId:
179
	 * $sClass has no prefix, while $sId has.
180
	 * $sClass can be applyed css in project css file,
181
	 * 	while $sId can be applyed css inline in tpl file.
182
	 * @var	string
183
	 */
184
	protected $sClass = 'fl_lt';
185
186
	/**
187
	 * Identify of this list,
188
	 * Also used in html, as div id property.
189
	 * @var	string
190
	 */
191
	protected $sId = 'fl_lt';
192
193
194
	/**
195
	 * Construct
196
	 *
197
	 * $ard, $art can't use referenct because title and data value maybe
198
	 * changed in treatment.
199
	 * @param	object	&$tpl	Smarty object, will save as {@link $oTpl}.
200
	 * @param	array	$ard	Data array, will save as {@link $aData}.
201
	 * @param	array	$art	Title of list.
202
	 * @param	string	$id		Identify of this list, while multi list
203
	 * 							in page, this is needed.
204
	 * 							Note: will be applyed prefix automatic
205
	 * 							when write to $sId.
206
	 * @param	array	&$conf	Configuration.
207
	 */
208
	public function __construct (&$tpl, $ard = array(), $art = array(),
209
		$id = '', &$conf = array())	{
210
		$this->oTpl = $tpl;
211
212
		// Config will effect SetData, so set it first.
213
		$this->SetCfg($conf);
214
		$this->oTpl->assignByRef('lt_config', $this->aCfg);
215
216
		$this->SetData($ard, $art);
217
		$this->SetId($id);
218
	} // end of func ListTable
219
220
221
	/**
222
	 * Fit data and title when their items count diff
223
	 *
224
	 * <code>
225
	 * fit_data_title:	0=data fit title, cut data items who's index not
226
	 * 					in title
227
	 * 					1=title fit data.
228
	 * 					2=fit to fewest, only items both have allowed.
229
	 * 					3=fit to mostest, all items in title or data allowed.
230
	 * </code>
231
	 * Notice: data have multi row(2 dim), title have only 1 row(1 dim).
232
	 * @see	$aCfg['fit_data_title']
233
	 */
234
	protected function FitDataTitle () {
235
		if (empty($this->aData) || empty($this->aTitle))
236
			return ;
237
238
		// Store result
239
		$ar_title = array();
240
		$ar_data = array();
241
242
		// Will compare by array keys, data use it's first/current row
243
//		$keys_data = array_keys($this->aData[0]);
244
		$keys_data = array_keys(current($this->aData));
245
		$keys_title = array_keys($this->aTitle);
246
247
		switch ($this->aCfg['fit_data_title']) {
248
			case 0:
249
				// data fit to title
250
251
				// Int index and string are difference
252
				// In common, we check only title's index type
253
				// Int index, can only fit by index position
254
				if (0 === $keys_title[0]) {
255
					$ar_title = &$this->aTitle;
256
					foreach ($keys_title as $k => $v)
257
						foreach ($this->aData as $idx => $row)
258
							if (isset($row[$keys_data[$k]]))
259
								$ar_data[$idx][$keys_data[$k]] = &$row[$keys_data[$k]];
260
							else
261
								$ar_data[$idx][$keys_data[$k]] = $this->aCfg['fit_empty'];
262
				}
263
				else {
264
					$ar_title = &$this->aTitle;
265
					foreach ($keys_title as $k => $v)
266
						foreach ($this->aData as $idx => $row)
267
							if (isset($row[$v]))
268
								$ar_data[$idx][$v] = &$row[$v];
269
							else
270
								$ar_data[$idx][$v] = $this->aCfg['fit_empty'];
271
				}
272
				break;
273
			case 1:
274
				// title fit to data, inser empty title if havn't
275
276
				// Int index, can only fit by index position
277
				if (0 === $keys_title[0]) {
278
					$ar_data = &$this->aData;
279 View Code Duplication
					foreach ($keys_data as $k => $v)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
280
						if (isset($keys_title[$k]))
281
							$ar_title[$k] = &$this->aTitle[$k];
282
						else
283
							// Use data's index name
284
							$ar_title[$k] = $v;
285
				}
286
				else {
287
					$ar_data = &$this->aData;
288 View Code Duplication
					foreach ($keys_data as $k => $v)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
289
						if (isset($this->aTitle[$v]))
290
							$ar_title[$v] = &$this->aTitle[$v];
291
						else
292
							$ar_title[$v] = $v;
293
				}
294
				break;
295
			case 2:
296
				// Fit to fewest
297
				// Cut title first, then fit to title
298
				// Cut title:
299
				$ar_title = &$this->aTitle;
300
				if (0 === $keys_title[0]) {
301
					// Int indexed
302
					// Remove title if title has more items than data
303 View Code Duplication
					for ($i = count($keys_data); $i < count($keys_title); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
304
						unset($ar_title[$i]);
305
				}
306
				else {
307
					// String indexed
308
					// Remove item in title which not in data
309
					foreach ($keys_title as $k => $v)
310
						if (!in_array($v, $keys_data))
311
							unset($ar_title[$v]);
312
				}
313
				// Then use function itself to fit data to cutted title
314
				$this->aCfg['fit_data_title'] = 0;
315
				$this->FitDataTitle();
316
				$this->aCfg['fit_data_title'] = 2;
317
				$ar_data = &$this->aData;
318
				$ar_title = &$this->aTitle;
319
				break;
320
			case 3:
321
				// Fit to mostest
322
				// Fill title first, then fit to title
323
				// Fill title:
324
				if (0 === $keys_title[0]) {
325
					// Add as append
326
					$ar_title = &$this->aTitle;
327
					// Int indexed
328
					// Add title if title has fewer items than data
329 View Code Duplication
					for ($i = count($keys_title); $i < count($keys_data); $i++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
330
						// Can only use field name in data
331
						$ar_title[$i] = $keys_data[$i];
332
				}
333
				else {
334
					// Add as insert
335
					// need to merge keys first to keep order
336
					$keys_merge = array_merge($keys_title, $keys_data);
337 View Code Duplication
					foreach ($keys_merge as $k => $v)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
338
						if (in_array($v, $keys_title))
339
							$ar_title[$v] = $this->aTitle[$v];
340
						else
341
							// Title items is fewer, need to fill
342
							// These infact is keys from data,
343
							// because of merge, so we can use $v directly
344
							$ar_title[$v] = $v;
345
				}
346
				$this->aTitle = &$ar_title;
347
				// Then use function itself to fit data to cutted title
348
				$this->aCfg['fit_data_title'] = 0;
349
				$this->FitDataTitle();
350
				$this->aCfg['fit_data_title'] = 2;
351
				$ar_data = &$this->aData;
352
				$ar_title = &$this->aTitle;
353
				break;
354
			default:
355
		}
356
357
358
		// Data write back
359
		//var_dump($ar_data);
360
		$this->aData = &$ar_data;
361
		$this->aTitle = &$ar_title;
362
	} // end of func FitDataTitle
363
364
365
	/**
366
	 * Get full output html
367
	 * @return	string
368
	 */
369
	public function GetHtml () {
370
		return $this->oTpl->fetch($this->aCfg['tpl']);
371
	} // end of func GetHtml
372
373
374
	/**
375
	 * Get http GET param.
376
	 * @return	array
377
	 */
378
	public function GetParam() {
379
		$this->aParam = &$_GET;
380
		if (!empty($this->aParam) && !get_magic_quotes_gpc()) {
381
			foreach ($this->aParam as $k=>$v) {
382
				$this->aParam[$k] = addslashes($v);
383
			}
384
		}
385
386
		// :NOTICE: Will got only url of backend if ProxyPass actived
387
		// Can treat as below before new ListTable obj.
388
/*
389
		$ar = array('/needless1/', '/needless1/');
390
		$_SERVER['REQUEST_URI'] = str_replace($ar, '/', $_SERVER['REQUEST_URI']);
391
		$_SERVER['SCRIPT_NAME'] = str_replace($ar, '/', $_SERVER['SCRIPT_NAME']);
392
*/
393
		$this->aUrl['base'] = GetSelfUrl(false);
0 ignored issues
show
Deprecated Code introduced by
The function GetSelfUrl() has been deprecated with message: Use Fwlib\Util\HttpUtil::getSelfUrl()

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
394
395
		if (isset($this->aParam[$this->aCfg['page_param']])) {
396
			$this->ParsePageCur($this->aParam[$this->aCfg['page_param']]);
397
		}
398
399
		// Orderby
400
		if (isset($this->aParam[$this->aCfg['orderby_param'] . '_idx']))
401
			$this->SetOrderby($this->aParam[$this->aCfg['orderby_param'] . '_idx'], $this->aParam[$this->aCfg['orderby_param'] . '_dir']);
402
403
		return $this->aParam;
404
	} // end of func GetParam
405
406
407
	/**
408
	 * Get info about some part of query sql
409
	 * what can directly use in SqlGenerator, eg: limit, orderby
410
	 *
411
	 * @return	array
412
	 * @see	SqlGenerator
413
	 */
414
	public function GetSqlInfo () {
415
		$ar = array();
416
417
		$ar['LIMIT'] = $this->aCfg['page_size'] * ($this->aCfg['page_cur'] - 1)
418
			. ', ' . $this->aCfg['page_size'];
419
420
		if (1 == $this->aCfg['orderby']) {
421
			// orderby_idx is column name
422
			$ar['ORDERBY'] = $this->aCfg['orderby_idx']
423
				. ' ' . $this->aCfg['orderby_dir'];
424
		}
425
426
		return $ar;
427
	} // end of func GetSqlInfo
428
429
430
	/**
431
	 * Get info about some part of query sql from url $_REQUEST
432
	 * what can directly use in SqlGenerator, eg: limit, orderby
433
	 *
434
	 * @return	array
435
	 * @see	SqlGenerator
436
	 */
437
	public function GetSqlInfoFromUrl () {
438
		$ar = array();
439
440
		// Limit
441
		$i_page = $this->ParsePageCur();
442
		$ar['LIMIT'] = ($i_page - 1) * $this->aCfg['page_size']
443
			. ', ' . $this->aCfg['page_size'];
444
445
		// Orderby
446
		$s = $this->aCfg['orderby_param'];
447
		$s_idx = GetRequest($_REQUEST, $s . '_idx');
0 ignored issues
show
Deprecated Code introduced by
The function GetRequest() has been deprecated with message: Use Fwlib\Util\HttpUtil::getRequest()

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
448
		if (0 < strlen($s_idx)) {
449
			// Orderby enabled
450
			$s_dir = GetRequest($_REQUEST, $s . '_dir', 'asc');
0 ignored issues
show
Deprecated Code introduced by
The function GetRequest() has been deprecated with message: Use Fwlib\Util\HttpUtil::getRequest()

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
451
			$ar['ORDERBY'] = $s_idx . ' ' . $s_dir;
452
		}
453
454
		return $ar;
455
	} // end of func GetSqlInfoFromUrl
456
457
458
	/**
459
	 * Parse & compute page_cur param
460
	 *
461
	 * @param	int	$p	Page num param come from outer
462
	 * @return	int
463
	 */
464
	protected function ParsePageCur ($p = 0) {
465
		if (0 == $p) {
466
			// Read from GET prarm
467
			$i = GetRequest($_REQUEST, $this->aCfg['page_param']);
0 ignored issues
show
Deprecated Code introduced by
The function GetRequest() has been deprecated with message: Use Fwlib\Util\HttpUtil::getRequest()

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
468
			// Special & dangous setting, use only if 1 LT in page
469
			$i1 = GetRequest($_REQUEST, 'p');
0 ignored issues
show
Deprecated Code introduced by
The function GetRequest() has been deprecated with message: Use Fwlib\Util\HttpUtil::getRequest()

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
470
			if (!empty($i))
471
				$page_cur = $i;
472
			elseif (!empty($i1))
473
				$page_cur = $i1;
474
			else
475
				$page_cur = 1;
476
		}
477
		else
478
			$page_cur = $p;
479
		$page_cur = intval($page_cur);
480
481
		// Validate min and max
482
		// Min
483
		if (1 > $page_cur)
484
			$page_cur = 1;
485
		// Max
486
		if (0 < $this->aCfg['rows_total']
487
			&& 0 < $this->aCfg['page_size']) {
488
			$i = ceil($this->aCfg['rows_total']
489
				/ $this->aCfg['page_size']);
490
			if ($i < $page_cur)
491
				$page_cur = intval($i);
492
		}
493
494
		// Result
495
		$this->aCfg['page_cur'] = $page_cur;
496
		return $page_cur;
497
	} // end of func ParsePageCur
498
499
500
	/**
501
	 * Set table data and title to display.
502
	 * @param	array	&$ard	Data, will save as {@link $aData}.
503
	 * @param	array	&$art	Title of list.
504
	 */
505
	public function SetData (&$ard = array(), &$art = array()) {
506
		if (!empty($ard))
507
			$this->aData = $ard;
508
		if (!empty($art))
509
			$this->aTitle = $art;
510
511
		// Same number of items maybe index diff, so always do fit.
512
		$this->FitDataTitle();
513
514
		$this->oTpl->assignByRef('lt_data', $this->aData);
515
		$this->oTpl->assignByRef('lt_title', $this->aTitle);
516
517
		return ;
518
		/* obsolete
519
		//$this->aData = &$ar;
520
		// 将输入的数组转换成用数字作为索引的,因为SMARTY不支持ASSOC索引
521
		$this->aData = array();
522
		if (empty($ar))
523
		{
524
			return(false);
525
		}
526
		foreach ($ar as $key=>$val)
527
		{
528
			array_push($this->aData, $val);
529
		}
530
		//
531
		$this->mTotalRows = count($this->aData);
532
		*/
533
	} // end of func SetData
534
535
536
	/**
537
	 * Set identify and class of this list <div> in html
538
	 * @param	string	$id
539
	 * @param	string	$class
540
	 * @return	string
541
	 */
542
	public function SetId ($id, $class = '') {
543
		if (empty($id))
544
			$this->sId = $this->aCfg['code_prefix'];
545
		else
546
			$this->sId = $this->aCfg['code_prefix'] . '_' . $id;
547
		if (!empty($class))
548
			$this->sClass = $class;
549
		else
550
			// On default, class = id
551
			$this->sClass = $this->sId;
552
		$this->oTpl->assignByRef('lt_id', $this->sId);
553
		$this->oTpl->assignByRef('lt_class', $this->sClass);
554
555
		// Change page_param
556
		$this->aCfg['page_param'] = $this->sId . '_p';
557
		$this->ParsePageCur();
558
559
		// Change orderby param
560
		$this->aCfg['orderby_param'] = $this->sId . '_o';
561
562
		// Find param by new Id
563
		$this->GetParam();
564
565
		return $this->sId;
566
	} // end of func SetId
567
568
569
	/**
570
	 * Set orderby info
571
	 *
572
	 * Didn't validate $idx to th array.
573
	 * @param	mixed	$idx	Idx of th array
574
	 * @param	string	$dir	asc/desc, lower letter only
575
	 */
576
	public function SetOrderby ($idx, $dir = 'asc') {
577
		$this->aCfg['orderby'] = 1;
578
579
		// If had got orderby info from url, exit
580
		if (0 < strlen($this->aCfg['orderby_idx']))
581
			return;
582
583
		$this->aCfg['orderby_idx'] = $idx;
584
		$dir = strtolower($dir);
585
		if ('asc' == $dir) {
586
			$dir_rev = 'desc';
587
			$this->aCfg['orderby_dir'] = 'asc';
588
			$this->aCfg['orderby_text']
589
				= $this->aCfg['orderby_text_asc'];
590
		} else {
591
			$dir_rev = 'asc';
592
			$this->aCfg['orderby_dir'] = 'desc';
593
			$this->aCfg['orderby_text']
594
				= $this->aCfg['orderby_text_desc'];
595
		}
596
597
		// Url param
598
		// Empty idx will fill in tpl
599
		// Keep value of $this->aParam first
600
		$ar = $this->aParam;
601
		$this->aUrl['o_cur'] = $this->SetParam(array($this->aCfg['orderby_param'] . '_dir' => $dir_rev)
602
			, array($this->aCfg['orderby_param'] . '_idx'));
603
		// Same with cur dir, or all new 'asc'
604
		$this->aUrl['o_other'] = $this->SetParam(array($this->aCfg['orderby_param'] . '_dir'=> $this->aCfg['orderby_dir'])
605
			, array($this->aCfg['orderby_param'] . '_idx'));;
606
		// Restore value of $this->aParam
607
		$this->aParam = $ar;
608
		$this->oTpl->assignByRef('lt_url', $this->aUrl);
609
	} // end of func SetOrderby
610
611
612
	/**
613
	 * Set pager info
614
	 *
615
	 * Config data will also write to $aCfg, the difference with direct set config
616
	 * is this will add more treatment about pager.
617
	 * And use after SetCfg()
618
	 * @param	int		$rows_total	Total row/record number
619
	 * @param	int		$page_cur	Current displayed page, default is get from GET param
620
	 * 								if fail, set to 1.
621
	 * @see		$aCfg
622
	 */
623
	public function SetPager ($rows_total= 0, $page_cur = 0) {
624
		// Enable pager disp
625
		$this->aCfg['pager'] = true;
626
627
		// Auto compute total rows if not assigned
628
		if (0 == $rows_total)
629
			$rows_total = count($this->aData);
630
		$this->aCfg['rows_total'] = $rows_total;
631
632
		// Some param needed
633
		$page_cur = $this->ParsePageCur($page_cur);
634
		$page_size = $this->aCfg['page_size'];
635
		$page_max = ceil($rows_total / $page_size);
636
637
		// If data rows exceeds page_size, trim it
638
		if (count($this->aData) > $page_size) {
639
			// If page = 3/5, trim page 1, 2 first
640
			for ($i = 0; $i < ($page_cur - 1) * $page_size; $i ++)
641
				unset($this->aData[$i]);
642
			// Then trim page 4, 5
643
			for ($i = $page_cur * $page_size; $i < $page_max * $page_size; $i ++)
644
				unset($this->aData[$i]);
645
		}
646
647
		$this->aCfg['pager_text_cur_value'] = str_replace(
648
			array('{page_cur}', '{page_max}', '{rows_total}', '{page_size}'),
649
			array($page_cur, $page_max, $rows_total, $page_size),
650
			$this->aCfg['pager_text_cur']);
651
652
		// Generate url for pager
653
		//$this->aUrl['base'] = GetSelfUrl(true);	// Move to GetParam()
654
		if (1 < $page_cur) {
655
			// Not first page
656
//			$this->aUrl['first'] = $this->aUrl['base'] . '&' . $this->sId
657
//				. '-page_no=' . $page_cur;
658
//			$this->aUrl['prev'] = $this->aUrl['base'] . '&' . $this->sId
659
//				. '-page_no=' . ($page_cur - 1);
660
			$this->aUrl['p_first'] = $this->SetParam($this->aCfg['page_param'], 1);
661
			$this->aUrl['p_prev'] = $this->SetParam($this->aCfg['page_param'], $page_cur - 1);
662
		} else {
663
			$this->aUrl['p_first'] = '';
664
			$this->aUrl['p_prev'] = '';
665
		}
666
		if ($page_cur < $page_max) {
667
			// Not last page
668
//			$this->aUrl['next'] = $this->aUrl['base'] . '&' . $this->sId
669
//				. '-page_no=' . ($page_cur + 1);
670
//			$this->aUrl['last'] = $this->aUrl['base'] . '&' . $this->sId
671
//				. '-page_no=' . $page_max;
672
			$this->aUrl['p_next'] = $this->SetParam($this->aCfg['page_param'], $page_cur + 1);
673
			$this->aUrl['p_last'] = $this->SetParam($this->aCfg['page_param'], $page_max);
674
		} else {
675
			$this->aUrl['p_next'] = '';
676
			$this->aUrl['p_last'] = '';
677
		}
678
679
		// Assign url to tpl
680
		$this->oTpl->assignByRef('lt_url', $this->aUrl);
681
		$this->oTpl->assign('lt_url_form', $this->SetParam(array(), $this->aCfg['page_param']));
682
683
		// Assign hidden input
684
		if (!empty($this->aParam)) {
685
			$s = '';
686
			foreach ($this->aParam as $k => $v)
687
			{
688
                $k = filter_var($k, FILTER_SANITIZE_STRING );
689
                $v = filter_var($v, FILTER_SANITIZE_STRING );
690
                $s .= "<input type=\"hidden\" name=\"$k\" value=\"$v\" />\n";
691
			}
692
            /*foreach ($this->aParam as $k => $v)
693
                $s .= "<input type=\"hidden\" name=\"$k\" value=\"$v\" />\n";*/
694
            $this->oTpl->assign('lt_url_form_hidden', $s);
695
			$this->oTpl->assign('lt_url_form_hidden', $s);
696
		}
697
698
		// Add page_param deleted in above SetParam
699
		// needed to display right form url in next table in this page
700
		$this->SetParam($this->aCfg['page_param'], $page_cur);
701
	} // end of func SetPager
702
703
704
	/**
705
	 * Set url param, get the url
706
	 *
707
	 * If $k is string, then $v is string too and means $k=$v.
708
	 * if $k is array, then $v is array to,
709
	 * and values in $k/$v is added/removed from url param.
710
	 * Always 'save' setting and return result url.
711
	 *
712
	 * @param	mixed	$k
713
	 * @param	mixed	$v
714
	 * @return	string
715
	 * @see func/request.php::GetParam()
716
	 */
717
	public function SetParam ($k, $v = '') {
718 View Code Duplication
		if (!is_array($k) && !is_array($v)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
719
			$this->aParam[addslashes($k)] = addslashes($v);
720
		}
721
		if (is_array($k)) {
722
			foreach ($k as $key => $val)
723
				$this->aParam[addslashes($key)] = addslashes($val);
724
			if (!is_array($v))
725
				$v = array($v);
726
			foreach ($v as $val)
727
				if (isset($this->aParam[$val]))
728
					unset($this->aParam[$val]);
729
		}
730
731
		// Generate url and return
732
		$s = '';
733
		foreach ($this->aParam as $k => $v)
734
			$s .= "&$k=$v";
735
		if (!empty($s))
736
			$s{0} = '?';
737
		$s = $this->aUrl['base'] . $s;
738
		return filter_var($s, FILTER_SANITIZE_STRING);
739
		//return $s;
740
	} // end of func SetParam
741
742
743
} // end class ListTable
744
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
745