Subversion Repositories php_library

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 rodolico 1
<?php
2
 
3
/*
4
   Copyright 2007
5
   Daily Data, Inc.
6
   All rights reserved
7
   Description:
8
      Library of routines for TimeTracker
9
 
10
   Revision History:
11
   Revision 10 - 20090115 - R. W. Rodolico
12
   Modified editData routine to grab display query from table definition if key field not defined in complex join definition
13
 
14
*/
15
 
16
 
17
   define( HTML_QUOTE_CHAR, '"' );
18
   define( CONSTANT_NO_VALUE_DROPDOWN, '--------' );
19
 
20
   $LOGIN_PAGE = 'login.html';
21
 
22
   function getParameter( $parameterName, $default = '' ) {
23
      if (isset($_POST[$parameterName])) {
24
         return $_POST[$parameterName];
25
      }
26
      if (isset($_GET[$parameterName])) {
27
         return $_GET[$parameterName];
28
      }
29
      return $default;
30
   }
31
 
32
   function printLog ( $string ) {
33
      if ( 0 ) {
34
         $fh = fopen('/tmp/queryDatabaseExtended.sql', 'a');
35
         fwrite($fh, $string . "\n");
36
         fclose($fh);
37
      }
38
   }   
39
 
40
   function whoami () {
41
      $output = '';
42
      $i = queryDatabase("select concat(surname,', ',given_name) name from worker where worker_id = " . $_SESSION['effective_worker_id']);
43
      $output .= $i;
44
      if ( $_SESSION['effective_worker_id'] != $_SESSION['worker_id']) {
45
         $i = queryDatabase("select concat(surname,', ',given_name) name from worker where worker_id = " . $_SESSION['worker_id']);
46
         $output .= " ($i)";
47
      }
48
      return $output;
49
   }
50
 
51
   function logOut() {
52
      unset( $_SESSION['user'] );
53
      redirectPage($LOGIN_PAGE,array('message'=>'Logged Out, please log back in to continue'));
54
   }
55
 
56
   function objectDebugScreen ( $obj ) {
57
      print '<pre>';
58
      print_r ($obj);
59
      print "</pre>\n";
60
   }
61
 
62
 
63
/*   function verifyLogin( $loginID, $password ) {
64
      if ( strlen($loginID) > 10 ) {
65
         $loginID = substr($loginID,1,10);
66
      }
67
 
68
      $sql = "select count(*) numRows, min(worker_id) worker_id from login where username = " .
69
              makeSafeSQLValue($loginID) . ' and pass = md5(' . makeSafeSQLValue($password) . ") and enabled = 'Y'";
70
      $info = queryDatabase( $sql );
71
      if ( $info[0]['numRows'] == 1 ) {
72
         $_SESSION['worker_id'] = ($info[0]['worker_id'] ? $info[0]['worker_id'] : -1); // keep track of the current worker
73
         $_SESSION['effective_worker_id'] = $info[0]['worker_id']; // This allows superusers to enter info as if they were a different worker
74
         $_SESSION['user'] = $loginID;
75
         $sql = "select permission_id from user_permission where username ='" . $_SESSION['user'] . "'";
76
         $info = queryDatabase( $sql );
77
         for ( $i = 0; $i < count($info); $i++ ) {
78
            $permission[$info[$i]['permission_id']] = true;
79
         }
80
         $_SESSION['permission'] = $permission;
81
         validateDatabaseVersion();
82
         redirectPage('user_menu.html');
83
      } else {
84
         return false;
85
      }
86
   }
87
*/
88
   function makeSafeSQLValue ( $value, $type='S' ) {
89
      if(get_magic_quotes_gpc()) {
90
           $value = stripslashes($value);
91
       }
92
      $value = mysql_real_escape_string( $value );
93
      if (($type == 'S') and strlen($value)  > 0) { // put quotes around strings
94
         $value = "'" . $value . "'";
3 rodolico 95
      } elseif ($type == 'D') {
4 rodolico 96
         if ( $result = strtotime( $value ) ) {
3 rodolico 97
            $value = Date( 'Y-m-d H:i:s', $result);
98
         } else {
99
            $value = '0000-00-00';
100
         }
101
         $value = "'" . $value . "'";
1 rodolico 102
      } elseif (strlen($value) == 0) { // and substitue null for empty values otherwise;
103
         $value = 'null';
104
      }
105
      return $value;
106
   }
4 rodolico 107
 
1 rodolico 108
 
109
/*
110
   creates audit trail of modifications to the database
111
*/ 
112
   function audit ($sql ) {
113
      return ;
114
      $query = 'insert into _audit (_audit.user_id,_audit.sql) values ( ' . $_SESSION['worker_id'] . ', ' . makeSafeSQLValue($sql) . ')';
115
      mysql_query( $query );
116
      if( mysql_errno() ) {
117
         $error = 'MYSQL ERROR #'.mysql_errno().' : <small>' . mysql_error(). "</small><br><VAR>$query</VAR>";
118
         echo($error);
119
      }
120
   }
121
 
122
 
123
   /*
124
      Taken from comments at http://www.php.net/manual/en/function.mysql-query.php
125
      function originally named 'q'
126
      $r = q('Select id,foo FROM blah');
127
      echo $r[0]['id']; // first row, field 'id'
128
 
129
      // for single field single row selects
130
      // only the value is returned
131
      $count = q('SELECT count(*) from blah');
132
      // $count is the number
133
 
134
      Returns affected_rows and/or insert_id for anything other than select's.
135
      If you dont want field name keys then pass 0 for second parameter.
136
 
137
      For a query returning multiple rows, will return an associative array
138
         return['data'] contains an two dimensional array of all data received from the query
139
         return['meta']
140
            array of associative arrays. Each row in the array corresponds to a column in the query return
141
            Each array row contains the following:
142
               'name'   name of the column
143
               'length' maximum width of the column FOR THIS QUERY
144
               'numeric'true if the column is numeric
145
               'type'   type of the column (database dependant)
146
 
147
   */
148
 
149
      function queryDatabaseExtended($query,$assoc=1,$showErrors=true) {
150
      // print "<pre>In Query database\n---------------------\n$query\n---------------------\n</pre>";
151
      printLog( $query );
152
      $r = @mysql_query($query);
153
      if( mysql_errno() ) {
154
         $error = 'MYSQL ERROR #'.mysql_errno().' : <small>' . mysql_error(). "</small><br><VAR>$query</VAR>";
155
         if ( $showErrors ) echo($error);
156
         return FALSE;
157
      }
158
      if( ! preg_match ( '/^\s*select/i', $query ) ) {
159
         $f = array( 'affected_rows' => mysql_affected_rows(),'insert_id' => mysql_insert_id());
160
         // create audit trail
161
         audit($query);
162
         return $f;
163
      }
164
      $count = @mysql_num_rows($r);
165
      $fieldMeta = array();
166
      while ($i++ < mysql_num_fields($r)) {
167
         $meta = mysql_fetch_field ( $r );
168
         //objectDebugScreen($meta);
169
         $fieldMeta[] = array('name' => $meta->name, 'length' => $meta->max_length, 'numeric' => $meta->numeric, 'type' => $meta->type );
170
      }
171
      if( ! $count ) return '';
172
      $all = array();
173
      for( $i = 0; $i < $count; $i++ ) {
174
        if( $assoc ) $f = mysql_fetch_assoc($r);
175
        else $f = mysql_fetch_row($r);
176
        $all[] = $f;
177
      }
178
      mysql_free_result($r);
179
      return array( 'meta' => $fieldMeta, 'data' => $all, 'count' => $count);
180
   } // function queryDatabaseExtended
