Subversion Repositories php_library

Rev

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

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