Subversion Repositories php_library

Rev

Rev 47 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 rodolico 1
<?php
2
 
14 rodolico 3
/*
4
   Author: R. W. Rodolico
5
   Date:   20090403
6
 
7
   Class which holds basic reports for generation in client programs.
8
   Assumes a database table of at least the following format (all additional columns ignored)
9
      create table report (
10
         report_id   int unsigned not null auto_increment,
11
         name        varchar(20) not null comment 'Display Name of Report',
12
         query       text not null comment 'Query to be executed',
13
         parameters  text comment 'All parameters used in above',
14
         primary key (report_id)
15
      ) comment 'holds definition for report';
16
 
17
   Columns are defined as:
18
      name -- This is the name of the report for display. This is displayed by Report::listAllReports
19
      query -- an SQL Query for the report. Parameters may be inserted by surrounding them with '<' and '>'
20
               and these parameters will be replaced by user input values on execution.
21
      parameters -- List of parameter information to form query. These are one parameter per line. Each line
22
                    is a $parametersDelimiter delimited string of data.
23
 
24
                       1 - user prompt for value
25
                       2 - query.
26
                       3 - displayQuery
27
 
28
    This class is free software: you can redistribute it and/or modify
29
    it under the terms of the GNU General Public License as published by
30
    the Free Software Foundation, either version 3 of the License, or
31
    (at your option) any later version.
32
 
33
    This program is distributed in the hope that it will be useful,
34
    but WITHOUT ANY WARRANTY; without even the implied warranty of
35
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
36
    GNU General Public License for more details.
37
 
38
    You should have received a copy of the GNU General Public License
39
    along with this program.  If not, see <http://www.gnu.org/licenses/>                       
40
*/
41
 
42
   /* class QueryParameters
43
      Designed as a simple helper class to Reports. It simplified the writing of the Reports class by abstracting
44
      all of the parameters functions. The parameters are a very complex topic in and of themselves.
45
   */
1 rodolico 46
   class QueryParameters {
14 rodolico 47
      protected $parameter;    // parameter name. matches <param_name> in report query
48
      protected $prompt;       // user prompt when requesting a value for this parameter
49
      protected $query;        // if defined, generates a <select> block to acquire the value for this parameter instead of an <INPUT> block
50
      protected $displayQuery; // if defined, result is concated with any other displayQuery results for the title of the report
51
      protected $value;        // value used for displayQuery. See documentation
52
      private $parametersDelimiter = '++'; // parameter delimiter
1 rodolico 53
 
54
      function __constructor ( $parameter = '', $prompt = '', $query = '' ) {
55
         $this->parameter = $parameter;
56
         $this->prompt = $prompt;
57
         $this->query = $query;
58
      }
59
 
14 rodolico 60
      /* following functions are setters/getters for the class members */
61
      function parametersDelimiter ( $newDelimiter = '' ) {
62
         $oldValue = $this->parametersDelimiter;
63
         if ($newDelimiter) {
64
            $this->parametersDelimiter = $newDelimiter;
65
         }
66
         return $oldValue;
1 rodolico 67
      }
68
 
69
      function name ( $newParameter = '' ) {
70
         $oldParameter = $this->parameter;
71
         if ($newParameter) {
72
            $this->parameter = $newParameter;
73
         }
74
         return $oldParameter;
75
      }
76
 
77
      function value ( $newValue = '' ) {
78
         $oldValue = $this->value;
79
         if ($newValue) {
80
            $this->value = $newValue;
81
         }
82
         return $oldValue;
83
      }
84
 
85
      function prompt ( $newPrompt = '' ) {
86
         $oldPrompt = $this->prompt;
87
         if ($newPrompt) {
88
            $this->prompt = $newPrompt;
89
         }
90
         return $oldPrompt;
91
      }
92
 
93
      function query ( $newQuery = '' ) {
94
         $oldQuery = $this->query;
95
         if ($newQuery) {
96
            $this->query = $newQuery;
97
         }
98
         return $oldQuery;
99
      }
100
 
101
      function displayQuery ( $newQuery = '' ) {
102
         $oldQuery = $this->displayQuery;
103
         if ($newQuery) {
104
            $this->displayQuery = $newQuery;
105
         }
106
         return $oldQuery;
107
      }
108
 
14 rodolico 109
      // takes a single line of a parameters entry and breaks it into its values
110
      function stringToParameter( $string ) {
111
         $temp = explode( $this->parametersDelimiter, $string );
112
         $this->parameter = $temp[0];
113
         $this->prompt = $temp[1];
114
         $this->query = $temp[2];
115
         $this->displayQuery = $temp[3];
116
      }
117
 
118
      /* 
119
         creates a td with the prompt, and an <input> enter the value for that parameter. 
120
         If query is defined, will generate a <select> instead
121
      */
1 rodolico 122
      function toHTML () {
123
         $result = "<td>$this->prompt</td><td>";
124
         if ( $this->query ) {
125
            $result .= "<select name='report_param_$this->parameter'>" . queryToSelect( $this->query ) . '</select>';
126
         } else {
23 rodolico 127
            $result .= "<input type='text' name='report_param_$this->parameter'>";
1 rodolico 128
         }
129
         $result .= '</td>';
130
         return $result;
131
      }
132
   } // class QueryParameters