181
 
182
 
183
  function countNumberOfRows ( $sql ) {
184
     $count = queryDatabaseExtended("select count(*) numRows from ($sql) test");
185
     return $count['data'][0]['numRows'];
186
  }
187
 
188
   function makeWhereClause ($conditions) {
189
      $whereClause = ' where ' . implode (' and ', $conditions );
190
      return $whereClause;
191
   }
192
 
193
   function insertValuesIntoQuery( $query, $values ) {
194
      foreach ( $values as $name => $value ) {
195
         $query = search_replace_string($query, "<$name>", $value );
196
      }
197
      return $query;
198
   }
199
 
200
/*
201
   function showUserMenu () {
202
      $permission = $_SESSION['permission'];
203
      // objectDebugScreen($_SESSION['permission']);
204
      // print "Effective User = " . $_SESSION['effective_worker_id'];
205
      $result = '<ul>';
206
      if ( $permission[1] ) {
207
         $result .= '<li><a href="timesheet_input.html">Add/Enter Time Sheet/Expenses</a></li>';
208
         $result .= '<li><A href="edit_personal.html">Edit Personal Data</A></li>';
209
         $result .= '<li><A href="view_personal_payroll.html">View Past Payroll</A></li>';
210
         $result .= '<li><a href="docs/user_manual.html" target="_blank">User Manual (in separate window)</a></li>';
211
      }
212
      if ( $permission[2]) {
213
         $result .= '<li><a href="create_invoice.html">Create Invoice</a></li>';
214
         $result .= '<li><a href="view_invoice.html">View Invoices</a></li>';
215
      }
216
      if ( $permission[3]) {
217
         $result .= '<li><a href="create_payroll.html">Create Payroll</a></li>';
218
         $result .= '<li>View Payroll</li>';
219
         $result .= '<li><a href="docs/payroll_manual.html" target="_blank">Payroll Manual (in separate window)</a></li>';
220
      }
221
      if ( $permission[4]) {
222
         $result .= '<li>Create Worker</li>';
223
         $result .= '<li>View Worker</li>';
224
      }
225
      if ( $permission[5]) {
226
         $result .= '<li>Add Client</li>';
227
      }
228
      if ( $permission[6]) {
229
         $result .= '<li>Add Project</li>';
230
      }
231
      if ( $permission[7]) {
232
         $result .= '<li><A href="reports.html">View Payroll Reports</A></li>';
233
      }
234
      if ( $permission[8] ) {
235
         $result .= '<li><A href="becomeuser.html">Become another User</A></li>';
236
      }
237
      $result .= "<li><a href='/common-cgi/contact_us.php' target='_blank'>Submit Bug Report or Enhancement Request</a>";
238
      $result .= "<li><a href='viewBugz.html' >View Bugs or Enhancments Request</a>";
239
      $result .= "<li><a href='login.html?command=logout'>Log Out</a></ul>";
240
      return $result;
241
   }
242
 
243
   function getProjectName( $projectID ) {
244
      $sql = "select concat(client.name,' - ', project.project_name) project_name
245
              from project join client on project.client_id = client.client_id
246
              where project.project_id = $projectID
247
             ";
248
      return queryDatabase( $sql );
249
   }
250
 
251
 
252
   function getExpenseReason( $expenseReasonID ) {
253
      $sql ="select description
254
             from expense_reason
255
             where expense_reason_id = $expenseReasonID
256
            ";
257
      return queryDatabase( $sql );
258
   }
259
*/
260
 
261
   function addDateRange ( $dateStart, $dateEnd ) {
262
      $dateWhere = array();
263
      if ( strlen($dateStart) > 0 ) {
264
       array_push($dateWhere, "start_time >= '$dateStart'" );
265
      }
266
      if ( strlen($dateEnd) > 0 ) {
267
         array_push($dateWhere, "end_time <= '$dateEnd'");
268
      }
269
      return $dateWhere;
270
   }
271
 
272
   function search_replace_string($string, $searchFor, $replaceWith ) {
273
      $string = str_replace ( $searchFor, $replaceWith, $string );
274
      return $string;
275
   }
276
 
277
   /*
278
      Function takes an SQL statement and converts it to an HTML table.
279
      Return Value: HTML table representation of the query
280
      Parameters:
281
         $sql    A valid SQL query to run
282
         $format An optional array of format strings (suitable for printf) for each column (empty strings ignored)
283
         $makeTableDef  If True, the resulting HTML has the <table></table> tags; otherwise starts with header
284
         $append   Arbitrary string that is appended as a single column to each row
285
 
286
         NOTE ON $append
287
            $append may optionally contain variables of the form %colname%, which will be replaced
288
            with values from the current row. $colname is taken from the META data from the query, thus
289
            the query select foo from bar would have a meta of header of foo for column 0.
290
            $append is searched for strings of form %foo% in that case, and the current value of column
291
            foo replaces the tag %foo%.
292
            %foo% is ignored if foo is not a valid column name in a query.
293
            thus, a query such as select zip,city,state from zip_codes and a string of Hello %city% I'm glad
294
            you are in %State% will not replace the second as State is not a column of this query (it is case
295
            sensitive). Also, beware of items like select zip,concat(state,', ', city) from zip_codes. It is
296
            much better to rewrite that as select zip,concat(state,', ', city) mytown from zip_codes.
297
 
298
            If you don't know what all that means, get a book on SQL
299
   */
300
   function queryToTable ( $sql, $format = '', $makeTableDef = true, $append='' ) {
301
      //print "\n\n$sql\n\n";
302
      $tdTextDefinition = '<td valign=' . HTML_QUOTE_CHAR . 'top' . HTML_QUOTE_CHAR . '>';
303
      $tdNumberDefinition = '<td valign=' . HTML_QUOTE_CHAR .'top' . HTML_QUOTE_CHAR . 'align=' . HTML_QUOTE_CHAR . 'right' . HTML_QUOTE_CHAR . '>';
304
      $rows = array();
305
      $html = '';
306
      $fields;
307
      $info = array();
308
      if ( $result = queryDatabaseExtended($sql,0) ) {
309
         $meta = $result['meta'];
310
         // Build the searchFor array for $append
311
         $searchFor = array();
312
         foreach ( $meta as $field ) {
313
            $searchFor[] = '%' . $field['name'] . '%';
314
         }
315
         $info = $result['data'];
316
         unset ($result);
317
         /* special condition where only one row is returned. In that case, $info is not an array
318
           of associations, but a simple association. In this case, we need to convert it
319
         */
320
         if (count($info[0]) == 1) { // convert from association to single row array of associations
321
            $temp = array();
322
            foreach ($info as $column => $value) {
323
               $temp[0][$column] = $value;
324
            } // foreach
325
            $info = $temp;
326
         }
327
         if (count($format) > 0 ) { // we have some formats, so let's do it the hard, slow way
328
            for ( $row = 0; $row < count($info); $row++) {
329
               $rows[$row] = '';
330
               for ( $column = 0; $column < count($info[$row]); $column++  ) {
331
                  $rows[$row] .= strlen($format[$column]) && isset($info[$row][$column])> 0 ?
332
                                  ( $tdNumberDefinition . sprintf($format[$column],$info[$row][$column]) . '</td>')
333
                                  : ($tdTextDefinition . $info[$row][$column] . '</td>');
334
               } // for $column
335
               /*
336
                  let's append some stuff to the row if it exists.
337
                  We will take the array of SearchFor containing the column names
338
                  and the array of values from this row, then look for matches and replace them
339
                  with the correct values. Note, the column names in $append should have percent
340
                  signs appended and prepended, thus a column name of joe would be %joe% in %append
341
               */
342
               if (strlen($append) > 0) { // let's append some stuff to the row
343
                  $rows[$row] .= $tdTextDefinition . str_replace ( $searchFor, $info[$row], $append ) . '</td>';
344
               }
345
            } // for $row
346
         } else { // no formatting, so we just slam the stuff together
347
            for ( $row = 0; $row < count($info); $row++) {
348
               $currentValue = $tdTextDefinition . implode( '</td>' . $tdTextDefinition, $info[$row]) . '</td>';
349
               if (strlen($append) > 0) { // see explaination in if part of this structure
350
                  $currentValue  .= $tdTextDefinition . str_replace ( $searchFor, $info[$row], $append ) . '</td>';
351
               }
352
               $rows[] = $currentValue;
353
            }
354
         }
355
         // ok, let's get the field headers from the table
356
         $html .= '<tr>';
357
         foreach ( $meta as $field ) {
358
            $html .= '<th>' . $field['name'] . '</th>';
359
         }
360
         $html .= '</tr>';
361
         // we now have all the info, so let's make it into a table
362
         $html .= '<tr>' . implode('</tr><tr>', $rows ) . '</tr>';
363
 
364
         if ( $makeTableDef ) { // they want the <table> def, so let's give it to them
365
            $html = '<table border=' . HTML_QUOTE_CHAR . '1' . HTML_QUOTE_CHAR . '>' . $html . '</table>';
366
         } // if ( $makeTableDef
367
      } // if ( $info = queryDatabase($sql,0) )
368
      // print '<pre>';  print_r ($info); print '</pre>';
369
      return $html;
370
   }
