Completed
Branch master (4dc390)
by Fabio
30:44
created

TDataGrid   F

Complexity

Total Complexity 271

Size/Duplication

Total Lines 1522
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 26
Metric Value
wmc 271
lcom 1
cbo 26
dl 0
loc 1522
rs 0.5217

75 Methods

Rating   Name   Duplication   Size   Complexity  
A getTagName() 0 4 1
A getAutoGenerateColumnName() 0 4 1
A addParsedObject() 0 7 2
A getColumns() 0 6 2
A getAutoColumns() 0 6 2
A getItems() 0 6 2
A getItemCount() 0 4 2
A createStyle() 0 4 1
A getBackImageUrl() 0 4 1
A setBackImageUrl() 0 4 1
A getItemStyle() 0 9 2
A getAlternatingItemStyle() 0 9 2
A getSelectedItemStyle() 0 9 2
A getEditItemStyle() 0 9 2
A getHeaderStyle() 0 9 2
A getFooterStyle() 0 9 2
A getPagerStyle() 0 9 2
A getTableHeadStyle() 0 9 2
A getTableBodyStyle() 0 9 2
A getTableFootStyle() 0 9 2
A getCaption() 0 4 1
A setCaption() 0 4 1
A getCaptionAlign() 0 4 1
A setCaptionAlign() 0 4 1
A getHeader() 0 4 1
A getFooter() 0 4 1
A getTopPager() 0 4 1
A getBottomPager() 0 4 1
A getSelectedItem() 0 9 3
A getSelectedItemIndex() 0 4 1
C setSelectedItemIndex() 0 23 10
A getEditItem() 0 9 3
A getEditItemIndex() 0 4 1
B setEditItemIndex() 0 15 8
A getAllowSorting() 0 4 1
A setAllowSorting() 0 4 1
A getAutoGenerateColumns() 0 4 1
A setAutoGenerateColumns() 0 4 1
A getShowHeader() 0 4 1
A setShowHeader() 0 4 1
A getShowFooter() 0 4 1
A setShowFooter() 0 4 1
A getEmptyTemplate() 0 4 1
A setEmptyTemplate() 0 7 3
C bubbleEvent() 0 56 13
A onCancelCommand() 0 4 1
A onDeleteCommand() 0 4 1
A onEditCommand() 0 4 1
A onItemCommand() 0 4 1
A onSortCommand() 0 4 1
A onUpdateCommand() 0 4 1
A onItemCreated() 0 4 1
A onPagerCreated() 0 4 1
A onItemDataBound() 0 4 1
A onPageIndexChanged() 0 4 1
C saveState() 0 28 7
C loadState() 0 33 8
A reset() 0 10 1
C restoreGridFromViewState() 0 53 13
C performDataBinding() 0 70 17
C groupCells() 0 41 13
B getCellText() 0 13 5
A createItem() 0 4 1
A createItemInternal() 0 20 2
A initializeItem() 0 18 4
A createPager() 0 8 1
A buildPager() 0 12 3
B createPagerButton() 0 25 4
B buildNextPrevPager() 0 54 7
F buildNumericPager() 0 67 13
B createAutoColumns() 0 30 5
F applyItemStyles() 0 132 44
A renderBeginTag() 0 12 3
C render() 0 33 7
D renderTable() 0 33 9

How to fix   Complexity   

Complex Class

Complex classes like TDataGrid often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use TDataGrid, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * TDataGrid related class files.
4
 * This file contains the definition of the following classes:
5
 * TDataGrid, TDataGridItem, TDataGridItemCollection, TDataGridColumnCollection,
6
 * TDataGridPagerStyle, TDataGridItemEventParameter,
7
 * TDataGridCommandEventParameter, TDataGridSortCommandEventParameter,
8
 * TDataGridPageChangedEventParameter
9
 *
10
 * @author Qiang Xue <[email protected]>
11
 * @link https://github.com/pradosoft/prado
12
 * @copyright Copyright &copy; 2005-2015 The PRADO Group
13
 * @license https://github.com/pradosoft/prado/blob/master/COPYRIGHT
14
 * @package System.Web.UI.WebControls
15
 */
16
17
/**
18
 * Includes TBaseList, TPagedDataSource, TDummyDataSource and TTable classes
19
 */
20
Prado::using('System.Web.UI.WebControls.TBaseDataList');
21
Prado::using('System.Collections.TPagedDataSource');
22
Prado::using('System.Collections.TDummyDataSource');
23
Prado::using('System.Web.UI.WebControls.TTable');
24
Prado::using('System.Web.UI.WebControls.TPanel');
25
Prado::using('System.Web.UI.WebControls.TDataGridPagerStyle');
26
27
/**
28
 * TDataGrid class
29
 *
30
 * TDataGrid represents a data bound and updatable grid control.
31
 *
32
 * To populate data into the datagrid, sets its {@link setDataSource DataSource}
33
 * to a tabular data source and call {@link dataBind()}.
34
 * Each row of data will be represented by an item in the {@link getItems Items}
35
 * collection of the datagrid.
36
 *
37
 * An item can be at one of three states: browsing, selected and edit.
38
 * The state determines how the item will be displayed. For example, if an item
39
 * is in edit state, it may be displayed as a table row with input text boxes
40
 * if the columns are of type {@link TBoundColumn}; and if in browsing state,
41
 * they are displayed as static text.
42
 *
43
 * To change the state of an item, set {@link setEditItemIndex EditItemIndex}
44
 * or {@link setSelectedItemIndex SelectedItemIndex} property.
45
 *
46
 * Each datagrid item has a {@link TDataGridItem::getItemType type}
47
 * which tells the position and state of the item in the datalist. An item in the header
48
 * of the repeater is of type Header. A body item may be of either
49
 * Item, AlternatingItem, SelectedItem or EditItem, depending whether the item
50
 * index is odd or even, whether it is being selected or edited.
51
 *
52
 * A datagrid is specified with a list of columns. Each column specifies how the corresponding
53
 * table column will be displayed. For example, the header/footer text of that column,
54
 * the cells in that column, and so on. The following column types are currently
55
 * provided by the framework,
56
 * - {@link TBoundColumn}, associated with a specific field in datasource and displays the corresponding data.
57
 * - {@link TEditCommandColumn}, displaying edit/update/cancel command buttons
58
 * - {@link TButtonColumn}, displaying generic command buttons that may be bound to specific field in datasource.
59
 * - {@link TDropDownListColumn}, displaying a dropdown list when the item is in edit state
60
 * - {@link THyperLinkColumn}, displaying a hyperlink that may be bound to specific field in datasource.
61
 * - {@link TCheckBoxColumn}, displaying a checkbox that may be bound to specific field in datasource.
62
 * - {@link TTemplateColumn}, displaying content based on templates.
63
 *
64
 * There are three ways to specify columns for a datagrid.
65
 * <ul>
66
 *  <li>Automatically generated based on data source.
67
 *  By setting {@link setAutoGenerateColumns AutoGenerateColumns} to true,
68
 *  a list of columns will be automatically generated based on the schema of the data source.
69
 *  Each column corresponds to a column of the data.</li>
70
 *  <li>Specified in template. For example,
71
 *    <code>
72
 *     <com:TDataGrid ...>
73
 *        <com:TBoundColumn .../>
74
 *        <com:TEditCommandColumn .../>
75
 *     </com:TDataGrid>
76
 *    </code>
77
 *  </li>
78
 *  <li>Manually created in code. Columns can be manipulated via
79
 *  the {@link setColumns Columns} property of the datagrid. For example,
80
 *  <code>
81
 *    $column=new TBoundColumn;
82
 *    $datagrid->Columns[]=$column;
83
 *  </code>
84
 *  </li>
85
 * </ul>
86
 * Note, automatically generated columns cannot be accessed via
87
 * the {@link getColumns Columns} property.
88
 *
89
 * TDataGrid supports sorting. If the {@link setAllowSorting AllowSorting}
90
 * is set to true, a column with nonempty {@link setSortExpression SortExpression}
91
 * will have its header text displayed as a clickable link button.
92
 * Clicking on the link button will raise {@link onSortCommand OnSortCommand}
93
 * event. You can respond to this event, sort the data source according
94
 * to the event parameter, and then invoke {@link databind()} on the datagrid
95
 * to show to end users the sorted data.
96
 *
97
 * TDataGrid supports paging. If the {@link setAllowPaging AllowPaging}
98
 * is set to true, a pager will be displayed on top and/or bottom of the table.
99
 * How the pager will be displayed is determined by the {@link getPagerStyle PagerStyle}
100
 * property. Clicking on a pager button will raise an {@link onPageIndexChanged OnPageIndexChanged}
101
 * event. You can respond to this event, specify the page to be displayed by
102
 * setting {@link setCurrentPageIndex CurrentPageIndex}</b> property,
103
 * and then invoke {@link databind()} on the datagrid to show to end users
104
 * a new page of data.
105
 *
106
 * TDataGrid supports two kinds of paging. The first one is based on the number of data items in
107
 * datasource. The number of pages {@link getPageCount PageCount} is calculated based
108
 * the item number and the {@link setPageSize PageSize} property.
109
 * The datagrid will manage which section of the data source to be displayed
110
 * based on the {@link setCurrentPageIndex CurrentPageIndex} property.
111
 * The second approach calculates the page number based on the
112
 * {@link setVirtualItemCount VirtualItemCount} property and
113
 * the {@link setPageSize PageSize} property. The datagrid will always
114
 * display from the beginning of the datasource up to the number of
115
 * {@link setPageSize PageSize} data items. This approach is especially
116
 * useful when the datasource may contain too many data items to be managed by
117
 * the datagrid efficiently.
118
 *
119
 * When the datagrid contains a button control that raises an {@link onCommand OnCommand}
120
 * event, the event will be bubbled up to the datagrid control.
121
 * If the event's command name is recognizable by the datagrid control,
122
 * a corresponding item event will be raised. The following item events will be
123
 * raised upon a specific command:
124
 * - OnEditCommand, if CommandName=edit
125
 * - OnCancelCommand, if CommandName=cancel
126
 * - OnSelectCommand, if CommandName=select
127
 * - OnDeleteCommand, if CommandName=delete
128
 * - OnUpdateCommand, if CommandName=update
129
 * - onPageIndexChanged, if CommandName=page
130
 * - OnSortCommand, if CommandName=sort
131
 * Note, an {@link onItemCommand OnItemCommand} event is raised in addition to
132
 * the above specific command events.
133
 *
134
 * TDataGrid also raises an {@link onItemCreated OnItemCreated} event for
135
 * every newly created datagrid item. You can respond to this event to customize
136
 * the content or style of the newly created item.
137
 *
138
 * Note, the data bound to the datagrid are reset to null after databinding.
139
 * There are several ways to access the data associated with a datagrid row:
140
 * - Access the data in {@link onItemDataBound OnItemDataBound} event
141
 * - Use {@link getDataKeys DataKeys} to obtain the data key associated with
142
 * the specified datagrid row and use the key to fetch the corresponding data
143
 * from some persistent storage such as DB.
144
 * - Save the data in viewstate and get it back during postbacks.
145
 *
146
 * @author Qiang Xue <[email protected]>
147
 * @package System.Web.UI.WebControls
148
 * @since 3.0
149
 */
