Subversion Repositories phpLibraryV2

Rev

Rev 39 | 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'] ) ) {
181
            if ( empty( $paramters['query'] ) )
182
               return '';
183
            $save = $this->useAssociativeArray;
184
            $useAssociativeArray = false; // temporarily turn off associative arrays
185
            $this->query( $parameters['query'] );
186
            if ( $this->rowsAffected ) { // we returned at least one row
187
               foreach ($this->returnData as $rowNumber => $value ) {
188
                  $parameters['data'][$value[0]] = $value[1];
1 rodolico 189
               }
190
            }
191
         }
37 rodolico 192
         $selectedKey = isset( $parameters['selected'] ) ? $parameters['selected'] : '';
193
         $options = array();
194
         if ( isset( $parameters['nullok'] ) ) {
195
            $options[] = '<option value="-1">---</option>';
196
         }
197
         foreach ( $parameters['data'] as $key => $value ) {
198
            $options[] = sprintf( 
199
               '<option value="%s"%s>%s</option>',
200
               $key,
201
               $key == $selectedKey ? ' selected' : '',
202
               $value
203
               );
204
         } // foreach
205
         $return = implode( "\n", $options );
206
         if ( isset( $parameters['name'] ) ) {
207
            $return = "<select name='$parameters[name]'>\n$return\n</select>";
208
            if ( isset( $parameters['label'] ) ) {
209
               $return = "<label>$parameters[label]\n$return\n</label>\n";
1 rodolico 210
            }
211
         }
37 rodolico 212
         return $return;
1 rodolico 213
      }
214
 
37 rodolico 215
      /**
216
       * Create an HTML checkbox block from a query, or array of data passed in
217
       * 
218
       * if $parameters['data'] is set, no further query is used. $parameters['data']
219
       * should contain an array of data. Each row in that array should be another 
220
       * array with keys 
221
       *    'id' -- 'id' and 'name' of the checkbox
222
       *    'name' -- display name of the checkbox
223
       *    'checked' -- boolean (or 0/1) saying whether this has a check
224
       * 
225
       * of $parameters['data'] is not set and $parameters['query'] is set
226
       * the query will be run. It MUST contain the column names listed above.
227
       * 
39 rodolico 228
       * If $parameters['template'] is set, that template will be used. If it
229
       * is not set, a template will be defaulted to.
230
       * 
231
       * If $paramters['arrayName'] is set, the form of the template will be
232
       * name='arrayname[name]'
233
       * 
37 rodolico 234
       * Processing will then continue
1 rodolico 235
      */
236
 
37 rodolico 237
      function htmlCheckBoxes ( $parameters ) {
238
         if ( empty( $parameters['template'] ) ) { // they did not send us a template
39 rodolico 239
            if ( empty( $parameters['arrayName'] ) ) {
41 rodolico 240
               $parameters['template'] = "<li><input type='checkbox' id='~~id~~' name='~~id~~' ~~checked~~>\n<label for='~~id~~'>~~name~~</label></li>\n";
39 rodolico 241
            } else {
41 rodolico 242
               $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 243
            }
1 rodolico 244
         }
37 rodolico 245
         //print "<pre>" . print_r($parameters, true) . "</pre>"; die;
246
         if ( empty( $parameters['data'] ) ) {
247
            if ( empty( $parameters['query'] ) )
248
               return '';
249
            $save = $this->useAssociativeArray;
250
            $useAssociativeArray = false; // temporarily turn off associative arrays
251
            $this->doSQL( $parameters['query'] );
252
            if ( $this->rowsAffected ) { // we returned at least one row
253
               foreach ($this->returnData as $rowNumber => $value ) {
254
                  $parameters['data'][] = $value;
255
               }
256
            }
1 rodolico 257
         }
37 rodolico 258
         //print "<pre>" . print_r($parameters, true) . "</pre>"; die;
259
         foreach ( $parameters['data'] as $key => $value ) {
260
            $replacement = array(
261
               'id' => $value['id'], 
262
               'name' => $value['name'], 
263
               'checked' => $value['checked'] ? 'checked' : ''
264
               );
265
            $html[] = $this->templateReplace($parameters['template'],$replacement);
266
         }
41 rodolico 267
         return '<ul>' . implode( '', $html ) . '</ul>';
1 rodolico 268
      }
269
 
37 rodolico 270
      /**
271
       * Replaces instances of replacement strings in string
272
       * 
273
       * Designed to allow the caller to build a string with things to be
274
       * replaced, for example
275
       * <input type='text' name='~~name~~'>
276
       * All instances of ~~name~~ will be replaced 
277
       */
278
      public function templateReplace ( $template, $replacmentStrings, $delimiter = '~~' ) {
279
         //print "<pre>" . print_r($replacmentStrings, true) . "</pre>";
280
         //print "<pre>" . print_r($template, true) . "</pre>";
281
         foreach ( $replacmentStrings as $key => $replace ) {
282
            $search = '/' . $delimiter . $key . $delimiter . '/';
283
            //print "<pre>" . print_r($search, true) . "</pre>"; die;
284
            $template = preg_replace( $search, $replace, $template );
285
         }
286
         return $template;
287
      }
288
 
1 rodolico 289
   /*   
290
      function CSV ( $sql ) {
291
         $rows = array();
292
         $CSV = '';
293
         $info = array();
294
         if ( $result = queryDatabaseExtended($sql,0) ) {
295
            $meta = $result['meta'];
296
            //objectDebugScreen($result);
297
            $info = $result['data'];
298
            unset ($result);
299
            $headers = array();
300
            foreach ( $meta as $field ) {
301
               $headers[] = $field['name'];
302
            } // foreach
303
            $rows[] = implode("\t", $headers);
304
            // special condition where only one row is returned. In that case, $info is not an array
305
            //  of associations, but a simple association. In this case, we need to convert it
306
 
307
            if (count($info[0]) == 1) { // convert from association to single row array of associations
308
               $temp = array();
309
               foreach ($info as $column => $value) {
310
                  $temp[0][$column] = $value;
311
               } // foreach
312
               $info = $temp;
313
            }
314
            for ( $row = 0; $row < count($info); $row++) {
315
               $rows[] = implode("\t", $info[$row]);
316
            }
317
            // we now have all the info, so let's make it into a table
318
            $CSV .= implode("\n", $rows );
319
         } // if ( $info = queryDatabase($sql,0) )
320
         // print '<pre>';  print_r ($info); print '</pre>';
321
         return $CSV;
322
      }
323
 
324
   */
325
 
326
   } // class DBQueryHTML
327
 
328
?>