371
 
372
   /*
373
      function executes a query, then returns an array containing only the values of the first
374
      field in the return as the keys to an associative array. NOTE: any duplicates will be
375
      discarded. This is useful when you simply want to know if a value exists, ie if you
376
      are building an html select from a query, and a separate query needs to hold the
377
      values that are currently selected
378
   */
379
 
380
   function sqlValuesToKeys ($sql) {
381
      $returnValue = array();
382
      if ( $info = queryDatabaseExtended($sql,0) ) { // note we are turning off the associative array here
383
         $info = $info['data'];
384
         foreach ( $info as $key => $value ) { // only thing I know to do is iterate
385
            $returnValue[$value[0]] = true;
386
         }
387
      } // if
388
      return $returnValue;
389
   }
390
 
391
   /* this function will take the result of an SQL query that returns at least two columns.
392
      The first column becomes the keys in an associative array, and the second column
393
      becomes the value.
394
 
395
      Note, because it is an associative array, duplicates of the first column will only contain
396
      the last value.
397
   */
398
 
399
   function sqlColumnColumnArray ( $sql ) {
400
      $returnValue = array();
401
      if ( $info = queryDatabaseExtended($sql,0) ) { // note we are turning off the associative array here
402
         $info = $info['data'];
403
         foreach ( $info as $key => $value ) { // only thing I know to do is iterate
404
            $returnValue[$value[0]] = $value[1];
405
         }
406
      } // if
407
      return $returnValue;
408
   }
409
 
410
 
411
   /* the first returned column becomes the value, the second becomes the display element
412
   */
413
   function queryToSelect ( $sql, $selectedFieldsQuery = '' ) {
414
      $selectedFields = array();
415
      if (  preg_match ( '/^\s*select/i', $selectedFieldsQuery ) ) { // They passed in a query
416
         if (strlen($selectedFieldsQuery) ) {
417
            $selectedFields = sqlValuesToKeys($selectedFieldsQuery);
418
         }
419
      } else { // assume the passed in a value
420
         $selectedFields[$selectedFieldsQuery] = 1;
421
      }
422
      $info = queryDatabaseExtended( $sql, false );
423
      $info = $info['data'];
424
      $html = '';
425
      for ( $i = 0; $i < count($info); $i++ ) {
426
         $html .= '<option value="' . $info[$i][0] . '"';
427
         if ( $selectedFields[$info[$i][0]] ) {
428
            $html .= ' selected';
429
         }
430
         $html .= '>' . $info[$i][1] . '</option>';
431
      }
432
      return $html;
433
   }
434
 
435
   /* function will take a query and turn it into a series of check boxes. It must contain
436
      two columns, with the first becoming the the name of the checkbox
437
      and the second becoming the displayed value. an optional third column will be used
438
      to match if the $checkedValuesQuery is used.
439
      if $checkedValuesQuery is not empty, it will be run to see what boxes need to be
440
      checked by being compared to the third column of the $sql query.
441
      $htmlBefore will be placed before each check box, and $htmlAfter will be placed after
442
      each checkbox.
443
 
444
      if $tableColumns is set to a number, the checkboxes will be embedded in a group of
445
      <tr></tr>, each containing table columns of $tableColumns width. In this case, $htmlBefore
446
      will have <td> prepended and $htmlAfter will have </td> appended, meaning any passed
447
      values will be INSIDE of the td. NOTE: the <table></table> tags are NOT put in.
448
 
449
      NOTE: currently, using the table stuff will leave a dangling row with 0 elements if
450
      the number of elements equal the number of columns.
451
   */
452
 
453
   function queryToCheckBoxes ( $sql, $checkedValuesQuery = '', $htmlBefore = '', $htmlAfter = '', $table_columns='' ) {
454
      $html = '';
455
      if ($table_columns) {
456
         $htmlBefore = '<td>' . $htmlBefore;
457
         $htmlAfter .= '</td>';
458
         $html .= '<tr>';
459
      }
460
      $numColumns = 0;
461
      $checkBoxes = queryDatabaseExtended( $sql,0 );
462
      $selectedFields = array();
463
      if (strlen($checkedValuesQuery) ) {
464
         $selectedFields = sqlValuesToKeys($checkedValuesQuery);
465
      }
466
      foreach ($checkBoxes['data'] as $row => $values) {
467
         if ($table_columns && ++$numColumns == $table_columns) {
468
            $html .= '</tr><tr>';
469
            $numColumns = 0;
470
         }
471
         //objectDebugScreen($row);
472
         $html .= $htmlBefore . '<input type="checkbox" name="' . $values[0] . '"';
473
         if ( $selectedFields[$values[2]] ) {
474
            $html .= ' checked';
475
         }
476
         $html .= '>' . $values[1] . $htmlAfter;
477
         //<INPUT type="checkbox" checked name="temp">
478
      } // foreach
479
      $html .= '</tr>';
480
      return $html;
481
   }
482
 
483
   function makeMoney( $value ) {
484
      return sprintf( '%0.2f', $value );
485
   }
486
 