150
class TDataGrid extends TBaseDataList implements INamingContainer
151
{
152
	/**
153
	 * datagrid item types
154
	 * @deprecated deprecated since version 3.0.4. Use TListItemType constants instead.
155
	 */
156
	const IT_HEADER='Header';
157
	const IT_FOOTER='Footer';
158
	const IT_ITEM='Item';
159
	const IT_SEPARATOR='Separator';
160
	const IT_ALTERNATINGITEM='AlternatingItem';
161
	const IT_EDITITEM='EditItem';
162
	const IT_SELECTEDITEM='SelectedItem';
163
	const IT_PAGER='Pager';
164
165
	/**
166
	 * Command name that TDataGrid understands.
167
	 */
168
	const CMD_SELECT='Select';
169
	const CMD_EDIT='Edit';
170
	const CMD_UPDATE='Update';
171
	const CMD_DELETE='Delete';
172
	const CMD_CANCEL='Cancel';
173
	const CMD_SORT='Sort';
174
	const CMD_PAGE='Page';
175
	const CMD_PAGE_NEXT='Next';
176
	const CMD_PAGE_PREV='Previous';
177
	const CMD_PAGE_FIRST='First';
178
	const CMD_PAGE_LAST='Last';
179
180
	/**
181
	 * @var TDataGridColumnCollection manually created column collection
182
	 */
183
	private $_columns=null;
184
	/**
185
	 * @var TDataGridColumnCollection automatically created column collection
186
	 */
187
	private $_autoColumns=null;
188
	/**
189
	 * @var TList all columns including both manually and automatically created columns
190
	 */
191
	private $_allColumns=null;
192
	/**
193
	 * @var TDataGridItemCollection datagrid item collection
194
	 */
195
	private $_items=null;
196
	/**
197
	 * @var TDataGridItem header item
198
	 */
199
	private $_header=null;
200
	/**
201
	 * @var TDataGridItem footer item
202
	 */
203
	private $_footer=null;
204
	/**
205
	 * @var TPagedDataSource paged data source object
206
	 */
207
	private $_pagedDataSource=null;
0 ignored issues
show
Unused Code introduced by
The property $_pagedDataSource is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
208
	private $_topPager=null;
209
	private $_bottomPager=null;
210
	/**
211
	 * @var ITemplate template used when empty data is bounded
212
	 */
213
	private $_emptyTemplate=null;
214
	/**
215
	 * @var boolean whether empty template is effective
216
	 */
217
	private $_useEmptyTemplate=false;
218
219
	/**
220
	 * @return string tag name (table) of the datagrid
221
	 */
222
	protected function getTagName()
223
	{
224
		return 'table';
225
	}
226
227
	/**
228
	 * @return string Name of the class used in AutoGenerateColumns mode
229
	 */
230
	protected function getAutoGenerateColumnName()
231
	{
232
		return 'TBoundColumn';
233
	}
234
235
	/**
236
	 * Adds objects parsed in template to datagrid.
237
	 * Datagrid columns are added into {@link getColumns Columns} collection.
238
	 * @param mixed object parsed in template
239
	 */
240
	public function addParsedObject($object)
241
	{
242
		if($object instanceof TDataGridColumn)
243
			$this->getColumns()->add($object);
244
		else
245
			parent::addParsedObject($object);  // this is needed by EmptyTemplate
246
	}
247
248
	/**
249
	 * @return TDataGridColumnCollection manually specified datagrid columns
250
	 */
251
	public function getColumns()
252
	{
253
		if(!$this->_columns)
254
			$this->_columns=new TDataGridColumnCollection($this);
255
		return $this->_columns;
256
	}
257
258
	/**
259
	 * @return TDataGridColumnCollection automatically generated datagrid columns
260
	 */
261
	public function getAutoColumns()
262
	{
263
		if(!$this->_autoColumns)
264
			$this->_autoColumns=new TDataGridColumnCollection($this);
265
		return $this->_autoColumns;
266
	}
267
268
	/**
269
	 * @return TDataGridItemCollection datagrid item collection
270
	 */
271
	public function getItems()
272
	{
273
		if(!$this->_items)
274
			$this->_items=new TDataGridItemCollection;
275
		return $this->_items;
276
	}
277
278
	/**
279
	 * @return integer number of items
280
	 */
281
	public function getItemCount()
282
	{
283
		return $this->_items?$this->_items->getCount():0;
284
	}
285
286
	/**
287
	 * Creates a style object for the control.
288
	 * This method creates a {@link TTableStyle} to be used by datagrid.
289
	 * @return TTableStyle control style to be used
290
	 */
291
	protected function createStyle()
292
	{
293
		return new TTableStyle;
294
	}
295
296
	/**
297
	 * @return string the URL of the background image for the datagrid
298
	 */
299
	public function getBackImageUrl()
300
	{
301
		return $this->getStyle()->getBackImageUrl();
302
	}
303
304
	/**
305
	 * @param string the URL of the background image for the datagrid
306
	 */
307
	public function setBackImageUrl($value)
308
	{
309
		$this->getStyle()->setBackImageUrl($value);
310
	}
311
312
	/**
313
	 * @return TTableItemStyle the style for every item
314
	 */
315
	public function getItemStyle()
316
	{
317
		if(($style=$this->getViewState('ItemStyle',null))===null)
318
		{
319
			$style=new TTableItemStyle;
320
			$this->setViewState('ItemStyle',$style,null);
321
		}
322
		return $style;
323
	}
324
325
	/**
326
	 * @return TTableItemStyle the style for each alternating item
327
	 */
328
	public function getAlternatingItemStyle()
329
	{
330
		if(($style=$this->getViewState('AlternatingItemStyle',null))===null)
331
		{
332
			$style=new TTableItemStyle;
333
			$this->setViewState('AlternatingItemStyle',$style,null);
334
		}
335
		return $style;
336
	}
337
338
	/**
339
	 * @return TTableItemStyle the style for selected item
340
	 */
341
	public function getSelectedItemStyle()
342
	{
343
		if(($style=$this->getViewState('SelectedItemStyle',null))===null)
344
		{
345
			$style=new TTableItemStyle;
346
			$this->setViewState('SelectedItemStyle',$style,null);
347
		}
348
		return $style;
349
	}
350
351
	/**
352
	 * @return TTableItemStyle the style for edit item
353
	 */
354
	public function getEditItemStyle()
355
	{
356
		if(($style=$this->getViewState('EditItemStyle',null))===null)
357
		{
358
			$style=new TTableItemStyle;
359
			$this->setViewState('EditItemStyle',$style,null);
360
		}
361
		return $style;
362
	}
363
364
	/**
365
	 * @return TTableItemStyle the style for header
366
	 */
367
	public function getHeaderStyle()
368
	{
369
		if(($style=$this->getViewState('HeaderStyle',null))===null)
370
		{
371
			$style=new TTableItemStyle;
372
			$this->setViewState('HeaderStyle',$style,null);
373
		}
374
		return $style;
375
	}
376
377
	/**
378
	 * @return TTableItemStyle the style for footer
379
	 */
380
	public function getFooterStyle()
381
	{
382
		if(($style=$this->getViewState('FooterStyle',null))===null)
383
		{
384
			$style=new TTableItemStyle;
385
			$this->setViewState('FooterStyle',$style,null);
386
		}
387
		return $style;
388
	}
389
390
	/**
391
	 * @return TDataGridPagerStyle the style for pager
392
	 */
393
	public function getPagerStyle()
394
	{
395
		if(($style=$this->getViewState('PagerStyle',null))===null)
396
		{
397
			$style=new TDataGridPagerStyle;
398
			$this->setViewState('PagerStyle',$style,null);
399
		}
400
		return $style;
401
	}
402
403
	/**
404
	 * @return TStyle the style for thead element, if any
405
	 * @since 3.1.1
406
	 */
407
	public function getTableHeadStyle()
408
	{
409
		if(($style=$this->getViewState('TableHeadStyle',null))===null)
410
		{
411
			$style=new TStyle;
412
			$this->setViewState('TableHeadStyle',$style,null);
413
		}
414
		return $style;
415
	}
416
417
	/**
418
	 * @return TStyle the style for tbody element, if any
419
	 * @since 3.1.1
420
	 */
421
	public function getTableBodyStyle()
422
	{
423
		if(($style=$this->getViewState('TableBodyStyle',null))===null)
424
		{
425
			$style=new TStyle;
426
			$this->setViewState('TableBodyStyle',$style,null);
427
		}
428
		return $style;
429
	}
430
431
	/**
432
	 * @return TStyle the style for tfoot element, if any
433
	 * @since 3.1.1
434
	 */
435
	public function getTableFootStyle()
436
	{
437
		if(($style=$this->getViewState('TableFootStyle',null))===null)
438
		{
439
			$style=new TStyle;
440
			$this->setViewState('TableFootStyle',$style,null);
441
		}
442
		return $style;
443
	}
444
445
	/**
446
	 * @return string caption for the datagrid
447
	 */
448
	public function getCaption()
449
	{
450
		return $this->getViewState('Caption','');
451
	}
452
453
	/**
454
	 * @param string caption for the datagrid
455
	 */
456
	public function setCaption($value)
457
	{
458
		$this->setViewState('Caption',$value,'');
459
	}
460
461
	/**
462
	 * @return TTableCaptionAlign datagrid caption alignment. Defaults to TTableCaptionAlign::NotSet.
463
	 */
464
	public function getCaptionAlign()
465
	{
466
		return $this->getViewState('CaptionAlign',TTableCaptionAlign::NotSet);
467
	}
468
469
	/**
470
	 * @param TTableCaptionAlign datagrid caption alignment. Valid values include
471
	 */
472
	public function setCaptionAlign($value)
473
	{
474
		$this->setViewState('CaptionAlign',TPropertyValue::ensureEnum($value,'TTableCaptionAlign'),TTableCaptionAlign::NotSet);
475
	}
476
477
	/**
478
	 * @return TDataGridItem the header item
479
	 */
480
	public function getHeader()
481
	{
482
		return $this->_header;
483
	}
484
485
	/**
486
	 * @return TDataGridItem the footer item
487
	 */
488
	public function getFooter()
489
	{
490
		return $this->_footer;
491
	}
492
493
	/**
494
	 * @return TDataGridPager the pager displayed at the top of datagrid. It could be null if paging is disabled.
495
	 */
496
	public function getTopPager()
497
	{
498
		return $this->_topPager;
499
	}
500
501
	/**
502
	 * @return TDataGridPager the pager displayed at the bottom of datagrid. It could be null if paging is disabled.
503
	 */
504
	public function getBottomPager()
505
	{
506
		return $this->_bottomPager;
507
	}
508
509
	/**
510
	 * @return TDataGridItem the selected item, null if no item is selected.
511
	 */
512
	public function getSelectedItem()
513
	{
514
		$index=$this->getSelectedItemIndex();
515
		$items=$this->getItems();
516
		if($index>=0 && $index<$items->getCount())
517
			return $items->itemAt($index);
518
		else
519
			return null;
520
	}
521
522
	/**
523
	 * @return integer the zero-based index of the selected item in {@link getItems Items}.
524
	 * A value -1 means no item selected.
525
	 */
526
	public function getSelectedItemIndex()
527
	{
528
		return $this->getViewState('SelectedItemIndex',-1);
529
	}
530
531
	/**
532
	 * Selects an item by its index in {@link getItems Items}.
533
	 * Previously selected item will be un-selected.
534
	 * If the item to be selected is already in edit mode, it will remain in edit mode.
535
	 * If the index is less than 0, any existing selection will be cleared up.
536
	 * @param integer the selected item index
537
	 */
538
	public function setSelectedItemIndex($value)
539
	{
540
		if(($value=TPropertyValue::ensureInteger($value))<0)
541
			$value=-1;
542
		if(($current=$this->getSelectedItemIndex())!==$value)
543
		{
544
			$this->setViewState('SelectedItemIndex',$value,-1);
545
			$items=$this->getItems();
546
			$itemCount=$items->getCount();
547
			if($current>=0 && $current<$itemCount)
548
			{
549
				$item=$items->itemAt($current);
550
				if($item->getItemType()!==TListItemType::EditItem)
551
					$item->setItemType($current%2?TListItemType::AlternatingItem:TListItemType::Item);
552
			}
553
			if($value>=0 && $value<$itemCount)
554
			{
555
				$item=$items->itemAt($value);
556
				if($item->getItemType()!==TListItemType::EditItem)
557
					$item->setItemType(TListItemType::SelectedItem);
558
			}
559
		}
560
	}
561
562
	/**
563
	 * @return TDataGridItem the edit item
564
	 */
565
	public function getEditItem()
566
	{
567
		$index=$this->getEditItemIndex();
568
		$items=$this->getItems();
569
		if($index>=0 && $index<$items->getCount())
570
			return $items->itemAt($index);
571
		else
572
			return null;
573
	}
574
575
	/**
576
	 * @return integer the zero-based index of the edit item in {@link getItems Items}.
577
	 * A value -1 means no item is in edit mode.
578
	 */
579
	public function getEditItemIndex()
580
	{
581
		return $this->getViewState('EditItemIndex',-1);
582
	}
583
584
	/**
585
	 * Edits an item by its index in {@link getItems Items}.
586
	 * Previously editting item will change to normal item state.
587
	 * If the index is less than 0, any existing edit item will be cleared up.
588
	 * @param integer the edit item index
589
	 */
590
	public function setEditItemIndex($value)
591
	{
592
		if(($value=TPropertyValue::ensureInteger($value))<0)
593
			$value=-1;
594
		if(($current=$this->getEditItemIndex())!==$value)
595
		{
596
			$this->setViewState('EditItemIndex',$value,-1);
597
			$items=$this->getItems();
598
			$itemCount=$items->getCount();
599
			if($current>=0 && $current<$itemCount)
600
				$items->itemAt($current)->setItemType($current%2?TListItemType::AlternatingItem:TListItemType::Item);
601
			if($value>=0 && $value<$itemCount)
602
				$items->itemAt($value)->setItemType(TListItemType::EditItem);
603
		}
604
	}
605
606
	/**
607
	 * @return boolean whether sorting is enabled. Defaults to false.
608
	 */
609
	public function getAllowSorting()
610
	{
611
		return $this->getViewState('AllowSorting',false);
612
	}
613
614
	/**
615
	 * @param boolean whether sorting is enabled
616
	 */
617
	public function setAllowSorting($value)
618
	{
619
		$this->setViewState('AllowSorting',TPropertyValue::ensureBoolean($value),false);
620
	}
621
622
	/**
623
	 * @return boolean whether datagrid columns should be automatically generated. Defaults to true.
624
	 */
625
	public function getAutoGenerateColumns()
626
	{
627
		return $this->getViewState('AutoGenerateColumns',true);
628
	}
629
630
	/**
631
	 * @param boolean whether datagrid columns should be automatically generated
632
	 */
633
	public function setAutoGenerateColumns($value)
634
	{
635
		$this->setViewState('AutoGenerateColumns',TPropertyValue::ensureBoolean($value),true);
636
	}
637
638
	/**
639
	 * @return boolean whether the header should be displayed. Defaults to true.
640
	 */
641
	public function getShowHeader()
642
	{
643
		return $this->getViewState('ShowHeader',true);
644
	}
645
646
	/**
647
	 * @param boolean whether the header should be displayed
648
	 */
649
	public function setShowHeader($value)
650
	{
651
		$this->setViewState('ShowHeader',TPropertyValue::ensureBoolean($value),true);
652
	}
653
654
	/**
655
	 * @return boolean whether the footer should be displayed. Defaults to false.
656
	 */
657
	public function getShowFooter()
658
	{
659
		return $this->getViewState('ShowFooter',false);
660
	}
661
662
	/**
663
	 * @param boolean whether the footer should be displayed
664
	 */
665
	public function setShowFooter($value)
666
	{
667
		$this->setViewState('ShowFooter',TPropertyValue::ensureBoolean($value),false);
668
	}
669
670
	/**
671
	 * @return ITemplate the template applied when no data is bound to the datagrid
672
	 */
673
	public function getEmptyTemplate()
674
	{
675
		return $this->_emptyTemplate;
676
	}
677
678
	/**
679
	 * @param ITemplate the template applied when no data is bound to the datagrid
680
	 * @throws TInvalidDataTypeException if the input is not an {@link ITemplate} or not null.
681
	 */
682
	public function setEmptyTemplate($value)
683
	{
684
		if($value instanceof ITemplate || $value===null)
685
			$this->_emptyTemplate=$value;
686
		else
687
			throw new TInvalidDataTypeException('datagrid_template_required','EmptyTemplate');
688
	}
689
690
	/**
691
	 * This method overrides parent's implementation to handle
692
	 * {@link onItemCommand OnItemCommand} event which is bubbled from
693
	 * {@link TDataGridItem} child controls.
694
	 * If the event parameter is {@link TDataGridCommandEventParameter} and
695
	 * the command name is a recognized one, which includes 'select', 'edit',
696
	 * 'delete', 'update', and 'cancel' (case-insensitive), then a
697
	 * corresponding command event is also raised (such as {@link onEditCommand OnEditCommand}).
698
	 * This method should only be used by control developers.
699
	 * @param TControl the sender of the event
700
	 * @param TEventParameter event parameter
701
	 * @return boolean whether the event bubbling should stop here.
702
	 */
703
	public function bubbleEvent($sender,$param)
704
	{
705
		if($param instanceof TDataGridCommandEventParameter)
706
		{
707
			$this->onItemCommand($param);
708
			$command=$param->getCommandName();
709
			if(strcasecmp($command,self::CMD_SELECT)===0)
710
			{
711
				$this->setSelectedItemIndex($param->getItem()->getItemIndex());
712
				$this->onSelectedIndexChanged($param);
713
				return true;
714
			}
715
			else if(strcasecmp($command,self::CMD_EDIT)===0)
716
			{
717
				$this->onEditCommand($param);
718
				return true;
719
			}
720
			else if(strcasecmp($command,self::CMD_DELETE)===0)
721
			{
722
				$this->onDeleteCommand($param);
723
				return true;
724
			}
725
			else if(strcasecmp($command,self::CMD_UPDATE)===0)
726
			{
727
				$this->onUpdateCommand($param);
728
				return true;
729
			}
730
			else if(strcasecmp($command,self::CMD_CANCEL)===0)
731
			{
732
				$this->onCancelCommand($param);
733
				return true;
734
			}
735
			else if(strcasecmp($command,self::CMD_SORT)===0)
736
			{
737
				$this->onSortCommand(new TDataGridSortCommandEventParameter($sender,$param));
738
				return true;
739
			}
740
			else if(strcasecmp($command,self::CMD_PAGE)===0)
741
			{
742
				$p=$param->getCommandParameter();
743
				if(strcasecmp($p,self::CMD_PAGE_NEXT)===0)
744
					$pageIndex=$this->getCurrentPageIndex()+1;
745
				else if(strcasecmp($p,self::CMD_PAGE_PREV)===0)
746
					$pageIndex=$this->getCurrentPageIndex()-1;
747
				else if(strcasecmp($p,self::CMD_PAGE_FIRST)===0)
748
					$pageIndex=0;
749
				else if(strcasecmp($p,self::CMD_PAGE_LAST)===0)
750
					$pageIndex=$this->getPageCount()-1;
751
				else
752
					$pageIndex=TPropertyValue::ensureInteger($p)-1;
753
				$this->onPageIndexChanged(new TDataGridPageChangedEventParameter($sender,$pageIndex));
754
				return true;
755
			}
756
		}
757
		return false;
758
	}
759
760
	/**
761
	 * Raises <b>OnCancelCommand</b> event.
762
	 * This method is invoked when a button control raises <b>OnCommand</b> event
763
	 * with <b>cancel</b> command name.
764
	 * @param TDataGridCommandEventParameter event parameter
765
	 */
766
	public function onCancelCommand($param)
767
	{
768
		$this->raiseEvent('OnCancelCommand',$this,$param);
769
	}
770
771
	/**
772
	 * Raises <b>OnDeleteCommand</b> event.
773
	 * This method is invoked when a button control raises <b>OnCommand</b> event
774
	 * with <b>delete</b> command name.
775
	 * @param TDataGridCommandEventParameter event parameter
776
	 */
777
	public function onDeleteCommand($param)
778
	{
779
		$this->raiseEvent('OnDeleteCommand',$this,$param);
780
	}
781
782
	/**
783
	 * Raises <b>OnEditCommand</b> event.
784
	 * This method is invoked when a button control raises <b>OnCommand</b> event
785
	 * with <b>edit</b> command name.
786
	 * @param TDataGridCommandEventParameter event parameter
787
	 */
788
	public function onEditCommand($param)
789
	{
790
		$this->raiseEvent('OnEditCommand',$this,$param);
791
	}
792
793
	/**
794
	 * Raises <b>OnItemCommand</b> event.
795
	 * This method is invoked when a button control raises <b>OnCommand</b> event.
796
	 * @param TDataGridCommandEventParameter event parameter
797
	 */
798
	public function onItemCommand($param)
799
	{
800
		$this->raiseEvent('OnItemCommand',$this,$param);
801
	}
802
803
	/**
804
	 * Raises <b>OnSortCommand</b> event.
805
	 * This method is invoked when a button control raises <b>OnCommand</b> event
806
	 * with <b>sort</b> command name.
807
	 * @param TDataGridSortCommandEventParameter event parameter
808
	 */
809
	public function onSortCommand($param)
810
	{
811
		$this->raiseEvent('OnSortCommand',$this,$param);
812
	}
813
814
	/**
815
	 * Raises <b>OnUpdateCommand</b> event.
816
	 * This method is invoked when a button control raises <b>OnCommand</b> event
817
	 * with <b>update</b> command name.
818
	 * @param TDataGridCommandEventParameter event parameter
819
	 */
820
	public function onUpdateCommand($param)
821
	{
822
		$this->raiseEvent('OnUpdateCommand',$this,$param);
823
	}
824
825
	/**
826
	 * Raises <b>OnItemCreated</b> event.
827
	 * This method is invoked right after a datagrid item is created and before
828
	 * added to page hierarchy.
829
	 * @param TDataGridItemEventParameter event parameter
830
	 */
831
	public function onItemCreated($param)
832
	{
833
		$this->raiseEvent('OnItemCreated',$this,$param);
834
	}
835
836
	/**
837
	 * Raises <b>OnPagerCreated</b> event.
838
	 * This method is invoked right after a datagrid pager is created and before
839
	 * added to page hierarchy.
840
	 * @param TDataGridPagerEventParameter event parameter
841
	 */
842
	public function onPagerCreated($param)
843
	{
844
		$this->raiseEvent('OnPagerCreated',$this,$param);
845
	}
846
847
	/**
848
	 * Raises <b>OnItemDataBound</b> event.
849
	 * This method is invoked for each datagrid item after it performs
850
	 * databinding.
851
	 * @param TDataGridItemEventParameter event parameter
852
	 */
853
	public function onItemDataBound($param)
854
	{
855
		$this->raiseEvent('OnItemDataBound',$this,$param);
856
	}
857
858
	/**
859
	 * Raises <b>OnPageIndexChanged</b> event.
860
	 * This method is invoked when current page is changed.
861
	 * @param TDataGridPageChangedEventParameter event parameter
862
	 */
863
	public function onPageIndexChanged($param)
864
	{
865
		$this->raiseEvent('OnPageIndexChanged',$this,$param);
866
	}
867
868
	/**
869
	 * Saves item count in viewstate.
870
	 * This method is invoked right before control state is to be saved.
871
	 */
872
	public function saveState()
873
	{
874
		parent::saveState();
875
		if(!$this->getEnableViewState(true))
876
			return;
877
		if($this->_items)
878
			$this->setViewState('ItemCount',$this->_items->getCount(),0);
879
		else
880
			$this->clearViewState('ItemCount');
881
		if($this->_autoColumns)
882
		{
883
			$state=array();
884
			foreach($this->_autoColumns as $column)
885
				$state[]=$column->saveState();
886
			$this->setViewState('AutoColumns',$state,array());
887
		}
888
		else
889
			$this->clearViewState('AutoColumns');
890
		if($this->_columns)
891
		{
892
			$state=array();
893
			foreach($this->_columns as $column)
894
				$state[]=$column->saveState();
895
			$this->setViewState('Columns',$state,array());
896
		}
897
		else
898
			$this->clearViewState('Columns');
899
	}
900
901
	/**
902
	 * Loads item count information from viewstate.
903
	 * This method is invoked right after control state is loaded.
904
	 */
905
	public function loadState()
906
	{
907
		parent::loadState();
908
		if(!$this->getEnableViewState(true))
909
			return;
910
		if(!$this->getIsDataBound())
911
		{
912
			$state=$this->getViewState('AutoColumns',array());
913
			if(!empty($state))
914
			{
915
				$this->_autoColumns=new TDataGridColumnCollection($this);
916
				foreach($state as $st)
917
				{
918
					$column=new $this->AutoGenerateColumnName;
919
					$column->loadState($st);
920
					$this->_autoColumns->add($column);
921
				}
922
			}
923
			else
924
				$this->_autoColumns=null;
925
			$state=$this->getViewState('Columns',array());
926
			if($this->_columns && $this->_columns->getCount()===count($state))
927
			{
928
				$i=0;
929
				foreach($this->_columns as $column)
930
				{
931
					$column->loadState($state[$i]);
932
					$i++;
933
				}
934
			}
935
			$this->restoreGridFromViewState();
936
		}
937
	}
938
939
	/**
940
	 * Clears up all items in the datagrid.
941
	 */
942
	public function reset()
943
	{
944
		$this->getControls()->clear();
945
		$this->getItems()->clear();
946
		$this->_header=null;
947
		$this->_footer=null;
948
		$this->_topPager=null;
949
		$this->_bottomPager=null;
950
		$this->_useEmptyTemplate=false;
951
	}
952
953
	/**
954
	 * Restores datagrid content from viewstate.
955
	 */
956
	protected function restoreGridFromViewState()
957
	{
958
		$this->reset();
959
960
		$allowPaging=$this->getAllowPaging();
961
962
		$itemCount=$this->getViewState('ItemCount',0);
963
		$dsIndex=$this->getViewState('DataSourceIndex',0);
964
965
		$columns=new TList($this->getColumns());
966
		$columns->mergeWith($this->_autoColumns);
967
		$this->_allColumns=$columns;
968
969
		$items=$this->getItems();
970
971
		if($columns->getCount())
972
		{
973
			foreach($columns as $column)
974
				$column->initialize();
975
			$selectedIndex=$this->getSelectedItemIndex();
976
			$editIndex=$this->getEditItemIndex();
977
			for($index=0;$index<$itemCount;++$index)
978
			{
979
				if($index===0)
980
				{
981
					if($allowPaging)
982
						$this->_topPager=$this->createPager();
983
					$this->_header=$this->createItemInternal(-1,-1,TListItemType::Header,false,null,$columns);
984
				}
985
				if($index===$editIndex)
986
					$itemType=TListItemType::EditItem;
987
				else if($index===$selectedIndex)
988
					$itemType=TListItemType::SelectedItem;
989
				else if($index % 2)
990
					$itemType=TListItemType::AlternatingItem;
991
				else
992
					$itemType=TListItemType::Item;
993
				$items->add($this->createItemInternal($index,$dsIndex,$itemType,false,null,$columns));
994
				$dsIndex++;
995
			}
996
			if($index>0)
997
			{
998
				$this->_footer=$this->createItemInternal(-1,-1,TListItemType::Footer,false,null,$columns);
999
				if($allowPaging)
1000
					$this->_bottomPager=$this->createPager();
1001
			}
1002
		}
1003
		if(!$dsIndex && $this->_emptyTemplate!==null)
1004
		{
1005
			$this->_useEmptyTemplate=true;
1006
			$this->_emptyTemplate->instantiateIn($this);
1007
		}
1008
	}
1009
1010
	/**
1011
	 * Performs databinding to populate datagrid items from data source.
1012
	 * This method is invoked by {@link dataBind()}.
1013
	 * You may override this function to provide your own way of data population.
1014
	 * @param Traversable the bound data
1015
	 */
1016
	protected function performDataBinding($data)
1017
	{
1018
		$this->reset();
1019
		$keys=$this->getDataKeys();
1020
		$keys->clear();
1021
		$keyField=$this->getDataKeyField();
1022
1023
		// get all columns
1024
		if($this->getAutoGenerateColumns())
1025
		{
1026
			$columns=new TList($this->getColumns());
1027
			$autoColumns=$this->createAutoColumns($data);
1028
			$columns->mergeWith($autoColumns);
1029
		}
1030
		else
1031
			$columns=$this->getColumns();
1032
		$this->_allColumns=$columns;
1033
1034
		$items=$this->getItems();
1035
1036
		$index=0;
1037
		$allowPaging=$this->getAllowPaging() && ($data instanceof TPagedDataSource);
1038
		$dsIndex=$allowPaging?$data->getFirstIndexInPage():0;
1039
		$this->setViewState('DataSourceIndex',$dsIndex,0);
1040
		if($columns->getCount())
1041
		{
1042
			foreach($columns as $column)
1043
				$column->initialize();
1044
1045
			$selectedIndex=$this->getSelectedItemIndex();
1046
			$editIndex=$this->getEditItemIndex();
1047
			foreach($data as $key=>$row)
1048
			{
1049
				if($keyField!=='')
1050
					$keys->add($this->getDataFieldValue($row,$keyField));
1051
				else
1052
					$keys->add($key);
1053
				if($index===0)
1054
				{
1055
					if($allowPaging)
1056
						$this->_topPager=$this->createPager();
1057
					$this->_header=$this->createItemInternal(-1,-1,TListItemType::Header,true,null,$columns);
1058
				}
1059
				if($index===$editIndex)
1060
					$itemType=TListItemType::EditItem;
1061
				else if($index===$selectedIndex)
1062
					$itemType=TListItemType::SelectedItem;
1063
				else if($index % 2)
1064
					$itemType=TListItemType::AlternatingItem;
1065
				else
1066
					$itemType=TListItemType::Item;
1067
				$items->add($this->createItemInternal($index,$dsIndex,$itemType,true,$row,$columns));
1068
				$index++;
1069
				$dsIndex++;
1070
			}
1071
			if($index>0)
1072
			{
1073
				$this->_footer=$this->createItemInternal(-1,-1,TListItemType::Footer,true,null,$columns);
1074
				if($allowPaging)
1075
					$this->_bottomPager=$this->createPager();
1076
			}
1077
		}
1078
		$this->setViewState('ItemCount',$index,0);
1079
		if(!$dsIndex && $this->_emptyTemplate!==null)
1080
		{
1081
			$this->_useEmptyTemplate=true;
1082
			$this->_emptyTemplate->instantiateIn($this);
1083
			$this->dataBindChildren();
1084
		}
1085
	}
1086
1087
	/**
1088
	 * Merges consecutive cells who have the same text.
1089
	 * @since 3.1.1
1090
	 */
1091
	private function groupCells()
1092
	{
1093
		if(($columns=$this->_allColumns)===null)
1094
			return;
1095
		$items=$this->getItems();
1096
		foreach($columns as $id=>$column)
1097
		{
1098
			if(!$column->getEnableCellGrouping())
1099
				continue;
1100
			$prevCell=null;
1101
			$prevCellText=null;
1102
			foreach($items as $item)
1103
			{
1104
				$itemType=$item->getItemType();
1105
				$cell=$item->getCells()->itemAt($id);
1106
				if(!$cell->getVisible())
1107
					continue;
1108
				if($itemType===TListItemType::Item || $itemType===TListItemType::AlternatingItem || $itemType===TListItemType::SelectedItem)
1109
				{
1110
					if(($cellText=$this->getCellText($cell))==='')
1111
					{
1112
						$prevCell=null;
1113
						$prevCellText=null;
1114
						continue;
1115
					}
1116
					if($prevCell===null || $prevCellText!==$cellText)
1117
					{
1118
						$prevCell=$cell;
1119
						$prevCellText=$cellText;
1120
					}
1121
					else
1122
					{
1123
						if(($rowSpan=$prevCell->getRowSpan())===0)
1124
							$rowSpan=1;
1125
						$prevCell->setRowSpan($rowSpan+1);
1126
						$cell->setVisible(false);
1127
					}
1128
				}
1129
			}
1130
		}
1131
	}
1132
1133
	private function getCellText($cell)
1134
	{
1135
		if(($data=$cell->getText())==='' && $cell->getHasControls())
1136
		{
1137
			$controls=$cell->getControls();
1138
			foreach($controls as $control)
1139
			{
1140
				if($control instanceof IDataRenderer)
1141
					return $control->getData();
1142
			}
1143
		}
1144
		return $data;
1145
	}
1146
1147
	/**
1148
	 * Creates a datagrid item instance based on the item type and index.
1149
	 * @param integer zero-based item index
1150
	 * @param TListItemType item type
1151
	 * @return TDataGridItem created data list item
1152
	 */
1153
	protected function createItem($itemIndex,$dataSourceIndex,$itemType)
1154
	{
1155
		return new TDataGridItem($itemIndex,$dataSourceIndex,$itemType);
1156
	}
1157
1158
	private function createItemInternal($itemIndex,$dataSourceIndex,$itemType,$dataBind,$dataItem,$columns)
1159
	{
1160
		$item=$this->createItem($itemIndex,$dataSourceIndex,$itemType);
1161
		$this->initializeItem($item,$columns);
1162
		$param=new TDataGridItemEventParameter($item);
1163
		if($dataBind)
1164
		{
1165
			$item->setDataItem($dataItem);
0 ignored issues
show
Deprecated Code introduced by
The method TDataGridItem::setDataItem() has been deprecated with message: deprecated since version 3.1.0. Use {@link setData} instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

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

Loading history...
1166
			$this->onItemCreated($param);
1167
			$this->getControls()->add($item);
1168
			$item->dataBind();
1169
			$this->onItemDataBound($param);
1170
		}
1171
		else
1172
		{
1173
			$this->onItemCreated($param);
1174
			$this->getControls()->add($item);
1175
		}
1176
		return $item;
1177
	}
1178
1179
	/**
1180
	 * Initializes a datagrid item and cells inside it
1181
	 * @param TDataGrid datagrid item to be initialized
1182
	 * @param TDataGridColumnCollection datagrid columns to be used to initialize the cells in the item
1183
	 */
1184
	protected function initializeItem($item,$columns)
1185
	{
1186
		$cells=$item->getCells();
1187
		$itemType=$item->getItemType();
1188
		$index=0;
1189
		foreach($columns as $column)
1190
		{
1191
			if($itemType===TListItemType::Header)
1192
				$cell=new TTableHeaderCell;
1193
			else
1194
				$cell=new TTableCell;
1195
			if(($id=$column->getID())!=='')
1196
				$item->registerObject($id,$cell);
1197
			$cells->add($cell);
1198
			$column->initializeCell($cell,$index,$itemType);
1199
			$index++;
1200
		}
1201
	}
1202
1203
	protected function createPager()
1204
	{
1205
		$pager=new TDataGridPager($this);
1206
		$this->buildPager($pager);
1207
		$this->onPagerCreated(new TDataGridPagerEventParameter($pager));
1208
		$this->getControls()->add($pager);
1209
		return $pager;
1210
	}
1211
1212
	/**
1213
	 * Builds the pager content based on pager style.
1214
	 * @param TDataGridPager the container for the pager
1215
	 */
1216
	protected function buildPager($pager)
1217
	{
1218
		switch($this->getPagerStyle()->getMode())
1219
		{
1220
			case TDataGridPagerMode::NextPrev:
1221
				$this->buildNextPrevPager($pager);
1222
				break;
1223
			case TDataGridPagerMode::Numeric:
1224
				$this->buildNumericPager($pager);
1225
				break;
1226
		}
1227
	}
1228
1229
	/**
1230
	 * Creates a pager button.
1231
	 * Depending on the button type, a TLinkButton or a TButton may be created.
1232
	 * If it is enabled (clickable), its command name and parameter will also be set.
1233
	 * Derived classes may override this method to create additional types of buttons, such as TImageButton.
1234
	 * @param mixed the container pager instance of TActiveDatagridPager
1235
	 * @param string button type, either LinkButton or PushButton
1236
	 * @param boolean whether the button should be enabled
1237
	 * @param string caption of the button
1238
	 * @param string CommandName corresponding to the OnCommand event of the button
1239
	 * @param string CommandParameter corresponding to the OnCommand event of the button
1240
	 * @return mixed the button instance
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use TLabel|TLinkButton|TButton.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
1241
	 */
1242
	protected function createPagerButton($pager,$buttonType,$enabled,$text,$commandName,$commandParameter)
1243
	{
1244
		if($buttonType===TDataGridPagerButtonType::LinkButton)
1245
		{
1246
			if($enabled)
1247
				$button=new TLinkButton;
1248
			else
1249
			{
1250
				$button=new TLabel;
1251
				$button->setText($text);
1252
				return $button;
1253
			}
1254
		}
1255
		else
1256
		{
1257
			$button=new TButton;
1258
			if(!$enabled)
1259
				$button->setEnabled(false);
1260
		}
1261
		$button->setText($text);
1262
		$button->setCommandName($commandName);
1263
		$button->setCommandParameter($commandParameter);
1264
		$button->setCausesValidation(false);
1265
		return $button;
1266
	}
1267
1268
	/**
1269
	 * Builds a next-prev pager
1270
	 * @param TDataGridPager the container for the pager
1271
	 */
1272
	protected function buildNextPrevPager($pager)
1273
	{
1274
		$style=$this->getPagerStyle();
1275
		$buttonType=$style->getButtonType();
1276
		$controls=$pager->getControls();
1277
		$currentPageIndex=$this->getCurrentPageIndex();
1278
		if($currentPageIndex===0)
1279
		{
1280
			if(($text=$style->getFirstPageText())!=='')
1281
			{
1282
				$label=$this->createPagerButton($pager,$buttonType,false,$text,'','');
1283
				$controls->add($label);
1284
				$controls->add("\n");
1285
			}
1286
1287
			$label=$this->createPagerButton($pager,$buttonType,false,$style->getPrevPageText(),'','');
1288
			$controls->add($label);
1289
		}
1290
		else
1291
		{
1292
			if(($text=$style->getFirstPageText())!=='')
1293
			{
1294
				$button=$this->createPagerButton($pager,$buttonType,true,$text,self::CMD_PAGE,self::CMD_PAGE_FIRST);
1295
				$controls->add($button);
1296
				$controls->add("\n");
1297
			}
1298
1299
			$button=$this->createPagerButton($pager,$buttonType,true,$style->getPrevPageText(),self::CMD_PAGE,self::CMD_PAGE_PREV);
1300
			$controls->add($button);
1301
		}
1302
		$controls->add("\n");
1303
		if($currentPageIndex===$this->getPageCount()-1)
1304
		{
1305
			$label=$this->createPagerButton($pager,$buttonType,false,$style->getNextPageText(),'','');
1306
			$controls->add($label);
1307
			if(($text=$style->getLastPageText())!=='')
1308
			{
1309
				$controls->add("\n");
1310
				$label=$this->createPagerButton($pager,$buttonType,false,$text,'','');
1311
				$controls->add($label);
1312
			}
1313
		}
1314
		else
1315
		{
1316
			$button=$this->createPagerButton($pager,$buttonType,true,$style->getNextPageText(),self::CMD_PAGE,self::CMD_PAGE_NEXT);
1317
			$controls->add($button);
1318
			if(($text=$style->getLastPageText())!=='')
1319
			{
1320
				$controls->add("\n");
1321
				$button=$this->createPagerButton($pager,$buttonType,true,$text,self::CMD_PAGE,self::CMD_PAGE_LAST);
1322
				$controls->add($button);
1323
			}
1324
		}
1325
	}
1326
1327
	/**
1328
	 * Builds a numeric pager
1329
	 * @param TDataGridPager the container for the pager
1330
	 */
1331
	protected function buildNumericPager($pager)
1332
	{
1333
		$style=$this->getPagerStyle();
1334
		$buttonType=$style->getButtonType();
1335
		$controls=$pager->getControls();
1336
		$pageCount=$this->getPageCount();
1337
		$pageIndex=$this->getCurrentPageIndex()+1;
1338
		$maxButtonCount=$style->getPageButtonCount();
1339
		$buttonCount=$maxButtonCount>$pageCount?$pageCount:$maxButtonCount;
1340
		$startPageIndex=1;
1341
		$endPageIndex=$buttonCount;
1342
		if($pageIndex>$endPageIndex)
1343
		{
1344
			$startPageIndex=((int)(($pageIndex-1)/$maxButtonCount))*$maxButtonCount+1;
1345
			if(($endPageIndex=$startPageIndex+$maxButtonCount-1)>$pageCount)
1346
				$endPageIndex=$pageCount;
1347
			if($endPageIndex-$startPageIndex+1<$maxButtonCount)
1348
			{
1349
				if(($startPageIndex=$endPageIndex-$maxButtonCount+1)<1)
1350
					$startPageIndex=1;
1351
			}
1352
		}
1353
1354
		if($startPageIndex>1)
1355
		{
1356
			if(($text=$style->getFirstPageText())!=='')
1357
			{
1358
				$button=$this->createPagerButton($pager,$buttonType,true,$text,self::CMD_PAGE,self::CMD_PAGE_FIRST);
1359
				$controls->add($button);
1360
				$controls->add("\n");
1361
			}
1362
			$prevPageIndex=$startPageIndex-1;
1363
			$button=$this->createPagerButton($pager,$buttonType,true,$style->getPrevPageText(),self::CMD_PAGE,"$prevPageIndex");
1364
			$controls->add($button);
1365
			$controls->add("\n");
1366
		}
1367
1368
		for($i=$startPageIndex;$i<=$endPageIndex;++$i)
1369
		{
1370
			if($i===$pageIndex)
1371
			{
1372
				$label=$this->createPagerButton($pager,$buttonType,false,"$i",'','');
1373
				$controls->add($label);
1374
			}
1375
			else
1376
			{
1377
				$button=$this->createPagerButton($pager,$buttonType,true,"$i",self::CMD_PAGE,"$i");
1378
				$controls->add($button);
1379
			}
1380
			if($i<$endPageIndex)
1381
				$controls->add("\n");
1382
		}
1383
1384
		if($pageCount>$endPageIndex)
1385
		{
1386
			$controls->add("\n");
1387
			$nextPageIndex=$endPageIndex+1;
1388
			$button=$this->createPagerButton($pager,$buttonType,true,$style->getNextPageText(),self::CMD_PAGE,"$nextPageIndex");
1389
			$controls->add($button);
1390
			if(($text=$style->getLastPageText())!=='')
1391
			{
1392
				$controls->add("\n");
1393
				$button=$this->createPagerButton($pager,$buttonType,true,$text,self::CMD_PAGE,self::CMD_PAGE_LAST);
1394
				$controls->add($button);
1395
			}
1396
		}
1397
	}
1398
1399
	/**
1400
	 * Automatically generates datagrid columns based on datasource schema
1401
	 * @param Traversable data source bound to the datagrid
1402
	 * @return TDataGridColumnCollection
1403
	 */
1404
	protected function createAutoColumns($dataSource)
1405
	{
1406
		if(!$dataSource)
1407
			return null;
1408
		$autoColumns=$this->getAutoColumns();
1409
		$autoColumns->clear();
1410
		foreach($dataSource as $row)
1411
		{
1412
			foreach($row as $key=>$value)
1413
			{
1414
				$column=new $this->AutoGenerateColumnName;
1415
				if(is_string($key))
1416
				{
1417
					$column->setHeaderText($key);
1418
					$column->setDataField($key);
1419
					$column->setSortExpression($key);
1420
					$autoColumns->add($column);
1421
				}
1422
				else
1423
				{
1424
					$column->setHeaderText(TListItemType::Item);
1425
					$column->setDataField($key);
1426
					$column->setSortExpression(TListItemType::Item);
1427
					$autoColumns->add($column);
1428
				}
1429
			}
1430
			break;
1431
		}
1432
		return $autoColumns;
1433
	}
1434
1435
	/**
1436
	 * Applies styles to items, header, footer and separators.
1437
	 * Item styles are applied in a hierarchical way. Style in higher hierarchy
1438
	 * will inherit from styles in lower hierarchy.
1439
	 * Starting from the lowest hierarchy, the item styles include
1440
	 * item's own style, {@link getItemStyle ItemStyle}, {@link getAlternatingItemStyle AlternatingItemStyle},
1441
	 * {@link getSelectedItemStyle SelectedItemStyle}, and {@link getEditItemStyle EditItemStyle}.
1442
	 * Therefore, if background color is set as red in {@link getItemStyle ItemStyle},
1443
	 * {@link getEditItemStyle EditItemStyle} will also have red background color
1444
	 * unless it is set to a different value explicitly.
1445
	 */
1446
	protected function applyItemStyles()
1447
	{
1448
		$itemStyle=$this->getViewState('ItemStyle',null);
1449
1450
		$alternatingItemStyle=$this->getViewState('AlternatingItemStyle',null);
1451
		if($itemStyle!==null)
1452
		{
1453
			if($alternatingItemStyle===null)
1454
				$alternatingItemStyle=$itemStyle;
1455
			else
1456
				$alternatingItemStyle->mergeWith($itemStyle);
1457
		}
1458
1459
		$selectedItemStyle=$this->getViewState('SelectedItemStyle',null);
1460
1461
		$editItemStyle=$this->getViewState('EditItemStyle',null);
1462
		if($selectedItemStyle!==null)
1463
		{
1464
			if($editItemStyle===null)
1465
				$editItemStyle=$selectedItemStyle;
1466
			else
1467
				$editItemStyle->mergeWith($selectedItemStyle);
1468
		}
1469
1470
		$headerStyle=$this->getViewState('HeaderStyle',null);
1471
		$footerStyle=$this->getViewState('FooterStyle',null);
1472
		$pagerStyle=$this->getViewState('PagerStyle',null);
1473
		$separatorStyle=$this->getViewState('SeparatorStyle',null);
1474
1475
		foreach($this->getControls() as $index=>$item)
1476
		{
1477
			if(!($item instanceof TDataGridItem) && !($item instanceof TDataGridPager))
1478
				continue;
1479
			$itemType=$item->getItemType();
1480
			switch($itemType)
1481
			{
1482
				case TListItemType::Header:
1483
					if($headerStyle)
1484
						$item->getStyle()->mergeWith($headerStyle);
1485
					if(!$this->getShowHeader())
1486
						$item->setVisible(false);
1487
					break;
1488
				case TListItemType::Footer:
1489
					if($footerStyle)
1490
						$item->getStyle()->mergeWith($footerStyle);
1491
					if(!$this->getShowFooter())
1492
						$item->setVisible(false);
1493
					break;
1494
				case TListItemType::Separator:
1495
					if($separatorStyle)
1496
						$item->getStyle()->mergeWith($separatorStyle);
1497
					break;
1498
				case TListItemType::Item:
1499
					if($itemStyle)
1500
						$item->getStyle()->mergeWith($itemStyle);
1501
					break;
1502
				case TListItemType::AlternatingItem:
1503
					if($alternatingItemStyle)
1504
						$item->getStyle()->mergeWith($alternatingItemStyle);
1505
					break;
1506
				case TListItemType::SelectedItem:
1507
					if($selectedItemStyle)
1508
						$item->getStyle()->mergeWith($selectedItemStyle);
1509
					if($index % 2==1)
1510
					{
1511
						if($itemStyle)
1512
							$item->getStyle()->mergeWith($itemStyle);
1513
					}
1514
					else
1515
					{
1516
						if($alternatingItemStyle)
1517
							$item->getStyle()->mergeWith($alternatingItemStyle);
1518
					}
1519
					break;
1520
				case TListItemType::EditItem:
1521
					if($editItemStyle)
1522
						$item->getStyle()->mergeWith($editItemStyle);
1523
					if($index % 2==1)
1524
					{
1525
						if($itemStyle)
1526
							$item->getStyle()->mergeWith($itemStyle);
1527
					}
1528
					else
1529
					{
1530
						if($alternatingItemStyle)
1531
							$item->getStyle()->mergeWith($alternatingItemStyle);
1532
					}
1533
					break;
1534
				case TListItemType::Pager:
1535
					if($pagerStyle)
1536
					{
1537
						$item->getStyle()->mergeWith($pagerStyle);
1538
						if($index===0)
1539
						{
1540
							if($pagerStyle->getPosition()===TDataGridPagerPosition::Bottom || !$pagerStyle->getVisible())
1541
								$item->setVisible(false);
1542
						}
1543
						else
1544
						{
1545
							if($pagerStyle->getPosition()===TDataGridPagerPosition::Top || !$pagerStyle->getVisible())
1546
								$item->setVisible(false);
1547
						}
1548
					}
1549
					break;
1550
				default:
1551
					break;
1552
			}
1553
			if($this->_columns && $itemType!==TListItemType::Pager)
1554
			{
1555
				$n=$this->_columns->getCount();
1556
				$cells=$item->getCells();
0 ignored issues
show
Bug introduced by
The method getCells does only exist in TDataGridItem, but not in TDataGridPager.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
1557
				for($i=0;$i<$n;++$i)
1558
				{
1559
					$cell=$cells->itemAt($i);
1560
					$column=$this->_columns->itemAt($i);
1561
					if(!$column->getVisible())
1562
						$cell->setVisible(false);
1563
					else
1564
					{
1565
						if($itemType===TListItemType::Header)
1566
							$style=$column->getHeaderStyle(false);
1567
						else if($itemType===TListItemType::Footer)
1568
							$style=$column->getFooterStyle(false);
1569
						else
1570
							$style=$column->getItemStyle(false);
1571
						if($style!==null)
1572
							$cell->getStyle()->mergeWith($style);
1573
					}
1574
				}
1575
			}
1576
		}
1577
	}
1578
1579
	/**
1580
	 * Renders the openning tag for the datagrid control which will render table caption if present.
1581
	 * @param THtmlWriter the writer used for the rendering purpose
1582
	 */
1583
	public function renderBeginTag($writer)
1584
	{
1585
		parent::renderBeginTag($writer);
1586
		if(($caption=$this->getCaption())!=='')
1587
		{
1588
			if(($align=$this->getCaptionAlign())!==TTableCaptionAlign::NotSet)
1589
				$writer->addAttribute('align',strtolower($align));
1590
			$writer->renderBeginTag('caption');
1591
			$writer->write($caption);
1592
			$writer->renderEndTag();
1593
		}
1594
	}
1595
1596
	/**
1597
	 * Renders the datagrid.
1598
	 * @param THtmlWriter writer for the rendering purpose
1599
	 */
1600
	public function render($writer)
1601
	{
1602
		if($this->getHasControls())
1603
		{
1604
			$this->groupCells();
1605
			if($this->_useEmptyTemplate)
1606
			{
1607
				$control=new TWebControl;
1608
				$control->setID($this->getClientID());
1609
				$control->copyBaseAttributes($this);
1610
				if($this->getHasStyle())
1611
					$control->getStyle()->copyFrom($this->getStyle());
1612
				$control->renderBeginTag($writer);
1613
				$this->renderContents($writer);
1614
				$control->renderEndTag($writer);
1615
			}
1616
			else if($this->getViewState('ItemCount',0)>0)
1617
			{
1618
				$this->applyItemStyles();
1619
				if($this->_topPager)
1620
				{
1621
					$this->_topPager->renderControl($writer);
1622
					$writer->writeLine();
1623
				}
1624
				$this->renderTable($writer);
1625
				if($this->_bottomPager)
1626
				{
1627
					$writer->writeLine();
1628
					$this->_bottomPager->renderControl($writer);
1629
				}
1630
			}
1631
		}
1632
	}
1633
1634
	/**
1635
	 * Renders the tabular data.
1636
	 * @param THtmlWriter writer
1637
	 */
1638
	protected function renderTable($writer)
1639
	{
1640
		$this->renderBeginTag($writer);
1641
		if($this->_header && $this->_header->getVisible())
1642
		{
1643
			$writer->writeLine();
1644
			if($style=$this->getViewState('TableHeadStyle',null))
1645
				$style->addAttributesToRender($writer);
1646
			$writer->renderBeginTag('thead');
1647
			$this->_header->render($writer);
1648
			$writer->renderEndTag();
1649
		}
1650
		$writer->writeLine();
1651
		if($style=$this->getViewState('TableBodyStyle',null))
1652
			$style->addAttributesToRender($writer);
1653
		$writer->renderBeginTag('tbody');
1654
		foreach($this->getItems() as $item)
1655
			$item->renderControl($writer);
1656
		$writer->renderEndTag();
1657
1658
		if($this->_footer && $this->_footer->getVisible())
1659
		{
1660
			$writer->writeLine();
1661
			if($style=$this->getViewState('TableFootStyle',null))
1662
				$style->addAttributesToRender($writer);
1663
			$writer->renderBeginTag('tfoot');
1664
			$this->_footer->render($writer);
1665
			$writer->renderEndTag();
1666
		}
1667
1668
		$writer->writeLine();
1669
		$this->renderEndTag($writer);
1670
	}
1671
}
1672
1673
/**
1674
 * TDataGridItemEventParameter class
1675
 *
1676
 * TDataGridItemEventParameter encapsulates the parameter data for
1677
 * {@link TDataGrid::onItemCreated OnItemCreated} event of {@link TDataGrid} controls.
1678
 * The {@link getItem Item} property indicates the datagrid item related with the event.
1679
 *
1680
 * @author Qiang Xue <[email protected]>
1681
 * @package System.Web.UI.WebControls
1682
 * @since 3.0
1683
 */
