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