487
   function queryToCSV ( $sql ) {
488
      $rows = array();
489
      $CSV = '';
490
      $info = array();
491
      if ( $result = queryDatabaseExtended($sql,0) ) {
492
         $meta = $result['meta'];
493
         //objectDebugScreen($result);
494
         $info = $result['data'];
495
         unset ($result);
496
         $headers = array();
497
         foreach ( $meta as $field ) {
498
            $headers[] = $field['name'];
499
         } // foreach
500
         $rows[] = implode("\t", $headers);
501
         /* special condition where only one row is returned. In that case, $info is not an array
502
           of associations, but a simple association. In this case, we need to convert it
503
         */
504
         if (count($info[0]) == 1) { // convert from association to single row array of associations
505
            $temp = array();
506
            foreach ($info as $column => $value) {
507
               $temp[0][$column] = $value;
508
            } // foreach
509
            $info = $temp;
510
         }
511
         for ( $row = 0; $row < count($info); $row++) {
512
            $rows[] = implode("\t", $info[$row]);
513
         }
514
         // we now have all the info, so let's make it into a table
515
         $CSV .= implode("\n", $rows );
516
      } // if ( $info = queryDatabase($sql,0) )
517
      // print '<pre>';  print_r ($info); print '</pre>';
518
      return $CSV;
519
   }
520
 
521
 
522
/* This function should only be run once, when the original data has been ported from the other system */
523
function normalizeTime () {
524
   //queryDatabase('update time_tracker set payroll_id = null where start_time > 20070101');
525
   $info = queryDatabase('select * from payroll where payroll_date >= 20070101 order by worker_id,payroll_date');
526
   for ( $i = 0; $i < count($info); $i++) {
527
      $payroll_id = $info[$i]['payroll_id'];
528
      $workerID = $info[$i]['worker_id'];
529
      $payroll_date = $info[$i]['payroll_date'];
530
      queryDatabase("update time_tracker set time_tracker.payroll_id = $payroll_id where payroll_id is null and worker_id = $workerID and start_time <= '$payroll_date'");
531
      queryDatabase("update expense set payroll_id = $payroll_id where payroll_id is null and worker_id = $workerID and expense_date <= 'payroll_date'");
532
   }
533
}
534
/*
535
   redirects to a different page (ie, sends out a location header)
536
   $page is required
537
   $parameters can be blank but, if they are not, they are a URL encoded string
538
   $path defaults to current uri if it is not passed in
539
   $host defaults to current server name if not passed in
540
*/
541
function redirectPage ( $page,$parameters=array(),$path='',$host='') {
542
   $params = '';
543
   if ( strlen($host) == 0 ) $host = $_SERVER['HTTP_HOST'];
544
   if ( strlen($path) == 0 ) $path = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
545
   if ( count($parameters) > 0 ) {
546
      foreach ($parameters as $var => $value ) {
11 rodolico 547
         $params[] = $var . '=' . rawurlencode($value);
1 rodolico 548
      }
11 rodolico 549
      $params = '?' . implode( '&', $params );
1 rodolico 550
   }
551
   $location = 'http://' . $host . $path . '/' . $page . $params;
552
   header("Location: $location");
553
   exit;
554
}
555
 
556
   function FileErrorMessage ( $errorCode ) {
557
      switch ($errorCode) {
558
         case 1:
559
             return("The uploaded file exceeds the upload_max_filesize directive (" . ini_get("upload_max_filesize") . ") in php.ini.");
560
         case 2:
561
             return("The uploaded file exceeds the MAX_FILE_SIZE directive (" . MAX_UPLOAD_FILE_SIZE . ").");
562
         case 3:
563
             return("The uploaded file was only partially uploaded.");
564
         case 4:
565
             return("No file was uploaded.");
566
         case 6:
567
             return("Missing a temporary folder.");
568
         case 7:
569
             return("Failed to write file to disk");
570
         default:
571
             return("Unknown File Error");
572
      }
573
   }
574
 
575
  /* this function will clean up nasty stuff on the uploaded file name before
576
     allowing it to be used to store the file to disk.
577
     It removes any non-alphanumerics, underscores, periods and dashes
578
  */
579
 
580
  function fixFileName ( $filename ) {
581
     $filename = strtolower( $filename );
582
     $filename = preg_replace('/\s+/', '_', $filename); // convert all spaces to underscore
583
     $filename = preg_replace( '/[^a-z0-9._-]/', '', $filename );
584
     return $filename;
585
  }
586
 
587
 
588
   /* function will take a hash, and return the hash with the values modified
589
      to the form $key$delimiter$value
590
      thus, a hash 'col1'=>'value1', 'col2'=>'value2' would return
591
      col1=>'col1=value1', col2=>'col2=value2'
592
      This is useful for creating an update or where clause, as the user can have
593
      a hash of conditions (or updates to make), call this function, then
594
      implode. Thus, in the above case, if we wanted to have a where clause
595
      we could say implode( ' and ', makeEqualsFromHash($conditions) ) and
596
      get col1=value1 and col2=value2 as the result.
597
   */
598
   function makeEqualsFromHash( $hash, $delimiter='=' ) {
599
      foreach ( $hash as $key => $value ) {
600
         $hash[$key] = $key . $delimiter . $value;
601
      }
602
      return $hash;
603
   }
604
 
605
   /*
606
      function will takes fieldList, a hash of column names and values, and either
607
      updates or inserts depending upon whether the record exists.
608
      It will do a query by taking $existsColumns to determine if the record exists.
609
         ($existsColumns is another hash of column names and values) As a convenience,
610
         if $existsColumns is empty, or the value is empty, will assume an insert
611
      If record exists
612
         creates an update out of $fieldList
613
      else
614
         creates an insert out of $fieldList
615
      then, executes the query
616
      Returns the value of lastInsert on insert
617
 
618
      NOTE: if the key field(s) are not automatically created on insert, they
619
      must be included in $fieldList also.
620
   */
621
   function addOrUpdate ( $tableName, $existsColumns, $fieldList ) {
622
      $sql = '';
623
      $insert = true;
624
      // assume we will have a whereClause
625
      $whereClause = true;
626
      // are there any null values?
627
      foreach($existsColumns as $key => $value) {
628
         if (strlen($value) == 0) {
629
            $whereClause = false;
630
         }
631
      }
632
      if ($whereClause and count($existsColumns) ) {
633
         $whereClause = implode(' and ', makeEqualsFromHash($existsColumns) );
634
         $result = queryDatabaseExtended( "select * from $tableName where $whereClause" );
635
         if ($result['count'] == 1) {
636
            $insert = false;
637
         }
638
      }
639
      if ($insert) { // we must be adding a record, so do an insert
640
         $sql = "insert into $tableName(";
641
         $sql .= implode(',',array_keys($fieldList) );
642
         $sql .= ') values (';
643
         $sql .= implode(',', $fieldList);
644
         $sql .= ')';
645
         $result = queryDatabaseExtended($sql);
646
         return ($result['insert_id']);
647
      } else { // must be a true update
648
         $sql = "update $tableName set " . implode(',',makeEqualsFromHash($fieldList) ) . " where $whereClause" ;
649
         //print "\n$sql\n<br>";
650
         queryDatabaseExtended( $sql );
651
      }
652
   }
653
 
654
   /* function generates a random password. Shamelessly stolen from
655
       http://www.laughing-buddha.net/jon/php/password/
656
   */
657
 
658
   function generatePassword ($length = 8) {
659
     // start with a blank password
660
     $password = "";
661
     // define possible characters
662
     $possible = "0123456789bcdfghjkmnpqrstvwxyz"; 
663
     // set up a counter
664
     $i = 0; 
665
     // add random characters to $password until $length is reached
666
     while ($i < $length) { 
667
        // pick a random character from the possible ones
668
        $char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
669
        // we don't want this character if it's already in the password
670
        if (!strstr($password, $char)) { 
671
          $password .= $char;
672
          $i++;
673
        }
674
      }
675
      // done!
676
      return $password;
677
   }
678
 
