1
|
|
|
<?php namespace EvolutionCMS\Support; |
2
|
|
|
|
3
|
|
|
use EvolutionCMS\Interfaces\DataGridInterface; |
4
|
|
|
|
5
|
|
|
# |
6
|
|
|
# DataGrid Class |
7
|
|
|
# Created By Raymond Irving 15-Feb,2004 |
8
|
|
|
# Based on CLASP 2.0 (www.claspdev.com) |
9
|
|
|
# ----------------------------------------- |
10
|
|
|
# Licensed under the LGPL |
11
|
|
|
# ----------------------------------------- |
12
|
|
|
# |
13
|
|
|
|
14
|
|
|
class DataGrid implements DataGridInterface{ |
15
|
|
|
|
16
|
|
|
public $ds; // datasource |
17
|
|
|
public $id; |
18
|
|
|
public $pageSize; // pager settings |
19
|
|
|
public $pageNumber; |
20
|
|
|
public $pager; |
21
|
|
|
public $pagerLocation; // top-right, top-left, bottom-left, bottom-right, both-left, both-right |
22
|
|
|
|
23
|
|
|
public $cssStyle; |
24
|
|
|
public $cssClass; |
25
|
|
|
|
26
|
|
|
public $columnHeaderStyle; |
27
|
|
|
public $columnHeaderClass; |
28
|
|
|
public $itemStyle; |
29
|
|
|
public $itemClass; |
30
|
|
|
public $altItemStyle; |
31
|
|
|
public $altItemClass; |
32
|
|
|
|
33
|
|
|
public $fields; |
34
|
|
|
public $columns; |
35
|
|
|
public $colWidths; |
36
|
|
|
public $colAligns; |
37
|
|
|
public $colWraps; |
38
|
|
|
public $colColors; |
39
|
|
|
public $colTypes; // coltype1, coltype2, etc or coltype1:format1, e.g. date:%Y %m |
40
|
|
|
// data type: integer,float,currency,date |
41
|
|
|
|
42
|
|
|
public $header; |
43
|
|
|
public $footer; |
44
|
|
|
public $cellPadding; |
45
|
|
|
public $cellSpacing; |
46
|
|
|
|
47
|
|
|
public $rowAlign; // vertical alignment: top, middle, bottom |
48
|
|
|
public $rowIdField; |
49
|
|
|
|
50
|
|
|
public $pagerStyle; |
51
|
|
|
public $pagerClass; |
52
|
|
|
public $pageClass; |
53
|
|
|
public $selPageClass; |
54
|
|
|
public $noRecordMsg = "No records found."; |
55
|
|
|
|
56
|
|
|
public $_itemStyle; |
57
|
|
|
public $_itemClass; |
58
|
|
|
public $_altItemClass; |
59
|
|
|
public $_altItemStyle; |
60
|
|
|
public $_isDataset; |
61
|
|
|
public $_colcount; |
62
|
|
|
public $_colnames; |
63
|
|
|
public $_colwidths; |
64
|
|
|
public $_colaligns; |
65
|
|
|
public $_colcolors; |
66
|
|
|
public $_coltypes; |
67
|
|
|
public $_colwraps; |
68
|
|
|
public $_alt; |
69
|
|
|
public $_total; |
70
|
|
|
public $_fieldnames; |
71
|
|
|
/** |
72
|
|
|
* @see datagrid modifier in manager/includes/extenders/modifiers.class.inc.php |
73
|
|
|
*/ |
74
|
|
|
public $cdelim; |
75
|
|
|
|
76
|
|
|
public static $dataGridCnt; |
77
|
|
|
|
78
|
|
|
public function __construct($id, $ds, $pageSize = 20, $pageNumber = -1) { |
79
|
|
|
// set id |
80
|
|
|
self::$dataGridCnt++; |
81
|
|
|
$this->id = $this->id ? empty($id) : "dg" . self::$dataGridCnt; |
82
|
|
|
|
83
|
|
|
// set datasource |
84
|
|
|
$this->ds = $ds; |
85
|
|
|
|
86
|
|
|
// set pager |
87
|
|
|
$this->pageSize = $pageSize; |
88
|
|
|
$this->pageNumber = $pageNumber; // by setting pager to -1 will cause pager to load it's last page number |
89
|
|
|
$this->pagerLocation = 'top-right'; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
public function setDataSource($ds) { |
93
|
|
|
$this->ds = $ds; |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
public function render() { |
97
|
|
|
$modx = evolutionCMS(); |
98
|
|
|
$columnHeaderStyle = ($this->columnHeaderStyle) ? "style='" . $this->columnHeaderStyle . "'" : ''; |
99
|
|
|
$columnHeaderClass = ($this->columnHeaderClass) ? "class='" . $this->columnHeaderClass . "'" : ""; |
100
|
|
|
$cssStyle = ($this->cssStyle) ? "style='" . $this->cssStyle . "'" : ''; |
101
|
|
|
$cssClass = ($this->cssClass) ? "class='" . $this->cssClass . "'" : ''; |
102
|
|
|
|
103
|
|
|
$pagerClass = ($this->pagerClass) ? "class='" . $this->pagerClass . "'" : ''; |
104
|
|
|
$pagerStyle = ($this->pagerStyle) ? "style='" . $this->pagerStyle . "'" : "style='background-color:#ffffff;'"; |
105
|
|
|
|
106
|
|
|
$this->_itemStyle = ($this->itemStyle) ? "style='" . $this->itemStyle . "'" : ''; |
107
|
|
|
$this->_itemClass = ($this->itemClass) ? "class='" . $this->itemClass . "'" : ''; |
108
|
|
|
$this->_altItemStyle = ($this->altItemStyle) ? "style='" . $this->altItemStyle . "'" : ''; |
109
|
|
|
$this->_altItemClass = ($this->altItemClass) ? "class='" . $this->altItemClass . "'" : ''; |
110
|
|
|
|
111
|
|
|
$this->_alt = 0; |
112
|
|
|
$this->_total = 0; |
113
|
|
|
|
114
|
|
|
$this->_isDataset = $modx->getDatabase()->isResult($this->ds); // if not dataset then treat as array |
115
|
|
|
|
116
|
|
|
if(!$cssStyle && !$cssClass) { |
117
|
|
|
$cssStyle = "style='width:100%;border:1px solid silver;font-family:verdana,arial; font-size:11px;'"; |
118
|
|
|
} |
119
|
|
|
if(!$columnHeaderStyle && !$columnHeaderClass) { |
120
|
|
|
$columnHeaderStyle = "style='color:black;background-color:silver'"; |
121
|
|
|
} |
122
|
|
|
if(!$this->_itemStyle && !$this->_itemClass) { |
123
|
|
|
$this->_itemStyle = "style='color:black;'"; |
124
|
|
|
} |
125
|
|
|
if(!$this->_altItemStyle && !$this->_altItemClass) { |
126
|
|
|
$this->_altItemStyle = "style='color:black;background-color:#eeeeee'"; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
if($this->_isDataset && !$this->columns) { |
130
|
|
|
$cols = $modx->getDatabase()->numFields($this->ds); |
131
|
|
|
for($i = 0; $i < $cols; $i++) $this->columns .= ($i ? "," : "") . $modx->getDatabase()->fieldName($this->ds, $i); |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
// start grid |
135
|
|
|
$tblStart = "<table $cssClass $cssStyle cellpadding='" . (isset($this->cellPadding) ? (int) $this->cellPadding : 1) . "' cellspacing='" . (isset($this->cellSpacing) ? (int) $this->cellSpacing : 1) . "'>"; |
136
|
|
|
$tblEnd = "</table>"; |
137
|
|
|
|
138
|
|
|
// build column header |
139
|
|
|
$this->_colnames = explode((strstr($this->columns, "||") !== false ? "||" : ","), $this->columns); |
140
|
|
|
$this->_colwidths = explode((strstr($this->colWidths, "||") !== false ? "||" : ","), $this->colWidths); |
141
|
|
|
$this->_colaligns = explode((strstr($this->colAligns, "||") !== false ? "||" : ","), $this->colAligns); |
142
|
|
|
$this->_colwraps = explode((strstr($this->colWraps, "||") !== false ? "||" : ","), $this->colWraps); |
143
|
|
|
$this->_colcolors = explode((strstr($this->colColors, "||") !== false ? "||" : ","), $this->colColors); |
144
|
|
|
$this->_coltypes = explode((strstr($this->colTypes, "||") !== false ? "||" : ","), $this->colTypes); |
145
|
|
|
$this->_colcount = count($this->_colnames); |
146
|
|
|
if(!$this->_isDataset) { |
147
|
|
|
$this->ds = explode((strstr($this->ds, "||") !== false ? "||" : ","), $this->ds); |
148
|
|
|
$this->ds = array_chunk($this->ds, $this->_colcount); |
149
|
|
|
} |
150
|
|
|
$tblColHdr = "<thead><tr>"; |
151
|
|
|
for($c = 0; $c < $this->_colcount; $c++) { |
152
|
|
|
$name = $this->_colnames[$c]; |
153
|
|
|
$width = $this->_colwidths[$c]; |
154
|
|
|
$tblColHdr .= "<td $columnHeaderStyle $columnHeaderClass" . ($width ? " width='$width'" : "") . ">$name</td>"; |
155
|
|
|
} |
156
|
|
|
$tblColHdr .= "</tr></thead>\n"; |
157
|
|
|
|
158
|
|
|
// build rows |
159
|
|
|
$rowcount = $this->_isDataset ? $modx->getDatabase()->getRecordCount($this->ds) : count($this->ds); |
160
|
|
|
$this->_fieldnames = explode(",", $this->fields); |
161
|
|
|
if($rowcount == 0) { |
162
|
|
|
$tblRows .= "<tr><td " . $this->_itemStyle . " " . $this->_itemClass . " colspan='" . $this->_colcount . "'>" . $this->noRecordMsg . "</td></tr>\n"; |
|
|
|
|
163
|
|
|
} else { |
164
|
|
|
// render grid items |
165
|
|
|
if($this->pageSize <= 0) { |
166
|
|
|
for($r = 0; $r < $rowcount; $r++) { |
167
|
|
|
$row = $this->_isDataset ? $modx->getDatabase()->getRow($this->ds) : $this->ds[$r]; |
168
|
|
|
$tblRows .= $this->RenderRowFnc($r + 1, $row); |
|
|
|
|
169
|
|
|
} |
170
|
|
|
} else { |
171
|
|
|
if(!$this->pager) { |
172
|
|
|
$this->pager = new DataSetPager($this->id, $this->ds, $this->pageSize, $this->pageNumber); |
173
|
|
|
$this->pager->setRenderRowFnc($this); // pass this object |
174
|
|
|
$this->pager->cssStyle = $pagerStyle; |
|
|
|
|
175
|
|
|
$this->pager->cssClass = $pagerClass; |
|
|
|
|
176
|
|
|
} else { |
177
|
|
|
$this->pager->pageSize = $this->pageSize; |
178
|
|
|
$this->pager->pageNumber = $this->pageNumber; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
$this->pager->render(); |
182
|
|
|
$tblRows = $this->pager->getRenderedRows(); |
183
|
|
|
$tblPager = $this->pager->getRenderedPager(); |
184
|
|
|
} |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
// setup header,pager and footer |
188
|
|
|
$o = $tblStart; |
189
|
|
|
$ptop = (substr($this->pagerLocation, 0, 3) == "top") || (substr($this->pagerLocation, 0, 4) == "both"); |
190
|
|
|
$pbot = (substr($this->pagerLocation, 0, 3) == "bot") || (substr($this->pagerLocation, 0, 4) == "both"); |
191
|
|
|
if($this->header) { |
192
|
|
|
$o .= "<tr><td bgcolor='#ffffff' colspan='" . $this->_colcount . "'>" . $this->header . "</td></tr>"; |
193
|
|
|
} |
194
|
|
View Code Duplication |
if($tblPager && $ptop) { |
195
|
|
|
$o .= "<tr><td align='" . (substr($this->pagerLocation, -4) == "left" ? "left" : "right") . "' $pagerClass $pagerStyle colspan='" . $this->_colcount . "'>" . $tblPager . " </td></tr>"; |
|
|
|
|
196
|
|
|
} |
197
|
|
|
$o .= $tblColHdr . $tblRows; |
198
|
|
View Code Duplication |
if($tblPager && $pbot) { |
199
|
|
|
$o .= "<tr><td align='" . (substr($this->pagerLocation, -4) == "left" ? "left" : "right") . "' $pagerClass $pagerStyle colspan='" . $this->_colcount . "'>" . $tblPager . " </td></tr>"; |
200
|
|
|
} |
201
|
|
|
if($this->footer) { |
202
|
|
|
$o .= "<tr><td bgcolor='#ffffff' colspan='" . $this->_colcount . "'>" . $this->footer . "</td></tr>"; |
203
|
|
|
} |
204
|
|
|
$o .= $tblEnd; |
205
|
|
|
return $o; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
// format column values |
209
|
|
|
|
210
|
|
|
public function RenderRowFnc($n, $row) { |
|
|
|
|
211
|
|
|
if($this->_alt == 0) { |
212
|
|
|
$Style = $this->_itemStyle; |
213
|
|
|
$Class = $this->_itemClass; |
214
|
|
|
$this->_alt = 1; |
215
|
|
|
} else { |
216
|
|
|
$Style = $this->_altItemStyle; |
217
|
|
|
$Class = $this->_altItemClass; |
218
|
|
|
$this->_alt = 0; |
219
|
|
|
} |
220
|
|
|
$o = "<tr>"; |
221
|
|
|
for($c = 0; $c < $this->_colcount; $c++) { |
222
|
|
|
$colStyle = $Style; |
223
|
|
|
$fld = trim($this->_fieldnames[$c]); |
224
|
|
|
$width = isset($this->_colwidths[$c]) ? $this->_colwidths[$c] : null; |
225
|
|
|
$align = isset($this->_colaligns[$c]) ? $this->_colaligns[$c] : null; |
226
|
|
|
$color = isset($this->_colcolors[$c]) ? $this->_colcolors[$c] : null; |
227
|
|
|
$type = isset($this->_coltypes[$c]) ? $this->_coltypes[$c] : null; |
228
|
|
|
$nowrap = isset($this->_colwraps[$c]) ? $this->_colwraps[$c] : null; |
229
|
|
|
$value = $row[($this->_isDataset && $fld ? $fld : $c)]; |
230
|
|
|
if($color && $Style) { |
231
|
|
|
$colStyle = substr($colStyle, 0, -1) . ";background-color:$color;'"; |
232
|
|
|
} |
233
|
|
|
$value = $this->formatColumnValue($row, $value, $type, $align); |
234
|
|
|
$o .= "<td $colStyle $Class" . ($align ? " align='$align'" : "") . ($color ? " bgcolor='$color'" : "") . ($nowrap ? " nowrap='$nowrap'" : "") . ($width ? " width='$width'" : "") . ">$value</td>"; |
235
|
|
|
} |
236
|
|
|
$o .= "</tr>\n"; |
237
|
|
|
return $o; |
238
|
|
|
} |
239
|
|
|
|
240
|
|
|
public function formatColumnValue($row, $value, $type, &$align) { |
|
|
|
|
241
|
|
|
if(strpos($type, ":") !== false) { |
242
|
|
|
list($type, $type_format) = explode(":", $type, 2); |
243
|
|
|
} |
244
|
|
|
switch(strtolower($type)) { |
245
|
|
|
case "integer": |
246
|
|
|
if($align == "") { |
247
|
|
|
$align = "right"; |
248
|
|
|
} |
249
|
|
|
$value = number_format($value); |
250
|
|
|
break; |
251
|
|
|
|
252
|
|
View Code Duplication |
case "float": |
253
|
|
|
if($align == "") { |
254
|
|
|
$align = "right"; |
255
|
|
|
} |
256
|
|
|
if(!$type_format) { |
|
|
|
|
257
|
|
|
$type_format = 2; |
258
|
|
|
} |
259
|
|
|
$value = number_format($value, $type_format); |
260
|
|
|
break; |
261
|
|
|
|
262
|
|
View Code Duplication |
case "currency": |
263
|
|
|
if($align == "") { |
264
|
|
|
$align = "right"; |
265
|
|
|
} |
266
|
|
|
if(!$type_format) { |
267
|
|
|
$type_format = 2; |
268
|
|
|
} |
269
|
|
|
$value = "$" . number_format($value, $type_format); |
270
|
|
|
break; |
271
|
|
|
|
272
|
|
|
case "date": |
273
|
|
|
if($align == "") { |
274
|
|
|
$align = "right"; |
275
|
|
|
} |
276
|
|
|
if(!is_numeric($value)) { |
277
|
|
|
$value = strtotime($value); |
278
|
|
|
} |
279
|
|
|
if(!$type_format) { |
280
|
|
|
$type_format = "%A %d, %B %Y"; |
281
|
|
|
} |
282
|
|
|
$value = strftime($type_format, $value); |
283
|
|
|
break; |
284
|
|
|
|
285
|
|
|
case "boolean": |
286
|
|
|
if($align == '') { |
287
|
|
|
$align = "center"; |
288
|
|
|
} |
289
|
|
|
$value = number_format($value); |
290
|
|
|
if($value) { |
291
|
|
|
$value = '•'; |
292
|
|
|
} else { |
293
|
|
|
$value = ' '; |
294
|
|
|
} |
295
|
|
|
break; |
296
|
|
|
|
297
|
|
|
case "template": |
298
|
|
|
// replace [+value+] first |
299
|
|
|
$value = str_replace("[+value+]", $value, $type_format); |
300
|
|
|
// replace other [+fields+] |
301
|
|
|
if(strpos($value, "[+") !== false) { |
302
|
|
|
foreach($row as $k => $v) { |
303
|
|
|
$value = str_replace("[+$k+]", $v, $value); |
304
|
|
|
} |
305
|
|
|
} |
306
|
|
|
break; |
307
|
|
|
|
308
|
|
|
} |
309
|
|
|
return $value; |
310
|
|
|
} |
311
|
|
|
} |
312
|
|
|
|
This error can happen if you refactor code and forget to move the variable initialization.
Let’s take a look at a simple example:
The above code is perfectly fine. Now imagine that we re-order the statements:
In that case,
$x
would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.