1684
class TDataGridItemEventParameter extends TEventParameter
1685
{
1686
	/**
1687
	 * The TDataGridItem control responsible for the event.
1688
	 * @var TDataGridItem
1689
	 */
1690
	private $_item=null;
1691
1692
	/**
1693
	 * Constructor.
1694
	 * @param TDataGridItem datagrid item related with the corresponding event
1695
	 */
1696
	public function __construct(TDataGridItem $item)
1697
	{
1698
		$this->_item=$item;
1699
	}
1700
1701
	/**
1702
	 * @return TDataGridItem datagrid item related with the corresponding event
1703
	 */
1704
	public function getItem()
1705
	{
1706
		return $this->_item;
1707
	}
1708
}
1709
1710
/**
1711
 * TDataGridPagerEventParameter class
1712
 *
1713
 * TDataGridPagerEventParameter encapsulates the parameter data for
1714
 * {@link TDataGrid::onPagerCreated OnPagerCreated} event of {@link TDataGrid} controls.
1715
 * The {@link getPager Pager} property indicates the datagrid pager related with the event.
1716
 *
1717
 * @author Qiang Xue <[email protected]>
1718
 * @package System.Web.UI.WebControls
1719
 * @since 3.0
1720
 */
1721
class TDataGridPagerEventParameter extends TEventParameter
1722
{
1723
	/**
1724
	 * The TDataGridPager control responsible for the event.
1725
	 * @var TDataGridPager
1726
	 */
1727
	protected $_pager=null;
1728
1729
	/**
1730
	 * Constructor.
1731
	 * @param TDataGridPager datagrid pager related with the corresponding event
1732
	 */
1733
	public function __construct(TDataGridPager $pager)
1734
	{
1735
		$this->_pager=$pager;
1736
	}
1737
1738
	/**
1739
	 * @return TDataGridPager datagrid pager related with the corresponding event
1740
	 */
1741
	public function getPager()
1742
	{
1743
		return $this->_pager;
1744
	}
1745
}
1746
1747
/**
1748
 * TDataGridCommandEventParameter class
1749
 *
1750
 * TDataGridCommandEventParameter encapsulates the parameter data for
1751
 * {@link TDataGrid::onItemCommand ItemCommand} event of {@link TDataGrid} controls.
1752
 *
1753
 * The {@link getItem Item} property indicates the datagrid item related with the event.
1754
 * The {@link getCommandSource CommandSource} refers to the control that originally
1755
 * raises the Command event.
1756
 *
1757
 * @author Qiang Xue <[email protected]>
1758
 * @package System.Web.UI.WebControls
1759
 * @since 3.0
1760
 */