14 rodolico 133
 
134
   /* 
135
      the Report class is designed to be semi-automatic. It can, with little code, create a <select> containing the available reports,
136
      display any parameters required for that report, then run the report and return a table containing the results.
137
   */
1 rodolico 138
 
139
   class Report {
14 rodolico 140
      protected $name;  // name of report
141
      protected $title; // title for the report
142
      protected $query; // query to generate the report
143
      protected $parameters = array(); // array of parameters entries for the report. Class QueryParameters
1 rodolico 144
      private $tableName = 'report';
145
      private $nameField = 'name';
146
      private $queryField = 'query';
147
      private $parametersField = 'parameters';
148
      private $idField = 'report_id';
149
 
14 rodolico 150
      /* will simply get a list of all reports from the table and allow the user to select one */
1 rodolico 151
      static public function listAllReports( $tableName = 'report', $nameField = 'name', $idField = 'report_id' ) {
152
         return queryToSelect( "select $idField, $nameField from $tableName" );
153
      }
154
 
155
      function __constructor ($name = '', $title = '', $query = '', $parameters = array() ) {
156
         $this->name = $name;
157
         $this->title = $title;
158
         $this->query = $query;
159
         $this->parameters = $parameters;
160
      }
161
 
14 rodolico 162
      /* setters/getters for the various class members */
1 rodolico 163
      function name ( $newName = '' ) {
164
         $oldName = $this->name;
165
         if ($newName) {
166
            $this->name = $newName;
167
         }
168
         return $oldName;
169
      }
170
 
171
      function query ( $newQuery = '' ) {
172
         $oldQuery = $this->query;
173
         if ($newQuery) {
174
            $this->query = $newQuery;
175
         }
176
         return $oldQuery;
177
      }
178
 
179
      function parameters ( $newParameters = array() ) {
180
         $oldParameters = $this->parameters;
181
         if ($newParameters) {
182
            $this->parameters = $newParameters;
183
         }
184
         return $oldParameters;
185
      }
186
 
187
      function addParameter ( $newParameter = array() ) {
188
         $this->parameters[] = $newParameter;
189
      }
190
 
14 rodolico 191
      /* get the report definition from the database. Will decipher the definition, filling out all class members with their values */
192
      function loadFromDatabase ( $id ) {
193
         $sql = "select $this->nameField, $this->queryField, $this->parametersField from $this->tableName where $this->idField = $id";
194
         $result = queryDatabaseExtended( $sql );
195
         $result = $result['data'][0];
196
         $this->name = $result[$this->nameField];
197
         $this->title = $result[$this->nameField];
198
         $this->query = $result[$this->queryField];
199
         $parameters = $result[$this->parametersField];
200
         $parameters = explode("\n", $parameters);
201
         foreach ( $parameters as $thisParam ) {
202
            if (! $thisParam ) {
203
               continue;
204
            }
205
            $temp = new QueryParameters();
206
            $temp->stringToParameter($thisParam);
207
            $this->parameters[] = $temp;
208
         }
209
      }
210
 
211
      /* 
212
         runs the report
20 rodolico 213
         $parameters, if passed in, is an array of paramtername=>value and will be used in place of any values on the form
214
         $additionalLimitations is a partial where clause. When passed in, it will replace the special parameter <additionalLimitations>.
215
                         if it is not passed in, <additionalLimitations> will be removed
25 rodolico 216
         $makeTitle, if set to false, will simply return the data in a table. If true, will return the title and the data
14 rodolico 217
         The return value is the title in an H1, the conditions in H2's, and the results in a table
218
       */
53 rodolico 219
      function run( $parameters = '', $additionalLimitations = '', $makeTitle = true, $titleTags = array('startTag' => '<h4>', 'endTag' => '</h4>', 'conditionStart' => '<h2>', 'conditionEnd' => '</h2>' ) ) {
1 rodolico 220
         $conditions = array();
26 rodolico 221
         foreach ( $this->parameters as $parameter ) {
222
            if ( $parameters[$parameter->name()] ) { // in the array passed in
223
               $parameter->value( $parameters[$parameter->name()] );
224
            } elseif ($_POST['report_param_' . $parameter->name()]) { // in $_POST
225
               $parameter->value($_POST['report_param_' . $parameter->name()]);
1 rodolico 226
            }
227
         }
23 rodolico 228
         // print "<pre>"; print_r( $this ); print "</pre>";
1 rodolico 229
         foreach ( $this->parameters as $parameter ) {
230
            $toFind = '<' . $parameter->name() . '>';
231
            $this->query = preg_replace( "/$toFind/", $parameter->value(), $this->query );
232
            if ( $parameter->displayQuery() ) {
233
               //$result = preg_replace( '/<value>/', $parameter->value(), $parameter->displayQuery() );
23 rodolico 234
               $sql = preg_replace( '/<value>/', $parameter->value(), $parameter->displayQuery() );
235
               // print "<pre>$sql</pre>\n";
236
               $result = queryDatabaseExtended($sql , false);
1 rodolico 237
               //print "<pre>" . print_r( $result ); print "</pre>";
238
               $conditions[] = $parameter->name() . ' - '  . $result['data'][0][0];
239
            } else {
240
               $conditions[] = $parameter->name() . ' - ' . $parameter->value();
241
            }
242
         }
20 rodolico 243
         if ($additionalLimitations) { // the user wants us to limit additionally
21 rodolico 244
            $this->query = preg_replace( '/<additionalLimitations>/', ' and ' . $additionalLimitations, $this->query );
20 rodolico 245
         } else {
21 rodolico 246
            $this->query = preg_replace( '/<additionalLimitations>/', '', $this->query );
20 rodolico 247
         }
23 rodolico 248
         // print "<pre>$this->query</pre>";
53 rodolico 249
         $return = queryToTable($this->query);
250
         if ( $return && $makeTitle ) {
251
            $return =   $titleTags['startTag'] . $this->title . $titleTags['endTag'] .
252
                        $titleTags['conditionStart'] .
253
                           implode($titleTags['conditionEnd'] . $titleTags['conditionStart'], $conditions) .
254
                           $titleTags['conditionEnd'] .
255
                        $return;
256
         }
257
         return $return;
1 rodolico 258
      }
259
 
14 rodolico 260
      /*
261
         Creates a table with the necessary INPUT or SELECT fields to get the parameter values from the user
262
         returns a table suitable for inserting into a FORM
263
      */
264
      function parameterInputScreen () {
1 rodolico 265
         $result = "<table border='1'>\n";
266
         $result .= "<tr><td colspan='2'>$this->name</td></tr>";
267
         foreach ( $this->parameters as $parameter ) {
268
            $result .= '<tr>' . $parameter->toHTML() . '</tr>';
269
         }
23 rodolico 270
         return $result . '</table>';
1 rodolico 271
      }
14 rodolico 272
 
273
      // kept because some code used the old name. I messed up when I wrote the original. I don't think the name is indicative of the
274
      // use of this function. This will be removed in the future.
275
      function toHTML( ) {
276
         return parameterInputScreen();
277
      }
1 rodolico 278
 
279
   } // class Report
280
 
53 rodolico 281
?>