679
   function showDateWithNulls( $date, $prompt='' ) {
680
      if ( is_null($date) or $date == '0000-00-00' ) {
681
        return $prompt;
682
      } else {
683
          return $date;
684
      }
685
   } // function showDateWithNulls
686
 
687
 
688
// functions merged from previous version
689
 
690
 
691
   // Quote variable to make safe
692
   function makeQuerySafe ( $fieldValue ) {
693
      // Stripslashes
694
      if (get_magic_quotes_gpc()) {
695
         $fieldValue = stripslashes($fieldValue);
696
      }
697
      // Quote if not a number or a numeric string
698
      if (!is_numeric($value)) {
699
         $fieldValue = "'" . mysql_real_escape_string($fieldValue) . "'";
700
      }
701
      return $fieldValue;
702
   }
703
 
704
 
705
   function HumanReadable2Number ( $hr ) {
706
      $hr = strtolower($hr);
707
      $num = $hr;
708
      if ( preg_match('/([0-9]+)([tgmk])/', $hr ,$matches) ) {
709
         $num = $matches[1];
710
         $modifier = $matches[2];
711
         if ($modifier == 'g') { 
712
            $num *= 1024 * 1024 * 1024; 
713
         } elseif ($modifier == 'm' ) { 
714
            $num *= 1024 * 1024; 
715
         } elseif ($modifier == 'k' ) { 
716
            $num *= 1024;
717
         } else { 
718
            return "Unable to decipher the number $hr"; 
719
         }
720
      }
721
      return $num;
722
   }
723
 
724
   function Number2HumanReadable( $num ) {
725
      if ( $num > 1024 * 1024 * 1024 ) {
726
         return round( $num / (1024*1024 * 1024) ) . 'G';
727
      } elseif ( $num > 1024 * 1024 ) {
728
         return round( $num / (1024*1024) ) . 'M';
729
      } elseif ( $num > 1024 ) {
730
         return round( $num / 1024 ) . 'k';
731
      } else {
732
         return $num . " bytes";
733
      }
734
   }
735
 
736
   function doSQL( $sql ) {
737
      // print '<pre>' . "$sql\n" . '</pre>';
738
      queryDatabaseExtended($sql);
739
      #mysql_query ($sql);
740
   }
741
 
742
   function deleteData ( $tableInfo, $id ) {
743
      $sql = 'delete from ' . $tableInfo['table name'] . ' where ' . $tableInfo['key field'] . " = $id";
744
      queryDatabaseExtended($sql);
745
      #mysql_query ($sql);
746
      return '';
747
   }
748
 
749
   function addData ( $tableInfo ) {
750
      $maxFileSize = min(HumanReadable2Number(MAX_UPLOAD_FILE_SIZE),HumanReadable2Number(ini_get("upload_max_filesize")));
751
      $result = '';
752
      $result .= "<p><form enctype='multipart/form-data' action='" . $_SERVER['PHP_SELF'] . "' method='post'>";
753
      $result .= "<input type='hidden' name='currentdb' value='" . $tableInfo['table name'] . "' />";
754
      $result .= "<input type='hidden' name='MAX_FILE_SIZE' value='$maxFileSize' />";
755
      $result .= '<table border="1">';
756
      foreach ($tableInfo['field info'] as $field => $value) {
757
         $displayName = $value['display name'] ? $value['display name'] : $field; 
758
         $result .= "<tr><td valign='top'>$displayName";
759
         if ( $value['type'] == 'file' ) {
760
            $result .= "<br><font size='-2'>Max Size " . Number2HumanReadable($maxFileSize) . "</font>";
761
         }
762
         $result .= "</td><td>";
763
         if ( $value['readonly'] ) {
764
            $result .= $info[$field];
765
         } else {
766
            if ( $value['type']  == 'string' ) {
767
               $maxWidth = $value['width'] or MAX_INPUT_FIELD_DISPLAY;
768
               $displayWidth = $maxWidth < MAX_INPUT_FIELD_DISPLAY ? $maxWidth : MAX_INPUT_FIELD_DISPLAY;
769
               $result .= "<input type='text' name='$field' size='$displayWidth' maxlength='$maxWidth' value=''>";
770
            } elseif ($value['type'] == 'password') {
771
               $result .= "<input type='text' name='$field' size='$displayWidth' maxlength='$maxWidth' value=''>";
772
            } elseif ( $value['type'] == 'text' ) {
773
               $result .= "<textarea name='$field' rows='5' cols='40'></textarea>";
774
            } elseif ( $value['type'] == 'file' ) {
775
               $result .= "<input type='file' name='$field' value=''>";
776
            } elseif ( $value['type']  == 'lookup' ) {
777
               $result .= "<select name='$field'>";
778
               $result .= makeDropDown ( $value['table'], $value['keyfield'], $value['display_field'], 0 );
779
               $result .= "</select>";
780
            } elseif ( $value['type']  == 'bool' ) {
781
               $result .= "<input type='radio' name='$field' value='1'";
782
               $result .= ">True<input type='radio' name='$field' value='0'";
783
               $result .= " checked>False";
784
            } else {
785
               $result .= "<input type='text' name='$field' value=''>";
786
            }
787
         }
788
         $result .= "</td></tr>\n";
789
      }
790
      // process any multi selects we may have
791
      if ($tableInfo['complex join']) { 
792
         foreach ($tableInfo['complex join'] as $table => $value) {
793
            $result .= '<tr><td>' . $table . '</td><td>';
794
            $result .= makeMultiSelect( $tableInfo['table name'], $tableInfo['key field'], $id, $value);
795
            $result .= '</td></tr>';
796
         } // foreach
797
      } // if
798
      $result .= "<tr><td colspan='2' align='center'><input type='submit' /></td></tr>
799
      <input type=hidden name='mode' value='added' /> 
800
      <input type=hidden name='id' value='"; 
801
      $result .= $id; 
802
      $result .= "'></table></form> <p>"; 
803
      return $result;
804
   }
805
 
806
  function saveFilesUploaded( $fieldName ) {
807
     $result = '';
808
     $uploaddir =  $_SERVER['DOCUMENT_ROOT'] . IMAGE_DIRECTORY;
809
     $result = fixFileName( basename($_FILES[$fieldName]['name']) );
810
     if (! move_uploaded_file($_FILES[$fieldName]['tmp_name'], $uploaddir . $result)) {
811
       $result = '';
812
   }
813
     return $result;
814
  }
815
 
816
 
817
  function makeDropDown ( $table, $index_field, $display_field = '', $keyvalue = '' ) {
818
     /*
819
       this executes a query on $table (using $index_field and $display_field), then
820
       uses the result to populate a list of <option> tags suitable for inclusion in
821
       a <SELECT>. If $index_field for a row equals $keyvalue, that option has its
822
       SELECT paramter turned on
823
     */
824
     $returnValue = '';
825
     if ( $display_field ) { // they are passing in a table, index field, display field and key value
826
        $sql = "select $index_field,$display_field from $table";
827
     } else { // in the two parameter form, first parameter is query, second is keyvalue
828
        $sql = $table; 
829
        $keyvalue = $index_field;
830
     }
831
     $data = queryDatabaseExtended($sql);
832
     #$data = $data['data'];
833
     #$data = mysql_query($sql) or die(mysql_error());
834
     #while($info = mysql_fetch_array( $data ))  {
835
     $index_field = $data['meta'][0]['name'];
836
     $display_field = $data['meta'][1]['name'];
837
     foreach ($data['data'] as $info) {
838
        $returnValue .= "<option value='" . $info[$index_field] . "'";
839
        if ( $info[$index_field] == $keyvalue ) { 
840
           $returnValue .= ' selected' ; 
841
        }
842
        $returnValue .= '>' . $info[$display_field] . "</option>\n";
843
     }
844
     return $returnValue;
845
  }