1761
class TDataGridCommandEventParameter extends TCommandEventParameter
1762
{
1763
	/**
1764
	 * @var TDataGridItem the TDataGridItem control responsible for the event.
1765
	 */
1766
	private $_item=null;
1767
	/**
1768
	 * @var TControl the control originally raises the <b>Command</b> event.
1769
	 */
1770
	private $_source=null;
1771
1772
	/**
1773
	 * Constructor.
1774
	 * @param TDataGridItem datagrid item responsible for the event
1775
	 * @param TControl original event sender
1776
	 * @param TCommandEventParameter original event parameter
1777
	 */
1778
	public function __construct($item,$source,TCommandEventParameter $param)
1779
	{
1780
		$this->_item=$item;
1781
		$this->_source=$source;
1782
		parent::__construct($param->getCommandName(),$param->getCommandParameter());
1783
	}
1784
1785
	/**
1786
	 * @return TDataGridItem the TDataGridItem control responsible for the event.
1787
	 */
1788
	public function getItem()
1789
	{
1790
		return $this->_item;
1791
	}
1792
1793
	/**
1794
	 * @return TControl the control originally raises the <b>Command</b> event.
1795
	 */
1796
	public function getCommandSource()
1797
	{
1798
		return $this->_source;
1799
	}
1800
}
1801
1802
/**
1803
 * TDataGridSortCommandEventParameter class
1804
 *
1805
 * TDataGridSortCommandEventParameter encapsulates the parameter data for
1806
 * {@link TDataGrid::onSortCommand SortCommand} event of {@link TDataGrid} controls.
1807
 *
1808
 * The {@link getCommandSource CommandSource} property refers to the control
1809
 * that originally raises the OnCommand event, while {@link getSortExpression SortExpression}
1810
 * gives the sort expression carried with the sort command.
1811
 *
1812
 * @author Qiang Xue <[email protected]>
1813
 * @package System.Web.UI.WebControls
1814
 * @since 3.0
1815
 */
