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