Subversion Repositories phpLibraryV2

Rev

Rev 43 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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