1816
class TDataGridSortCommandEventParameter extends TEventParameter
1817
{
1818
	/**
1819
	 * @var string sort expression
1820
	 */
1821
	private $_sortExpression='';
1822
	/**
1823
	 * @var TControl original event sender
1824
	 */
1825
	private $_source=null;
1826
1827
	/**
1828
	 * Constructor.
1829
	 * @param TControl the control originally raises the <b>OnCommand</b> event.
1830
	 * @param TDataGridCommandEventParameter command event parameter
1831
	 */
1832
	public function __construct($source,TDataGridCommandEventParameter $param)
1833
	{
1834
		$this->_source=$source;
1835
		$this->_sortExpression=$param->getCommandParameter();
1836
	}
1837
1838
	/**
1839
	 * @return TControl the control originally raises the <b>OnCommand</b> event.
1840
	 */
1841
	public function getCommandSource()
1842
	{
1843
		return $this->_source;
1844
	}
1845
1846
	/**
1847
	 * @return string sort expression
1848
	 */
1849
	public function getSortExpression()
1850
	{
1851
		return $this->_sortExpression;
1852
	}
1853
}
1854
1855
/**
1856
 * TDataGridPageChangedEventParameter class
1857
 *
1858
 * TDataGridPageChangedEventParameter encapsulates the parameter data for
1859
 * {@link TDataGrid::onPageIndexChanged PageIndexChanged} event of {@link TDataGrid} controls.
1860
 *
1861
 * The {@link getCommandSource CommandSource} property refers to the control
1862
 * that originally raises the OnCommand event, while {@link getNewPageIndex NewPageIndex}
1863
 * returns the new page index carried with the page command.
1864
 *
1865
 * @author Qiang Xue <[email protected]>
1866
 * @package System.Web.UI.WebControls
1867
 * @since 3.0
1868
 */
