1 |
jonen |
1.1 |
<?php |
2 |
|
|
/** |
3 |
jonen |
1.2 |
* $Id: ArrayDataListSource.inc,v 1.9 2004/02/09 23:02:36 hemna Exp $ |
4 |
jonen |
1.1 |
* |
5 |
|
|
* This file contains the DataListSource class |
6 |
|
|
* that gets the data from an array |
7 |
|
|
* |
8 |
|
|
* @author Suren Markossian <suren_markossian@yahoo.com> |
9 |
|
|
* @package phpHtmlLib |
10 |
|
|
*/ |
11 |
|
|
|
12 |
jonen |
1.2 |
/** |
13 |
|
|
* We require the DataListSource |
14 |
|
|
*/ |
15 |
|
|
require_once($phphtmllib."/widgets/data_list/DataListSource.inc"); |
16 |
jonen |
1.1 |
|
17 |
|
|
|
18 |
|
|
/** |
19 |
|
|
* |
20 |
|
|
* This DataListSource child class gets the data from an |
21 |
|
|
* external array |
22 |
|
|
* |
23 |
|
|
* The array is a 2D array and each sub-array is a set of elements for |
24 |
|
|
* each row in the list |
25 |
|
|
* |
26 |
|
|
* @author Suren Markossian <suren_markossian@yahoo.com> |
27 |
|
|
* @package phpHtmlLib |
28 |
|
|
*/ |
29 |
|
|
class ArrayDataListSource extends DataListSource { |
30 |
|
|
|
31 |
|
|
|
32 |
|
|
/** |
33 |
|
|
* The constructor. |
34 |
|
|
* |
35 |
|
|
* @param array data - an array of array elements for each row |
36 |
|
|
*/ |
37 |
|
|
function ArrayDataListSource(&$data) { |
38 |
|
|
$this->_data = $data; |
39 |
|
|
} |
40 |
|
|
|
41 |
|
|
/** |
42 |
|
|
* This function does the query |
43 |
|
|
* and search/sort |
44 |
|
|
*/ |
45 |
|
|
function do_query() { |
46 |
|
|
|
47 |
|
|
// do data pre-processing if neccessary |
48 |
jonen |
1.2 |
if ($this->get_searchby_value()) { |
49 |
|
|
$this->_prequery_filter(); |
50 |
|
|
} |
51 |
jonen |
1.1 |
|
52 |
|
|
$count = count($this->_data); |
53 |
|
|
|
54 |
|
|
if ($count > 0) { |
55 |
|
|
$this->set_total_rows($count); |
56 |
|
|
$this->sort(); |
57 |
|
|
return true; |
58 |
|
|
} else { |
59 |
|
|
return false; |
60 |
|
|
} |
61 |
|
|
} |
62 |
|
|
|
63 |
|
|
/** |
64 |
|
|
* This is a method that should be defined by the |
65 |
|
|
* child class to do any pre-query type of things. |
66 |
|
|
* Such as building a sql query string for a DB, |
67 |
|
|
* or checking to make sure the file on disk exists |
68 |
|
|
* if the source is a file on disk. |
69 |
|
|
* |
70 |
|
|
*/ |
71 |
|
|
function do_prequery() { |
72 |
|
|
return NULL; |
73 |
|
|
} |
74 |
|
|
|
75 |
|
|
/** |
76 |
|
|
* This function returns the next row of |
77 |
|
|
* valid data. |
78 |
|
|
* |
79 |
|
|
*/ |
80 |
|
|
function get_next_data_row() { |
81 |
|
|
$index = $this->get_data_index(); |
82 |
|
|
$limit = $this->get_limit(); |
83 |
|
|
$offset = $this->get_offset(); |
84 |
|
|
|
85 |
|
|
if ($limit == -1) { |
86 |
|
|
// don't limit the data |
87 |
|
|
if ($index > $this->get_total_rows()) { |
88 |
|
|
return NULL; |
89 |
|
|
} else { |
90 |
|
|
return $this->_data[$index]; |
91 |
|
|
} |
92 |
|
|
} else { |
93 |
jonen |
1.2 |
// Check if we are still in the display range |
94 |
|
|
if (!is_null($index) && $index < $limit && isset($this->_data[$offset + $index])) { |
95 |
|
|
return $this->_data[$offset + $index]; |
96 |
jonen |
1.1 |
} else { |
97 |
|
|
return NULL; |
98 |
|
|
} |
99 |
|
|
} |
100 |
|
|
} |
101 |
|
|
|
102 |
|
|
/** |
103 |
|
|
* This is used to perform pre-query filtering |
104 |
|
|
* Gives us a chance to run the next row through a filter |
105 |
|
|
* before any processing has been done |
106 |
|
|
* |
107 |
|
|
* @param array - the row to run through the filter |
108 |
|
|
* |
109 |
|
|
* @return boolean - TRUE = allow the row. FALSE = drop it. |
110 |
|
|
*/ |
111 |
|
|
function prequery_row_filter(&$row_data) { |
112 |
jonen |
1.2 |
return $this->_find_data($row_data); |
113 |
jonen |
1.1 |
} |
114 |
|
|
|
115 |
|
|
/** |
116 |
|
|
* This is called to allow rebuilding the data array |
117 |
|
|
* to remove elements that have to be filtered |
118 |
|
|
* |
119 |
|
|
* This is done on pre-processing phase and used for |
120 |
|
|
* simple and advanced searches |
121 |
|
|
* |
122 |
|
|
*/ |
123 |
|
|
function _prequery_filter() { |
124 |
|
|
|
125 |
|
|
while (list($key,$row_data) = each($this->_data)) { |
126 |
|
|
if (!$this->prequery_row_filter($row_data)) { |
127 |
|
|
unset($this->_data[$key]); |
128 |
|
|
} |
129 |
|
|
} |
130 |
|
|
|
131 |
|
|
// re-index the array |
132 |
|
|
$this->_data = array_values($this->_data); |
133 |
|
|
} |
134 |
|
|
|
135 |
|
|
/** |
136 |
|
|
* This function returns the |
137 |
|
|
* data_index value and increments it |
138 |
|
|
* |
139 |
|
|
* @return int |
140 |
|
|
*/ |
141 |
|
|
function get_data_index() { |
142 |
|
|
$this->_data_index = key($this->_data); |
143 |
|
|
next($this->_data); |
144 |
|
|
return $this->_data_index; |
145 |
|
|
} |
146 |
|
|
|
147 |
jonen |
1.2 |
/** |
148 |
|
|
* This method sorts our data array by the requested |
149 |
|
|
* column order by. This could be expensive for HUGE |
150 |
|
|
* arrays. |
151 |
|
|
* |
152 |
|
|
* @return none |
153 |
|
|
*/ |
154 |
jonen |
1.1 |
function sort() { |
155 |
|
|
$sortby = $this->get_orderby(); |
156 |
jonen |
1.2 |
|
157 |
|
|
$column_name = NULL; |
158 |
|
|
// get the column name |
159 |
|
|
foreach($this->_columns as $name => $data) { |
160 |
|
|
if ($sortby == $data["data_name"]) { |
161 |
|
|
$column_name = $name; |
162 |
|
|
break; |
163 |
|
|
} |
164 |
|
|
} |
165 |
|
|
|
166 |
jonen |
1.1 |
// we need to sort the data by the |
167 |
|
|
// column in the table |
168 |
jonen |
1.2 |
if ($column_name != NULL && $this->_columns[$column_name]["sortable"] != NOT_SORTABLE) { |
169 |
jonen |
1.1 |
// looks like we can sort this column |
170 |
jonen |
1.2 |
if ($this->_columns[$column_name]["sortable"] == SORTABLE_NUMERIC) { |
171 |
|
|
usort($this->_data, array($this, "cmp_numeric")); |
172 |
|
|
} else { |
173 |
|
|
usort($this->_data, array($this, "cmp")); |
174 |
|
|
} |
175 |
jonen |
1.1 |
} |
176 |
|
|
} |
177 |
|
|
|
178 |
jonen |
1.2 |
/** |
179 |
|
|
* This method is used for comparing 2 string values |
180 |
|
|
* |
181 |
|
|
* @param string first entry to compare |
182 |
|
|
* @param string second entry to compare |
183 |
|
|
* @return natural compare results |
184 |
|
|
*/ |
185 |
jonen |
1.1 |
function cmp($data1, $data2) { |
186 |
|
|
$sortby = $this->get_orderby(); |
187 |
jonen |
1.2 |
|
188 |
jonen |
1.1 |
$ret = strnatcmp( $data1[$sortby], $data2[$sortby]); |
189 |
jonen |
1.2 |
|
190 |
jonen |
1.1 |
if ($this->get_reverseorder() == "true") { |
191 |
|
|
$ret *= -1; |
192 |
|
|
} |
193 |
|
|
return $ret; |
194 |
|
|
} |
195 |
jonen |
1.2 |
|
196 |
|
|
/** |
197 |
|
|
* This method is used for comparing 2 numerical |
198 |
|
|
* values |
199 |
|
|
* |
200 |
|
|
* @param string first entry to compare |
201 |
|
|
* @param string second entry to compare |
202 |
|
|
* @return compare results |
203 |
|
|
*/ |
204 |
|
|
function cmp_numeric($data1, $data2) { |
205 |
|
|
|
206 |
|
|
$sortby = $this->get_orderby(); |
207 |
|
|
if ($data1[$sortby]==$data2[$sortby]) $ret = 0; |
208 |
|
|
else $ret = ($data1[$sortby] < $data2[$sortby]) ? -1 : 1; |
209 |
|
|
|
210 |
|
|
if ($this->get_reverseorder() == "true") { |
211 |
|
|
$ret *= -1; |
212 |
|
|
} |
213 |
|
|
return $ret; |
214 |
|
|
} |
215 |
|
|
|
216 |
|
|
/** |
217 |
|
|
* This is used to do the default search |
218 |
|
|
* capability in the DataListSource parent class. |
219 |
|
|
* This is used so we can filter our results to |
220 |
|
|
* what the user searched for. |
221 |
|
|
* |
222 |
|
|
* @param array the row data entry. |
223 |
|
|
* We will look for a specific column's |
224 |
|
|
* value here to test against. |
225 |
|
|
* @return boolean found it or not |
226 |
|
|
*/ |
227 |
|
|
function _find_data( $row_data ) { |
228 |
|
|
//look for the 'needle' in the 'haystack' |
229 |
|
|
|
230 |
|
|
$needle = $this->get_searchby_value(); |
231 |
|
|
$haystack = $row_data[$this->get_searchby()]; |
232 |
|
|
|
233 |
|
|
switch ($this->get_simplesearch_modifier()) { |
234 |
|
|
case "BEGINS": |
235 |
|
|
if (strncasecmp($needle, $haystack, strlen($needle)) == 0) { |
236 |
|
|
return TRUE; |
237 |
|
|
} else { |
238 |
|
|
return FALSE; |
239 |
|
|
} |
240 |
|
|
break; |
241 |
|
|
|
242 |
|
|
case "CONTAINS": |
243 |
|
|
if (stristr($haystack, $needle)) { |
244 |
|
|
return TRUE; |
245 |
|
|
} else { |
246 |
|
|
return FALSE; |
247 |
|
|
} |
248 |
|
|
break; |
249 |
|
|
case "EXACT": |
250 |
|
|
if (strcasecmp($needle, $haystack) == 0) { |
251 |
|
|
return TRUE; |
252 |
|
|
} else { |
253 |
|
|
return FALSE; |
254 |
|
|
} |
255 |
|
|
break; |
256 |
|
|
case "ENDS": |
257 |
|
|
$needle_len = strlen( $needle ); |
258 |
|
|
$haystack_len = strlen( $haystack ); |
259 |
|
|
if ($needle_len > $haystack_len) { |
260 |
|
|
return FALSE; |
261 |
|
|
} else if ($needle_len == $haystack_len) { |
262 |
|
|
$tmp = $haystack; |
263 |
|
|
} else { |
264 |
|
|
$tmp = substr($haystack, $haystack_len - $needle_len); |
265 |
|
|
} |
266 |
|
|
if (strncasecmp($needle, $tmp, $needle_len) == 0) { |
267 |
|
|
return TRUE; |
268 |
|
|
} else { |
269 |
|
|
return FALSE; |
270 |
|
|
} |
271 |
|
|
break; |
272 |
|
|
} |
273 |
|
|
} |
274 |
jonen |
1.1 |
|
275 |
|
|
} |
276 |
|
|
?> |