846
 
847
  function makeMultiSelect ( $thisTable, $thisKeyfield, $thisValue, $multiSelectDefinition ){
848
      /*
849
         This is some funky code that creates a multi select box for when the current table has a one to many relationship
850
         with another table through an intermediate table, ie professionals joined to projects through an intermediate table,
851
         professionals_projects.
852
 
853
         It creates a query of the form
854
            select dislayfield, keyfield, nullfield
855
            from foreign_table left outer join
856
                  (this_table join joining_table on join_condition)
857
                  on join_condition
858
            where this_table.keyfield = this_record_id;
859
 
860
         Display Field generally comes from the foreign table, as does keyfield. A multi select box is created which contains
861
         the keyfield as the value and the display field displayed. If nullfield is not null, the item is option is selected.
862
 
863
         The following real world example may help:
864
            table professionals
865
                professionals_id (key field)
866
                name             (the name of the professional)
867
            table projects (the current one being edited)
868
                projects_id      (key field)
869
                other stuff
870
            table projects_professionals
871
               projects_id       (fk into projects)
872
               professionals_id   (fk into professionals)
873
         A query such as
874
            select professionals.professionals_id, professionals.name, professionals_projects.projects_id
875
            from professionals left outer join
876
                  (projects join professionals_projects on projects.project_id = professionals_projects.projects_id)
877
                  on professionals.professionals_id = professionals_projects.professionals_id
878
            where projects.project_id = $id;
879
         would return a row for every entry in the professionals table, but with a null value in the projects_id
880
         column if there was no matching entry in the professionals_projects table. This can be used to build
881
         the select
882
      */
883
      if ($thisValue) {
884
         // first build the query
885
         $sql = 'select ';
886
         $sql .= $multiSelectDefinition['values table']['table name'] . '.' . $multiSelectDefinition['values table']['display field'] . ',' ;
887
         $sql .= $multiSelectDefinition['values table']['table name'] . '.' . $multiSelectDefinition['values table']['key field'] . ', ' ;
888
         $sql .= $multiSelectDefinition['null field'] . ' ';
889
         $sql .= 'from ' . $multiSelectDefinition['values table']['table name'] . ' left outer join (';
890
         $sql .= $thisTable . ' join ' . $multiSelectDefinition['join table']['table name'] . ' on ';
891
         $sql .= $multiSelectDefinition['join table']['join condition'] . ') on ';
892
         $sql .= $multiSelectDefinition['values table']['join condition'] . " where $thisTable.$thisKeyfield  = $thisValue";
893
      } else {
894
         $sql = 'select ';
895
         $sql .= $multiSelectDefinition['values table']['table name'] . '.' . $multiSelectDefinition['values table']['display field'] . ',' ;
896
         $sql .= $multiSelectDefinition['values table']['table name'] . '.' . $multiSelectDefinition['values table']['key field'] . ', ' ;
897
         $sql .= ' null ';
898
         $sql .= 'from ' . $multiSelectDefinition['values table']['table name'];
899
      }
900
      print "<pre>$sql</pre>";
901
      // now, run it
902
      $result = "\n<SELECT name='" . $multiSelectDefinition['values table']['table name'] . "[]' multiple>\n";
903
      $data = queryDatabaseExtended($sql);
904
      foreach ( $data['data'] as $info ) {
905
      #$data = mysql_query( $sql ) or die(mysql_error());
906
      #while ( $info = mysql_fetch_array( $data ) ) {
907
         /*
908
            we will refer to fields by number due to the inconsistency of labeling returned rows, ie the query may
909
            request table.fieldname or simply fieldname, but the result set will always call it simply fieldname
910
            since we control the query, we know that field 0 is the display name, field 1 is the keyfield and
911
            field 2 is the field that will be null or not
912
         */
913
         $result .= "<option value=" . $info[1] ;
914
         if ($info[2]) { $result .= " selected"; }
915
         $result .= '>' . $info[0] . "</option>\n";
916
      } // while
917
      $result .= "</SELECT>\n";
918
      return $result;
919
  }
920
 
921
   function editData ( $tableInfo, $id ) {
922
      $maxFileSize = min(HumanReadable2Number(MAX_UPLOAD_FILE_SIZE),HumanReadable2Number(ini_get("upload_max_filesize")));
923
      $result = '';
924
      $result .= "<p><form enctype='multipart/form-data' action='" . $_SERVER['PHP_SELF'] . "' method='post'>"; 
925
      $result .= "<input type='hidden' name='currentdb' value='" . $tableInfo['table name'] . "' />";
926
      $result .= "<input type='hidden' name='MAX_FILE_SIZE' value='$maxFileSize' />";
927
      $result .= '<table border="1">';
928
 
929
      $sql = "SELECT * FROM " . $tableInfo['table name'] . " where " . $tableInfo['key field'] . " = $id";
930
      #$data = mysql_query( $sql ) or die(mysql_error());
931
      #$info = mysql_fetch_array( $data ) or die(mysql_error());
932
      ######### FIX THIS
933
      $data = queryDatabaseExtended($sql);
934
      $info = $data['data'][0];
935
      foreach ($tableInfo['field info'] as $field => $value) {
936
         $displayName = $value['display name'] ? $value['display name'] : $field; 
937
         $result .= "<tr><td valign='top'>$displayName";
938
         if ( $value['type'] == 'file' ) {
939
            $result .= "<br><font size='-2'>Max Size " . Number2HumanReadable($maxFileSize) . "</font>";
940
         }
941
         $result .= "</td><td>";
942
         if ( $value['readonly'] ) {
943
            $result .= $info[$field];
944
         } else {
945
            if ( $value['type']  == 'string' ) {
946
               $maxWidth = $value['width'] or MAX_INPUT_FIELD_DISPLAY;
947
               $displayWidth = $maxWidth < MAX_INPUT_FIELD_DISPLAY ? $maxWidth : MAX_INPUT_FIELD_DISPLAY;
948
               $result .= "<input type='text' name='$field' size='$displayWidth' maxlength='$maxWidth' value='" . $info[$field] . "'>";
949
            } elseif ( $value['type'] == 'password') {
950
               $maxWidth = $value['width'] or MAX_INPUT_FIELD_DISPLAY;
951
               $displayWidth = $maxWidth < MAX_INPUT_FIELD_DISPLAY ? $maxWidth : MAX_INPUT_FIELD_DISPLAY;
952
               $result .= "<input type='text' name='$field' size='$displayWidth' maxlength='$maxWidth' value=''>";
953
            } elseif ( $value['type'] == 'text' ) {
954
               $width = $value['width'] ? $value['width'] : MAX_INPUT_FIELD_DISPLAY;
955
               $rows = $value['height'] or DEFAULT_TEXTAREA_HEIGHT;
956
               $result .= "<textarea name='$field' rows='$rows' cols='$width'>" . $info[$field] . "</textarea>";
957
            } elseif ( $value['type'] == 'file' ) {
958
               $result .= "<input type='hidden' name='MAX_FILE_SIZE' value='" . MAX_UPLOAD_FILE_SIZE . "' />";
959
               if ( $value['filetype'] == 'picture' ) {
960
                  $result .= "<img src='" . IMAGE_DIRECTORY . $info[$field] . "' height='" . EDIT_IMAGE_HEIGHT . "' alt='Image'>";
961
               }
962
               $result .= "<br>";
963
               $result .= "<input type='file' name='$field' value='" . $info[$field] . "'>";
964
            } elseif ( $value['type']  == 'lookup' ) {
965
               $result .= "<select name='$field'>";
966
               if ( $value['null_ok'] ) {
967
                  $result .= '<option value="' . CONSTANT_NO_VALUE_DROPDOWN . '">' . CONSTANT_NO_VALUE_DROPDOWN . '</option>';
968
               }
969
               if ($value['query']) { // they want to pass a query, so we'll do that. Query has key in first column, display in second
970
                  $result .= makeDropDown ($value['query'], $info[$field] );
971
               } else { // no query, so we give the table name, keyfield, and display field
972
                  $result .= makeDropDown ( $value['table'], $value['keyfield'], $value['display_field'], $info[$field] );
973
               } 
974
               $result .= "</select>";
975
            } elseif ( $value['type']  == 'bool' ) {
976
               $result .= "<input type='radio' name='$field' value='1'";
977
               if ( $info[$field] ) {
978
                  $result .= ' checked';
979
               }
980
               $result .= ">True<input type='radio' name='$field' value='0'";
981
               if ( ! $info[$field] ) {
982
                  $result .= ' checked';
983
               }
984
               $result .= ">False";
985
            } else {
986
               $result .= "<input type='text' name='$field' value='" . $info[$field] . "'>";
987
            }
988
         }
989
         $result .= "</td></tr>\n";
990
      }
991
 
992
      global $DATABASE_DEFINITION;
993
      // process any multi selects we may have
994
      if ($tableInfo['complex join']) { 
995
         foreach ($tableInfo['complex join'] as $table => $value) {
996
            if ($value['values table']['key field']) {
997
               $valueQuery = 'select ' . $value['values table']['key field'] . ',' . $value['values table']['display field'] . ' from ' . $value['values table']['table name'];
998
            } else {
999
               $valueQuery = $DATABASE_DEFINITION[$value['values table']['table name']]['display query'];
1000
            }
1001
            $selectedFieldsQuery = 'select ' .  $value['join table']['values link'] .  ' from ' .  $value['join table']['table name'] . ' where ' . $value['join table']['my link'] . " = $id";
1002
#            $result .= makeMultiSelect( $tableInfo['table name'], $tableInfo['key field'], $id, $value);
1003
            $result .= "<tr><td>$table</td><td>\n";
1004
            $result .= "\n<SELECT name='" . $value['values table']['table name'] . "[]' multiple>";
1005
            $result .= queryToSelect( $valueQuery, $selectedFieldsQuery);
1006
            $result .= '</select>';
1007
            $result .= '</td></tr>';
1008
         } // foreach
1009
      } // if
1010
 
1011
 
1012
      $result .= "<tr><td colspan='2' align='center'><input type='submit' /></td></tr> 
1013
      <input type=hidden name='mode' value='edited'> 
1014
      <input type=hidden name='id' value='"; 
1015
      $result .= $id; 
1016
      $result .= "'> 
1017
      </table> 
1018
      </form> <p>";
1019
      return $result;
1020
   } // editData