1869
class TDataGridPageChangedEventParameter extends TEventParameter
1870
{
1871
	/**
1872
	 * @var integer new page index
1873
	 */
1874
	private $_newIndex;
1875
	/**
1876
	 * @var TControl original event sender
1877
	 */
1878
	private $_source=null;
1879
1880
	/**
1881
	 * Constructor.
1882
	 * @param TControl the control originally raises the <b>OnCommand</b> event.
1883
	 * @param integer new page index
1884
	 */
1885
	public function __construct($source,$newPageIndex)
1886
	{
1887
		$this->_source=$source;
1888
		$this->_newIndex=$newPageIndex;
1889
	}
1890
1891
	/**
1892
	 * @return TControl the control originally raises the <b>OnCommand</b> event.
1893
	 */
1894
	public function getCommandSource()
1895
	{
1896
		return $this->_source;
1897
	}
1898
1899
	/**
1900
	 * @return integer new page index
1901
	 */
1902
	public function getNewPageIndex()
1903
	{
1904
		return $this->_newIndex;
1905
	}
1906
}
1907
1908
/**
1909
 * TDataGridItem class
1910
 *
1911
 * A TDataGridItem control represents an item in the {@link TDataGrid} control,
1912
 * such as heading section, footer section, or a data item.
1913
 * The index and data value of the item can be accessed via {@link getItemIndex ItemIndex}>
1914
 * and {@link getDataItem DataItem} properties, respectively. The type of the item
1915
 * is given by {@link getItemType ItemType} property. Property {@link getDataSourceIndex DataSourceIndex}
1916
 * gives the index of the item from the bound data source.
1917
 *
1918
 * @author Qiang Xue <[email protected]>
1919
 * @package System.Web.UI.WebControls
1920
 * @since 3.0
1921
 */
