From: Anthony Talarico Date: Thu, 31 Mar 2016 14:06:40 +0000 (-0400) Subject: setting up flight data files X-Git-Url: http://cvs2.gaslightmedia.com/gitweb/index.cgi?a=commitdiff_plain;h=4e4aa858e8f864a99c45a378a241b672696affe5;p=prog%2FPelstonFlightData.git setting up flight data files --- diff --git a/functions.inc b/functions.inc new file mode 100755 index 0000000..ae70eea --- /dev/null +++ b/functions.inc @@ -0,0 +1,10633 @@ + 0 + +function debug_mail( $to, $subject, $message, $headers = '', $parameters = '' ) + { + + if( SI_DEBUG_MAIL ) + { + echo '

+ + + + + + + +
MAIL DEBUG
Recipient(s): '.$to.'
Subject: '.$subject.'
Headers:
'.$headers.'
Parameters:
'.$parameters.'
'.$message.'
+

+ '; + return( true ); + } + else + return( mail( $to, $subject, $message, $headers, $parameters ) ); + + } + + +/*********************************************************************** +* * +* FUNCTIONS FROM SETUP.PHP * +* * +***********************************************************************/ + +function cp1252_to_utf8($str) + { + global $cp1252_map; + return strtr(utf8_encode($str), $cp1252_map); + } + +/*********************************************************************** +* * +* GENERAL FUNCTIONS * +* * +***********************************************************************/ + + // Check for a valid credit card number doing Luhn check + +function CreditVal( $Num, $Name = '', $Accepted='' ) + { + $GoodCard = 1; + $Num = ereg_replace("[^[:digit:]]", "", $Num); + switch ($Name) + { + case "mastercard" : + $GoodCard = ereg("^5[1-5].{14}$", $Num); + break; + + case "visa" : + $GoodCard = ereg("^4.{15}$|^4.{12}$", $Num); + break; + + case "americanexpress" : + $GoodCard = ereg("^3[47].{13}$", $Num); + break; + + case "discover" : + $GoodCard = ereg("^6011.{12}$", $Num); + break; + + case "dinnerscard" : + $GoodCard = ereg("^30[0-5].{11}$|^3[68].{12}$", $Num); + break; + + default: + if( ereg("^5[1-5].{14}$", $Num) ) $Name = "mastercard"; + elseif( ereg("^4.{15}$|^4.{12}$", $Num) ) $Name = "visa"; + elseif( ereg("^3[47].{13}$", $Num) ) $Name = "americanexpress"; + elseif( ereg("^6011.{12}$", $Num) ) $Name = "discover"; + elseif( ereg("^30[0-5].{11}$|^3[68].{12}$", $Num) ) $Name="dinerscard"; + break; + } + + // If there's a limit on card types we accept, check for it here. + + if( $Accepted ) + { + $type_verified = FALSE; + $brands = explode_trim( ",", $Accepted ); + foreach( $brands as $brand ) + if( $Name == $brand ) + $type_verified = TRUE; + + if( !$type_verified ) return(FALSE); + } + + $Num = strrev($Num); + $Total = 0; + + for ($x=0; $xERROR: credit_card_check() requires SI_CC_ACCCEPTS parameter!

"; + exit; + } + + // Permit secret test code + + if( $Num == "0011001100110011" ) + return( "Test" ); + else + { + // Check each selected card type for a pattern match + $Name = ""; + reset( $si_cc_verify ); + $i = 0; + while( list($k, $v) = each($si_cc_verify) ) + if( ( $accepted & pow(2,$i++) ) && ereg( $v, $Num ) ) + { + $Name = $k; + break; + } + } + + // Fail if nothing matched + + if( $Name == "" ) + return( FALSE ); + + // Now do strong test + + $Num = strrev($Num); + + $Total = 0; + + for ($x=0; $x= 3 ) echo "

db_connect() - Using existing connection - \$conn_str = ".$conn_str."

"; + return( $ret ); + } + + // If we need to open a different connection, close the current one first + + if( $ret != 0 ) + db_close( $ret ); + + $last_connect = $conn_str; + + } + + if( SI_DEBUG >= 3 ) echo "
db_connect()[".__LINE__."]: \$conn_str = ".$conn_str."

"; + + switch( SI_DB_TYPE ) + { + case "postgres": + $ret = pg_connect( $conn_str ); + break; + default: + return( 0 ); + } + + if( !$ret && $fail_mode ) + html_error( DB_ERROR_MSG, 1 ); + + return( $ret ); + +} + + // Close the connection to database specified by the handle dbd + +function db_close( $dbd ) +{ + + // IF we're using static connections, don't actually close it + + if( SI_DB_STATIC == TRUE ) + return( TRUE ); + + switch( SI_DB_TYPE ) + { + case "postgres": + $ret = pg_close( $dbd ); + break; + default: + return( 0 ); + } + + return( $ret ); +} + + // Create a persistant connection to database specified in $conn_str + +function db_pconnect( $conn_str ) +{ + + if( SI_DEBUG >= 3 ) echo "
db_cponnect()[".__LINE__."]: \$conn_str = ".$conn_str."

"; + + switch( SI_DB_TYPE ) + { + case "postgres": + $ret = pg_pconnect( $conn_str ); + break; + default: + return( 0 ); + } + + return( $ret ); +} + + + // Execute an SQL query + +function db_exec( $dbd, $qs ) +{ + + if( SI_DEBUG >= 3 ) echo "
db_exec()[".__LINE__."]: \$qs = ".$qs."

"; + + switch( SI_DB_TYPE ) + { + case "postgres": + $ret = pg_exec( $dbd, $qs ); + break; + + default: + return( 0 ); + } + + return( $ret ); +} + + // Get data and store in associative indices, using the field names as keys. + +function db_fetch_row( $res, $i ) +{ + + if( SI_DEBUG >= 3 ) echo "
db_fetch()[".__LINE__."]: Row = ".$i."

"; + + if( db_numrows($res) == 0 ) + return( FALSE ); + + switch( SI_DB_TYPE ) + { + case "postgres": + $row = pg_fetch_array( $res, $i, PGSQL_ASSOC ); + break; + + default: + return( FALSE ); + } + + return( $row ); + +} + + // Free result memory. + +function db_freeresult( $res ) +{ + + switch( SI_DB_TYPE ) + { + case "postgres": + $ret = pg_freeresult( $res ); + break; + + default: + return( 0 ); + } + + return( $ret ); +} + + // Determine number of rows in a result index + +function db_numrows( $res ) +{ + + switch( SI_DB_TYPE ) + { + case "postgres": + $ret = pg_numrows( $res ); + break; + + default: + return( -1 ); + } + + return( $ret ); +} + + // Additional Database functions from setup.php - Don't use for new code + +function db_fetch_array($res, $i, $type) +{ + + switch (DB_TYPE) + { + case "postgres": + $row = pg_fetch_array($res, $i, $type); + break; + + default: + return(0); + } + + return($row); +} + +function db_auto_array($qs, $i, $type) +{ + + $dbd = db_connect(); + if(!$dbd) + { + return(0); + } + $res = db_exec($dbd, $qs); + if(!$res) + { + return(0); + } + + $row = db_fetch_array($res, $i, $type); + + if(!db_freeresult($res)) + { + return(0); + } + + db_close($dbd); + return($row); +} + +/*********************************************************************** + * + * BEGIN Auto functions + * + ***********************************************************************/ + + // Retrieve a result as an array based soley on a query + +function db_auto_get_row( $qs, $i = 0, $conn_str = SI_CONN_STR, $fail_mode = 'FALSE' ) +{ + + if( SI_DEBUG >= 2 ) echo "
db_auto_get_row()[".__LINE__."]: \$qs = $qs, Row = $i

"; + + if( !($dbd = db_connect( $conn_str, $fail_mode )) ) + return( FALSE ); + + if( ($res = db_exec($dbd, SI_DB_SET_DATE_STYLE_STRING.$qs)) ) + { + $row = db_fetch_row( $res, $i ); + db_freeresult( $res ); + } + + db_close( $dbd ); + return( $row ); +} + + + // Retrieve a set of results based soley on a query + +function db_auto_get_data( $qs, $conn_str = SI_CONN_STR, $fail_mode = FALSE, $rows = 500, $start = 0 ) +{ + + if( SI_DEBUG >= 2 ) echo "
db_auto_get_data()[".__LINE__."]: \$qs = $qs, \$rows = $rows, \$start = $start

"; + + if( !($dbd = db_connect( $conn_str, $fail_mode)) ) + return( FALSE ); + + if( ($res = db_exec($dbd, SI_DB_SET_DATE_STYLE_STRING.$qs)) ) + { + $totalrows = pg_NumRows( $res ); + $stop = $start + $rows; + if( $stop > $totalrows ) + $stop = $totalrows; + + for( $i=$start ; $i<$stop ; $i++ ) + { + $data["$i|$totalrows"] = db_fetch_row( $res, $i ); + } + } + db_close( $dbd ); + + return( $data ); +} + + // Execute a query. + +function db_auto_exec( $qs, $conn_str = SI_CONN_STR, $fail_mode = 'FALSE' ) +{ + + if( SI_DEBUG >= 2 ) echo "
db_auto_exec()[".__LINE__."]: \$qs = $qs, \$conn_str = $conn_str

"; + + $dbd = db_connect( $conn_str, $fail_mode ); + if( !$dbd ) + return( 0 ); + + if( !( $result = db_exec($dbd, $qs)) ) + { + db_close( $dbd ); + return( 0 ); + } + else + { + $oid = pg_getlastoid( $result ); + db_close( $dbd ); + if( empty($oid) || $oid == -1 ) + return( 1 ); + else + return( $oid ); + } +} + + // Get information on database fields + +function db_data_fields( $conn_str, $table ) +{ + $dbd = db_connect( $conn_str, FALSE ); + if( !$dbd ) + return( 0 ); + + $qs = "SELECT * FROM $table LIMIT 1;"; + $res = db_exec( $dbd, $qs ); + for( $i=0 ; $i 0 ) + echo "file_upload(): temp file = $form_field, file name = $file_name"; + + // Get rid of screwy characters in file names + + if( ereg( '[!@#$%^&()+={};: ]', $file_name ) ) + $file_name = ereg_replace( "[!@#$%^&()+={};: ]", "x", $file_name ); + + // Check if destination path is valid + + if( !is_dir( $base_path ) ) + die( $base_path." not a directory" ); + + // Check if file name is in use + + $new_file_name = $file_name; + if( file_exists( $base_path."/".$file_name ) ) // If so + $new_file_name = mktime()."_".$file_name; // Prefix with timestamp + + // Save file to destination directory + + $new_file_location = $base_path."/".$new_file_name; + + if( SI_DEBUG > 0 ) + echo ", new file name = $new_file_location
"; + + copy( $form_field, $new_file_location ); + chmod( $new_file_location, 0664 ); + + // Return where it was stored + + return( $new_file_name ); +} + + // Duplicate a file + +function file_duplicate( $file_name, $base_path = SI_BASE_FILE_PATH ) +{ + + if( empty($file_name) ) + return( "" ); + + // Check to see if specified file exists + + if( !is_file($base_path."/".$file_name) ) + return( "" ); + + // Create new file name + + for( $i=1 ; $i<1000 ; $i++ ) + { + if( !is_file($base_path."/"."c".$i."_".$file_name) ) + break; + } + + if( $i == 1000 ) + return( "" ); + + $new_file_name = "c".$i."_".$file_name; + + copy( $base_path."/".$file_name, $base_path."/".$new_file_name ); + + return( $new_file_name ); +} + + + + // Delete a stored File + +function file_delete( $file_name, $base_path = SI_BASE_FILE_PATH ) +{ + + if( !is_writable ( $base_path."/".$file_name ) ) + return( FALSE ); + + if( !is_file($base_path."/".$file_name) || !unlink($base_path."/".$file_name) ) + return( FALSE ); + + return( TRUE ); +} + + + // Read the specified file and return the results + +function file_get( $file_name, $max_size = 0, $base_path = SI_BASE_PATH ) +{ + + if( !is_readable ( $base_path."/".$file_name ) ) + return( FALSE ); + + $f = fopen( $base_path."/".$file_name, "r" ); + $s = filesize($base_path."/".$file_name); + if( $max_size == 0 || $s <= $max_size ) + $file_contents = fread( $f, $s ); + else + return( FALSE ); + + return( $file_contents ); +} + + +function file_ouput_secure( $file_name, $md5, $path = '' ) +{ + + // Check for required secret string + + if( !defined('SI_FILE_SECRET') || SI_FILE_SECRET == '' ) + { + echo '

ERROR: SI_FILE_SECRET parameter required for file_output_secure()
+ SI_FILE_SECRET defined parameter not found or no contents! Please check siteinfo.inc file.

'; + exit; + } + + // Check sanity of parameters + + if( empty($file_name) ) + { + if( SI_DEBUG > 0 ) echo 'file_output_secure(): No file name supplied
'; + return( false ); + } + + if( ereg( '\.\./', $file_name ) ) // Note that strpos function is defective so it's not used here + { + if( SI_DEBUG > 0 ) echo 'file_output_secure(): "../" not permitted in file name
'; + return( false ); + } + + if( empty($md5) || $md5 != md5( $file_name.SI_FILE_SECRET ) ) + { + if( SI_DEBUG > 0 ) echo 'file_output_secure(): md5 security parameter is not supplied or is not valid for $file_name
'; + return( false ); + } + + // Assemble complete file path and name + + if( empty($path) ) + $pathname = SI_BASE_FILE_PATH.'/'.$file_name; + else + $pathname = SI_BASE_PATH.'/'.$path.'/'.$file_name; + + // Make sure file exists and is readable + + if( !is_readable( $pathname ) ) + { + if( SI_DEBUG > 0 ) echo 'file_output_secure(): Specified file doesn\'t exist or is unreadable - '.$pathname.'
'; + return( false ); + } + + + // Get mime type for specified file + + $mimetype = shell_exec( 'file -bi '.$pathname ); + $length = filesize( $pathname ); + + // Output File + + header( "Content-type: $mimetype" ); + header( "Content-Length: $length" ); + header( "Content-Disposition: inline; filename=$file_name" ); + readfile( $pathname ); + + // Since output was successful, don't return, just quit + + exit; + +} + + +/*********************************************************************** +* * +* GRAPHICS FUNCTIONS * +* * +***********************************************************************/ + + // Return information about an image + +function img_info( $path2image ) +{ + + $type = array + ( + 1 => 'GIF', + 2 => 'JPG', + 3 => 'PNG', + 4 => 'SWF', + 5 => 'PSD', + 6 => 'BMP', + 7 => 'TIFF(intel byte order)', + 8 => 'TIFF(motorola byte order)', + 9 => 'JPC', + 10 => 'JP2', + 11 => 'JPX', + 12 => 'JB2', + 13 => 'SWC', + 14 => 'IFF', + 15 => 'WBMP', + 16 => 'XBM' + ); + + if( file_exists($path2image) ) + { + $i = GetImageSize( $path2image ); + $r['width'] = $i[0]; + $r['height'] = $i[1]; + $r['type_num'] = $i[2]; + $r['type'] = $type[$i[2]]; + $r['size'] = $i[3]; + $r['bits'] = $i[4]; + $r['channels'] = $i[5]; + + return( $r ); + } + else + return( FALSE ); +} + + + // Create a thumbnail image based on a full scale jpeg or gif + +function graphic_thumb($img, $timg, $type) +{ + switch( $type ) + { + case "image/gif": + $cmd = SI_GRPH_GIFTOPNM." $img | ".SI_GRPH_PNMSCALE." -height ".SI_THEIGHT." | ".SI_GRPH_PPMQUANT." 256 | ".SI_GRPH_PPMTOGIF." -interlace > $timg"; + break; + + case "image/jpeg": + $cmd = SI_GRPH_DJPEG." $img | ".SI_GRPH_PNMSCALE." -height ".SI_THEIGHT." | ".SI_GRPH_CJPEG." -outfile $timg"; + break; + + default: + echo "

Graphic type not defined: type $type

\n"; + + /* we can only do gifs and jpegs at this point. + * png would be a nice addition + */ + + return( 0 ); + } + exec( $cmd ); + return( 1 ); +} + + + // Creates a resized image based on a full scale jpeg or gif + +function graphic_resize( $img, $timg, $type, $w, $h ) +{ + switch ( $type ) + { + case "image/gif": + $cmd = SI_GRPH_GIFTOPNM." $img | "; + + if( $w && $h ) + $cmd .= SI_GRPH_PNMSCALE." -width $w -height $h |"; + elseif( $h ) + $cmd .= SI_GRPH_PNMSCALE." -height $h |"; + elseif( $w ) + $cmd .= SI_GRPH_PNMSCALE." -width $w |"; + $cmd .= SI_GRPH_PPMQUANT." 256 | ".SI_GRPH_PPMTOGIF." -interlace > $timg"; + break; + + case "image/jpeg": + $cmd = DJPEG." $img | "; + if( $w && $h ) + $cmd .= SI_GRPH_PNMSCALE." -width $w -height $h |"; + elseif( $h ) + $cmd .= SI_GRPH_PNMSCALE." -height $h |"; + elseif( $w ) + $cmd .= SI_GRPH_PNMSCALE." -width $w |"; + $cmd .= CJPEG." -outfile $timg"; + + break; + + case "image/pjpeg": + $cmd = DJPEG." $img | "; + + if( $w && $h ) + $cmd .= SI_GRPH_PNMSCALE." -width $w -height $h |"; + elseif( $h ) + $cmd .= SI_GRPH_PNMSCALE." -height $h |"; + elseif( $w ) + $cmd .= SI_GRPH_PNMSCALE." -width $w |"; + $cmd .= CJPEG." -outfile $timg"; + + break; + + default: + echo "

Graphic type not defined: type $type

\n"; + /* we can only do gifs and jpegs at this point. + * png would be a nice addition + */ + return( 0 ); + } + exec( $cmd ); + return( 1 ); +} + + + // Resize an image based on a full scale jpeg or gif + +function img_resize( $path2image, $path2thumb, $axis, $size ) +{ + $imageName = basename( $path2image ); + $thumbName = basename( $path2thumb ); + + if( TRUE ) // Not testing submitted file type at this time + { + $imageAttributes = GetImageSize( $path2image ); + $imageWidth = $imageAttributes[0]; + $imageHeight = $imageAttributes[1]; + if( $imageWidth < $size && $imageHeight < $size ) + { + exec( "cp $path2image $path2thumb" ); + chmod( $path2thumb, 0664 ); + } + else + { + if( ($axis == "h" || $axis == "a") && ($imageHeight > $imageWidth) ) + exec( SI_GRPH_CONVERT." -geometry $size $path2image $path2thumb" ); + if( ($axis == "w" || $axis == "a") && ($imageWidth >= $imageHeight) ) + exec( SI_GRPH_CONVERT." -geometry $size $path2image $path2thumb"); + } + + $img_resize_array = array( "$imageName", "$path2image", "$thumbName", "$path2thumb" ); + return( $img_resize_array ); + } + else + { + echo '' + .'Unable to complete Resize Function, The file being processed is not an acceptable image file. Please use only .GIF or .JPG files' + .'
' + .'
' + ."Hit your browser's back button to continue" + .'

'; + $error[0] = "ERROR"; + return( $error ); + } +} + + // Upload an image + +function img_upload( $form_field,$img_name,$destination_path ) +{ + + if (ereg('[!@#$%^&()+={};:\'\\ ]', $img_name)) + { + $img_name = ereg_replace("[!@#$%^&()+={};:'\\ ]", "x", $img_name); + $dumb = "dumber"; + } + + if( TRUE ) // Huh? - Oh, need to check for legal image type at some point + { + $i = "0"; + + // Check for valid destination path + + if( !is_dir($destination_path) ) + die( $destination_path." not a directory" ); // This is totally fatal + + // Get entries in that directory and check if the supplied name is in use + + $d = dir( $destination_path ); + $img_name_in_use = "FALSE"; + while ($entry = $d->read()) + { + if ($entry == $img_name) + { + $img_name_in_use = "TRUE"; + } + ++ $i; + } + + $d->close(); + + // If the name is in use, give it a name that can't match anything + + if( $img_name_in_use == "TRUE" ) + { + $new_img_name = mktime().$img_name; + $new_img_location = $destination_path.'/'.$new_img_name; + + // And store the image in the destination + + copy( $form_field, $new_img_location ); + chmod( $new_img_location, 0664 ); + $img_upload_array = array( "$new_img_name", "$new_img_location" ); + } + else + { + // Otherwise, supplied name is fine + + $new_img_name = $img_name; + $new_img_location = $destination_path.'/'.$new_img_name; + + copy( $form_field, $new_img_location ); + chmod( $new_img_location, 0664 ); + $img_upload_array = array( "$new_img_name", "$new_img_location" ); + } + } + else // Can't get here right now + { + echo ''.'The file you uploaded was of an incorrect type, please only upload .GIF or .JPG files'.'
'.'
'."Hit your browser's back button to continue".'

'; + $error[0] = "ERROR"; + return ($error); + } + + return( $img_upload_array ); +} + + // Main image processing function + +function process_image( $image, $image_name, $resized_size = SI_RESIZED_SIZE, + $midsized_size = SI_MIDSIZED_SIZE, $thumb_size = SI_THUMB_SIZE ) +{ + + // Check for paths + + if( !defined("SI_IMG_ORIGINAL_PATH") ) + html_error( "not defined SI_IMG_ORIGINAL_PATH", 1 ); + if( !defined("SI_IMG_RESIZED_PATH") ) + html_error( "not defined SI_IMG_RESIZED_PATH", 1 ); + if( !defined("SI_IMG_MIDSIZED_PATH") ) + html_error( "not defined SI_IMG_MIDSIZED_PATH", 1 ); + if( !defined("SI_IMG_THUMB_PATH") ) + html_error( "not defined SI_IMG_THUMB_PATH", 1 ); + + if( !defined("SI_RESIZED_SIZE") ) + html_error( "not defined SI_RESIZED_SIZE",1 ); + if( !defined("SI_MIDSIZED_SIZE") ) + html_error( "not defined SI_MIDSIZED_SIZE",1 ); + if( !defined("SI_RESIZED_SIZE") ) + html_error( "not defined SI_THUMB_SIZE",1 ); + + if( !($image_upload_array = img_upload($image, $image_name, SI_IMG_ORIGINAL_PATH)) ) + html_error( "image could not be uploaded", 1 ); + + // Resize image using progressively smaller images as the source to minimize work + + img_resize( $image_upload_array[1], SI_IMG_RESIZED_PATH."/".$image_upload_array[0], 'a', SI_RESIZED_SIZE ); + img_resize( SI_IMG_RESIZED_PATH."/".$image_upload_array[0], SI_IMG_MIDSIZED_PATH."/".$image_upload_array[0], 'a', SI_MIDSIZED_SIZE ); + img_resize( SI_IMG_MIDSIZED_PATH."/".$image_upload_array[0], SI_IMG_THUMB_PATH."/".$image_upload_array[0], 'a', SI_THUMB_SIZE ); + $image_name = $image_upload_array[0]; + + return( $image_name ); +} + + // Delete an image + +function delete_image( $image_name ) +{ + $ok = TRUE; + if( !is_file(SI_IMG_ORIGINAL_PATH."/".$image_name) || !unlink(SI_IMG_ORIGINAL_PATH."/".$image_name) ) + $ok = FALSE; + if( !is_file(SI_IMG_RESIZED_PATH."/".$image_name) || !unlink(SI_IMG_RESIZED_PATH."/".$image_name) ) + $ok = FALSE; + if( !is_file(SI_IMG_MIDSIZED_PATH."/".$image_name) || !unlink(SI_IMG_MIDSIZED_PATH."/".$image_name) ) + $ok = FALSE; + if( !is_file(SI_IMG_THUMB_PATH."/".$image_name) || !unlink(SI_IMG_THUMB_PATH."/".$image_name) ) + $ok = FALSE; + + return( $ok ); +} + + // Duplicate an image + +function duplicate_image( $image_name ) +{ + + if( empty($image_name) ) + return( "" ); + + // Check to see if specified image exists + + if( !is_file(SI_IMG_ORIGINAL_PATH."/".$image_name) ) + return( "" ); + + // Create new file name using "copy_" and timestamp + + for( $i=1 ; $i<100 ; $i++ ) + { + if( !is_file(SI_IMG_ORIGINAL_PATH."/"."p".$i."_".$image_name) ) + break; + } + + if( $i == 100 ) + return( "" ); + + $new_image_name = "p".$i."_".$image_name; + + copy( SI_IMG_ORIGINAL_PATH."/".$image_name, SI_IMG_ORIGINAL_PATH."/".$new_image_name ); + copy( SI_IMG_RESIZED_PATH."/".$image_name, SI_IMG_RESIZED_PATH."/".$new_image_name ); + copy( SI_IMG_MIDSIZED_PATH."/".$image_name, SI_IMG_MIDSIZED_PATH."/".$new_image_name ); + copy( SI_IMG_THUMB_PATH."/".$image_name, SI_IMG_THUMB_PATH."/".$new_image_name ); + + return( $new_image_name ); +} + + +/*********************************************************************** +* * +* GENERAL SUPPORT FUNCTIONS / CLASSES * +* * +***********************************************************************/ + +class timestampfunc +{ + + function newdate( $timestamp ) + { + $z = date( "m:Y", $timestamp ); + $z = split( ":", $z ); + return $z; + } + + function first_of_month( $timestamp ) + { + $z = $this->newdate( $timestamp ); + $first_of_month = $z[0]."/1/".$z[1]; + return strtotime( $first_of_month ); + } + + function first_last_month( $timestamp ) + { + $z = $this->newdate( $timestamp ); + $z[0]--; + if( $z[0] <= 0 ) + { + $z[0] = 12; + $z[1]--; + } + $first_of_month = ($z[0])."/1/".$z[1]; + return strtotime( $first_of_month ); + } + + function first_next_month( $timestamp ) + { + $z = $this->newdate( $timestamp ); + $z[0]++; + if( $z[0] > 12 ) + { + $z[0] = 1; + $z[1]++; + } + $first_of_month = ($z[0])."/1/".$z[1]; + return strtotime( $first_of_month ); + } + + function first_of_Xmonth( $timestamp, $x ) + { + $z = $this->newdate( $timestamp ); + $r = mktime( 0,0,0, ($z[0]+$x), 1, $z[1] ); + return $r; + } + +} + + + // Return Positive values only, otherwise 0 + +function pos_value( $value ) +{ + + if( $value > 0 ) + return( $value ); + return( 0 ); +} + + + // Format a number as US Dollars + +function money( $value, $option = "" ) +{ + + if( $option == "NOPREFIX" ) + $prefix = ""; + else + $prefix = "$"; + + // Do value sanity check + + if( !is_numeric( $value ) ) + return( $prefix."0.00" ); + + return( $prefix.number_format($value, 2, ".", "," ) ); +} + + + // Convert "key^value~key^value" string to an array + +function strtoarray( $s ) +{ + + $a = array(); + + // Create array of entries - If there's less than 2 entries, fail + + if( count($ea = explode( '~', $s )) < 2 ) + return( FALSE ); + + foreach( $ea as $e ) + { + // Each entry must have exactly 2 parts + + if( count($d = explode( "^", $e )) != 2 ) + return( FALSE ); + + $a[trim($d[0])] = trim($d[1]); + } + + return( $a ); +} + + + // Convert array to a "key^value~key^value" string + +function arraytostr( $a ) +{ + + $s = ''; + + // Supplied value must be array of 2 or more entries + + if( !is_array($a) || count($a) < 2 ) + return( FALSE ); + + $sep = ""; + + while( list($k,$v) = each($a) ) + { + $s .= $sep."$k^$v"; + $sep = '~'; + } + + return( $s ); +} + + + // Replace {tokens} + +function replace_tokens( $s, $tokens ) +{ + + if( !is_array($tokens) ) + { + echo '

ERROR: replace_tokens() - Parameter 2 ($tokens) is not an array

'; + exit; + } + + while( list($k,$v) = each($tokens) ) + { + $s = str_replace( "{".$k."}", $v, $s ); // Non ereg version - faster, case must match +// $s = eregi_replace( "\\{".$k."\\}", $v, $s ); // Ereg version + } + + return( $s ); + +} + + + // Conditionally replace tokens + +function cond_replace_tokens( $s, $tokens, $x="cond" ) +{ + + if( !is_array($tokens) ) + { + echo '

ERROR: cond_replace_tokens() - Parameter 2 ($tokens) is not an array

'; + exit; + } + + while( list($k,$v) = each($tokens) ) + { + $p0 = 0; // Reset starting pointer position + + while( ($start = strpos( $s, "", $start )) ) // Find end of {if:} tag + return( "ERROR: cond_replace_tokens() - Can't find end of {if:} tag at $start.

\n\n".htmlentities(substr($s,$start,500))."
" ); + + $p = $start + 8 + strlen($k); // Set position where "=" should be if it's used + $cond = substr($s,$p,1); + switch( $cond ) + { + case "=": + case "!": + case ">": + case "<": + $if_val_test = TRUE; // If valid comparison character? + $if_val = substr( $s, $p+1, $if_end-$p-1 ); + break; + default: + $if_val_test = FALSE; + break; + } + + // Separate out strings for both yes and no conditions + + $yes_start = $if_end + 4; // Point past tag + $ci = ""; // Closed {/if} take intro only if there's no {else} + $else_if = strpos( $s, "", $yes_start ); + if( $else_if && ( !$slash_if || ($else_if < $slash_if) ) ) // If there's an {else} + { + $yes_string = substr( $s, $yes_start, $else_if-$yes_start ); + $no_start = $else_if + 11 + strlen($k); // Point past tag + if( !($no_end = strpos( $s, "{/if:$k}-->", $no_start )) ) // If there's no --> end of cond tag + return( "ERROR: cond_replace_tokens() - Matching {/if:} tag not found after {else:} at $start for \"$k\".

\n\n".htmlentities(substr($s,$start,500))."
" ); + + $end = $no_end + 9 + strlen($k); + + $no_string = substr( $s, $no_start, $no_end-$no_start ); + } + else + { + $no_string = ""; + if( !($slash_if = strpos( $s, "", $yes_start )) ) // If there's no end of cond tag + return( "ERROR: cond_replace_tokens() - Matching {/if} tag not found at $start for \"$k\".

\n\n".htmlentities(substr($s,$start,500))."
" ); + $end = $slash_if + 13 + strlen($k); + $yes_string = substr( $s, $yes_start, $slash_if-$yes_start ); + } + + if( $if_val_test != FALSE ) // If there's a compare value, test with that + switch( $cond ) + { + case "=": + $t = ( trim($v) == trim($if_val) ); + break; + case "!": + $t = ( trim($v) != trim($if_val) ); + break; + case ">": + $t = ( trim($v) > trim($if_val) ); + break; + case "<": + $t = ( trim($v) < trim($if_val) ); + break; + default: + return( "ERROR: cond_replace_tokens() - Internal unknown conditional operator error ($cond)- Code Bad, fix code!" ); + } + else // otherwise just use token value + $t = ( trim($v) != "" ); // if it's not empty use yes_string + + if( $t ) // Replace with appropriate string + $s = substr_replace( $s, $yes_string, $start, $end-$start ); + else + $s = substr_replace( $s, $no_string, $start, $end-$start ); + } + else + $p0 = $start + 1; + } + $p0 = $start; + } + + return( $s ); + +} + + // Replace {file:xxx} token with a file + +function replace_file_tokens( $s ) +{ + + $p0 = 0; // Reset starting pointer position + + while( $p0 < strlen($s) && ($start = strpos( $s, "", $start )) ) // Find end of {file:} tag + return( "ERROR: replace_file_tokens() - Can't find end of {file:} tag at $start.

\n\n".htmlentities(substr($s,$start,500))."
" ); + + $filename = substr( $s, $start+10, $file_end-$start-10 ); // Get file name + // Check for a matching tag + + if( ($slash_file = strpos( $s, "", $file_end)) // If there's a {/file} tag + && !($next_file = strpos( $s, "" + } + + $end = $file_end + 4; + + // Check if file name is valid + + if( ($file_contents = file_get( $filename )) == FALSE ) + return( "ERROR: replace_file_tokens() - Can't load specified file '$filename' for {file:} tag.

\n\n".htmlentities(substr($s,$start,500))."
" ); + + $s = substr_replace( $s, $file_contents, $start, $end-$start ); + + $p0 = $end; + } + + return( $s ); + +} + + + // Convert an array of data to an HTML table + +function tableize_array($arr, $len=100 ) +{ + // Verify that parameter is actually an array + + if( !is_array($arr) ) + { + $return = "Error: Variable not an array"; + return $return; + } + + // If everything's going fine so far, build out the table + + $return = '

'; + + foreach( $arr as $key=>$val ) + { + $return .= '\n"; + } + + $return .= "
'.$key.' '; + if( is_array($val) ) + $return .= tableize_array( $val ); + else + { + if( strlen($val) > $len ) + $x = substr( $val, 0, $len )."......."; + else + $x = $val; + $return .= "
".htmlentities( $x )."
"; + } + + $return .= "
"; + + return $return; +} + + + // Select field data from an array based on which function it will be used for + // returning a string suitable for the admin_ functions + +function admin_field_select( $fields, $filter ) +{ + + $r = ''; + $sep = ''; + + if( ! is_array($fields) || trim($filter) == '' ) + { + echo "

ERROR: admin_field_select() - No Field or Filter data supplied!

"; + return( FALSE ); + } + + foreach( $fields as $f ) + { + $x = explode( ',', $f ); + if( strstr( $x[5], $filter ) ) + { + if( $filter == 'f' ) // List filters require slight difference in fields + $r .= $sep.$x[0].','.$x[1].','.$x[2].','.$x[4]; + else + $r .= $sep.$x[0].','.$x[1].','.$x[2].','.$x[3].','.$x[4]; + $sep = '|'; + } + } + + return( $r ); +} + + // Select field data from an array based on which function it will be used for + // returning an array of arrays of data. + +function admin_fields_select_array( $fields, $filter ) +{ + + $r = array(); + + if( ! is_array($fields) || trim($filter) == '' ) + { + echo "

ERROR: admin_field_select_array() - No Field or Filter data supplied!

"; + return( FALSE ); + } + + while( list($key, $val) = each($fields) ) + { + $x = explode( ',', $val ); + if( strstr( $x[5], $filter ) ) + { + $r[$key]['name'] = trim($x[0]); + $y = explode( '.', trim($x[1]) ); + foreach( $y as $z ) + $r[$key]['type'][] = trim($z); + $r[$key]['title'] = trim($x[2]); + $r[$key]['required'] = trim($x[3]); + $r[$key]['variable'] = trim($x[4]); + $r[$key]['sample'] = trim($x[6]); + } + } + + return( $r ); +} + + // Generate standard admin low-level menu + + // New version using standard HTML (

's) for admin sections +function admin_menu_std( $action, $a_title, $id, $opt, $options = 'lveda', $add_menu = '', $params = '' ) +{ + + $m = ''; + $nl = "\n"; + +// if( $a_title != '' ) +// $m .= ''.$a_title.':'; + + $link = SI_THIS_SCRIPT.'?Action='.urlencode($action); + if( trim($params) != '' ) + $link .= '&'.$params; + + if( strstr($options,'l') ) + { + if( $opt == "List" ) + $m .= '
  • [List]
  • '.$nl; + else + $m .= '
  • [List]
  • '.$nl; + } + + if( strstr($options,'v') ) + { + if( $opt == "View" ) + $m .= '
  • [View]
  • '.$nl; + elseif( empty($id) ) + $m .= '
  • [View]
  • '.$nl; + else + $m .= '
  • [View]
  • '.$nl; + } + + if( strstr($options,'e') ) + { + if( $opt == "Edit" ) + $m .= '
  • [Edit]
  • '.$nl; + elseif( empty($id) ) + $m .= '
  • [Edit]
  • '.$nl; + else + $m .= '
  • [Edit]
  • '.$nl; + } + + if( strstr($options,'d') ) + { + if( $opt == "Delete" ) + $m .= '
  • [Delete]<
  • '.$nl; + elseif( empty($id) ) + $m .= '
  • [Delete]
  • '.$nl; + else + $m .= '
  • [Delete]
  • '.$nl; + } + + if( strstr($options,'a') ) + { + if( $opt == "Add" ) + $m .= '
  • [Add]
  • '.$nl; + else + $m .= '
  • [Add]
  • '.$nl; + } + + if( $add_menu != '' ) + $m .= " - $add_menu".$nl; + + return( $m ); +} + // Standard version +function admin_menu( $action, $a_title, $id, $opt, $options = 'lveda', $add_menu = '', $params = '' ) +{ + + $m = ''.$a_title.': '; + + $link = SI_THIS_SCRIPT.'?Action='.urlencode($action); + if( trim($params) != '' ) + $link .= '&'.$params; + + if( strstr($options,'l') ) + { + if( $opt == "List" ) + $m .= '[List] '; + else + $m .= '[List] '; + } + + if( strstr($options,'v') ) + { + if( $opt == "View" ) + $m .= '[View] '; + elseif( empty($id) ) + $m .= '[View] '; + else + $m .= '[View] '; + } + + if( strstr($options,'e') ) + { + if( $opt == "Edit" ) + $m .= '[Edit] '; + elseif( empty($id) ) + $m .= '[Edit] '; + else + $m .= '[Edit] '; + } + + if( strstr($options,'d') ) + { + if( $opt == "Delete" ) + $m .= '[Delete] '; + elseif( empty($id) ) + $m .= '[Delete] '; + else + $m .= '[Delete] '; + } + + if( strstr($options,'a') ) + { + if( $opt == "Add" ) + $m .= '[Add] '; + else + $m .= '[Add] '; + } + + if( $add_menu != '' ) + $m .= " - $add_menu"; + + return( $m ); +} + + + // Clean up input parameters and test them for proper type of data + +function clean_input( $var_name, $type = 'text', $required = false ) +{ + + $reason = ''; // If problems, indicates reason here + + // Trim whitespace, slashes, and stupid characters + + $in = stripslashes( trim( $GLOBALS[$var_name] ) ); + + if( $in != '' ) + { + switch( $type ) + { + + case 'int': + if( !is_numeric($in) ) + $reason = 'not an integer'; + else + $in = intval( $in ); + break; + + case 'float': + $in = preg_replace( "/^(\\$)?(.*)$/i", "\\2", $in ); + if( !is_numeric( $in ) ) + $reason = 'not a valid number'; + else + $in = floatval( $in ); + break; + + case 'phone': + if( preg_match( "/^((\([0-9]{3}\))[ ]*|([0-9]{3}) *-* *)?[0-9]{3} *-* *[0-9]{4} *.{0,10}$/i", $in ) == 0 ) + $reason = 'not a valid phone number'; + else // Reformat as we want it + $in = preg_replace( "/^((\(([0-9]{3})\))[ ]*|(([0-9]{3}))[ -]*)?([0-9]{3}) *-* *([0-9]{4}) *(.{0,10})$/i", "\\3\\4-\\6-\\7 \\8", $in ); + break; + + case 'zip': + // Check if it's a US ZIP + if( preg_match( "/^(([0-9]{5})([ -+]?([0-9]{4}))?)$/i", $in ) != 0 ) + { + $in = preg_replace( "/^([0-9]{5})[ -+]?([0-9]{4})$/i", "\\1-\\2", $in ); + if( strlen($in) < 8 ) + { + $in = preg_replace( "/^([0-9]{5}).*/i", "\\1", $in ); + } + } + elseif( preg_match( "/^[a-zA-Z]\d[a-zA-Z][ -]?\d[a-zA-Z]\d$/i", $in ) != 0 ) + { + $in = preg_replace( "/^([a-zA-Z]\d[a-zA-Z])[ -]?(\d[a-zA-Z]\d)$/i", "\\1 \\2" ,$in ); + } + else + $reason = 'not a valid ZIP or Postal Code'; + break; + + case 'state': + global $si_states_array; + if( !isset($si_states_array[$in]) ) + $reason = 'not a valid state code'; + break; + + case 'country': + global $si_countries_array; + if( !isset($si_countries_array[$in]) ) + $reason = 'not a valid country code'; + break; + + case 'email': + if( preg_match( "/^[A-Z0-9._%-]+@[A-Z0-9._%-]+\.[A-Z]{2,4}$/i", $in ) == 0 ) + $reason = 'not a valid E-Mail address'; + break; + + case 'creditcard': + global $si_cc_verify; + $match = FALSE; + reset( $si_cc_verify ); + while( list($k, $v) = each($si_cc_verify) ) + { + if( preg_match( "/".$v."/i", $in ) != 0 ) + { + $match = TRUE; + break; + } + } + if( !$match ) + $reason = 'not a valid credit card number'; + break; + + case 'date': + if( ($t = strtotime($in)) === -1 ) + $reason = 'not a valid date'; + else + $in = date( 'n/j/Y', $t ); + break; + + case 'text': + break; + + case 'inet': + if( preg_match( "/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i", $in ) == 0 ) + $reason = 'not a valid IP address or netmask'; + break; + + default: + break; + + } + } + + // Check for a required field + + if( $required && $in == '' ) + $reason .= ($reason != '' ? ' and is ':'' ).'required'; + + $GLOBALS[$var_name] = $in; + return( $reason ); + +} + + // Convert data to search engine friendly URL + +function data_to_url( $prefix = '' ) +{ + + $url = $prefix; + + // Make sure we have at least a prefix and one parameter + + if( ($args = func_get_args()) == 0 || count($args) < 2 ) + return( false ); + + for( $i=1 ; $i +
    + Close +
    QuickTip
    +
    +
    +
    '.$t.'
    + '.$message.' +
    +
    + + '.$title.'' ); + +} + + // Returns Title text with QuickEdit Pop-Up support - Uses QuickTip Java functions + +function quick_edit( $key, $prompt, $form ) +{ + if( trim($prompt) == '' || trim($form) == '' ) + return( false ); + + $t = strip_tags( $prompt ); // Get rid of any HTML tags in title + + return( '
    +
    + Close +
    QuickEdit
    +
    +
    + '.$form.' +
    +
    + + '.$prompt.'' ); + +} + + +/*======================================================================= + + CATEGORY SUPPORT FUNCTIONS + +=======================================================================*/ + + // Returns PL/pgSQL category_path support function for specified data table + +function category_path_func( $table_name ) +{ + + // Stick table name in function + + return( str_replace ( '{TABLE_NAME}', $table_name, " + + /* + Function category_path( int ) + + Returns a ~ delimited string containing... + A string to use for sorting by category, sub-cat, sub-sub-cat, ... + A | delimited string of the names of the category hierarchy + A | delimited string of the id of each step in the category hierarchy + + Use in a query like... + + SELECT *, cateogory_path(id) FROM table_name; + + */ + + CREATE OR REPLACE FUNCTION category_path( int ) RETURNS text AS ' + + DECLARE + this_node ALIAS FOR $1; + node RECORD; + sort text := ''''; + path TEXT := ''''; + ids TEXT := ''''; + level INT := 0; + children RECORD; + child_count INT := 0; + sort_fix int := 100000; -- Added to sort numbers to make sure sort is pseudo-numeric + + BEGIN + SELECT INTO node * FROM {TABLE_NAME} WHERE id = this_node; + sort := node.sort + sort_fix || ''_'' || this_node; -- Makes sure sort is numeric + path := node.name; + ids := node.id; + SELECT INTO children COUNT(id) FROM {TABLE_NAME} WHERE parent = this_node; + child_count := children.count; + IF FOUND THEN + WHILE node.parent > 0 LOOP + SELECT INTO node * FROM {TABLE_NAME} WHERE id = node.parent; + sort := node.sort + sort_fix || ''_'' || node.id || ''_'' || sort; + path := node.name || ''|'' || path; + ids := node.id || ''|'' || ids; + level := level + 1; + END LOOP; + END IF; + + -- Note: 0 below is to enforce proper ordering by sort field + RETURN sort || ''_0~'' || path || ''~'' || ids || ''~'' || level || ''~'' || child_count; + + END; + + ' LANGUAGE plpgsql; + + " ) ); + +} + + // Get category node + +function cat_get_node( $table, $qs = '' ) +{ + + // Get specified nodes list + + $query = category_path_func( $table ) + ."SELECT *, category_path(id) AS cat_path_data FROM $table ".(trim($qs)!=''?" WHERE $qs":"").";"; + + if( !($r = db_auto_get_row( $query, 0, SI_CONN_STR, FALSE ) ) ) + return FALSE; + + // Process node paths into useable arrays + + $p = explode( "~", $r['cat_path_data'] ); + $r['cat_fullpath'] = $p[1]; + $r['cat_names'] = explode( "|", $p[1] ); + $r['cat_id_path'] = $p[2]; + $r['cat_ids'] = explode( "|", $p[2] ); + $r['cat_level'] = $p[3]; + + return( $r ); + +} + + // Get array of selected category nodes + +function cat_get_nodes( $table, $qs = '', $order = 'cat_path_data' ) +{ + + // Get specified nodes list + + $query = category_path_func( $table ) + ."SELECT *, category_path(id) AS cat_path_data FROM $table ".($qs!=''?" WHERE $qs":"")." ORDER BY $order;"; + + if( !($r = db_auto_get_data( $query, SI_CONN_STR, FALSE) ) ) + return( FALSE ); + + // Process node paths into useable arrays + + $num = count( $r ); + + while( list($key, $val) = each($r) ) + { + $p = explode( "~", $r[$key]['cat_path_data'] ); + $r[$key]['cat_fullpath'] = $p[1]; + $r[$key]['cat_names'] = explode( "|", $p[1] ); + $r[$key]['cat_id_path'] = $p[2]; + $r[$key]['cat_ids'] = explode( "|", $p[2] ); + $r[$key]['cat_level'] = $p[3]; + } + + + return( $r ); + +} + + // Get array of expanded node hierarchy for menus + +function cat_get_expanded_nodes( $table, $id ) +{ + + // Always get all top level nodes + + $q = 'parent = 0'; + + // If target supplied, get siblings and siblings of all parents + + $expanded = array(); + if( $id > 0 ) + { + $r = cat_get_node( $table, "id = $id" ); + + // For each level up, add to query to get all siblings + + if( $r ) + foreach( $r['cat_ids'] as $c ) + { + $q .= " OR parent = $c"; + $expanded[$c] = TRUE; + } + } + + // Get all selected nodes + + if( !($nodes = cat_get_nodes( $table, $q ) ) ) + return( FALSE ); // If there's no top level nodes, then quit. + + // Set expanded flags for nodes with expanded children + + reset($nodes); + while( list($key, $val) = each($nodes) ) + $nodes[$key]['expanded'] = $expanded[$val['id']] == TRUE; + + // Make array keys the path data string to sort on + + foreach( $nodes as $n ) + $list[$n['cat_path_data']] = $n; + + // Sort on those keys + + ksort( $list ); + + return( $list ); + +} + + + // Get array of an entire category tree from target down + +function cat_get_tree( $table, $id ) +{ + + // Not written + +} + + // Resequence category node siblings + +function cat_resequence_siblings( $table, $parent ) +{ + + // Get all siblings + + if( !($nodes = db_auto_get_data( "SELECT id, sort FROM $table WHERE parent = $parent ORDER BY sort;", SI_CONN_STR, FALSE ) ) ) + return( FALSE ); + + $query = 'BEGIN;'; + + $sort = 10; + + foreach( $nodes as $n ) + { + $query .= "UPDATE $table SET sort = $sort WHERE id = ".$n['id'].";"; + $sort += 10; + } + + $query .= 'COMMIT;'; + + if( !db_auto_exec( $query, SI_CONN_STR, FALSE ) ) + return( FALSE ); + + return( TRUE ); + +} + + // Move a category node + +/* +function cat_move_node( $table, $parent ) +{ + + NOT WRITTEN YET + +} +*/ + + + // Delete a category node and optionally its children + + +function cat_delete_node( $table, $id, $method = 'node' ) +{ + // Check submitted data + + if( empty($table) || empty($id) || $id < 1 ) + return( FALSE ); + + // Get parent of node to be deleted + + if( !($target = db_auto_get_row( "SELECT * FROM $table WHERE id = $id;", 0, SI_CONN_STR, FALSE )) ) + return( FALSE ); + $new_parent = $target['parent']; + + // Delete target and reassign all children to parent + + if( !db_auto_exec( "BEGIN; + DELETE FROM $table WHERE id = $id; + UPDATE $table SET parent = $new_parent WHERE parent = $id; + COMMIT;", SI_CONN_STR, FALSE ) ) + return( FALSE ); + + return( TRUE ); +} + + + +/*======================================================================= + + HIGH LEVEL FUNCTIONS + +=======================================================================*/ + + // Build a numeric picklist + +function build_numeric_picklist( $fieldname, $starting, $ending, $selected="", $option="", $class="" ) +{ + if( $starting > $ending ) + return( "*** Picklist generation error: build_numeric_piclist() ***" ); + + $r = ''; + + return( $r ); + +} + + // Build a picklist + +function build_picklist( $fieldname, $data, $selected, $type = "standard", $options = "", $class="" ) +{ + + if( !is_array($data) ) + return( "ERROR: build_picklist() data supplied is not an array for field $fieldname.\n" ); + + // Set default option status + + $option_blank = $option_order = $option_numeric = $option_descending = $option_multi = FALSE; + + // Scan for supplied options + + if( !empty($options) ) + { + $opt_array = explode_trim( "~", $options ); + foreach( $opt_array as $opt ) + { + switch( $opt ) + { + case "blank": + $option_blank = TRUE; + break; + + case "numeric": + $option_numeric = TRUE; + $option_order = TRUE; + break; + + case "alpha": + $option_numeric = FALSE; // If it's not numeric, it's alpha + $option_order = TRUE; + break; + + case "descending": + $option_descending = TRUE; + break; + + case "ascending": + $option_descending = FALSE; // If it's not descending, it's ascending + break; + + case "multi": + $option_multi = TRUE; // Permit multiple select with CTRL or SHIFT + break; + + default: + return( "Illegal build_picklist() option\n" ); + break; + } + } + } + + if( $option_order ) + { + if( $option_descending ) + { // Sort Descending + if( $option_numeric ) + arsort( $data, SORT_NUMERIC ); + else + arsort( $data, SORT_STRING ); + } + else + { // Sort Ascending + if( $option_numeric ) + asort( $data, SORT_NUMERIC ); + else + asort( $data, SORT_STRING ); + } + } + + if( $option_multi ) + $str = ''; + + if( $option_blank ) + $str .= "