1021
 
1022
   function makeList( $currentDB, $sql, $display_list, $keyfield ) {
1023
     $result = '';
1024
     #$data = mysql_query($sql) or die(mysql_error()); 
1025
     $result .= "<table cellpadding=3>";
1026
     $result .= '<tr>';
1027
     foreach ($display_list as $field ) {
1028
        $result .= "<th>" . $field . "</th> "; 
1029
     }
1030
     $result .= "</tr>\n";
1031
     $result .= "<td colspan=5 align=right><a href=" .$_SERVER['PHP_SELF']. "?currentdb=$currentDB&mode=add>Add</a></td>";
1032
      $data = queryDatabaseExtended($sql);
1033
      foreach ( $data['data'] as $info ) {
1034
#     while($info = mysql_fetch_array( $data ))  {
1035
        $result .= '<tr>';
1036
        foreach ($display_list as $field ) {
1037
           $result .= "<td>" . $info[$field] . "</td> "; 
1038
        }
1039
        $result .= "<td><a href=" . $_SERVER['PHP_SELF'] . "?id=" . $info[$keyfield] .  "&currentdb=$currentDB&mode=edit>Edit</a></td>"; 
1040
        $result .= "<td><a href=" .$_SERVER['PHP_SELF']. "?id=" . $info[$keyfield] . "&currentdb=$currentDB&mode=remove>Remove</a></td></tr>";
1041
     } 
1042
     $result .= "</table>"; 
1043
     return $result;
1044
   }
1045
 
1046
   /* 
1047
      function is called after information is modified via the editData function above.
1048
      Strictly takes the information from the form, then updates the database.
1049
   */
1050
   function updateData( $tableInfo, $id ) {
1051
      $sql = '';    // we will build the resulting SQL here
1052
      $result = '';   // our output string, ie what we will be sending back to the calling routine
1053
      $fileName = ''; // used to store the modified file name, if the field has a file upload
1054
      // for each field in the table definition
1055
      foreach ($tableInfo['field info'] as $field => $value) {
1056
         if ( $value['type'] == 'file' && $_FILES[$field]['name'] ) {
1057
            $fileName = saveFilesUploaded( $field );
1058
            if ( ! $fileName ) { 
1059
               $result .=  "Error Saving File $field: " . FileErrorMessage($_FILES[$field]['error']) . "\n<br>";
1060
            }
1061
         }
8 rodolico 1062
         if ( isset($_POST[$field]) || $_FILES[$field]['name'] ) {
9 rodolico 1063
            if ( $value['type'] == 'password' && strlen($_POST[$field]) == 0 ) { // we don't update passwords unless they put something in
1064
               continue;
1065
            }
1 rodolico 1066
            if ( $sql ) { $sql .= ','; }   // put in a comma if we already have info in the $sql
1067
            $fieldList .= $field;
1068
            if ( $_POST[$field] ) {
1069
               if ( $_POST[$field] == CONSTANT_NO_VALUE_DROPDOWN ) {
1070
                  $sql .= $field . '= NULL';
1071
               } elseif ($value['type'] == 'password') {
1072
                  $sql .= $field . '=' . 'md5(' . makeQuerySafe($_POST[$field]) . ')';
1073
               } else {
1074
                  $sql .= $field . "=" . makeQuerySafe($_POST[$field]);
1075
               }
1076
            } else {
1077
               $sql .= $field . "=" . makeQuerySafe($fileName);
1078
            }
1079
         }
1080
      }
1081
      // the sql created above needs some stuff added, do that here. We will put the "update" and table name, then
1082
      // limit based upon the id passed in.
1083
      $result = doSQL( 'update '. $tableInfo['table name'] . ' set ' . $sql . " where " . $tableInfo['key field'] . " = $id " );
1084
      if ($tableInfo['complex join']) { // we possibly had a change in the multi table
1085
         foreach ($tableInfo['complex join'] as $table => $value) {
1086
            $result .= doSQL ('delete from ' . $value['join table']['table name'] . ' where ' . $value['join table']['my link'] . '=' . $id );
1087
            $currentItem = $value['values table']['table name'];
1088
            $items = $_POST[$currentItem];
1089
            $sql = '';
1090
            foreach ( $items as $item => $secondary_key ) {
1091
               $result .= doSQL(
1092
                                 'insert into ' . $value['join table']['table name'] . '(' .
1093
                                 $value['join table']['values link'] . ',' . $value['join table']['my link'] .
1094
                                 ") values ($secondary_key, $id)"
1095
               );
1096
            }
1097
         } // foreach
1098
      } // if
1099
      // return the sql generated to the calling routine so they can print it if they want.
1100
      return $result;
1101
   }