1922
class TDataGridItem extends TTableRow implements INamingContainer
1923
{
1924
	/**
1925
	 * @var integer index of the data item in the Items collection of datagrid
1926
	 */
1927
	private $_itemIndex='';
1928
	/**
1929
	 * @var integer index of the item from the bound data source
1930
	 */
1931
	private $_dataSourceIndex=0;
1932
	/**
1933
	 * type of the TDataGridItem
1934
	 * @var string
1935
	 */
1936
	private $_itemType='';
1937
	/**
1938
	 * value of the data item
1939
	 * @var mixed
1940
	 */
1941
	private $_data=null;
1942
1943
	/**
1944
	 * Constructor.
1945
	 * @param integer zero-based index of the item in the item collection of datagrid
1946
	 * @param TListItemType item type
1947
	 */
1948
	public function __construct($itemIndex,$dataSourceIndex,$itemType)
1949
	{
1950
		$this->_itemIndex=$itemIndex;
1951
		$this->_dataSourceIndex=$dataSourceIndex;
1952
		$this->setItemType($itemType);
1953
		if($itemType===TListItemType::Header)
1954
			$this->setTableSection(TTableRowSection::Header);
1955
		else if($itemType===TListItemType::Footer)
1956
			$this->setTableSection(TTableRowSection::Footer);
1957
	}
1958
1959
	/**
1960
	 * @return TListItemType item type.
1961
	 */
1962
	public function getItemType()
1963
	{
1964
		return $this->_itemType;
1965
	}
1966
1967
	/**
1968
	 * @param TListItemType item type
1969
	 */
1970
	public function setItemType($value)
1971
	{
1972
		$this->_itemType=TPropertyValue::ensureEnum($value,'TListItemType');
1973
	}
1974
1975
	/**
1976
	 * @return integer zero-based index of the item in the item collection of datagrid
1977
	 */
1978
	public function getItemIndex()
1979
	{
1980
		return $this->_itemIndex;
1981
	}
1982
1983
	/**
1984
	 * @return integer the index of the datagrid item from the bound data source
1985
	 */
1986
	public function getDataSourceIndex()
1987
	{
1988
		return $this->_dataSourceIndex;
1989
	}
1990
1991
	/**
1992
	 * @return mixed data associated with the item
1993
	 * @since 3.1.0
1994
	 */
1995
	public function getData()
1996
	{
1997
		return $this->_data;
1998
	}
1999
2000
	/**
2001
	 * @param mixed data to be associated with the item
2002
	 * @since 3.1.0
2003
	 */
2004
	public function setData($value)
2005
	{
2006
		$this->_data=$value;
2007
	}
2008
2009
	/**
2010
	 * This property is deprecated since v3.1.0.
2011
	 * @return mixed data associated with the item
2012
	 * @deprecated deprecated since v3.1.0. Use {@link getData} instead.
2013
	 */
2014
	public function getDataItem()
2015
	{
2016
		return $this->getData();
2017
	}
2018
2019
	/**
2020
	 * This property is deprecated since v3.1.0.
2021
	 * @param mixed data to be associated with the item
2022
	 * @deprecated deprecated since version 3.1.0. Use {@link setData} instead.
2023
	 */
2024
	public function setDataItem($value)
2025
	{
2026
		return $this->setData($value);
2027
	}
2028
2029
	/**
2030
	 * This method overrides parent's implementation by wrapping event parameter
2031
	 * for <b>OnCommand</b> event with item information.
2032
	 * @param TControl the sender of the event
2033
	 * @param TEventParameter event parameter
2034
	 * @return boolean whether the event bubbling should stop here.
2035
	 */
2036
	public function bubbleEvent($sender,$param)
2037
	{
2038
		if($param instanceof TCommandEventParameter)
2039
		{
2040
			$this->raiseBubbleEvent($this,new TDataGridCommandEventParameter($this,$sender,$param));
2041
			return true;
2042
		}
2043
		else
2044
			return false;
2045
	}
2046
}
2047
2048
2049
/**
2050
 * TDataGridPager class.
2051
 *
2052
 * TDataGridPager represents a datagrid pager.
2053
 *
2054
 * @author Qiang Xue <[email protected]>
2055
 * @package System.Web.UI.WebControls
2056
 * @since 3.0
2057
 */
