1 |
rodolico |
1 |
<?php
|
|
|
2 |
|
|
|
3 |
/*
|
|
|
4 |
This class simply extends DBQuery to allow output to be converted to HTML
|
|
|
5 |
*/
|
|
|
6 |
|
34 |
rodolico |
7 |
require_once( 'DBQuery.class.php' );
|
1 |
rodolico |
8 |
|
|
|
9 |
class DBQueryHTML extends DBQuery {
|
47 |
rodolico |
10 |
|
|
|
11 |
protected $htmlQuoteChar = '"';
|
1 |
rodolico |
12 |
|
|
|
13 |
/*
|
|
|
14 |
Function takes an SQL statement and converts it to an HTML table.
|
|
|
15 |
Return Value: HTML table representation of the query
|
|
|
16 |
Parameters:
|
|
|
17 |
$sql A valid SQL query to run
|
|
|
18 |
$format An optional array of format strings (suitable for printf) for each column (empty strings ignored)
|
|
|
19 |
$makeTableDef If True, the resulting HTML has the <table></table> tags; otherwise starts with header
|
|
|
20 |
$append Arbitrary string that is appended as a single column to each row
|
|
|
21 |
|
|
|
22 |
NOTE ON $append
|
|
|
23 |
$append may optionally contain variables of the form %colname%, which will be replaced
|
|
|
24 |
with values from the current row. $colname is taken from the META data from the query, thus
|
|
|
25 |
the query select foo from bar would have a meta of header of foo for column 0.
|
|
|
26 |
$append is searched for strings of form %foo% in that case, and the current value of column
|
|
|
27 |
foo replaces the tag %foo%.
|
|
|
28 |
%foo% is ignored if foo is not a valid column name in a query.
|
|
|
29 |
thus, a query such as select zip,city,state from zip_codes and a string of Hello %city% I'm glad
|
|
|
30 |
you are in %State% will not replace the second as State is not a column of this query (it is case
|
|
|
31 |
sensitive). Also, beware of items like select zip,concat(state,', ', city) from zip_codes. It is
|
|
|
32 |
much better to rewrite that as select zip,concat(state,', ', city) mytown from zip_codes.
|
|
|
33 |
|
|
|
34 |
If you don't know what all that means, get a book on SQL
|
|
|
35 |
*/
|
47 |
rodolico |
36 |
function queryToTable ( $format = array(), $makeTableDef = true, $append='', $headers = '' ) {
|
|
|
37 |
// print "\n\n<pre>$this->query</pre>\n\n";
|
|
|
38 |
$tdTextDefinition = '<td valign=' . $this->htmlQuoteChar . 'top' . $this->htmlQuoteChar . '>';
|
|
|
39 |
$tdNumberDefinition = '<td valign=' . $this->htmlQuoteChar .'top' . $this->htmlQuoteChar . 'align=' . $this->htmlQuoteChar . 'right' . $this->htmlQuoteChar . '>';
|
1 |
rodolico |
40 |
$html = '';
|
|
|
41 |
$rows = array();
|
47 |
rodolico |
42 |
$save = $this->returnType;
|
|
|
43 |
$this->returnType = MYSQLI_ASSOC; // temporarily turn off associative arrays
|
|
|
44 |
$columnNames = array();
|
1 |
rodolico |
45 |
$this->run();
|
|
|
46 |
if ( $this->rowsAffected ) { // we returned at least one row
|
47 |
rodolico |
47 |
|
|
|
48 |
//print "<pre>Found " . $this->rowsAffected . "\n</pre>";
|
|
|
49 |
// get the column names; we'll use them later
|
1 |
rodolico |
50 |
foreach ( $this->columnMetaData as $field ) {
|
47 |
rodolico |
51 |
$columnNames[] = $field['name'];
|
1 |
rodolico |
52 |
}
|
47 |
rodolico |
53 |
|
|
|
54 |
// Build the searchFor array for $append
|
|
|
55 |
$searchFor = $columnNames;
|
|
|
56 |
array_walk( $searchFor, function ( &$value, $key ) { $value = '%' . $value . '%'; } );
|
|
|
57 |
// print '<pre>SearchFor ' . print_r( $searchFor, true ) . '</pre>'; die;
|
|
|
58 |
//print "<pre>" . print_r($this->columnMetaData,true) . '</pre>'; die;
|
1 |
rodolico |
59 |
/* special condition where only one row is returned. In that case, $this->returnData is not an array
|
|
|
60 |
of associations, but a simple association. In this case, we need to convert it
|
|
|
61 |
*/
|
|
|
62 |
if (count($this->returnData[0]) == 1) { // convert from association to single row array of associations
|
|
|
63 |
$temp = array();
|
|
|
64 |
foreach ($this->returnData as $column => $value) {
|
|
|
65 |
$temp[0][$column] = $value;
|
|
|
66 |
} // foreach
|
|
|
67 |
$this->returnData = $temp;
|
|
|
68 |
}
|
|
|
69 |
if (count($format) > 0 ) { // we have some formats, so let's do it the hard, slow way
|
|
|
70 |
for ( $row = 0; $row < count($this->returnData); $row++) {
|
|
|
71 |
$rows[$row] = '';
|
|
|
72 |
for ( $column = 0; $column < count($this->returnData[$row]); $column++ ) {
|
|
|
73 |
$rows[$row] .= strlen($format[$column]) && isset($this->returnData[$row][$column])> 0 ?
|
|
|
74 |
( $tdNumberDefinition . sprintf($format[$column],$this->returnData[$row][$column]) . '</td>')
|
|
|
75 |
: ($tdTextDefinition . $this->returnData[$row][$column] . '</td>');
|
|
|
76 |
} // for $column
|
|
|
77 |
/*
|
|
|
78 |
let's append some stuff to the row if it exists.
|
|
|
79 |
We will take the array of SearchFor containing the column names
|
|
|
80 |
and the array of values from this row, then look for matches and replace them
|
|
|
81 |
with the correct values. Note, the column names in $append should have percent
|
|
|
82 |
signs appended and prepended, thus a column name of joe would be %joe% in %append
|
|
|
83 |
*/
|
|
|
84 |
if (strlen($append) > 0) { // let's append some stuff to the row
|
|
|
85 |
$rows[$row] .= $tdTextDefinition . str_replace ( $searchFor, $this->returnData[$row], $append ) . '</td>';
|
|
|
86 |
}
|
|
|
87 |
} // for $row
|
|
|
88 |
} else { // no formatting, so we just slam the stuff together
|
|
|
89 |
for ( $row = 0; $row < count($this->returnData); $row++) {
|
47 |
rodolico |
90 |
$temp = array();
|
|
|
91 |
foreach ( $columnNames as $col ) {
|
|
|
92 |
$temp[] = $this->returnData[$row][$col];
|
|
|
93 |
}
|
|
|
94 |
$currentValue = $tdTextDefinition . implode( '</td>' . $tdTextDefinition, $temp) . '</td>';
|
1 |
rodolico |
95 |
if (strlen($append) > 0) { // see explaination in if part of this structure
|
|
|
96 |
$currentValue .= $tdTextDefinition . str_replace ( $searchFor, $this->returnData[$row], $append ) . '</td>';
|
|
|
97 |
}
|
|
|
98 |
$rows[] = $currentValue;
|
|
|
99 |
}
|
|
|
100 |
}
|
|
|
101 |
// ok, let's get the field headers from the table
|
|
|
102 |
$html .= '<tr>';
|
|
|
103 |
if ( $headers ) { // user has passed in some header fields for us to use
|
|
|
104 |
$html .= '<th>' . implode( '</th><th>', $headers ) . '</th>';
|
|
|
105 |
} else { // no headers, so we just get them from the returned column names
|
|
|
106 |
foreach ( $this->columnMetaData as $field ) {
|
47 |
rodolico |
107 |
$html .= '<th>' . ((array)$field)['name'] . '</th>';
|
1 |
rodolico |
108 |
}
|
|
|
109 |
} // if headers .. else
|
|
|
110 |
$html .= '</tr>';
|
|
|
111 |
// we now have all the info, so let's make it into a table
|
|
|
112 |
$html .= '<tr>' . implode('</tr><tr>', $rows ) . '</tr>';
|
|
|
113 |
} else {
|
|
|
114 |
$html = '<tr><td>No rows returned by the query</td></tr>';
|
|
|
115 |
}
|
|
|
116 |
if ( $makeTableDef ) { // they want the <table> def, so let's give it to them
|
47 |
rodolico |
117 |
$html = '<table border=' . $this->htmlQuoteChar . '1' . $this->htmlQuoteChar . '>' . $html . '</table>';
|
1 |
rodolico |
118 |
} // if ( $makeTableDef
|
|
|
119 |
|
47 |
rodolico |
120 |
$this->returnType = $save;
|
1 |
rodolico |
121 |
//return '<pre>' . print_r ($this,true) . '</pre>';
|
|
|
122 |
return $html;
|
|
|
123 |
}
|
|
|
124 |
|
|
|
125 |
/*
|
|
|
126 |
function executes a query, then returns an array containing only the values of the first
|
|
|
127 |
field in the return as the keys to an associative array. NOTE: any duplicates will be
|
|
|
128 |
discarded. This is useful when you simply want to know if a value exists, ie if you
|
|
|
129 |
are building an html select from a query, and a separate query needs to hold the
|
|
|
130 |
values that are currently selected
|
|
|
131 |
*/
|
|
|
132 |
|
|
|
133 |
function valuesToKeys () {
|
|
|
134 |
$returnValue = array();
|
|
|
135 |
$save = $this->useAssociativeArray;
|
|
|
136 |
$useAssociativeArray = false; // temporarily turn off associative arrays
|
|
|
137 |
$this->run();
|
|
|
138 |
if ( $this->rowsAffected ) { // we returned at least one row
|
|
|
139 |
foreach ( $info as $key => $value ) { // only thing I know to do is iterate
|
|
|
140 |
$returnValue[$this->returnData[0]] = true;
|
|
|
141 |
}
|
|
|
142 |
} // if
|
|
|
143 |
$useAssociativeArray = $save;
|
|
|
144 |
return $returnValue;
|
|
|
145 |
}
|
|
|
146 |
|
|
|
147 |
/* this function will take the result of an SQL query that returns at least two columns.
|
|
|
148 |
The first column becomes the keys in an associative array, and the second column
|
|
|
149 |
becomes the value.
|
|
|
150 |
|
|
|
151 |
Note, because it is an associative array, duplicates of the first column will only contain
|
|
|
152 |
the last value.
|
|
|
153 |
*/
|
|
|
154 |
|
47 |
rodolico |
155 |
function ColumnColumnArray ( $query = null ) {
|
|
|
156 |
if ( isset( $query) ) {
|
|
|
157 |
$this->parameters['query'] = $query;
|
|
|
158 |
}
|
1 |
rodolico |
159 |
$returnValue = array();
|
|
|
160 |
$save = $this->useAssociativeArray;
|
|
|
161 |
$useAssociativeArray = false; // temporarily turn off associative arrays
|
|
|
162 |
$this->run();
|
|
|
163 |
if ( $this->rowsAffected ) { // we returned at least one row
|
47 |
rodolico |
164 |
//print '<pre>' . print_r($this->parameters, true) . '</pre>'; die;
|
|
|
165 |
foreach ( $this->returnData as $key => $value ) { // only thing I know to do is iterate
|
|
|
166 |
$returnValue[$value[0]] = $value[1];
|
1 |
rodolico |
167 |
}
|
|
|
168 |
} // if
|
|
|
169 |
$useAssociativeArray = $save;
|
|
|
170 |
return $returnValue;
|
|
|
171 |
}
|
|
|
172 |
|
37 |
rodolico |
173 |
|
|
|
174 |
/**
|
|
|
175 |
* Builds an HTML select out of a query, or data
|
|
|
176 |
*
|
|
|
177 |
* $parameters may contain the following keys
|
|
|
178 |
*
|
|
|
179 |
* Must have one of the following. If both are present, 'query' is
|
|
|
180 |
* ignored
|
|
|
181 |
* 'query' - An SQL query to run. Should return 2 columns; first is value, second id display
|
|
|
182 |
* 'data' - An array of key/value pair. Key is used for value, value is display
|
|
|
183 |
*
|
|
|
184 |
* 'name' - HTML name for the select. If this is not set, only the options will be returned
|
|
|
185 |
* 'class' - used for class='whatever' in select
|
|
|
186 |
* 'selected' - key in 'data' or result of 'query' which will be selected
|
|
|
187 |
* 'label' - used as <label>. If this is not set, no <label> is generated
|
|
|
188 |
* 'nullok' - adds a entry at top with value of -1 and display of three dashes (---)
|
|
|
189 |
*
|
|
|
190 |
*
|
|
|
191 |
* @parameters string $parameters an array of data to decide what/how to process
|
|
|
192 |
* @returns string an HTML select entity
|
|
|
193 |
*/
|
|
|
194 |
function htmlSelect ( $parameters ) {
|
1 |
rodolico |
195 |
|
37 |
rodolico |
196 |
//print "<pre>" . print_r( $parameters, true ) . "</pre>"; die;
|
|
|
197 |
|
|
|
198 |
if ( empty( $parameters['data'] ) ) {
|
45 |
rodolico |
199 |
// print "<pre>No data, running query\n" . $parameters['query'] . "</pre>"; die;
|
|
|
200 |
if ( empty( $parameters['query'] ) )
|
37 |
rodolico |
201 |
return '';
|
|
|
202 |
$save = $this->useAssociativeArray;
|
|
|
203 |
$useAssociativeArray = false; // temporarily turn off associative arrays
|
45 |
rodolico |
204 |
//print "<pre>Running Query\n</pre>";
|
|
|
205 |
$data = $this->doSQL( $parameters['query'] );
|
|
|
206 |
//print "<pre>" . print_r( $data, true ) . "</pre>"; die;
|
|
|
207 |
if ( $data['rowsAffected'] ) { // we returned at least one row
|
|
|
208 |
$data = $data['returnData'];
|
|
|
209 |
foreach ($data as $rowNumber => $value ) {
|
37 |
rodolico |
210 |
$parameters['data'][$value[0]] = $value[1];
|
1 |
rodolico |
211 |
}
|
|
|
212 |
}
|
|
|
213 |
}
|
45 |
rodolico |
214 |
//return "<pre>Data is \n" . print_r( $parameters['data'], true ) . "</pre>";
|
37 |
rodolico |
215 |
$selectedKey = isset( $parameters['selected'] ) ? $parameters['selected'] : '';
|
|
|
216 |
$options = array();
|
|
|
217 |
if ( isset( $parameters['nullok'] ) ) {
|
|
|
218 |
$options[] = '<option value="-1">---</option>';
|
|
|
219 |
}
|
|
|
220 |
foreach ( $parameters['data'] as $key => $value ) {
|
|
|
221 |
$options[] = sprintf(
|
|
|
222 |
'<option value="%s"%s>%s</option>',
|
|
|
223 |
$key,
|
|
|
224 |
$key == $selectedKey ? ' selected' : '',
|
|
|
225 |
$value
|
|
|
226 |
);
|
|
|
227 |
} // foreach
|
|
|
228 |
$return = implode( "\n", $options );
|
|
|
229 |
if ( isset( $parameters['name'] ) ) {
|
|
|
230 |
$return = "<select name='$parameters[name]'>\n$return\n</select>";
|
|
|
231 |
if ( isset( $parameters['label'] ) ) {
|
|
|
232 |
$return = "<label>$parameters[label]\n$return\n</label>\n";
|
1 |
rodolico |
233 |
}
|
|
|
234 |
}
|
37 |
rodolico |
235 |
return $return;
|
1 |
rodolico |
236 |
}
|
|
|
237 |
|
37 |
rodolico |
238 |
/**
|
|
|
239 |
* Create an HTML checkbox block from a query, or array of data passed in
|
|
|
240 |
*
|
|
|
241 |
* if $parameters['data'] is set, no further query is used. $parameters['data']
|
|
|
242 |
* should contain an array of data. Each row in that array should be another
|
|
|
243 |
* array with keys
|
|
|
244 |
* 'id' -- 'id' and 'name' of the checkbox
|
|
|
245 |
* 'name' -- display name of the checkbox
|
|
|
246 |
* 'checked' -- boolean (or 0/1) saying whether this has a check
|
|
|
247 |
*
|
|
|
248 |
* of $parameters['data'] is not set and $parameters['query'] is set
|
|
|
249 |
* the query will be run. It MUST contain the column names listed above.
|
|
|
250 |
*
|
39 |
rodolico |
251 |
* If $parameters['template'] is set, that template will be used. If it
|
|
|
252 |
* is not set, a template will be defaulted to.
|
|
|
253 |
*
|
|
|
254 |
* If $paramters['arrayName'] is set, the form of the template will be
|
|
|
255 |
* name='arrayname[name]'
|
|
|
256 |
*
|
37 |
rodolico |
257 |
* Processing will then continue
|
1 |
rodolico |
258 |
*/
|
|
|
259 |
|
37 |
rodolico |
260 |
function htmlCheckBoxes ( $parameters ) {
|
|
|
261 |
if ( empty( $parameters['template'] ) ) { // they did not send us a template
|
39 |
rodolico |
262 |
if ( empty( $parameters['arrayName'] ) ) {
|
41 |
rodolico |
263 |
$parameters['template'] = "<li><input type='checkbox' id='~~id~~' name='~~id~~' ~~checked~~>\n<label for='~~id~~'>~~name~~</label></li>\n";
|
39 |
rodolico |
264 |
} else {
|
41 |
rodolico |
265 |
$parameters['template'] = "<li><input type='checkbox' id='$parameters[arrayName]~~id~~' name='$parameters[arrayName][~~id~~]' ~~checked~~>\n<label for='~~id~~'>~~name~~</label></li>\n";
|
39 |
rodolico |
266 |
}
|
1 |
rodolico |
267 |
}
|
37 |
rodolico |
268 |
//print "<pre>" . print_r($parameters, true) . "</pre>"; die;
|
|
|
269 |
if ( empty( $parameters['data'] ) ) {
|
|
|
270 |
if ( empty( $parameters['query'] ) )
|
|
|
271 |
return '';
|
|
|
272 |
$save = $this->useAssociativeArray;
|
|
|
273 |
$useAssociativeArray = false; // temporarily turn off associative arrays
|
|
|
274 |
$this->doSQL( $parameters['query'] );
|
|
|
275 |
if ( $this->rowsAffected ) { // we returned at least one row
|
|
|
276 |
foreach ($this->returnData as $rowNumber => $value ) {
|
|
|
277 |
$parameters['data'][] = $value;
|
|
|
278 |
}
|
|
|
279 |
}
|
1 |
rodolico |
280 |
}
|
37 |
rodolico |
281 |
//print "<pre>" . print_r($parameters, true) . "</pre>"; die;
|
|
|
282 |
foreach ( $parameters['data'] as $key => $value ) {
|
|
|
283 |
$replacement = array(
|
|
|
284 |
'id' => $value['id'],
|
|
|
285 |
'name' => $value['name'],
|
|
|
286 |
'checked' => $value['checked'] ? 'checked' : ''
|
|
|
287 |
);
|
|
|
288 |
$html[] = $this->templateReplace($parameters['template'],$replacement);
|
|
|
289 |
}
|
41 |
rodolico |
290 |
return '<ul>' . implode( '', $html ) . '</ul>';
|
1 |
rodolico |
291 |
}
|
|
|
292 |
|
37 |
rodolico |
293 |
/**
|
|
|
294 |
* Replaces instances of replacement strings in string
|
|
|
295 |
*
|
|
|
296 |
* Designed to allow the caller to build a string with things to be
|
|
|
297 |
* replaced, for example
|
|
|
298 |
* <input type='text' name='~~name~~'>
|
|
|
299 |
* All instances of ~~name~~ will be replaced
|
|
|
300 |
*/
|
|
|
301 |
public function templateReplace ( $template, $replacmentStrings, $delimiter = '~~' ) {
|
43 |
rodolico |
302 |
//print "<pre>Replacement Strings\n" . print_r($replacmentStrings, true) . "</pre>";
|
|
|
303 |
//print "<pre>Template\n" . print_r($template, true) . "</pre>"; die;
|
37 |
rodolico |
304 |
foreach ( $replacmentStrings as $key => $replace ) {
|
43 |
rodolico |
305 |
if ( is_array( $replace ) )
|
|
|
306 |
continue;
|
37 |
rodolico |
307 |
$search = '/' . $delimiter . $key . $delimiter . '/';
|
|
|
308 |
//print "<pre>" . print_r($search, true) . "</pre>"; die;
|
|
|
309 |
$template = preg_replace( $search, $replace, $template );
|
|
|
310 |
}
|
|
|
311 |
return $template;
|
|
|
312 |
}
|
|
|
313 |
|
1 |
rodolico |
314 |
/*
|
|
|
315 |
function CSV ( $sql ) {
|
|
|
316 |
$rows = array();
|
|
|
317 |
$CSV = '';
|
|
|
318 |
$info = array();
|
|
|
319 |
if ( $result = queryDatabaseExtended($sql,0) ) {
|
|
|
320 |
$meta = $result['meta'];
|
|
|
321 |
//objectDebugScreen($result);
|
|
|
322 |
$info = $result['data'];
|
|
|
323 |
unset ($result);
|
|
|
324 |
$headers = array();
|
|
|
325 |
foreach ( $meta as $field ) {
|
|
|
326 |
$headers[] = $field['name'];
|
|
|
327 |
} // foreach
|
|
|
328 |
$rows[] = implode("\t", $headers);
|
|
|
329 |
// special condition where only one row is returned. In that case, $info is not an array
|
|
|
330 |
// of associations, but a simple association. In this case, we need to convert it
|
|
|
331 |
|
|
|
332 |
if (count($info[0]) == 1) { // convert from association to single row array of associations
|
|
|
333 |
$temp = array();
|
|
|
334 |
foreach ($info as $column => $value) {
|
|
|
335 |
$temp[0][$column] = $value;
|
|
|
336 |
} // foreach
|
|
|
337 |
$info = $temp;
|
|
|
338 |
}
|
|
|
339 |
for ( $row = 0; $row < count($info); $row++) {
|
|
|
340 |
$rows[] = implode("\t", $info[$row]);
|
|
|
341 |
}
|
|
|
342 |
// we now have all the info, so let's make it into a table
|
|
|
343 |
$CSV .= implode("\n", $rows );
|
|
|
344 |
} // if ( $info = queryDatabase($sql,0) )
|
|
|
345 |
// print '<pre>'; print_r ($info); print '</pre>';
|
|
|
346 |
return $CSV;
|
|
|
347 |
}
|
|
|
348 |
|
|
|
349 |
*/
|
|
|
350 |
|
|
|
351 |
} // class DBQueryHTML
|
|
|
352 |
|
|
|
353 |
?>
|