1102
 
1103
   /*
1104
      function is called after addData. This does the actual insert into the database
1105
   */
1106
   function insertData ( $tableInfo ) {
1107
      $result = '';
1108
      $sql = '';
1109
      $fieldList = '';
1110
      $valueList = '';
1111
      $fileName = '';
1112
      foreach ($tableInfo['field info'] as $field => $value) {
1113
         if ( $value['type'] == 'file' && $_FILES[$field]['name'] ) {
1114
            $fileName = saveFilesUploaded( $field );
1115
            if ( ! $fileName ) { 
1116
               $result .=  "Error Saving File $field: " . FileErrorMessage($_FILES[$field]['error']) . "\n<br>";
1117
            }
1118
         }
1119
         if ( $_POST[$field] || $_FILES[$field]['name'] ) {
1120
            if ( $fieldList ) { 
1121
               $fieldList .= ','; 
1122
               $valueList .= ', '; 
1123
            }
1124
            $fieldList .= $field;
1125
            if ( $_POST[$field] ) {
1126
               if ( $value['type'] == 'password' ) {
1127
                  $valueList .= 'md5(' . makeQuerySafe($_POST[$field]) . ')';
1128
               } else {
1129
                  $valueList .= makeQuerySafe($_POST[$field]);
1130
               }
1131
            } else {
1132
               $valueList .= makeQuerySafe($fileName);
1133
            }
1134
         }
1135
      }
1136
      $result = doSQL( "Insert into " . $tableInfo['table name'] . "($fieldList) values ($valueList)" );
1137
      if ($tableInfo['complex join']) { // we possibly had a change in the multi table
1138
         foreach ($tableInfo['complex join'] as $table => $value) {
1139
            $result .= doSQL ('delete from ' . $value['join table']['table name'] . ' where ' . $value['join table']['my link'] . '=' . $id );
1140
            $currentItem = $value['values table']['table name'];
1141
            $items = $_POST[$currentItem];
1142
            $sql = '';
1143
            foreach ( $items as $item => $secondary_key ) {
1144
               $result .= doSQL(
1145
                                 'insert into ' . $value['join table']['table name'] . '(' .
1146
                                 $value['join table']['values link'] . ',' . $value['join table']['my link'] .
1147
                                 ") values ($secondary_key, $id)"
1148
               );
1149
            }
1150
         } // foreach
1151
      } // if
1152
      return $result;
1153
   }
1154
 
1155
 
1156
   function doAdmin() {
1157
      global $DATABASE_DEFINITION;
1158
      foreach ( $DATABASE_DEFINITION as $key => $field ) {
1159
        print '<li><a href=' . $_SERVER['PHP_SELF'] . '?currentdb=' . $field['table name'] . '>' . ($field['display name'] ? $field['display name'] : $field['table name']) . '</a></li>';
1160
      }
1161
      print '</ul>';
1162
 
1163
      $currentDB = $_GET['currentdb'];
1164
      if (! $currentDB ) {
1165
        $currentDB = $_POST['currentdb'];
1166
        if (! $currentDB ) {
1167
            $currentDB = DEFAULT_TABLE;
1168
        }
1169
      }
1170
      $dbDisplayName = $DATABASE_DEFINITION[$currentDB]['display name'] ? $DATABASE_DEFINITION[$currentDB]['display name'] : $currentDB;
1171
      // load our two global parameters, check for get, then post
1172
      $id = $_GET['id'];
1173
      $mode = $_GET['mode'];
1174
      if (! $id ) { $id = $_POST['id']; }
1175
      if (! $mode ) { $mode = $_POST['mode']; }
1176
      $mode = escapeshellcmd( $mode );
1177
      $id = escapeshellcmd( $id );
1178
 
1179
      if ( $mode=="add") {
1180
         Print '<h2>Add $dbDisplayName</h2>';
1181
         print addData( $DATABASE_DEFINITION[$currentDB] );
1182
      } 
1183
 
1184
      if ( $mode=="added") 
1185
      {
1186
        print insertData( $DATABASE_DEFINITION[$currentDB] );
1187
        print "Record Added";
1188
      }
1189
      if ( $mode=="edit") 
1190
      { 
1191
        print "<h2>Edit $dbDisplayName</h2>";
1192
        print editData( $DATABASE_DEFINITION[$currentDB], $id );
1193
      } 
1194
 
1195
      if ( $mode=="edited") { 
1196
      updateData( $DATABASE_DEFINITION[$currentDB], $id );
1197
      Print "$currentDB Updated!<p>";
1198
      }
1199
      if ( $mode=="remove") {
1200
        print deleteData( $DATABASE_DEFINITION[$currentDB], $id );
1201
        Print "$currentDB has been removed <p>";
1202
      }
1203
      Print "<h2>$dbDisplayName</h2><p>";
1204
 
1205
      print makeList( $currentDB, $DATABASE_DEFINITION[$currentDB]['display query'], $DATABASE_DEFINITION[$currentDB]['display columns'], $DATABASE_DEFINITION[$currentDB]['key field'] );
1206
   }
1207
 
1208
/*
1209
   function will encrypt $message using the key whose fingerprint is $key_fingerprint
1210
   in the gpg store in $homedir.
1211
 
1212
   To get the fingerprint of a key, execute
1213
      gpg --homedir $homedir --fingerprint (replacing $homedir with the .gpg directory)
1214
 
1215
   returns the encrypted string, or false if there was an error
1216
 
1217
   Ensure $homedir can be read by the web server
1218
 
1219
   Note, this function requires the PHP interface to gpgme be installed. It is named
1220
   gnupg, and is available with the following command:
1221
      pecl install gnupg (then, install in php.ini as the instructions say)
1222
   Under Debian and Ubuntu, you must have the php dev and gpgme packages installed also
1223
      apt-get install php5-dev libgpgme11-dev libgpg-error-dev libgpgme11
1224
 
1225
  Example:
1226
  print gpg_encrypt_information( '76DDD066339769A61F0FF8EEB9563752960C9534', 
1227
                                 'just a test',
1228
                                 '/home/http/.gnupg' );
1229
 
1230
*/
1231
function gpg_encrypt_information( $key_fingerprint, $message, $gpgdir = '' ) {
1232
  if (strlen($gpgdir) == 0 ) {
1233
     $gpgdir = GPGDIR;
1234
  }
1235
  putenv("GNUPGHOME=$gpgdir");
1236
  $res = gnupg_init();
1237
  //print "$res<br>\n";
1238
  if ( gnupg_addencryptkey($res,$key_fingerprint) ) {
1239
    $enc = gnupg_encrypt($res, $message);
1240
    return $enc;
1241
  } else { // we failed somewhere
1242
    print "Failed to find key in $homedir for key $key_fingerprint<br>\n";
1243
    return false;
1244
  }
1245
} // function gpg_encrypt_information
1246
 
1247
// if worker_id is null and the file we are calling is not login,
1248
// redirect to login
1249
 
1250
/*if ( ! $_SESSION['worker_id'] && basename($_SERVER['PHP_SELF']) != $LOGIN_PAGE) {
1251
   redirectPage($LOGIN_PAGE,array('message'=>'Session Timeout, Please Log In'));
1252
}*/
1253
 
1254
 
1255
?>