2058
class TDataGridPager extends TPanel implements INamingContainer
2059
{
2060
	private $_dataGrid;
2061
2062
	/**
2063
	 * Constructor.
2064
	 * @param TDataGrid datagrid object
2065
	 */
2066
	public function __construct($dataGrid)
2067
	{
2068
		$this->_dataGrid=$dataGrid;
2069
	}
2070
2071
	/**
2072
	 * This method overrides parent's implementation by wrapping event parameter
2073
	 * for <b>OnCommand</b> event with item information.
2074
	 * @param TControl the sender of the event
2075
	 * @param TEventParameter event parameter
2076
	 * @return boolean whether the event bubbling should stop here.
2077
	 */
2078
	public function bubbleEvent($sender,$param)
2079
	{
2080
		if($param instanceof TCommandEventParameter)
2081
		{
2082
			$this->raiseBubbleEvent($this,new TDataGridCommandEventParameter($this,$sender,$param));
2083
			return true;
2084
		}
2085
		else
2086
			return false;
2087
	}
2088
2089
	/**
2090
	 * @return TDataGrid the datagrid owning this pager
2091
	 */
2092
	public function getDataGrid()
2093
	{
2094
		return $this->_dataGrid;
2095
	}
2096
2097
	/**
2098
	 * @return string item type.
2099
	 */
2100
	public function getItemType()
2101
	{
2102
		return TListItemType::Pager;
2103
	}
2104
}
2105
2106
2107
/**
2108
 * TDataGridItemCollection class.
2109
 *
2110
 * TDataGridItemCollection represents a collection of data grid items.
2111
 *
2112
 * @author Qiang Xue <[email protected]>
2113
 * @package System.Web.UI.WebControls
2114
 * @since 3.0
2115
 */
2116
class TDataGridItemCollection extends TList
2117
{
2118
	/**
2119
	 * Inserts an item at the specified position.
2120
	 * This overrides the parent implementation by inserting only TDataGridItem.
2121
	 * @param integer the speicified position.
2122
	 * @param mixed new item
2123
	 * @throws TInvalidDataTypeException if the item to be inserted is not a TDataGridItem.
2124
	 */
2125
	public function insertAt($index,$item)
2126
	{
2127
		if($item instanceof TDataGridItem)
2128
			parent::insertAt($index,$item);
2129
		else
2130
			throw new TInvalidDataTypeException('datagriditemcollection_datagriditem_required');
2131
	}
2132
}
2133
2134
/**
2135
 * TDataGridColumnCollection class.
2136
 *
2137
 * TDataGridColumnCollection represents a collection of data grid columns.
2138
 *
2139
 * @author Qiang Xue <[email protected]>
2140
 * @package System.Web.UI.WebControls
2141
 * @since 3.0
2142
 */
2143
class TDataGridColumnCollection extends TList
2144
{
2145
	/**
2146
	 * the control that owns this collection.
2147
	 * @var TControl
2148
	 */
2149
	private $_o;
2150
2151
	/**
2152
	 * Constructor.
2153
	 * @param TDataGrid the control that owns this collection.
2154
	 */
2155
	public function __construct(TDataGrid $owner)
2156
	{
2157
		$this->_o=$owner;
2158
	}
2159
2160
	/**
2161
	 * @return TDataGrid the control that owns this collection.
2162
	 */
2163
	protected function getOwner()
2164
	{
2165
		return $this->_o;
2166
	}
2167
2168
	/**
2169
	 * Inserts an item at the specified position.
2170
	 * This overrides the parent implementation by inserting only TDataGridColumn.
2171
	 * @param integer the speicified position.
2172
	 * @param mixed new item
2173
	 * @throws TInvalidDataTypeException if the item to be inserted is not a TDataGridColumn.
2174
	 */
2175
	public function insertAt($index,$item)
2176
	{
2177
		if($item instanceof TDataGridColumn)
2178
		{
2179
			$item->setOwner($this->_o);
0 ignored issues
show
Compatibility introduced by
$this->_o of type object<TControl> is not a sub-type of object<TDataGrid>. It seems like you assume a child class of the class TControl to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
2180
			parent::insertAt($index,$item);
2181
		}
2182
		else
2183
			throw new TInvalidDataTypeException('datagridcolumncollection_datagridcolumn_required');
2184
	}
2185
}
2186
2187
/**
2188
 * TDataGridPagerMode class.
2189
 * TDataGridPagerMode defines the enumerable type for the possible modes that a datagrid pager can take.
2190
 *
2191
 * The following enumerable values are defined:
2192
 * - NextPrev: pager buttons are displayed as next and previous pages
2193
 * - Numeric: pager buttons are displayed as numeric page numbers
2194
 *
2195
 * @author Qiang Xue <[email protected]>
2196
 * @package System.Web.UI.WebControls
2197
 * @since 3.0.4
2198
 */
2199
class TDataGridPagerMode extends TEnumerable
2200
{
2201
	const NextPrev='NextPrev';
2202
	const Numeric='Numeric';
2203
}
2204
2205
2206
/**
2207
 * TDataGridPagerButtonType class.
2208
 * TDataGridPagerButtonType defines the enumerable type for the possible types of datagrid pager buttons.
2209
 *
2210
 * The following enumerable values are defined:
2211
 * - LinkButton: link buttons
2212
 * - PushButton: form submit buttons
2213
 *
2214
 * @author Qiang Xue <[email protected]>
2215
 * @package System.Web.UI.WebControls
2216
 * @since 3.0.4
2217
 */
2218
class TDataGridPagerButtonType extends TEnumerable
2219
{
2220
	const LinkButton='LinkButton';
2221
	const PushButton='PushButton';
2222
}
2223
2224
2225
/**
2226
 * TDataGridPagerPosition class.
2227
 * TDataGridPagerPosition defines the enumerable type for the possible positions that a datagrid pager can be located at.
2228
 *
2229
 * The following enumerable values are defined:
2230
 * - Bottom: pager appears only at the bottom of the data grid.
2231
 * - Top: pager appears only at the top of the data grid.
2232
 * - TopAndBottom: pager appears on both top and bottom of the data grid.
2233
 *
2234
 * @author Qiang Xue <[email protected]>
2235
 * @package System.Web.UI.WebControls
2236
 * @since 3.0.4
2237
 */
2238
class TDataGridPagerPosition extends TEnumerable
2239
{
2240
	const Bottom='Bottom';
2241
	const Top='Top';
2242
	const TopAndBottom='TopAndBottom';
2243
}
2244
2245