From 0eb43ec8fa5b2060f478959d42cfe0ad34a73b34 Mon Sep 17 00:00:00 2001 From: Rick Boatright Date: Wed, 25 Jan 2017 17:53:24 -0600 Subject: [PATCH 01/17] Addf files to replace phpweather, php weather used a now-dead noaa service. The replacement saratoga-weather uses a service which is guaranteed to work for a long time. Plus it looks better. -- added files and added variables to config.inc.php --- config.inc.php | 69 +- get-metar-conditions-inc.php | 1317 ++++++++++++++++++++++++++++++++++ include-metar-display.php | 354 +++++++++ leftmain.php | 223 +----- sidebar-metar-display.php | 103 +++ 5 files changed, 1853 insertions(+), 213 deletions(-) create mode 100644 get-metar-conditions-inc.php create mode 100644 include-metar-display.php create mode 100644 sidebar-metar-display.php diff --git a/config.inc.php b/config.inc.php index bd0d2a1..2e8e6ec 100644 --- a/config.inc.php +++ b/config.inc.php @@ -19,7 +19,7 @@ $db_hostname = "localhost"; $db_username = "timeclock"; -$db_password = "P4ssw0rd1!"; +$db_password = "clocktime"; $db_name = "timeclock"; @@ -190,9 +190,7 @@ /* A logo or graphic, this is displayed in the top left of each page. - Set it to "none" to ignore this option. - This can either be a relative path (from the root directory) or URL. -*/ + Set it to "none" to ignore this option. */ $logo = "images/logos/phptimeclock.png"; @@ -317,19 +315,12 @@ /* To display the punch-in/out times in the timezone of the web server, leave this option set - to "yes". If using PHP 5.1+ then leave this as-is, to change the time zone please use - date.timezone in your php.ini. Leaving date.timezone unset may cause PHP to choose the - wrong timezone (see below). Setting this option to "yes" will display the punch-in/out - times according to the timezone through date("Z"). The default setting is "no". */ + to "yes". Setting this option to "no" AND setting the above $use_client_tz option to "no", + will display the punch-in/out times in GMT. Default is "yes". */ $use_server_tz = "no"; -/* If you are using PHP 5.1+ and do not have access to chance your php.ini config file then - uncomment the following line and change it to the correct time zone. */ -//date_default_timezone_set("America/St_Johns"); - - /* --- WEATHER INFO --- */ @@ -338,7 +329,46 @@ $display_weather = "yes"; +/* Display weather in US or metric measurements. Options are "f" or "c". Default is "c" */ + +$weather_units = "c"; + +/* set this list to your local weather station location + the entry format (all fields are required) is + + 'Metar(ICAO) | Name of station | dist-mi | dist-km | direction |' + + Note that the trailing | is required. + You may have two in the array, which will show weather conditions + for two different stations, in which case you enter + array('a|b|c|d|e|','F|G|H|I|J|') + You can find a list of valid ICAO codes at: + https://pilotweb.nas.faa.gov/qryhtml/icao/ */ + +$WxList = array(); +$WxList = array('KTOP|Topeka, Kansas|4|7|NE|'); + +/* NOTE: this *MUST* be set correctly to + translate UTC times to your LOCAL time for the weather displays. + The list of valid timezone names can be found at + + http://us.php.net/manual/en/timezones.php + + pick the one that is closest to your location + + $WxTimeZone = 'America/Los_Angeles'; + or + $WxTimeZone = 'Europe/Brussels'; + + */ + +$WxTimeZone = 'America/Chicago'; + +/* ************************************************************************* + the next two config values are depricated, don't bother to update them. + ************************************************************************* */ + /* ICAO (International Civil Aviation Organization) for your local airport. This is the unique four letter international ID for the airport. METAR reports are created at roughly 4500 airports from around the world, so you probably live near one of them. @@ -348,19 +378,13 @@ $display_weather is set to "no", this option is ignored. If $display_weather is set to "yes", you MUST provide an ICAO here. */ -$metar = "CYYT"; - +$metar = "KTOP"; /* This is the city and country (or can be city and state) of the airport for the ICAO used above. The max length for this field is 100 characters. If $display_weather is set to "no", this option is ignored. */ -$city = "St. Johns, NL, Canada"; - - -/* Display weather in US or metric measurements. Options are "f" or "c". Default is "c" */ - -$weather_units = "c"; +$city = "Topeka, KS"; /* --- APP NAME, VERSION NUMBER, ETC. --- */ @@ -377,5 +401,6 @@ /* --- DO NOT CHANGE ANYTHING BELOW THIS LINE!!! --- */ + $dbversion = "1.4"; -?> +?> \ No newline at end of file diff --git a/get-metar-conditions-inc.php b/get-metar-conditions-inc.php new file mode 100644 index 0000000..3c71766 --- /dev/null +++ b/get-metar-conditions-inc.php @@ -0,0 +1,1317 @@ + Mostly Cloudy + [1] => 2 + [2] => day_partly_cloudy.gif + [3] => Cloudy +) + +KCDR='2011/01/23 00:01 KCDR 230001Z AUTO 02018KT 1/4SM -SN FZFG BKN007 OVC012 M06/M07 A2986 RMK AO2 PRESRR P0000' +Array +( + [0] => Light Snow, Freezing Fog, Overcast + [1] => 16 + [2] => night_snow.gif + [3] => Snow +) + +WIOO='2011/01/22 23:30 WIOO 222330Z 00000KT 3000 FU FEW011CB BKN008 25/25 Q1011 TEMPO AT0000 5000 -RA' +Array +( + [0] => Smoke, Mostly Cloudy + [1] => 7 + [2] => haze.gif + [3] => Haze +) + + +Author: Ken True - webmaster@saratoga-weather.org (with a lot of code borrowed from my own works and others :) +Referemce: METAR Coding http://www.ofcm.gov/fmh-1/pdf/L-CH12.pdf from Federal Meteorological Handbook No. 1 (FCM-H1-2005) +Also see: http://en.wikipedia.org/wiki/METAR for more descriptions. +Note: Runway conditions are not decoded by this function. + +Version 1.00 - 21-Jan-2011 - initial release +Version 1.01 - 24-Mar-2011 - added optional return of large-icon .jpg image name for condition and $metar array. +Version 1.02 - 10-Aug-2011 - fixes for function name collisions with *-mesomap.php programs +Version 1.03 - 01-Oct-2011 - added support for alternative animated icon set from http://www.meteotreviglio.com/ +Version 1.04 - 09-Oct-2011 - fixed issue with 'RA' (rain) condition non-detection +Version 1.05 - 17-Nov-2011 - added $metarGMT optional return and UOM specs +Version 1.06 - 19-Nov-2011 - fixed formatting for Wind Chill +Version 1.07 - 19-Nov-2011 - fixed runway decode for European METARs +Version 1.08 - 22-Nov-2011 - fixed Notice: type errata +Version 1.09 - 23-Nov-2011 - fix for metar reports with >1 runway reports or limited visibility reports +Version 1.10 - 24-Nov-2011 - fix for CAVOK with km/miles selection based on wind units +Version 1.11 - 29-Nov-2011 - added cloud-details return for wxmetar.php page +Version 1.12 - 04-May-2012 - added fix for variable wind decode like VRB02G03KT +Version 1.13 - 31-Aug-2012 - added fixes for incomplete visibility and multiple conditions decode +Version 1.14 - 23-May-2016 - chg source to tgftp.nws.noaa.gov/data from weather.noaa.gov/pub/data (deprecated site) + +*/ +global $Debug, $GMCVersion; + +$GMCVersion = 'get-metar-conditions-inc.php - Version 1.14 - 23-May-2016'; + +if (isset($_REQUEST['sce']) && ( strtolower($_REQUEST['sce']) == 'view' or + strtolower($_REQUEST['sce']) == 'show') ) { + //--self downloader -- + $filenameReal = __FILE__; + $download_size = filesize($filenameReal); + header('Pragma: public'); + header('Cache-Control: private'); + header('Cache-Control: no-cache, must-revalidate'); + header("Content-type: text/plain"); + header("Accept-Ranges: bytes"); + header("Content-Length: $download_size"); + header('Connection: close'); + + readfile($filenameReal); + exit; +} +// local settings +$cacheFileDir = './'; // default cache file directory + +global $cacheFileDir; +//------------ override from Settings.php -------------------- +global $SITE; +if(isset($SITE['cacheFileDir'])) {$cacheFileDir = $SITE['cacheFileDir']; } +//------------ end override from Settings.php ---------------- +# ------------------------------------------------------------------------------ +# main function mtr_conditions +#------------------------------------------------------------------------------- + +function mtr_conditions ($icao,$curtime='',$sunrise='',$sunset='',$useJpgIcon=false,$UOM='°F,mph,inHg,in') { + global $lang, $Debug, $mtrInfo, $metarPtr, $group, $GMCVersion; + global $Icons, $IconsLarge, $IconsText, $cacheFileDir; + $metarCacheName = $cacheFileDir."metarcache-$icao.txt"; + $metarRefetchSeconds = 600; // fetch every 10 minutes + list($uomTemp,$uomWind,$uomBaro,$uomRain) = explode(',',$UOM.',,,,'); + global $UOMS; + $UOMS = array( + 'TEMP' => "$uomTemp", + 'WIND' => "$uomWind", + 'BARO' => "$uomBaro", + 'RAIN' => "$uomRain" + ); + + if(isset($_REQUEST['cache']) and strtolower($_REQUEST['cache']) == 'refresh') { + $metarRefetchSeconds = 0; + } + if(isset($_REQUEST['cache']) and strtolower($_REQUEST['cache']) == 'norefresh') { + $metarRefetchSeconds = 9999999; + } + + $mtrInfo = array(); + $Debug .= "\n"; +// $Debug .= "\n"; + if(isset($icao) and strlen($icao) == 4) { + + $Debug .= "\n"; + $host = 'tgftp.nws.noaa.gov'; + $path = '/data/observations/metar/stations/'; + $metarURL = 'http://' . $host . $path . $icao . '.TXT'; + + $html = ''; + $raw = ''; +// get the metar data from the cache or from the URL if the cache is 'stale' + if (file_exists($metarCacheName) and filemtime($metarCacheName) + $metarRefetchSeconds > time()) { + $WhereLoaded = "from cache $metarCacheName"; + $html = implode('', file($metarCacheName)); + } else { + $WhereLoaded = "from URL $metarURL"; + $rawhtml = mtr_fetchUrlWithoutHanging($metarURL); + $i = strpos($rawhtml,"\r\n\r\n"); + $headers = substr($rawhtml,0,$i-1); + $content = substr($rawhtml,$i+2); + $RC = ''; + if (preg_match("|^HTTP\/\S+ (.*)\r\n|",$rawhtml,$matches)) { + $RC = trim($matches[1]); + } + if(!preg_match('|200 |',$RC)) { + $t = array("unable to load $icao data RC=$RC",5,'day_partly_cloudy.gif',"unable to load $icao data RC=$RC",array(),$metarGMT); + $Debug .= "\n"; + return $t; + } + if(preg_match('|Content-Encoding: gzip|Ui',$headers)) { + $Debug .= "\n"; + // $Debug .= "\n"; + $err = 'None'; + $html = trim(mtr_gzdecode($content,$err)); + $Debug .= "\n"; + if($err <> 'None') { + $Debug .= "\n"; + } + } else { + $html = $content; + } + $fp = fopen($metarCacheName, "w"); + if($fp) { + $write = fputs($fp, $html); + fclose($fp); + } else { + $Debug .= "\n"; + } + } // end of get the METAR from cache or URL + $raw_metar = preg_replace("/[\n\r ]+/", ' ', trim(implode(' ', (array)$html))); + $Debug .= "\n"; + $Debug .= "\n"; + $metar = trim($raw_metar); + $metarDate = preg_replace('|/|','-',substr($metar,0,16)) . ':00 GMT'; + $metarGMT = strtotime($metarDate); + $age = abs(time() - $metarGMT); // age in seconds + $Debug .= "\n"; + + mtr_load_iconDefs(); // initialize ICON defs to use and lookup arrays + +/* + Metar formatter expects + CYXU='2010/11/30 23:00 CYXU 302300Z 15013G18KT 5SM -RA BR OVC005 11/10 A2969 RMK SF8 SLP059' +*/ + +// Clean up the metar.. some are not properly formatted, human made, most likely + $unprocMetar = $metar; + $metar = preg_replace('|[\r\n]+|is','',$metar); // remove internal newlines + $metar = preg_replace('|/////KT|is','VRB00KT',$metar); // replace bogus wind report + $metar = preg_replace('|@|is','',$metar); // remove strange @ in metar + $metar = preg_replace('|///|is',' ',$metar); // remove strange standalone slashes + $metar = preg_replace('| /|is',' ',$metar); // remove strange standalone slashes + $metar = preg_replace('| / |is',' ',$metar); // remove strange standalone slashes + $metar = preg_replace('| \s+|is',' ',$metar); // remove multiple spaces + $metar = preg_replace('| COR |i',' ',$metar); // remove COR (correction) from raw metar + $metar = preg_replace('|(\d{5}) KT|i','${1}KT',$metar); // fix any space in wind value + $metar = preg_replace('| 999 |',' 9999 ',$metar); // fix malformed unlimited visibility + $metar = preg_replace('| LRA |',' -RA ',$metar); // fix malformed light rain + $metar = preg_replace('| HRA |',' +RA ',$metar); // fix malformed light rain + // $metar = preg_replace('| (\d)SM|i',' 0${1}SM',$metar); // fix malformed visibility to two digits + // $metar = preg_replace('| (\d+) (\d+)/(\d+)SM |i',' $1_$2/${3}SM ',$metar); // fix NOAA visibility + + mtr_process($metar,$icao); // actually parse the metar for conditions.. results in $mtrInfo array + + // assemble the conditions string: + // use conditions first + // use sky (clouds) second + // + $mtrInfo['RAW-METAR'] = $unprocMetar; + $Sky = isset($mtrInfo['CLOUDS'])?trim($mtrInfo['CLOUDS']):''; + $Weather = isset($mtrInfo['CONDITIONS'])?trim($mtrInfo['CONDITIONS']):''; + + $Conds = $Weather; // Choose any conditions report first + + if($Sky <> '' and $Conds <> '') {$Conds .= ", $Sky"; } // append a clouds descriptor if available + if($Conds == '' and $Sky <> '') {$Conds = $Sky; } // no weathercond .. use sky only + + $iconnumber = mtr_get_iconnumber('',$Conds,$sunrise,$sunset); + if(!$useJpgIcon) { + $useicon = $Icons[$iconnumber]; + } else { + $useicon = $IconsLarge[$iconnumber]; + } + $icondescr = $IconsText[$iconnumber]; + + $t = array($Conds,$iconnumber,$useicon,$icondescr,$mtrInfo,$metarGMT); + } else { + $t = array("$icao not loaded",5,'day_partly_cloudy.gif',"unable to load data RC=$RC",array(),$metarGMT); + } // end of ICAO processing + + $Debug .= "\n"; + return $t; +} +// ------------------------------------------------------------ + +// get contents from one URL and return as string + function mtr_fetchUrlWithoutHanging($url,$useFopen=false) { +// thanks to Tom at Carterlake.org for this script fragment + global $Debug, $needCookie,$timeStamp,$TOTALtime; + $overall_start = time(); + if (! $useFopen) { + // Set maximum number of seconds (can have floating-point) to wait for feed before displaying page without feed + $numberOfSeconds=5; + + // Suppress error reporting so Web site visitors are unaware if the feed fails + error_reporting(0); + + // Extract resource path and domain from URL ready for fsockopen + $FullUrl = $url; + $urlParts = parse_url($url); + + $domain = $urlParts['host']; + if(isset($urlParts['port'])) { + $port = $urlParts['port']; + } else { + $port = 80; + } + $resourcePath = $urlParts['path']; + $resourcePath = preg_replace('|nocache|','?'.$timeStamp,$resourcePath); + if(isset($urlParts['query'])) {$resourcePath .= "?" . $urlParts['query']; } + if(isset($urlParts['fragment'])) {$resourcePath .= "#" . $urlParts['fragment']; } + $T_start = mtr_microtime_float(); + $hostIP = gethostbyname($domain); + $T_dns = mtr_microtime_float(); + $ms_dns = sprintf("%01.3f",round($T_dns - $T_start,3)); + + $Debug .= "\n"; +// print "GET $resourcePath HTTP/1.1 \n Host: $domain Port: $port IP=$hostIP\n"; + + // Establish a connection + $socketConnection = fsockopen($hostIP, $port, $errno, $errstr, $numberOfSeconds); + $T_connect = mtr_microtime_float(); + $T_puts = 0; + $T_gets = 0; + $T_close = 0; + + if (!$socketConnection) + { + // You may wish to remove the following debugging line on a live Web site + $Debug .= "\n"; +// print "Network error: $errstr ($errno)\n"; + } // end if + else { + $xml = ''; + $getString = "GET $resourcePath HTTP/1.1\r\nHost: $domain\r\nConnection: Close\r\n"; + if (isset($needCookie[$domain])) { + $getString .= $needCookie[$domain] . "\r\n"; + $Debug .= "\n"; + } + $getString .= "User-agent: Mesomap Loader\r\nAccept: text/plain,text/html\r\nAccept-Encoding: gzip;q=0,compress;q=0\r\n"; + $getString .= "\r\n"; +// print "Sending:\n$getString\n\n"; + fputs($socketConnection, $getString); + $T_puts = mtr_microtime_float(); + + // Loop until end of file + $TGETstats = array(); + $TGETcount = 0; + while (!feof($socketConnection)) + { + $T_getstart = mtr_microtime_float(); + $xml .= fgets($socketConnection, 16384); + $T_getend = mtr_microtime_float(); + $TGETcount++; + $TGETstats[$TGETcount] = sprintf("%01.3f",round($T_getend - $T_getstart,3)); + } // end while + $T_gets = mtr_microtime_float(); + fclose ($socketConnection); + $T_close = mtr_microtime_float(); + } // end else + $ms_connect = sprintf("%01.3f",round($T_connect - $T_dns,3)); + + if($T_close > 0) { + $ms_puts = sprintf("%01.3f",round($T_puts - $T_connect,3)); + $ms_gets = sprintf("%01.3f",round($T_gets - $T_puts,3)); + $ms_close = sprintf("%01.3f",round($T_close - $T_gets,3)); + $ms_total = sprintf("%01.3f",round($T_close - $T_start,3)); + } else { + $ms_puts = 'n/a'; + $ms_gets = 'n/a'; + $ms_close = 'n/a'; + $ms_total = sprintf("%01.3f",round($T_connect - $T_start,3)); + } + + $Debug .= "\n"; +// print "HTTP stats: dns=$ms_dns conn=$ms_connect put=$ms_puts get($TGETcount blocks)=$ms_gets close=$ms_close total=$ms_total secs \n"; +// foreach ($TGETstats as $block => $mstimes) { +// print "HTTP Block $block took $mstimes\n"; +// } + $TOTALtime+= ($T_close - $T_start); + $overall_end = time(); + $overall_elapsed = $overall_end - $overall_start; + $Debug .= "\n"; +// print "fetch function elapsed= $overall_elapsed secs.\n"; + return($xml); + } else { +// print "\n"; + $T_start = mtr_microtime_float(); + + $xml = implode('',file($url)); + $T_close = mtr_microtime_float(); + $ms_total = sprintf("%01.3f",round($T_close - $T_start,3)); + $Debug .= "\n"; +// print " file() stats: total=$ms_total secs.\n"; + $TOTALtime+= ($T_close - $T_start); + $overall_end = time(); + $overall_elapsed = $overall_end - $overall_start; + $Debug .= "\n"; +// print "fetch function elapsed= $overall_elapsed secs.\n"; + return($xml); + } + + } // end mtr_fetchUrlWithoutHanging +// ------------------------------------------------------------------ + +function mtr_microtime_float() +{ + list($usec, $sec) = explode(" ", microtime()); + return ((float)$usec + (float)$sec); +} +// ------------------------------------------------------------------ +function mtr_gzdecode($rawdata,&$error='',&$filename='',$maxlength=null) +{ + //0d0a1f8b0800000000000003454d390ec3300cdbfb0aee45654a71e463ed5ef40bdd0214feff5adb49130814285122d502535082 + if(strcmp(substr($data,0,2),"\x0d\x0a")) { // got an extra \r\n in the data? + $data = substr($rawdata,2); + } else { + $data = $rawdata; + } + $len = strlen($data); + if ($len < 18 || strcmp(substr($data,0,2),"\x1f\x8b")) { + $error = "Not in GZIP format."; + return null; // Not GZIP format (See RFC 1952) + } + $method = ord(substr($data,2,1)); // Compression method + $flags = ord(substr($data,3,1)); // Flags + if ($flags & 31 != $flags) { + $error = "Reserved bits not allowed."; + return null; + } + // NOTE: $mtime may be negative (PHP integer limitations) + $mtime = unpack("V", substr($data,4,4)); + $mtime = $mtime[1]; + $xfl = substr($data,8,1); + $os = substr($data,8,1); + $headerlen = 10; + $extralen = 0; + $extra = ""; + if ($flags & 4) { + // 2-byte length prefixed EXTRA data in header + if ($len - $headerlen - 2 < 8) { + return false; // invalid + } + $extralen = unpack("v",substr($data,8,2)); + $extralen = $extralen[1]; + if ($len - $headerlen - 2 - $extralen < 8) { + return false; // invalid + } + $extra = substr($data,10,$extralen); + $headerlen += 2 + $extralen; + } + $filenamelen = 0; + $filename = ""; + if ($flags & 8) { + // C-style string + if ($len - $headerlen - 1 < 8) { + return false; // invalid + } + $filenamelen = strpos(substr($data,$headerlen),chr(0)); + if ($filenamelen === false || $len - $headerlen - $filenamelen - 1 < 8) { + return false; // invalid + } + $filename = substr($data,$headerlen,$filenamelen); + $headerlen += $filenamelen + 1; + } + $commentlen = 0; + $comment = ""; + if ($flags & 16) { + // C-style string COMMENT data in header + if ($len - $headerlen - 1 < 8) { + return false; // invalid + } + $commentlen = strpos(substr($data,$headerlen),chr(0)); + if ($commentlen === false || $len - $headerlen - $commentlen - 1 < 8) { + return false; // Invalid header format + } + $comment = substr($data,$headerlen,$commentlen); + $headerlen += $commentlen + 1; + } + $headercrc = ""; + if ($flags & 2) { + // 2-bytes (lowest order) of CRC32 on header present + if ($len - $headerlen - 2 < 8) { + return false; // invalid + } + $calccrc = crc32(substr($data,0,$headerlen)) & 0xffff; + $headercrc = unpack("v", substr($data,$headerlen,2)); + $headercrc = $headercrc[1]; + if ($headercrc != $calccrc) { + $error = "Header checksum failed."; + return false; // Bad header CRC + } + $headerlen += 2; + } + // GZIP FOOTER + $datacrc = unpack("V",substr($data,-8,4)); + $datacrc = sprintf('%u',$datacrc[1] & 0xFFFFFFFF); + $isize = unpack("V",substr($data,-4)); + $isize = $isize[1]; + // decompression: + $bodylen = $len-$headerlen-8; + if ($bodylen < 1) { + // IMPLEMENTATION BUG! + return null; + } + $body = substr($data,$headerlen,$bodylen); + $data = ""; + if ($bodylen > 0) { + switch ($method) { + case 8: + // Currently the only supported compression method: + $data = gzinflate($body,$maxlength); + break; + default: + $error = "Unknown compression method."; + return false; + } + } // zero-byte body content is allowed + // Verifiy CRC32 + $crc = sprintf("%u",crc32($data)); + $crcOK = $crc == $datacrc; + $lenOK = $isize == strlen($data); + if (!$lenOK || !$crcOK) { + $error = ( $lenOK ? '' : 'Length check FAILED. ') . ( $crcOK ? '' : 'Checksum FAILED.'); + return false; + } + return $data; +} +// ------------------------------------------------------------------ +function mtr_load_iconDefs () { + +global $Icons, $IconsLarge, $IconsText, $Conditions, $Debug; + + // CURRENT CONDITIONS ICONS FOR clientraw.txt + // create array for icons. There are 35 possible values in clientraw.txt + // It would be simpler to do this with array() but to make it easier to + // modify each element is defined individually. Each index [#] corresponds + // to the value provided in clientraw.txt + $Icons[0] = "day_clear.gif"; // image sunny.visible + $Icons[1] = "night_clear.gif"; // image clearnight.visible + $Icons[2] = "day_partly_cloudy.gif"; // image cloudy.visible + $Icons[3] = "day_partly_cloudy.gif"; // image cloudy2.visible + $Icons[4] = "night_partly_cloudy.gif"; // image night cloudy.visible + $Icons[5] = "day_clear.gif"; // image dry.visible + $Icons[6] = "fog.gif"; // image fog.visible + $Icons[7] = "haze-sm.gif"; // image haze.visible + $Icons[8] = "day_heavy_rain.gif"; // image heavyrain.visible + $Icons[9] = "day_mostly_sunny.gif"; // image mainlyfine.visible + $Icons[10] = "mist-sm.gif"; // image mist.visible + $Icons[11] = "fog.gif"; // image night fog.visible + $Icons[12] = "night_heavy_rain.gif"; // image night heavyrain.visible + $Icons[13] = "night_cloudy.gif"; // image night overcast.visible + $Icons[14] = "night_rain.gif"; // image night rain.visible + $Icons[15] = "night_light_rain.gif"; // image night showers.visible + $Icons[16] = "night_snow.gif"; // image night snow.visible + $Icons[17] = "night_tstorm.gif"; // image night thunder.visible + $Icons[18] = "day_cloudy.gif"; // image overcast.visible + $Icons[19] = "day_partly_cloudy.gif"; // image partlycloudy.visible + $Icons[20] = "day_rain.gif"; // image rain.visible + $Icons[21] = "day_rain.gif"; // image rain2.visible + $Icons[22] = "day_light_rain.gif"; // image showers2.visible + $Icons[23] = "sleet.gif"; // image sleet.visible + $Icons[24] = "sleet.gif"; // image sleetshowers.visible + $Icons[25] = "day_snow.gif"; // image snow.visible + $Icons[26] = "day_snow.gif"; // image snowmelt.visible + $Icons[27] = "day_snow.gif"; // image snowshowers2.visible + $Icons[28] = "day_clear.gif"; // image sunny.visible + $Icons[29] = "day_tstorm.gif"; // image thundershowers.visible + $Icons[30] = "day_tstorm.gif"; // image thundershowers2.visible + $Icons[31] = "day_tstorm.gif"; // image thunderstorms.visible + $Icons[32] = "tornado.gif"; // image tornado.visible + $Icons[33] = "windy-sm.gif"; // image windy.visible + $Icons[34] = "day_partly_cloudy.gif"; // stopped rainning + $Icons[35] = "windyrain-sm.gif"; // wind + rain + + $IconsText[0] = 'Sunny'; + $IconsText[1] = 'Clear'; + $IconsText[2] = 'Cloudy'; + $IconsText[3] = 'Cloudy2'; + $IconsText[4] = 'Partly Cloudy'; + $IconsText[5] = 'Dry'; + $IconsText[6] = 'Fog'; + $IconsText[7] = 'Haze'; + $IconsText[8] = 'Heavy Rain'; + $IconsText[9] = 'Mainly Fine'; + $IconsText[10] = 'Mist'; + $IconsText[11] = 'Fog'; + $IconsText[12] = 'Heavy Rain'; + $IconsText[13] = 'Overcast'; + $IconsText[14] = 'Rain'; + $IconsText[15] = 'Showers'; + $IconsText[16] = 'Snow'; + $IconsText[17] = 'Thunder'; + $IconsText[18] = 'Overcast'; + $IconsText[19] = 'Partly Cloudy'; + $IconsText[20] = 'Rain'; + $IconsText[21] = 'Rain2'; + $IconsText[22] = 'Showers2'; + $IconsText[23] = 'Sleet'; + $IconsText[24] = 'Sleet Showers'; + $IconsText[25] = 'Snow'; + $IconsText[26] = 'Snow Melt'; + $IconsText[27] = 'Snow Showers2'; + $IconsText[28] = 'Sunny'; + $IconsText[29] = 'Thunder Showers'; + $IconsText[30] = 'Thunder Showers2'; + $IconsText[31] = 'Thunder Storms'; + $IconsText[32] = 'Tornado'; + $IconsText[33] = 'Windy'; + $IconsText[34] = 'Stopped Raining'; + $IconsText[35] = 'Wind/Rain'; + + $IconsLarge = array( + "skc.jpg", // 0 imagesunny.visible + "nskc.jpg", // 1 imageclearnight.visible + "bkn.jpg", // 2 imagecloudy.visible + "sct.jpg", // 3 imagecloudy2.visible + "nbkn.jpg", // 4 imagecloudynight.visible + "sct.jpg", // 5 imagedry.visible + "fg.jpg", // 6 imagefog.visible + "hazy.jpg", // 7 imagehaze.visible + "ra.jpg", // 8 imageheavyrain.visible + "few.jpg", // 9 imagemainlyfine.visible + "mist.jpg", // 10 imagemist.visible + "nfg.jpg", // 11 imagenightfog.visible + "nra.jpg", // 12 imagenightheavyrain.visible + "novc.jpg", // 13 imagenightovercast.visible + "nra.jpg", // 14 imagenightrain.visible + "nshra.jpg", // 15 imagenightshowers.visible + "nsn.jpg", // 16 imagenightsnow.visible + "ntsra.jpg", // 17 imagenightthunder.visible + "ovc.jpg", // 18 imageovercast.visible + "sct.jpg", // 19 imagepartlycloudy.visible + "ra.jpg", // 20 imagerain.visible + "ra.jpg", // 21 imagerain2.visible + "shra.jpg", // 22 imageshowers2.visible + "ip.jpg", // 23 imagesleet.visible + "ip.jpg", // 24 imagesleetshowers.visible + "sn.jpg", // 25 imagesnow.visible + "sn.jpg", // 26 imagesnowmelt.visible + "sn.jpg", // 27 imagesnowshowers2.visible + "skc.jpg", // 28 imagesunny.visible + "scttsra.jpg", // 29 imagethundershowers.visible + "hi_tsra.jpg", // 30 imagethundershowers2.visible + "tsra.jpg", // 31 imagethunderstorms.visible + "nsvrtsra.jpg", // 32 imagetornado.visible + "wind.jpg", // 33 imagewindy.visible + "ra1.jpg", // 34 stopped rainning + "windyrain.jpg" // 35 windy/rain + ); + + + +/* the following is a lookup table for conditions text from the metar to return + the WD Icon number above. It is sorted such that the most severe conditions + are at the top of the list, with least severe at the bottom. This is done + so that significant weather icon will prevail when multiple conditions/sky cover + messages are emitted by the METAR station. + + tornado/waterspout + thunder (in any form) + Ice / Snow/ Freezing / Sleet + Rain + Fog + Haze/Smoke/Dust/Volcano + cloud cover + +*/ + +$Condstring = ' +# +cond|tornado|32|32|Severe storm| +cond|thunder|31|17|Thunder storm| +cond|ice|23|23|Sleet| +cond|snow|25|16|Snow| +cond|freezing rain|23|23|FrzgRn| +cond|freezing drizzle|23|23|FrzgRn| +cond|freezing fog|6|11|FrzgFog| +cond|hail|23|23|Hail| +cond|heavy rain|8|12|Rain| +cond|light rain|22|15|Rain| +cond|showers|22|15|Showers| +cond|rain|20|14|Rain| +cond|fog|6|11|Fog| +cond|drizzle|22|15|Drizzle| +cond|mist|10|10|Mist| +cond|haze|7|7|Haze| +cond|dust|7|7|Dust| +cond|smoke|7|7|Smoke| +cond|volcanic|7|7|Volcanic Ash| +cond|sand|7|7|Sand| +cond|overcast|18|18|Overcast| +cond|mostly cloudy|2|4|Mostly Cloudy| +cond|partly cloudy|19|4|Partly Cloudy| +cond|few clouds|9|4|Few Clouds| +cond|clear|0|1|Clear| +cond|cloud|19|4|Variable Clouds| +# +'; + +$config = explode("\n",$Condstring); +foreach ($config as $key => $rec) { // load the parser condition strings + $recin = trim($rec); + if ($recin and substr($recin,0,1) <> '#') { // got a non comment record + list($type,$keyword,$dayicon,$nighticon,$condition) = explode('|',$recin . '|||||'); + + if (isset($type) and strtolower($type) == 'cond' and isset($condition)) { + $Conditions["$keyword"] = "$dayicon\t$nighticon\t$condition"; +// $Debig .= "\n"; + } + } // end if not comment or blank +} // end loading of loop over config recs + + + +return; + +} +// ------------------------------------------------------------------ +function mtr_get_iconnumber ($time,$condString,$sunrise,$sunset) { + // Many thanks to Larry at Anole Computer for the basis of + // this routine. + // adapted by Ken True to be compatible with WD icon set + global $Icons, $IconsText, $Conditions, $Debug; + + $Debug .= "\n"; + if(!preg_match('/^\d{1,2}:\d{2}[:\d{2}]{0,1}\s*[am|pm]*$/i',$sunrise)) { $sunrise = ''; } + if(!preg_match('/^\d{1,2}:\d{2}[:\d{2}]{0,1}\s*[am|pm]*$/i',$sunset)) { $sunset = ''; } + + $sunrise2 = mtr_fixupTime(($sunrise<>'')?"$sunrise":"6:00a"); + $sunset2 = mtr_fixupTime(($sunset<>'')?"$sunset":"7:00p"); + $time2 = mtr_fixupTime(($time<>'')?"$time":date("H:i",time())); + if ($time2 >= $sunrise2 and $time2 <= $sunset2) { + $daynight = 'day'; + } // end if + else { + $daynight = 'night'; + } // end else + $Debug .= "\n"; + $condString = trim($condString); + reset($Conditions); // Do search in load order + + $iconnumb = 5; // default is a sunny icon + // scan over the conditions table and see if an icon fits the description in the table + foreach ($Conditions as $cond => $condrec) { // look for matching condition + + if(preg_match("!$cond!i",$condString,$mtemp)) { + list($dayicon,$nighticon,$condition) = explode("\t",$condrec); + if (preg_match('|night|i',$daynight)) { + $iconnumb = $nighticon; + } else { + $iconnumb = $dayicon; + } + break; + } + } // end of conditions search + + return $iconnumb; +} +// ------------------------------------------------------------------ +function mtr_fixupTime ($intime) { + global $Debug; + $tfixed = preg_replace('/\s+([AM|PM])/i',"$1",$intime); + $tfixed = preg_replace('/^(\S+)\s+(\S+)$/is',"$2",$tfixed); + $t = explode(':',$tfixed); + if (preg_match('/p/i',$tfixed)) { $t[0] = $t[0] + 12; } + if ($t[0] > 23) {$t[0] = 12; } + if (preg_match('/^12.*a/i',$tfixed)) { $t[0] = 0; } + if ($t[0] < '10') {$t[0] = sprintf("%02d",$t[0]); } // leading zero on hour. + $t2 = join(':',$t); // put time back to gether; + $t2 = preg_replace('/[^\d\:]/is','',$t2); // strip out the am/pm if any + $Debug .= "\n"; + return($t2); + +} + +// --------------------------------------------------------- + +function mtr_process($metar,$icao) { + global $lang,$Debug, $mtrInfo, $metarPtr, $group,$UOMS; + $Debug .= "\n"; + $Debug .= "\n"; + // This function directs the examination of each group of the METAR. The problem + // with a METAR is that not all the groups have to be there. Some groups could be + // missing. Fortunately, the groups must be in a specific order. (This function + // also assumes that a METAR is well-formed, that is, no typographical mistakes.) + // This function uses a function variable to organize the sequence in which to + // decode each group. Each function checks to see if it can decode the current + // METAR part. If not, then the group pointer is advanced for the next function + // to try. If yes, the function decodes that part of the METAR and advances the + // METAR pointer and group pointer. (If the function can be called again to + // decode similar information, then the group pointer does not get advanced.) + // This function was modified by Ken True - webmaster@saratoga-weather.org to + // work with the template sets. + $lang = 'en'; + foreach ($mtrInfo as $i => $value) { // clear out prior contents + unset($mtrInfo[$i]); +// $mtrInfo[$i] = ''; + } +// $Debug .= "\n"; + $mtrInfo['STATION'] = $icao; + $mtrInfo['METAR'] = $metar; + + if ($metar != '') { + $metarParts = explode(' ',$metar); + $groupName = array('mtr_get_station', + 'mtr_get_time', + 'mtr_get_station_type', + 'mtr_get_wind', + 'mtr_get_var_wind', + 'mtr_get_visibility', + 'mtr_get_runway', + 'mtr_get_conditions', + 'mtr_get_cloud_cover', + 'mtr_get_temperature', + 'mtr_get_altimeter'); + $metarPtr = 3; // mtr_get_station identity is ignored + $group = 1; // start with Time + + while ($group < count($groupName)) { + $part = $metarParts[$metarPtr]; + $Debug .= "\n"; + $groupName[$group]($part); // $groupName is a function variable + } + } else { + $mtrInfo['ERROR'] = 'Data not available'; + } + $Debug .= "\n"; +} + +//---------------------------------------------------------------- +// Ignore station code. Script assumes this matches requesting +// $station. This function is never called. It is here for +// completeness of documentation. +function mtr_get_station($part) +{ global $lang,$Debug, $mtrInfo, $metarPtr, $group; + if (strlen($part) == 4 and $group == 0) + { + $group++; + $metarPtr++; + } +} + +function mtr_get_time($part) +{ global $lang,$Debug, $mtrInfo, $metarPtr, $group; + // Ignore observation time. This information is found in the + // first line of the NWS file. + // Format is ddhhmmZ where dd = day, hh = hours, mm = minutes + // in UTC time. + if (substr($part,-1) == 'Z') { + $dd = substr($part,0,2); + $hh = substr($part,2,2); + $mm = substr($part,4,2); + + $metarPtr++; + } + $group++; +} + +function mtr_get_station_type($part) +{ global $lang,$Debug, $mtrInfo, $metarPtr, $group; + // Ignore station type if present. + if ($part == 'AUTO' || $part == 'COR') + $metarPtr++; + $group++; +} + + function mtr_speed($part, $unit) + { + global $lang,$Debug, $mtrInfo, $metarPtr, $group, $UOMS; + // Convert wind speed into miles per hour. + // Some other common conversion factors (to 6 significant digits): + // 1 mi/hr = 1.15080 knots = 0.621371 km/hr = 2.23694 m/s + // 1 ft/s = 1.68781 knots = 0.911344 km/hr = 3.28084 m/s + // 1 knot = 0.539957 km/hr = 1.94384 m/s + // 1 km/hr = 1.852 knots = 3.6 m/s + // 1 m/s = 0.514444 knots = 0.277778 km/s + if ($unit == 'KT') + $speed = 1.1508 * $part; // from knots + elseif ($unit == 'MPS') + $speed = 2.23694 * $part; // from meters per second + else + $speed = 0.621371 * $part; // from km per hour + $speedkph = $speed / 0.621371; + if (preg_match('|mph|i',$UOMS['WIND'])) + $speed ="" . round($speed) . " mph (". round($speedkph) . " km/h)"; + else + $speed = "" . round($speedkph) . " km/h"; + return $speed; + } + +//------------------------------------------------------------------------- +// Decodes wind direction and speed information. +// Format is dddssKT where ddd = degrees from North, ss = speed, +// KT for knots or dddssGggKT where G stands for gust and gg = gust +// speed. (ss or gg can be a 3-digit number.) +// KT can be replaced with MPH for meters per second or KMH for +//kilometers per hour. +function mtr_get_wind($part) +{ global $lang,$Debug, $mtrInfo, $metarPtr, $group; + + + if (preg_match('/^([0-9G]{5,10}|VRB[0-9G]{2,7})(KT|MPS|KMH)$/',$part,$pieces)) + { + $part = $pieces[1]; + $unit = $pieces[2]; + if ($part == '00000') + { + $mtrInfo['WIND'] = 'calm'; // no wind + } + else + { + preg_match('/([0-9]{3}|VRB)([0-9]{2,3})G?([0-9]{2,3})?/',$part,$pieces); + if ($pieces[1] == 'VRB') + $direction = 'varies'; + else + { + $angle = (integer) $pieces[1]; + $compass = array('N','NNE','NE','ENE','E','ESE','SE','SSE', + 'S','SSW','SW','WSW','W','WNW','NW','NNW'); + $direction = $compass[round($angle / 22.5) % 16]; + } + if (!isset($pieces[3]) or (isset($pieces[3]) and $pieces[3] == 0 ) ) { + $gust = ''; + } else { + $gust = ', gusting to ' . mtr_speed($pieces[3], $unit); + } + if ($unit == 'KT') { + $speed = 1.1508 * $pieces[2]; // from knots + } elseif ($unit == 'MPS') { + $speed = 2.23694 * $pieces[2]; // from meters per second + } else { + $speed = 0.621371 * $pieces[2]; // from km per hour + } + + $mtrInfo['WINDMPH'] = $direction . ' at ' . round($speed) . ' mph'; + $mtrInfo['WIND'] = $direction . ' at ' . mtr_speed($pieces[2], $unit) . $gust; + } + $metarPtr++; + } + $group++; +} + +function mtr_get_var_wind($part) +{ global $lang,$Debug, $mtrInfo, $metarPtr, $group; + // Ignore variable wind direction information if present. + // Format is fffVttt where V stands for varies from fff + // degrees to ttt degrees. + if (preg_match('/([0-9]{3})V([0-9]{3})/',$part,$pieces)) + $metarPtr++; + $group++; +} + + +//------------------------------------------------------------------ +// Decodes visibility information. This function will be called a +// second time if visibility is limited to an integer mile plus a +// fraction part. +// Format is mmSM for mm = statute miles, or m n/dSM for m = mile +// and n/d = fraction of a mile, or just a 4-digit number nnnn (with +// leading zeros) for nnnn = meters. + +function mtr_get_visibility($part) { + + global $lang,$Debug, $mtrInfo, $metarPtr, $group, $UOMS; + static $integerMile = ''; + if (strlen($part) == 1) + { + // visibility is limited to a whole mile plus a fraction part + $integerMile = $part . ' '; + $metarPtr++; + } + elseif (preg_match('|^\d{4}$|',$part)) { + // international code for meters of visibility + $kmVis = round($part/1000); + $miVis = round($part/1609); + if ($miVis > 1) {$unit = ' miles';} else {$unit = ' mile';} + if (preg_match('|mph|i',$UOMS['WIND'])) { + $mtrInfo['VISIBILITY'] = " $miVis $unit ($kmVis km)"; + } else { + $mtrInfo['VISIBILITY'] = "$kmVis km"; + } + $integerMile = ''; + $metarPtr++; + $group++; + } + elseif (substr($part,-2) == 'SM') + { + // visibility is in miles + $part = substr($part,0,strlen($part)-2); + if (substr($part,0,1) == 'M') + { + $prefix = 'less than '; + $part = substr($part, 1); + } + else + $prefix = ''; + + if (preg_match('|mph|i',$UOMS['WIND'])) + { + if (($integerMile == '' && preg_match('![/]!',$part,$pieces)) || $part == '1') + $unit = ' mile'; + else + $unit = ' miles'; + } + $kmVis = round( $part * 1.6 ); + if (preg_match('|mph|i',$UOMS['WIND'])) + $mtrInfo['VISIBILITY'] = $prefix . $integerMile . + " $part $unit ($kmVis km)"; + else + $mtrInfo['VISIBILITY'] = "$kmVis km"; + $integerMile = ''; + $metarPtr++; + $group++; + } + elseif (substr($part,-2) == 'KM') + { + // unknown (Reported by NFFN in Fiji) + $integerMile = ''; + $metarPtr++; + $group++; + } + elseif (preg_match('/^([0-9]{4})/',$part,$pieces)) + { + // visibility is in meters + $distance = round($part/ 621.4, 1); // convert to miles + if ($distance > 5) + $distance = round($distance); + if ($distance <= 1) + $unit = ' mile'; + else + $unit = ' miles'; + $mtrInfo['VISIBILITY'] = $distance . $unit; + $integerMile = ''; + $metarPtr++; + $group++; + } + elseif ($part == 'CAVOK') + { + // good weather + if (preg_match('|mph|i',$UOMS['WIND'])) { + $mtrInfo['VISIBILITY'] = 'greater than 7 miles (10 km)'; // or 10 km + } else { + $mtrInfo['VISIBILITY'] = 'greater than 10 km'; // or 10 km + } + $mtrInfo['CONDITIONS'] = 'Clear'; +// $mtrInfo['CLOUDS'] = 'clear skies'; + $metarPtr++; + $group += 4; // can skip the next 3 groups + } + else + { + $group++; + } +} + +function mtr_get_runway($part) +{ global $lang,$Debug, $mtrInfo, $metarPtr, $group; + // Ignore runway information if present. Maybe called a second time. + // Format is Rrrr/vvvvFT where rrr = runway number and + // vvvv = visibility in feet. +// if (substr($part,0,1) == 'R') + if(preg_match('|^\d{4}[NESW]+$|',$part)) { + // WMO formatted limited visibility + $metarPtr++; + return; + } + if(preg_match('|^R\d\d|',$part)) { + $metarPtr++; + } else { + $group++; + } +} + + + +function mtr_get_conditions($part) { +global $lang,$Debug, $mtrInfo, $metarPtr, $group; + // Decodes current weather conditions. This function maybe called several times + // to decode all conditions. To learn more about weather condition codes, visit section + // 12.6.8 - Present Weather Group of the Federal Meteorological Handbook No. 1 at + // www.nws.noaa.gov/oso/oso1/oso12/fmh1/fmh1ch12.htm + if(preg_match('|^R\d\d|',$part)) { // more than one runway conditions report? + $metarPtr++; + } + static $conditions = ''; + $Debug .= "\n"; + static $wxCode = array( + 'VC' => 'Nearby ', + 'MI' => 'Shallow ', + 'PR' => 'Partial ', + 'BC' => 'Patches of ', + 'DR' => 'Low Drifting ', + 'BL' => 'Blowing ', + 'SH' => 'Showers', + 'TS' => 'Thunderstorm', + 'FZ' => 'Freezing ', + 'DZ' => 'Drizzle', + 'RA' => 'Rain', + 'SN' => 'Snow', + 'SG' => 'Snow Grains', + 'IC' => 'Ice Crystals', + 'PE' => 'Ice Pellets', + 'GR' => 'Hail', + 'GS' => 'Small Hail', // and/or snow pellets + 'UP' => '', // leave 'Unknown' out of the conditions .. reads better :) + 'BR' => 'Mist', + 'FG' => 'Fog', + 'FU' => 'Smoke', + 'VA' => 'Volcanic Ash', + 'DU' => 'Widespread Dust', + 'SA' => 'Sand', + 'HZ' => 'Haze', + 'PY' => 'Spray', + 'PO' => 'Well-developed Dust/Sand Whirls', + 'SQ' => 'Squalls', + 'FC' => 'Funnel Cloud, Tornado, or Waterspout', + 'SS' => 'Sandstorm/Duststorm'); + if (preg_match('/^(-|\+|VC)?(TS|SH|FZ|BL|DR|MI|BC|PR|RA|DZ|SN|SG|GR|GS|PE|IC|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS)+$/',$part,$pieces)) { + $Debug .= "\n"; + $join = (strlen($conditions) == 0)?'':', '; // append conditions with a ', ' between + if (substr($part,0,1) == '-') { + $prefix = 'Light '; + $part = substr($part,1); + } + elseif (substr($part,0,1) == '+') { + $prefix = 'Heavy '; + $part = substr($part,1); + } + elseif (substr($part,0,2) == 'VC') { + $prefix = 'Nearby '; + $part = substr($part,2); + } + else $prefix = ''; // moderate conditions have no descriptor + $conditions .= $join . $prefix; + // The 'showers' code 'SH' is moved behind the next 2-letter code to make the English translation read better. + if (substr($part,0,2) == 'SH') $part = substr($part,2,2) . substr($part,0,2). substr($part, 4); + while ($code = substr($part,0,2)) { + $join = (strlen($conditions) < 1)?' ':', '; + $conditions .= $wxCode[$code]. $join; + $part = substr($part,2); + } + $conditions = preg_replace('|, $|','',$conditions); // remove trailing comma if any + $conditions = preg_replace('| , |is',', ',$conditions); // replace space before comma + $conditions = preg_replace('|\s+|is',' ',$conditions); // remove multiple spaces + $mtrInfo['CONDITIONS'] = $conditions; +// $Debug .= "\n"; + $metarPtr++; + } + else { + $mtrInfo['CONDITIONS'] = $conditions; + $group++; +// $Debug .= "\n"; + $conditions = ''; +// $Debug .= "\n"; + } +} + +function mtr_get_cloud_cover($part) { +global $lang,$Debug, $mtrInfo, $metarPtr, $group, $UOMS; + // Decodes cloud cover information. This function maybe called several times + // to decode all cloud layer observations. Only the last layer is saved. + // Format is SKC or CLR for clear skies, or cccnnn where ccc = 3-letter code and + // nnn = altitude of cloud layer in hundreds of feet. 'VV' seems to be used for + // very low cloud layers. (Other conversion factor: 1 m = 3.28084 ft) + $doMetric = preg_match('|C|',$UOMS['TEMP']); + static $cloudCode = array( + 'SKC' => 'Clear', + 'CLR' => 'Clear', + 'FEW' => 'Few Clouds', + 'FW' => 'Few Clouds', + 'SCT' => 'Partly Cloudy', + 'BKN' => 'Mostly Cloudy', + 'BK' => 'Mostly Cloudy', + 'OVC' => 'Overcast', +// 'NSC' => 'No significant clouds', // official designation.. we map to Partly Cloudy + 'NSC' => 'Partly Cloudy', +// 'NCD' => 'No cloud detected', // official designation .. we map to Clear + 'NCD' => 'Clear', +// 'TCU' => 'Towering Cumulus', // official designation .. we map to Thunder Storm + 'TCU' => 'Thunderstorm', +// 'CB' => 'Cumulonimbus', // official designation .. we map to Thunder Storm + 'CB' => 'Thunderstorm', + 'VV' => 'Overcast'); + $Debug .= "\n"; + if ($part == 'VV') { + $metarPtr++; + } + + if ($part == 'SKC' || $part == 'CLR' || $part == 'NSC' || $part == 'NCD'|| $part == 'TCU'|| $part == 'CB') { + $mtrInfo['CLOUDS'] = $cloudCode[$part]; + $metarPtr++; + $group++; + } + else { + if (preg_match('/^([A-Z]{2,3})([0-9]{3})/',$part,$pieces)) { // codes for CB and TCU are ignored + $mtrInfo['CLOUDS'] = $cloudCode[$pieces[1]]; + $altitude = (integer) 100 * $pieces[2]; // units are feet + $altitudeM = round($altitude/3.28084); + if(!isset($mtrInfo['CLOUD-DETAILS'])) {$mtrInfo['CLOUD-DETAILS'] = '';} + if($doMetric) { + $mtrInfo['CLOUD-DETAILS'] .= $cloudCode[$pieces[1]]." ${altitudeM} m\t"; + } else { + $mtrInfo['CLOUD-DETAILS'] .= $cloudCode[$pieces[1]]." ${altitude} ft\t"; + } + if ($pieces[1] == 'VV') { + $mtrInfo['CLOUDS'] = "Overcast"; + } else { + + } + $metarPtr++; + } + else { + $group++; + } + } +} + + function mtr_get_heat_index($tempF, $rh) + { global $lang,$Debug, $mtrInfo, $metarPtr, $group, $UOMS; + // Calculate Heat Index based on temperature in F and relative + //humidity (65 = 65%) + if ($tempF > 79 && $rh > 39) + { + $hiF = -42.379 + 2.04901523 * $tempF + 10.14333127 * + $rh - 0.22475541 * $tempF * $rh; + $hiF += -0.00683783 * pow($tempF, 2) - 0.05481717 * pow($rh, 2); + $hiF += 0.00122874 * pow($tempF, 2) * $rh + 0.00085282 * $tempF + * pow($rh, 2); + $hiF += -0.00000199 * pow($tempF, 2) * pow($rh, 2); + $hiF = round($hiF); + $hiC = round(($hiF - 32) / 1.8); + if(preg_match('|C|',$UOMS['TEMP'])) { + $mtrInfo['HEAT INDEX'] = "$hiC°C"; + } else { + $mtrInfo['HEAT INDEX'] = "$hiF°F ($hiC°C)"; + } + } + } + + function mtr_get_wind_chill($tempF) + { + global $lang,$Debug, $mtrInfo, $metarPtr, $group,$UOMS; + + // Calculate Wind Chill Temperature based on temperature in F and + // wind speed in miles per hour + if (isset($mtrInfo['WINDMPH']) and $tempF < 51 && $mtrInfo['WINDMPH'] !== 'calm') + { + $pieces = explode(' ', $mtrInfo['WINDMPH']); + $windspeed = (integer) $pieces[2]; // wind speed must be in mph + if ($windspeed > 3) + { + $chillF = 35.74 + 0.6215 * $tempF - 35.75 * pow($windspeed, 0.16) + + 0.4275 * $tempF * pow($windspeed, 0.16); + $chillF = round($chillF); + $chillC = round(($chillF - 32) / 1.8); + if(preg_match('|C|',$UOMS['TEMP'])) { + $mtrInfo['WIND CHILL'] = "$chillC°C"; + } else { + $mtrInfo['WIND CHILL'] = "$chillF°F ($chillC°C)"; + } + } + } + } + +//------------------------------------------------------------------------- +// Decodes temperature and dew point information. Relative humidity is +// calculated. Also, depending on the temperature, Heat Index or Wind +// Chill Temperature is calculated. +// Format is tt/dd where tt = temperature and dd = dew point temperature. +// All units are in Celsius. A 'M' preceeding the tt or dd indicates a +// negative temperature. Some stations do not report dew point, so the +// format is tt/ or tt/XX. +function mtr_get_temperature($part) +{ + global $lang, $Debug, $mtrInfo, $metarPtr, $group, $UOMS; + + if (preg_match('/^(M?[0-9]{2})\/(M?[0-9]{2}|[X]{2})?$/',$part,$pieces)) + { + $doMetric = preg_match('|C|',$UOMS['TEMP']); + + $tempC = (integer) strtr($pieces[1], 'M', '-'); + $tempF = round(1.8 * $tempC + 32); + if (!$doMetric) { + $mtrInfo['TEMP'] = $tempF . "°F (" . $tempC . "°C)"; + } else { + $mtrInfo['TEMP'] = $tempC . "°C"; + } + mtr_get_wind_chill($tempF); + if (isset($pieces[2]) and strlen($pieces[2]) != 0 && $pieces[2] != 'XX') + { + $dewC = (integer) strtr($pieces[2], 'M', '-'); + $dewF = round(1.8 * $dewC + 32); + if (!$doMetric) { + $mtrInfo['DEWPT'] = $dewF . "°F (" . $dewC . "°C)"; + } else { + $mtrInfo['DEWPT'] = $dewC . "°C"; + } + $rh = round(100 * pow((112 - (0.1 * $tempC) + $dewC) / + (112 + (0.9 * $tempC)), 8)); + $mtrInfo['HUMIDITY'] = $rh . '%'; + mtr_get_heat_index($tempF, $rh); + } + $metarPtr++; + $group++; + } + else + { + $group++; + } +} + + +//----------------------------------------------------------------------- +// Decodes altimeter or barometer information. +// Format is Annnn where nnnn represents a real number as nn.nn in +// inches of Hg, +// or Qpppp where pppp = hectoPascals. +// Some other common conversion factors: +// 1 millibar = 1 hPa +// 1 in Hg = 0.02953 hPa +// 1 mm Hg = 25.4 in Hg = 0.750062 hPa +// 1 lb/sq in = 0.491154 in Hg = 0.014504 hPa +// 1 atm = 0.33421 in Hg = 0.0009869 hPa + +function mtr_get_altimeter($part) +{ global $Debug, $mtrInfo, $metarPtr, $group, $UOMS; + if (preg_match('/^(A|Q)([0-9]{4})/',$part,$pieces)) + { + if ($pieces[1] == 'A') + { + $pressureIN = substr($pieces[2],0,2) . '.' . substr($pieces[2],2); + // units are inches Hg, converts to hectoPascals + $pressureHPA = round($pressureIN / 0.02953,1); + } + else + { + $pressureHPA = (integer) $pieces[2]; // units are hectoPascals + $pressureIN = round(0.02953 * $pressureHPA,2); // convert to inches Hg + } + if(preg_match('|inhg|i',$UOMS['BARO'])) { + $mtrInfo['BAROMETER'] = "$pressureIN inHg ($pressureHPA hPa)"; + } else { + $mtrInfo['BAROMETER'] = "$pressureHPA hPa"; + } + $metarPtr++; + $group++; + } + else + { + $group++; + } +} + + +// end of the mtr_process function set +//---------------------------------------------- + +?> \ No newline at end of file diff --git a/include-metar-display.php b/include-metar-display.php new file mode 100644 index 0000000..14378c1 --- /dev/null +++ b/include-metar-display.php @@ -0,0 +1,354 @@ +
+\n"; + +if(file_exists("get-metar-conditions-inc.php")) { + include_once("get-metar-conditions-inc.php"); + print "\n"; +} else { + print "

Unable to find/load get-metar-conditions-inc.php.

\n"; + return; +} + + + +$UOM = "$uomTemp,$uomWind,$uomBaro,$uomRain"; +//$UOM = "°C,km/h,hPa,mm"; +// +$toDisplay = array( // keys in $mtr array to display (if they exist) and in this order +'TEMP' => 'Temperature', +'WIND CHILL' => 'Wind Chill', +'HEAT INDEX' => 'Heat Index', +'WIND' => 'Wind', +'DEWPT' => 'Dew Point', +'HUMIDITY' => 'Humidity', +'BAROMETER' => 'Barometer', +'CONDITIONS' => 'Summary', +'CLOUDS' => 'Clouds', +'VISIBILITY' => 'Visibility', +'CLOUD-DETAILS' => 'Cloud details', +); + +// Get translation values if available +foreach ($toDisplay as $key => $val) { + $toDisplay[$key] = langtransstr($val); +} + +if ($mtrLang <> 'en') { // try changing windrose graphics test for the Calm graphic + $tfile = preg_replace('|^'.$wrName.'|',$wrName.$mtrLang.'-',$wrCalm); + print "\n"; + if (file_exists($condIconDir.$tfile)) { + $wrCalm = $tfile; // change the PHP dashboard settings too + $wrName = $wrName . $mtrLang . '-'; + print "\n"; + } +} +$maxCols = 1; +if(isset($SITE['CSSscreen']) and preg_match('|wide|',$SITE['CSSscreen'])) { + $maxCols = 3; +} +$thisCol = 0; + +echo "\n"; +echo "\n"; + +foreach ($MetarList as $idx => $Mrec) { + + list($mtrICAO,$mtrName,$mtrDistanceM,$mtrDistanceK,$direction) = explode('|',$Mrec.'|||||'); + if($mtrICAO == '') { continue;} + $Debug = ''; + list($condwords,$iconnum,$condicon,$condicondesc,$mtr,$metarGMT) = + mtr_conditions($mtrICAO, $time, $sunrise, $sunset, true,$UOM); + + $metarUpdated = date($SITE['timeFormat'],$metarGMT); + if(isset($_REQUEST['debug']) and strtolower($_REQUEST['debug']) == 'y') { + print $Debug; + print "\n"; + } + +// now $mtr array contains the decoded values +foreach ($toDisplay as $key => $legend) { + + if (!isset($mtr[$key]) or strlen($mtr[$key]) < 1) { continue; } + if($key == 'CONDITIONS' or $key == 'CLOUDS') { + $mtr[$key] = fixupCondition($mtr[$key]); // handle translations if needed + } + if($key == 'CLOUD-DETAILS') { + $cd = explode("\t",$mtr[$key]); + foreach ($cd as $k => $cdrec) { + if(preg_match('/^(.*) (\d+.*)$/',$cdrec,$matches)) { + + $cd[$k] = fixupCondition($matches[1]) . " ".$matches[2]; + print "\n"; + } + } + + $mtr[$key] = join("
\n",$cd); + } + if($key == 'WIND') { + $t = explode(" ",$mtr[$key]); + $dirlabel = $t[0]; + if(isset($t[0])) $t[0] = langtransstr($t[0]); // translate wind direction + if(isset($t[1])) $t[1] = ''; // remove 'at' + $mtr[$key] = join(' ',$t); + } +} +// time to format the output for display +if($thisCol >= $maxCols) { + print "\n"; + print "\n"; + print "\n"; + $thisCol = 0; +} + +?> + +
 
+ + + + + + + + + + + + $legend) { + + if (!isset($mtr[$key]) or strlen($mtr[$key]) < 1) { continue; } + if ($key == 'WIND') {continue;} + $t = $mtr[$key]; + if ($key == 'VISIBILITY') { + $t = preg_replace('|greater than|i',langtransstr('greater than'),$t); + } + $t = preg_replace('|\((.*)\)|U'," , $1",$t); // fix parenthesis issue in RTL language + print " \n"; + print " \n"; + print " \n"; + print " \n"; +} + + print " \n"; + print " \n"; + print " \n"; + if(isset($_REQUEST['debug']) and strtolower($_REQUEST['debug']) == 'y') { + print " \n"; + print " \n"; + print " \n"; + } +?> + +
+ '' and $mtrDistanceK <> '') { + echo "
".langtransstr('Distance from station').": "; + if($direction <> '') { + echo " ".langtransstr($direction). " "; + } + if(isset($SITE['uomDistance']) and preg_match('|mi|i',$SITE['uomDistance'])) { + echo "${mtrDistanceM}mi, "; + } + //echo "${mtrDistanceK}km"; + + } ?> +
+ + $maxAge) { + print "
".langtransstr('NOT Current')."\n"; + } + ?> +
+ <?php $t1 = fixupCondition($condwords);
+                  echo $t1; ?>
+ +
+ +  + '') ) { // use calm instead + $wr = $condIconDir . $wrCalm; + } + $t = preg_match('|calm|i',$mtr['WIND'])?langtransstr('Calm'):$mtr['WIND']; + $t = preg_replace('|varies|i',langtransstr('varies'),$t); + $t = preg_replace('|gusting to|',langtransstr('Gust').":",$t); + $t = preg_replace('|\((.*)\)|U'," , $1",$t); + // fix parenthesis issue in RTL language + + ?> + <?php echo $wrtext; ?>
+ : + + +
${legend}:".$t."
".$mtr['RAW-METAR']."
".$mtr['METAR']."
+
+ +
+ + '.jpg') { + $tempicon = preg_replace('|\.jpg|',$condIconType,$tempicon); + } + return($tempicon); + } + +// Function to process %Currentsolarcondition% string and +// remove duplicate stuff, then fix capitalization, and translate from English if needed +// + function fixupCondition( $inCond ) { + global $DebugMode; + + $Cond = str_replace('_',' ',trim($inCond)); + $Cond = strtolower($Cond); + $dt = ''; + + $vals = array(); + if(strpos($Cond,'/') !==false) { + $dt .= "\n"; + $vals = explode("/",$Cond); + } + if(strpos($Cond,',') !==false) { + $dt .= "\n"; + $vals = explode(",",$Cond); + } + $ocnt = count($vals); + if($ocnt < 1) { return(langtransstr(trim($inCond))); } + foreach ($vals as $k => $v) { + if($DebugMode) { $dt .= "\n"; } + $v = ucfirst(strtolower(trim($v))); + $vals[$k] = langtransstr($v); + if($DebugMode) { $dt .= "\n"; } + } + + if($vals[0] == '') {$junk = array_shift($vals);} + if(isset($vals[2]) and $vals[0] == $vals[2]) {$junk = array_pop($vals);} + reset($vals); + $t = join(', ',$vals); + +// return($Cond . "' orig=$ocnt n=" . count($vals) ." t='$t'"); + if($DebugMode) { + $t = "" . $dt . $t; + } + return($t); + + } +?> \ No newline at end of file diff --git a/leftmain.php b/leftmain.php index 5b6f994..927abad 100644 --- a/leftmain.php +++ b/leftmain.php @@ -28,9 +28,9 @@ if (isset($displayname)) { $displayname = addslashes($displayname); $query = "select displayname from " . $db_prefix . "employees where displayname = '" . $displayname . "'"; - $emp_name_result = mysql_query($query); + $emp_name_result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($emp_name_result)) { + while ($row = mysqli_fetch_array($emp_name_result)) { $tmp_displayname = "" . $row['displayname'] . ""; } if ((!isset($tmp_displayname)) && (!empty($displayname))) { @@ -45,9 +45,9 @@ if (isset($fullname)) { $fullname = addslashes($fullname); $query = "select empfullname from " . $db_prefix . "employees where empfullname = '" . $fullname . "'"; - $emp_name_result = mysql_query($query); + $emp_name_result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($emp_name_result)) { + while ($row = mysqli_fetch_array($emp_name_result)) { $tmp_empfullname = "" . $row['empfullname'] . ""; } if ((!isset($tmp_empfullname)) && (!empty($fullname))) { @@ -76,152 +76,11 @@ ob_end_flush(); } -if ($display_weather == 'yes') { - - include 'phpweather.php'; - $metar = get_metar($metar); - $data = process_metar($metar); - - if ($weather_units == "f") { - $mph = " mph"; - $miles = " miles"; - - // weather info // - - if (!isset($data['temp_f'])) { - $temp = ''; - } else { - $temp = $data['temp_f']; - } - if (!isset($data['windchill_f'])) { - $windchill = ''; - } else { - $windchill = $data['windchill_f']; - } - if (!isset($data['wind_dir_text_short'])) { - $wind_dir = ''; - } else { - $wind_dir = $data['wind_dir_text_short']; - } - if (!isset($data['wind_miles_per_hour'])) { - $wind = ''; - } else { - $wind = round($data['wind_miles_per_hour']); - } - if ($wind == 0) { - $wind_dir = 'None'; - $mph = ''; - $wind = ''; - } else { - $wind_dir = $wind_dir; - } - if (!isset($data['visibility_miles'])) { - $visibility = ''; - } else { - $visibility = $data['visibility_miles'] . $miles; - } - if (!isset($data['rel_humidity'])) { - $humidity = 'None'; - } else { - $humidity = round($data['rel_humidity'], 0); - } - if (!isset($data['time'])) { - $time = ''; - } else { - $time = date($timefmt, $data['time']); - } - if (!isset($data['cloud_layer1_condition'])) { - $cloud_cover = ''; - } else { - $cloud_cover = $data['cloud_layer1_condition']; - } - if (($temp <> '') && ($temp >= '70') && ($humidity <> '')) { - $heatindex = number_format(-42.379 + (2.04901523 * $temp) + (10.1433312 * $humidity) - (0.22475541 * $temp * $humidity) - - (0.00683783 * ($temp * $temp)) - (0.05481717 * ($humidity * $humidity)) - + (0.00122874 * ($temp * $temp) * $humidity) + (0.00085282 * $temp * ($humidity * $humidity)) - - (0.00000199 * ($temp * $temp) * ($humidity * $humidity))); - } - } else { - $mph = " kmh"; - $miles = " km"; - - // weather info // - - if (!isset($data['temp_c'])) { - $temp = ''; - } else { - $temp = $data['temp_c']; - } - if (!isset($data['temp_f'])) { - $tempF = ''; - } else { - $tempF = $data['temp_f']; - } - if (!isset($data['windchill_c'])) { - $windchill = ''; - } else { - $windchill = $data['windchill_c']; - } - if (!isset($data['wind_dir_text_short'])) { - $wind_dir = ''; - } else { - $wind_dir = $data['wind_dir_text_short']; - } - if (!isset($data['wind_meters_per_second'])) { - $wind = ''; - } else { - $wind = round($data['wind_meters_per_second'] / 1000 * 60 * 60); - } - if ($wind == 0) { - $wind_dir = 'None'; - $mph = ''; - $wind = ''; - } else { - $wind_dir = $wind_dir; - } - if (!isset($data['visibility_km'])) { - $visibility = ''; - } else { - $visibility = $data['visibility_km'] . $miles; - } - if (!isset($data['rel_humidity'])) { - $humidity = 'None'; - } else { - $humidity = round($data['rel_humidity'], 0); - } - if (!isset($data['time'])) { - $time = ''; - } else { - $time = date($timefmt, $data['time']); - } - if (!isset($data['cloud_layer1_condition'])) { - $cloud_cover = ''; - } else { - $cloud_cover = $data['cloud_layer1_condition']; - } - if (($tempF <> '') && ($tempF >= '70') && ($humidity <> '')) { - $heatindexF = number_format(-42.379 + (2.04901523 * $tempF) + (10.1433312 * $humidity) - (0.22475541 * $tempF * $humidity) - - (0.00683783 * ($tempF * $tempF)) - (0.05481717 * ($humidity * $humidity)) - + (0.00122874 * ($tempF * $tempF) * $humidity) + (0.00085282 * $tempF * ($humidity * $humidity)) - - (0.00000199 * ($tempF * $tempF) * ($humidity * $humidity))); - $heatindex = round(($heatindexF - 32) * 5 / 9); - } - } - if ((isset($heatindex)) || ($windchill <> '')) { - if (!isset($heatindex)) { - $feelslike = $windchill; - } else { - $feelslike = $heatindex; - } - } else { - $feelslike = $temp; - } -} echo "\n"; echo " \n"; -echo " \n"; if ($request == 'POST') { @@ -392,9 +233,9 @@ class=misc_items style='padding-left:0px;padding-right:0px;' tabindex=5>\n"; echo "\n"; @@ -514,9 +355,9 @@ class=misc_items style='padding-left:0px;padding-right:0px;' tabindex=5>\n"; echo "\n"; diff --git a/sidebar-metar-display.php b/sidebar-metar-display.php new file mode 100644 index 0000000..8e807c4 --- /dev/null +++ b/sidebar-metar-display.php @@ -0,0 +1,103 @@ + + + + +\n"; +# end of utility functions +?> + +Metar display script from Saratoga-Weather.org

\n"; + } else { + print "

Sorry.. include-metar-display.php not found

\n"; + } +?> From fad72f821d53f20bd6ecbb63cf4385e8ba0f6876 Mon Sep 17 00:00:00 2001 From: Rick Boatright Date: Wed, 25 Jan 2017 17:56:26 -0600 Subject: [PATCH 02/17] Create metar-images folder --- metar-images/bkn.gif | Bin 0 -> 9686 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 metar-images/bkn.gif diff --git a/metar-images/bkn.gif b/metar-images/bkn.gif new file mode 100644 index 0000000000000000000000000000000000000000..980e5eea8848fa2964c488c9b8cd18ae84cdc8fd GIT binary patch literal 9686 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

qGn~VOolnsMsM%d2y_3Pe8QjI_Q?+2QY2DMg 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 literal 0 HcmV?d00001 From 8a8a3a9490f754c2db5a1b65cd61a4fa43ec2273 Mon Sep 17 00:00:00 2001 From: Rick Boatright Date: Wed, 25 Jan 2017 18:00:53 -0600 Subject: [PATCH 03/17] add metar images part 1 --- metar-images/E.gif | Bin 0 -> 892 bytes metar-images/ENE.gif | Bin 0 -> 901 bytes metar-images/ESE.gif | Bin 0 -> 901 bytes metar-images/N.gif | Bin 0 -> 888 bytes metar-images/NE.gif | Bin 0 -> 896 bytes metar-images/NNE.gif | Bin 0 -> 905 bytes metar-images/NNW.gif | Bin 0 -> 906 bytes metar-images/NW.gif | Bin 0 -> 888 bytes metar-images/S.gif | Bin 0 -> 889 bytes metar-images/SE.gif | Bin 0 -> 892 bytes metar-images/SSE.gif | Bin 0 -> 905 bytes metar-images/SSW.gif | Bin 0 -> 907 bytes metar-images/SW.gif | Bin 0 -> 896 bytes metar-images/W.gif | Bin 0 -> 890 bytes metar-images/bkn.jpg | Bin 0 -> 1359 bytes metar-images/dust.gif | Bin 0 -> 26827 bytes metar-images/dust.jpg | Bin 0 -> 1779 bytes metar-images/falling-old.gif | Bin 0 -> 54 bytes metar-images/falling.gif | Bin 0 -> 54 bytes metar-images/few.gif | Bin 0 -> 9505 bytes metar-images/few.jpg | Bin 0 -> 4919 bytes metar-images/fg.gif | Bin 0 -> 19198 bytes metar-images/fg.jpg | Bin 0 -> 1019 bytes metar-images/hazy.gif | Bin 0 -> 10773 bytes metar-images/hazy.jpg | Bin 0 -> 1150 bytes metar-images/hi_ntsra.gif | Bin 0 -> 10330 bytes metar-images/hi_ntsra.jpg | Bin 0 -> 1540 bytes metar-images/hi_tsra.gif | Bin 0 -> 10021 bytes metar-images/hi_tsra.jpg | Bin 0 -> 1668 bytes metar-images/index.php | 11 +++++++++ metar-images/ip.gif | Bin 0 -> 9508 bytes metar-images/ip.jpg | Bin 0 -> 3017 bytes metar-images/mist.gif | Bin 0 -> 10773 bytes metar-images/mist.jpg | Bin 0 -> 1840 bytes metar-images/nbkn.gif | Bin 0 -> 8285 bytes metar-images/nbkn.jpg | Bin 0 -> 1273 bytes metar-images/nfew.gif | Bin 0 -> 6877 bytes metar-images/nfew.jpg | Bin 0 -> 1320 bytes metar-images/nfg.gif | Bin 0 -> 19239 bytes metar-images/nfg.jpg | Bin 0 -> 764 bytes metar-images/night_clear.gif | Bin 0 -> 1015 bytes metar-images/night_cloudy.gif | Bin 0 -> 956 bytes metar-images/night_heavy_rain.gif | Bin 0 -> 1067 bytes metar-images/night_light_rain.gif | Bin 0 -> 972 bytes metar-images/night_partly_cloudy.gif | Bin 0 -> 1060 bytes metar-images/night_rain.gif | Bin 0 -> 986 bytes metar-images/night_sleet.gif | Bin 0 -> 972 bytes metar-images/night_snow.gif | Bin 0 -> 925 bytes metar-images/night_tstorm.gif | Bin 0 -> 1106 bytes metar-images/novc.gif | Bin 0 -> 5947 bytes metar-images/novc.jpg | Bin 0 -> 811 bytes metar-images/nra.gif | Bin 0 -> 12576 bytes metar-images/nra.jpg | Bin 0 -> 1873 bytes metar-images/nsct.gif | Bin 0 -> 8295 bytes metar-images/nsct.jpg | Bin 0 -> 1364 bytes metar-images/nscttra.gif | Bin 0 -> 9029 bytes metar-images/nscttsra.jpg | Bin 0 -> 1619 bytes metar-images/nshra.gif | Bin 0 -> 15034 bytes metar-images/nshra.jpg | Bin 0 -> 9204 bytes metar-images/nskc.gif | Bin 0 -> 4831 bytes metar-images/nskc.jpg | Bin 0 -> 1776 bytes metar-images/nsn.gif | Bin 0 -> 10936 bytes metar-images/nsn.jpg | Bin 0 -> 1275 bytes metar-images/nsvrtsra.gif | Bin 0 -> 8189 bytes metar-images/nsvrtsra.jpg | Bin 0 -> 1602 bytes metar-images/ntsra.gif | Bin 0 -> 11622 bytes metar-images/ntsra.jpg | Bin 0 -> 1671 bytes metar-images/nwind.jpg | Bin 0 -> 2141 bytes metar-images/ovc.gif | Bin 0 -> 9080 bytes metar-images/ovc.jpg | Bin 0 -> 1191 bytes metar-images/ra.gif | Bin 0 -> 12797 bytes metar-images/ra.jpg | Bin 0 -> 1839 bytes metar-images/ra1.gif | Bin 0 -> 12797 bytes metar-images/ra1.jpg | Bin 0 -> 1650 bytes metar-images/readme-graphics.txt | 33 +++++++++++++++++++++++++++ metar-images/rising.gif | Bin 0 -> 54 bytes metar-images/sct.gif | Bin 0 -> 10712 bytes metar-images/sct.jpg | Bin 0 -> 1333 bytes metar-images/scttsra.gif | Bin 0 -> 9917 bytes metar-images/scttsra.jpg | Bin 0 -> 1750 bytes metar-images/shra.gif | Bin 0 -> 15599 bytes metar-images/shra.jpg | Bin 0 -> 1576 bytes metar-images/shra2.gif | Bin 0 -> 15599 bytes metar-images/shra2.jpg | Bin 0 -> 1580 bytes metar-images/skc.gif | Bin 0 -> 8158 bytes metar-images/skc.jpg | Bin 0 -> 1167 bytes metar-images/sn.gif | Bin 0 -> 10212 bytes metar-images/sn.jpg | Bin 0 -> 1196 bytes metar-images/spacer.gif | Bin 0 -> 43 bytes metar-images/tsra.gif | Bin 0 -> 11564 bytes metar-images/tsra.jpg | Bin 0 -> 1869 bytes metar-images/wind.gif | Bin 0 -> 6271 bytes metar-images/wind.jpg | Bin 0 -> 1940 bytes metar-images/windyrain.gif | Bin 0 -> 16666 bytes metar-images/windyrain.jpg | Bin 0 -> 2285 bytes 95 files changed, 44 insertions(+) create mode 100644 metar-images/E.gif create mode 100644 metar-images/ENE.gif create mode 100644 metar-images/ESE.gif create mode 100644 metar-images/N.gif create mode 100644 metar-images/NE.gif create mode 100644 metar-images/NNE.gif create mode 100644 metar-images/NNW.gif create mode 100644 metar-images/NW.gif create mode 100644 metar-images/S.gif create mode 100644 metar-images/SE.gif create mode 100644 metar-images/SSE.gif create mode 100644 metar-images/SSW.gif create mode 100644 metar-images/SW.gif create mode 100644 metar-images/W.gif create mode 100644 metar-images/bkn.jpg create mode 100644 metar-images/dust.gif create mode 100644 metar-images/dust.jpg create mode 100644 metar-images/falling-old.gif create mode 100644 metar-images/falling.gif create mode 100644 metar-images/few.gif create mode 100644 metar-images/few.jpg create mode 100644 metar-images/fg.gif create mode 100644 metar-images/fg.jpg create mode 100644 metar-images/hazy.gif create mode 100644 metar-images/hazy.jpg create mode 100644 metar-images/hi_ntsra.gif create mode 100644 metar-images/hi_ntsra.jpg create mode 100644 metar-images/hi_tsra.gif create mode 100644 metar-images/hi_tsra.jpg create mode 100644 metar-images/index.php create mode 100644 metar-images/ip.gif create mode 100644 metar-images/ip.jpg create mode 100644 metar-images/mist.gif create mode 100644 metar-images/mist.jpg create mode 100644 metar-images/nbkn.gif create mode 100644 metar-images/nbkn.jpg create mode 100644 metar-images/nfew.gif create mode 100644 metar-images/nfew.jpg create mode 100644 metar-images/nfg.gif create mode 100644 metar-images/nfg.jpg create mode 100644 metar-images/night_clear.gif create mode 100644 metar-images/night_cloudy.gif create mode 100644 metar-images/night_heavy_rain.gif create mode 100644 metar-images/night_light_rain.gif create mode 100644 metar-images/night_partly_cloudy.gif create mode 100644 metar-images/night_rain.gif create mode 100644 metar-images/night_sleet.gif create mode 100644 metar-images/night_snow.gif create mode 100644 metar-images/night_tstorm.gif create mode 100644 metar-images/novc.gif create mode 100644 metar-images/novc.jpg create mode 100644 metar-images/nra.gif create mode 100644 metar-images/nra.jpg create mode 100644 metar-images/nsct.gif create mode 100644 metar-images/nsct.jpg create mode 100644 metar-images/nscttra.gif create mode 100644 metar-images/nscttsra.jpg create mode 100644 metar-images/nshra.gif create mode 100644 metar-images/nshra.jpg create mode 100644 metar-images/nskc.gif create mode 100644 metar-images/nskc.jpg create mode 100644 metar-images/nsn.gif create mode 100644 metar-images/nsn.jpg create mode 100644 metar-images/nsvrtsra.gif create mode 100644 metar-images/nsvrtsra.jpg create mode 100644 metar-images/ntsra.gif create mode 100644 metar-images/ntsra.jpg create mode 100644 metar-images/nwind.jpg create mode 100644 metar-images/ovc.gif create mode 100644 metar-images/ovc.jpg create mode 100644 metar-images/ra.gif create mode 100644 metar-images/ra.jpg create mode 100644 metar-images/ra1.gif create mode 100644 metar-images/ra1.jpg create mode 100644 metar-images/readme-graphics.txt create mode 100644 metar-images/rising.gif create mode 100644 metar-images/sct.gif create mode 100644 metar-images/sct.jpg create mode 100644 metar-images/scttsra.gif create mode 100644 metar-images/scttsra.jpg create mode 100644 metar-images/shra.gif create mode 100644 metar-images/shra.jpg create mode 100644 metar-images/shra2.gif create mode 100644 metar-images/shra2.jpg create mode 100644 metar-images/skc.gif create mode 100644 metar-images/skc.jpg create mode 100644 metar-images/sn.gif create mode 100644 metar-images/sn.jpg create mode 100644 metar-images/spacer.gif create mode 100644 metar-images/tsra.gif create mode 100644 metar-images/tsra.jpg create mode 100644 metar-images/wind.gif create mode 100644 metar-images/wind.jpg create mode 100644 metar-images/windyrain.gif create mode 100644 metar-images/windyrain.jpg diff --git a/metar-images/E.gif b/metar-images/E.gif new file mode 100644 index 0000000000000000000000000000000000000000..0f359bd84ff76df033ed355c9e0c8cfe4f036eb3 GIT binary patch literal 892 zcmZ?wbhEHb|4IHo|Nh9GmHYYcC-ZUU%)6N%{(N}# z>y^+cA(e9~1{V!(f4_b2$Gr*9Cgk7Gx4&Y)@!dwJt4{M@&7bySn#5@d=`+$#em-e= z(h`0%Jmh9b;Elj#(&0f9JCjj}%#MSN%?p{8Z5(E8NpfJY1_0aI`_KRY literal 0 HcmV?d00001 diff --git a/metar-images/ENE.gif b/metar-images/ENE.gif new file mode 100644 index 0000000000000000000000000000000000000000..d28335480169079610797092daf2e53063d63f48 GIT binary patch literal 901 zcmZ?wbhEHbIrDC2{{4K*%a+W?nQwo;?RwSq`LE}JHv%tx zy_9e};n=5Rb&u-q{kV7j%lT<9rrr2Cr24OB9DV@Ya4?3GT9atnd8XMRI1X#2L6c#Wu@N-%enJ5S_ zALo&B>AItEq3P6gCOw7~43iggFp07hHOzE8bhuF@t|)-xz(J;oDxK$Y4j3*EVi4uD Mk^M0_!GXaV0PUOf3jhEB literal 0 HcmV?d00001 diff --git a/metar-images/ESE.gif b/metar-images/ESE.gif new file mode 100644 index 0000000000000000000000000000000000000000..ebdc51926085c8087d906f6d46a5625741e72e74 GIT binary patch literal 901 zcmZ?wbhEHb)x&_eNY;HGrZ+V%b$OL4tzY|eck)p-*4x?oX@ z@29~Ad?)$gkB2}l5PL_-(GVEe5K#Qd!pHyw zIv@g+Cm1-A7#KNZJT@daGIR0>i3BrGFOyblz( z=d;-*GlPo;(r2Wf|9XD=`|ZP@4hx+U;yKB)_ru2It;AA__w&Kl-OJ6TZoR+A2 zRF`=-Q|_#s>s8mBdpRdRpS=3*YQpUV=HtxCcanj|0&RiVJ4%j*z`%xp;!hSv1|ZM@ z5uiN5z!A#8$iWh@;BXT^8=IDhheN|*Ms88F8i~ROE{p=&Ogm<5RC4c?mQ7;$8Mv^O wTPfIT&jiN>Eu326VF4==8&C0ain|3U6gjf=a!7F$FfghdWM)-jV_~oc0OEG;AOHXW literal 0 HcmV?d00001 diff --git a/metar-images/NE.gif b/metar-images/NE.gif new file mode 100644 index 0000000000000000000000000000000000000000..ff683fa6b422caf77d1c492814028a78b581dd88 GIT binary patch literal 896 zcmZ?wbhEHbY8&e=j7*;SHE3NxSha!oH_YUGEh5E8N}XEax?@6HUt!ZvM@3LfewfO zIh6&aM*!^g}Fe$!SLV#9u5|-B_4$hY>i?P3O7y^HZ*oK zNrXJmIH2Olsbf7)#bV;p(@orwNfs4~%bI#vrH_bw*sRdP&N4};U_%4bq2&xrObpfl DEIjuJ literal 0 HcmV?d00001 diff --git a/metar-images/NNE.gif b/metar-images/NNE.gif new file mode 100644 index 0000000000000000000000000000000000000000..c5dc9e41121343116b2aee95063eebbb048b1709 GIT binary patch literal 905 zcmZ?wbhEHbgxEVuj)uU%hJfNv7Dfgj z&;b#kJi)+`#=yuS!_nZvASs=4x!Nc>sDjZ%PejI2#JAp-~ QU`0XTg9cV{W+nz}0K-B2*8l(j literal 0 HcmV?d00001 diff --git a/metar-images/NNW.gif b/metar-images/NNW.gif new file mode 100644 index 0000000000000000000000000000000000000000..82aa82f374b83ceb85180b7f4fb3c40051ea1b78 GIT binary patch literal 906 zcmZ?wbhEHb`-1 z%Qi*#i}rrlyXD=Mhd&;M+zd&(oA&(IbIuc-qNhdeuh_@lj$Qp`^~@JDA-0c_qaiR* zA)xq^g^>XWbU*|sPcU$#Gca<56dX9n(a0gp)}i2VptD7Q-$caWk%CL3vKp5{fnZ`s zCofY8%LB*9>@89XX)`(;4zlsdD#TrgXj#KBv}<)Qh3fpsC1ii6LC YhK0x2mE9d8IulY3aS98uu`pNz0KFFW8UO$Q literal 0 HcmV?d00001 diff --git a/metar-images/NW.gif b/metar-images/NW.gif new file mode 100644 index 0000000000000000000000000000000000000000..3406147ebf61bcc8a3db56dba4b28ea5b803fe05 GIT binary patch literal 888 zcmZ?wbhEHbDYmf2cm98X`R=){r&ceH!Ex| z+Z5d|+WTQIQ02oP4?}K-0L^^<>p9R^(bJ+pb7F7Du70z6=8KsS+egXK5E!TsQ2fcl z$N&U7AOe&p7&t;17&&A-HYhM~OK?f3WH>fBw{kN|6#STw(89$e93WD_kkrD=qMoPo zq0q^3q6j}nLxOBFB7vA1JAu6ca>`|anypZ9*;`~2rK+i|v# zn<3lZZx6f?=zZP$=hYwnc=+evAL%pFW|z#~{(f6@zo_?F@1j?WDjrs>c(cOh zvJFsV?}xox-faP@1Zq#aoA&(IbIuc-qNhdeuh;`^S^Z}9%oj5uwvUpdAuv!Op!k!8 zkpT#FKm;gHFmQx1FmlMua6EjVnca{>Am9PRp+<2ry_yFf9yBrusfH;Sd^phDBdM&y zAaH=uV}b~qjLL+-r_KyIs=I0=iXZy4n6lo9x%o-;%shR5j~IhX>CNnX3JN?N4AuY) C{`MaL literal 0 HcmV?d00001 diff --git a/metar-images/SE.gif b/metar-images/SE.gif new file mode 100644 index 0000000000000000000000000000000000000000..b471f4b561072c0f99ccf36311149fa32e092541 GIT binary patch literal 892 zcmZ?wbhEHb8qHbHz4;laah~0^)hc1amJA05 FYXAwW^S=N9 literal 0 HcmV?d00001 diff --git a/metar-images/SSE.gif b/metar-images/SSE.gif new file mode 100644 index 0000000000000000000000000000000000000000..2bf6effa102401ebccd57056acf6d08a156b7c67 GIT binary patch literal 905 zcmZ?wbhEHbWX`R>NKgoao%lSY5{-oVaD}7K}@vvg)>!s@F)rC$8-Tr>N?or)`KOe$x zh9CZPxc6Ca{{8$FZ&rN!`)%^`$?M*(<2=C$G|m2seeCVn)o)hMd@&PZ`zSdY0s|ES zia%Kx8Gt|sM1b-H14kMIBL|DYqXP$;+4(I592}0YwJ>XP%&?f)*ebv-t+T{qVuNF& zlm%D8frW<;3P`vZHM~fC#M~#(+E(H4@IYHHlh&Lg8U;*8S#1>E9%L{+a$u6}<=WyP W=)|y8LtQMC>p?^73S@g8%lb=t{d^y8>oLT6UP~D?CiPI8){{8v+ z@2B^5Z`Z4?_kP^l{(k%9=aWDD`B3q&V%m#ox)*eLPV!h@wv;|2&3}?#<(x{|-Lyro z7R`Jy^ZBpmEl*m`e>vavw5#`7?~QLamcCvpcUEr2n-zyY9nQR)x$)h`x4+*)9570b zhQNS?fZ|UUMg}0z0TG})!N8Hhz{nxP(ZI;U$s#<@q0!+$OACXX&jp1AiyC-%IJ!2R z2yEzRk+aiyu|gr)Nl2Epq@m*Aq9z_D6BY%ICS^`GL9Gc29fy{BGRU!cZAkd2=)xdq cVQ0a$pz$c1591sOO$MhcP3lc@yc`VH09L2;e*gdg literal 0 HcmV?d00001 diff --git a/metar-images/SW.gif b/metar-images/SW.gif new file mode 100644 index 0000000000000000000000000000000000000000..fd72a722aa8a456cd0cda584085c960e764d2043 GIT binary patch literal 896 zcmZ?wbhEHbes6q-)d9b5Nyo$*EE&woC@{r&d&ujeb?tWZC%?t0ZV@J3+l?bylBCuiQx-1u%|#lwo0 zCoPL!Ewa39dFkt=^Iy()J?-j!)(bRt>FcF(XXStz4}UrgQ4BN+;($?dGz11D1QdU= zFfssv4u}Bd2?mZ>21X7Uj|~b94BS=<5g7*-IIyy?c+5F*P~k|Ykh#T?hCm0lW;V8x zJpl$O?u=p_v*vg>Cbc$dtIBmSTx@pWP*Oi9^5VgPvvZjEJQQvuJZR~#mgSmqA#uf} K<*dw14AubuqWUrb literal 0 HcmV?d00001 diff --git a/metar-images/W.gif b/metar-images/W.gif new file mode 100644 index 0000000000000000000000000000000000000000..8a9a90783d19fa9a42267626ef6d10d15d724a40 GIT binary patch literal 890 zcmZ?wbhEHb7?pOMtH0oBA$2AYLOJ=Wry#lJqyqmf4-A16smM1NX zUM;e`Yx4+*)9570bhQNS?fZ|UU zMg}0z0TG})!N3vDz{nxPao_-J69+qAL4tzfAx0)GlM)SqMGRcbyaG2)d~9s!7iRJM z;j!t-aSjHl88Mm;j;zyE`E4o+7@oPais*7BI0!blve?#gH3)1;Xk~Ea^^uVfV6X-N Dg$44f literal 0 HcmV?d00001 diff --git a/metar-images/bkn.jpg b/metar-images/bkn.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9ae5b40087a8d7d7d43a57fb0a1b1d34b18bd92d GIT binary patch literal 1359 zcmb7;`!|#c9Eac6JMYYh@Xjz=W0ZH$amjs*Le^k3rL7^wL`6oq3^j)lTj>yTnH{;a zmCI&aBk2rDtsTlSX)Te0-KtKoqRs8@N z03da&I`{KnEDi%{fOs`@)B`|B0|Vh82>u^yKo}SxfLJ1mI5^_;4NR$wfCzpe$vfT5 z*^52;NeBYaC*@}y0H}We7z^Um&>T@i4Gj(Ov+qAjfKj3&s83}ercMD7s%bzQ0@Z~O z0(b(_blPg*o3Rre%=Zm$(Yf7)BNAP0qe?02wolx%o~b1rI+<)#-DTDvJI+19;n^P* zuP5s+_%`PDmayv_IPI4oUuq0K5hrw8q4~>o3XtfY5a&{Pa`)AW1fw;pKGD@YXCE!n zVrSg^DEqbL3{|jXJAHWKt2o&|Zy(lkMFYdfq*;;qB8)w7tc=nF)D5(4Tn}{=M>E(`Wmthh`xu`fNGPRSHiP93P&nfV>;oY7h{j3m6yco^6JH&iG z7Y}E-zklZ1%6NL5LgwO%=N4Aqj#eeCco`Ti{>%z)smfj$h#8iEIPFUw@k?dw1`-PX7HtX(pu#2w(g3QGoMz`8WxPgvldAimqW&1ZZpBH#g?-kui z;zqF!Yo)uk`sSR~p|1QIrbD;ysQT?qwo`U!F3)AG$o-EN1!vaL=hmWCO-P8JL?$?8 zhkZ~nU#>0pWQWs|0J;#z#oa%Q{ICEWT-F=~L96inoct@T^lDsRLPDD%Y!>Xi*V zgYYG$<&HsmOx&S7a%yUm#RgYva$WQOcYTCjn$JUWZuUaG_Y2v@lVzD@1&K8=;u-`& z4C{|hjmE@Ig=DVrKTgx}ANYTB>gax|CHBwdVa+5P`VZBnY5#V z5fr{;=Wkl}{9fc3-*?47TL1fld`X?D==9T8e|h_vO2M>GwJ=t0m=IBNM`+W*(Y^la z#-_z^p1eu$Xxy6<_sz{oNj#&rbmq8iZFAI+w8B4Oo7`gPklhTSD^OX>5x~XQ??+|q zL}w&9iHdPv=!4>l?%Nzne(G@1_Phe|?osmP#zRp-N{1k38&1||!=kZ$*_~&Rumm}4 z<>;}WmOQfN(Ul+58;Vmkm-MF1WnI{E^)K+iDP{lw literal 0 HcmV?d00001 diff --git a/metar-images/dust.gif b/metar-images/dust.gif new file mode 100644 index 0000000000000000000000000000000000000000..8a2400c01a244d26a38cd671e075a315e0dda904 GIT binary patch literal 26827 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 literal 0 HcmV?d00001 diff --git a/metar-images/dust.jpg b/metar-images/dust.jpg new file mode 100644 index 0000000000000000000000000000000000000000..81a636e22fce15ab82c8dcf23764b785764d0053 GIT binary patch literal 1779 zcmbV}do1OQNJ z+bswJe@Zb4rlbs4cv4X$)M)?^5DJCBpbEb*MRvU69e`n!uttX*lr^cJ!1rF*VU>_s zgupr0v}<`iUBnaV;fY9;_D&sLy?w^}O-#*5*6)yQY$;Ahon2hr+&xa7^7ipP?MM4G zAn@F0p9h`47!es29rIP}l+%I zxE-Bck9gfZj|T>y4LuhO3q>!*lT)vLo|eqaN|%;@S$Vsp9l95)5I)J8ce@RI}3WwPkj3SU0CmTzN=YWMov;wI))Eh6n}A)MjpO z^`z)t56le+GR^ZvxkOeHjdo?ye^*1Z`@|Ypk3x8<5A$Hpm-0p-4 zESt$;efYXBuvlk$I^S%#eRq=JXsw~Ci{867Cq)hOp46n6kXM&g(;KEYi)j4}jZbqn zgMD?sCN+;sqP|AQbVvgqmT%r#r8zf!JbGs=XHWxEc%NYqE67^wn@ulKyYNd!?KrI} zbM}KU?YF~aNL3dVQy@Wt;8`zNR5<_YInr`O@TBRUfmP-ezN2|7Iwf1*pIpy=Vb&1j zot|H_M7UOb^|0-al32Pkp)g3S)Oi0}(cbRf~A9S$KIy{(_sZSSEnUh#U+U$DHP8mjMz|(9cZt(B$yZBgbFv$#|6JHh1ps){i zwQ4AJ=k35>*r=5QUB10h^<;FE(;2spT`E~~PCd9>vK_g%;6!{-m9|!V()+asj@L83 zn!gx#M2auO66yr4Nq7<6&+4kaosUbFJws$&DE3U*Z8XH`E{P}(^JMSCn;6U9elk!sP^s$|OU96TkVfB00;yxdAC&moCeiQbh4cM=< f@gQo;F?D%kAN@AAS))wPqe7W#92FVa1 literal 0 HcmV?d00001 diff --git a/metar-images/falling-old.gif b/metar-images/falling-old.gif new file mode 100644 index 0000000000000000000000000000000000000000..add86abec4d9069562889037651ecb8d655c5209 GIT binary patch literal 54 zcmZ?wbhEHbWM|-DXkcLY&%p5N<$1-QEDRu^10p~&3{1Q}4QU)zD{mxC+E%$(i@_QI DTG|bv literal 0 HcmV?d00001 diff --git a/metar-images/falling.gif b/metar-images/falling.gif new file mode 100644 index 0000000000000000000000000000000000000000..613d76fddc99fef40eeac712f81fdf2929361dba GIT binary patch literal 54 zcmZ?wbhEHbWM|-DXkcXc&%p5i|9{1wEQ|~cj0`#qKmd|qVB+;@NaLtlc_V4kw#vm? G4AuZ>P7VJ6 literal 0 HcmV?d00001 diff --git a/metar-images/few.gif b/metar-images/few.gif new file mode 100644 index 0000000000000000000000000000000000000000..beb224cdda9985f5d4e42f5a02ec141db134eeac GIT binary patch literal 9505 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%0AjLgq{h+ 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 literal 0 HcmV?d00001 diff --git a/metar-images/fg.gif b/metar-images/fg.gif new file mode 100644 index 0000000000000000000000000000000000000000..9ac8354d58deeb284f84fa1899931213324a94b5 GIT binary patch literal 19198 zcmaI7XIzs((>E%ig&ul`gx-5cOr?buiV7%76H!oU3JNGC^w1-MfKmk%lnzp)h2EQh zqErP0r3*^nI`Mwb`SL!`edd?!HT&P4$(LNS)7IG3NJrO2`<&jnqjTqeZZCZQ(ZBkA zetxla{_DV}ud~y$wIfr5qaRzlM}~WbTl+@db$1U_CavAwZQZXwbk((fXl-rnu4`?r zqm0c36^-3>^>uZ1trh=1brp3L#dWR4b#-s+Q!DE7D*jPjaYbwK+v4Jiied`?F17e= zPEJKdPDNc#MR86=4rQUZxHzY{F0T|%ndB5xpd8}Akw~OWUlEA^7z#qjEPjwfL31jI z|Hd3*4w3MWArSsCInQ2rrRCt$avl+K2t*1>5g-x?#2oxTor2A5ZWKCIm+j+=2=CXo7Vx!9SQH8S5BA z*@VaY|I^|Y9PJg15BA4X$SN4`Pmy_qck{;w2jd<6|4k{YHvV|WV7#gSf8_mxDP-dx z?DbD|u%mylKV?Tiu$xzKuvf6ZTQEK-80i)4ew}kcbhr9VxmK-VaUS2j7$jysFj*kB{ zy198ddU;_fdMOV#FB>l}grk?6jn{ogFUo!jZsX>m=j3>qYaj_YJ;`0)uwE+ zu|ZKLsDENetPPg38})Cr!D6u}>_y68jMYP7u}CaR4|~NFtE`8`>SAqBD3l(`{NI35 zp?pm=jZ2# zK-kZyKrn#G($LNpjl>zMDXCCXojZ39_J@X+?Hq7Ufx@5r_nMpo1LrisLMAw8a3md4 zXbMsQi;ZDJBSK6H#29$^9BRX;+FA!y_Y;avsX_CAG-hI`QW*l6K9`m#85*(5o zE~tQhb*VTAPb6b&CcC&rlE|GTh1XSv2?SJ@pTZ+z;q)6}1F5>WqD>o~OLeZo*%vpH zsvSeUY5VIdE=xMy>j@i=bYp&{@XK{7J8K0;Y3jj4gaE(Z5r<&thHsX-O^v?En`@!`b(=L#R!8>Bk+t^Kr4=X-=HIW4KfZP$ z+Pl)meG|FhNquklyf)!Wb7;xkOvk!p4i*8GOdtL~9FnzO%0L5)_@A_Gu?m9Sz2a7r zol6-SeJAYh$@E|j@0S#D%h;v9fSY;UL;abNu z&t)ekkHr{AzGIOf@%jcD+K1B@v*`Fe5fKUek4tEyHC|j6WOj7V?@n@9FI`Czr@Ljy zgT>)M3@Rxq;RwOL#YkqgzEV<>^;9W_jUNX=^W5^u>UriIv2i2$`tQs_9y1S>aB5EC zIclOB8A>ARzi_yjd%ru+@EQE;M#)R-<18dIKMijr1R6(jOL96ZGh~)@hi()RFWtUX zEJ++g3*e1|HCxR@Q~)9xrP8D{zsp3^al zdpn1hKlMYD(U!e#>Yx+wfoxPdU_YUmH7koTnZY|%F+%gde7l)Mf_B2eS+CB0amtEE zl!2x3UMR+A8I^pD=&9hJ&*m<4_I?QQ9PeTh^;Wsd@co5gBop{q-do!9v$zf#QN#dM z3x6YYn^h@RB|&#`Mj z9^Ga)%nPm+HkF9bu&A57ax?VsOVGmb;h@tbu;a&eIcSg?VtSB5!>Rwc*`OMS)1#pK?8O*IcSI>O-J?jOMxO7u4_K|v=H-iRW!@jYen{;&KlPYxvLgfx_@3o zEYW<-SrEpoU)*|pxZN7~mX6mv$CnmjkmDQ8ThYeuC*gu0H{z?hycEE$w+=BDT#Q+W z=JzGud;G^Kzy;4568Nh};98LH3tnOltXJ^f4zmAjdNe$A%c$`a69Li;5>N@

OK|0K%ZvnG$Fx$RU}1)hxs18(C?4zxgRx8} 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 Kira7gzX literal 0 HcmV?d00001 diff --git a/metar-images/hazy.gif b/metar-images/hazy.gif new file mode 100644 index 0000000000000000000000000000000000000000..db178315be86bb7261c76362c4a7432515e517cc GIT binary patch literal 10773 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 C7Y6XJ-RSstPhN zGBdHV0s{vMfT{(V66|$%?W6rynRX4ZE;3BxYumtVisn0OP1bw_jKv_gNRxvUtlkUMr_`lgU}YtpRYIqAG*3$1WxUDud*Ddfs+cI_;Arr6Aee>u4YFm1BzTTCa z*B{wb^=E3AgdH|n6rFsp=J))7tyyw12fk`@p6cFmYRi-O1Gnfe|?!$#ixk+KzYR& zi#Ln35QDhw@dv-uCv16M@Mf+yt6}geLxZnD3pT9uOc9zV?OeLvuV%mDca|KBb8%(m zLgy_WcWCBbHMvyE$l?R@3rk0+Bm21 zdA(8gde)?*vzJ-U@$9Tu0i}LBmWQvJw&uvhoqM7-hRkvbxSfAPB~n@8LRpu{S*72C z-!sl%HU0eikky2OCb6=x(*>cAw{}f1^En{@Xl{*bVc``!wV>dm+~-7>wLepmT=rA& z#=%z;uUJd8UCJ(#7q;42_Re#DZoZG^)oo#0CoR>wzSF>YZ;(}cGD{ktg43F)LusM< zlIPY76wZ0|QSz*+vTlR)8$~gBCf(@PfJwsKuccQXseC1VrJ5t?z$L?0!$VG==7YIk jeDsS}{}mK`&~!)RO3~z3p?~)-=(yk#-D=er|NkZcv*xvT literal 0 HcmV?d00001 diff --git a/metar-images/hi_ntsra.gif b/metar-images/hi_ntsra.gif new file mode 100644 index 0000000000000000000000000000000000000000..21ba8ae58250a854076511ed87fb588f1729a807 GIT binary patch literal 10330 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 JY@IC*{|9VIkJI$TW22xJ zu_#MVSp(F9;DSU@5CjE5Vv$8pv2jCfK~GCMLA3g_Z|2XOH}Br}-FrXPh-w^=*Z2nb z0tkYDKlT8X0(b#!oEBaSr;XRb6A0R$5e-R19UUS?-+*jLr!tvzDvf4g<6>`N#j>W+ z99BE9R=9FF9CJIKH;?V*;>K}RgFplVfv7_?A(2d6Eoqjn|GQLI0g4A4uo8h#0HY9s zLMk~h0RX|4g}{e`5e-Na;IN*Ny75s5`vrm#)hN(GAOMpQGWPwZrWZdQ_?UVwJirs} zzj-)ZbI9%Rg?)v7c0ae7c5!zJUCNsuSl33KESuf$NiB@h+fkfeF*LiZvjrDY=2Tx7 z<{WNePS2_VO{an|N;(<92!LUXV6h+=AgC@wkEua+^1!(9*hY{h+$+XcJ>fdrv^LG` zmglb9S3YgF@9W{m<-(z=^yXHZXxG6XCq{=s)>?z=?qSQ0JN&EzB|f6`f(-M&g}8w!evqkjJ@2qnY1bpFC3 zm~cEuF(G5ga^jy#Vr&UAnP~$m5i__)-VJ|z4mAV{(P6S9Yhf5x4^O#DjR$WBil~*{ zEF~j9L&U=dEinxs1lH92gq6X9opk9Qr4ybZg5>r^A#gl6#L3&urTa`p^6H3aTc%J>4FQzF^1v9gjt-Q{-qS)n2HtRM@ZS3853dG?=`Vjs_p%7i ztB!JzY`(#NN{WqOYStKt&zH+*Pp;J3qW7D-QQF??1>I*~lB%1SwWb^LWWP2%R+ccS zft#liHu)X#KXLJ;-WBJd(XfX5HoF41=D4rztk8J-C1^>_xcuyMc3xvUI-VciwI(eU z*I`H+Y#N%tT`anGH&$V`F{Wy+FxyXlzoTT=(;XA2~iq2ExCiRrogGuP(~guGRgdL0>=Bn-=(jD;Uo*ZWLj zSNXj^m_08B7IT3?>V{@(oRaQ&l~^s+Mg{nR?DM`aI0**?vD@rDyn~MII5G3>L4Csd zo*AX_aSuA-b@NdTTf>sLLlHLpw|UPyxmWT2w=TPP={FIfN9ZI?`Q>zj)x%=O84wuQS$jeXpbjQRqErF$N5+rDV;_vWV^T0*(t zaBfg}xp+?r#nTUWDRGRQQz4ZP|0zE1CCOD5yM;s+l#V@7GOEJkh{>j7)54^*xkLmi z+(7BFj#TC+Jv%M>XFF?PD&7$>0VR9)J9-G)Mcm>DE3KV<_j+>#(b6q3-L|col{fxi z>$mnHL9=bcXJ6qGzHiKoQ@66yBY&@~yT{|QJf~aunK)ZrEzgv=zpBz! zg8EHWgLiQ|snL_mg&kJL6E&kVm2Gybo1sfBwN7PX98$Mbbl)^q27(lMig^>IoqKwp Z3ed)ooJW^t#3b3Vzs=Y>2q#c=?_ZkIAIty% literal 0 HcmV?d00001 diff --git a/metar-images/hi_tsra.gif b/metar-images/hi_tsra.gif new file mode 100644 index 0000000000000000000000000000000000000000..35fae107700b1dcb8c0090f291f4bfcfcc6abd04 GIT binary patch literal 10021 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 Pfd=#-HScXGf9wAOQ;um^ literal 0 HcmV?d00001 diff --git a/metar-images/hi_tsra.jpg b/metar-images/hi_tsra.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6e03160368939c5a00496d525d6af40b2f8ff111 GIT binary patch literal 1668 zcmb7^dpwhS9LJvv#@h01OmboCWh{TQDri zWV$n*!DKl(Ink`y9JZtTf`v{jH3YM4Ljzkm=JL2s_`Ejip6k7)Y) zk(51%maBs^%i9WYgv6q)#{*$+imH<|Zou+5$ba=cFtUh$Ovd8d7n8oR! zGpe9s=zdo=&YEfXw2RX!B-Qvv*NpX-ROo%<*%&lL4it?mbxK!|`)%y=Tkq&8GI8@xJ`Uo!i0S}nho zpuY?Xi0^9;;9oyB@;6>o;`W(YGR(Zwr7l&?g3(&O!_+LI83U$J?L?C}NR2!Bk@7)* zxN(e;GACKnie_!W&tICvU$wKTR9D|1o2IqD<` z!w}{NyctAb5UH*Rk7j4@=6@*lo1I#0Nb#~N(ptOJjZa_BowYBD`$U*9zeds+Crl|= zp0=HH!AcR&p>8@_VT96hF>>EnHU7iqlT z+_^^c28HQx{$_{necXV^#az0>+P>`WxA>=d?l_E=mDiQGnvt>rQhM{Has}wUj4&#> zy=Q)G^zE}XOCI+ZM=CX?w?)%tk_jiPF7EVwgsh$j>7B?c4q+3eE=&ag5tb5Md7 zFu4{0jQWfCoG4E|8W^{SD&4`({8Dy?ZDbNlL2WQ5sJ9JWtf?lbZ9wc8u9F6+rv>Q_ z?nY!8K`xB4 zP1S6a{CyfxHe$wb<%vcn>FVJ@KC$G_48pT+HF%zqL?!hrDVC+FJ+YDZ{pSaF>NpDW zwo5YF+mglnny2L)zrCH~;rH5n!h_Nb?tZQM>)$S!Mf&NUo(Nsk+pvtxJC*(-&My}t^8 z75T;^Jv}O5{>ACs_Te&1V~2SkO&g|p!1WBp$_B%+VDjv_b1PoNk(`F2odZ~2h4+W+ z7FvgQWIhpwB+-N_z^=ujQUyGCVu-l6d-5AukNtYfXjdu@%w*1y-VDnK4Dlwt-*8|+ zaS1w-9cw#k;J_o1CWNnjz-b$l5gT0&$8IU(FM!&bU)^aQByFfXuEb#;hI;QGY$GMF zsn6Z^oR^b+ZpnZ$AgYC2X0ExJmf?6!J0`=&s literal 0 HcmV?d00001 diff --git a/metar-images/index.php b/metar-images/index.php new file mode 100644 index 0000000..a013bb9 --- /dev/null +++ b/metar-images/index.php @@ -0,0 +1,11 @@ + + + + +Nothing to see here... + + + +

Nothing to see here... move along.

+ + \ No newline at end of file diff --git a/metar-images/ip.gif b/metar-images/ip.gif new file mode 100644 index 0000000000000000000000000000000000000000..7a8d8c5a43455ba8838d02c0c5632c82c8d528c1 GIT binary patch literal 9508 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 Vba$CcQ&bNrpT}|f*K>%i{{tkVZ^{4w literal 0 HcmV?d00001 diff --git a/metar-images/ip.jpg b/metar-images/ip.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cc5db3e91287e2f9873a6ef065c99d5e77031b92 GIT binary patch literal 3017 zcmbW1c{tSH9>>39Hfut%Q=Wz6J1~`e-Gt>h>AP``1 zG=ReiKTr~%4gkSM^w0RnS?4qE{c002S%ksJ6+AOQw)CwX2b6rgF~N($s?m<;}q)b z-2B4g((=ms#^(1QTiZLkd&gWL0Q^_Uj#}}j{)3C-h>PK<`Vjar7l#T6+M>&Iw+lKppJ(f=3OKf(URH4d9Y&%tQPIF9C-@E}W;qbx0Vp|c^wlBM*O)08Wwg*$gl!R|Cqmwc0N!i(L#pR85EDjlD~?-S-45d+_HGp0>* z?h%IgKh;^sPc0EuzKj{3A;HCG=Ga=4y37$7iFlJsfv)h=xUkuNj&b*`4cRmgWqAU* zKt{i(y4tMY*I)9N!u3tws846ND$LgH@VWLL{1FK!vVWz_&`yl%P}zlb7%dl!HP2^g zAU@#ru587Wgz5ci#-uf+>p}JrC@zfXG(`-KNwURVK&wN>#f%zdIGkC2n zxD|IvYo!fo=tYpK4Xa)d;n}&_)~J}a-NAF8w>|+m?1TTxKcesUdRSpYpHEQwRb6Br zFTi|ZiLc3R_g+Q(G(9StvwuxZcCB8jxJT_*HZ_Ijq7gJ(RJ{E%l6}m+EdsJHMKR^j zN~w8z2*fTE5X1r6v_TqmxeNtx$Sm0J{J=XaxNI`@6!it(rGE!Hy3MEmTlb_?fOzQ5hb~Irsw6daKHXOfw!cnSRJ&Ca_amg->KDKD zXb}M76{-k}z5bm{{}mkz5;4{=LZOod+oTZhs0vhI1=+89BqZlq zkfeibTMEjDf#sl5%EBFZ3u)t;#nzPvT@K>5L#B0M5 zwb97}SI@r%iR!kiRB7+1<~fmz>mi9W{sUhp%L6;p<6_^$FuK<_QR4_A!6`ne`t0Ymc4E!t7m zU56%5TABXds`0U<<&5;Ipd_#A?l&y;Wgvqb(5*~pmed(S~E`@Gs z=~-qZQlfD~@UHW3gWWyR9FC)Wk!T6glsK$bQBzXAw!@4mv-^gbiE-@zldo zX1Y)G!MSx<%xuF&Dk5Wxe0w~6N^!z77K64#e$5s#(L^WV`F313K?0WXA~uuz##K9Q znq{*Z=z1u~+Cig34bo0I8&EXa8>*7%DbXL@#b6U&-R z0Q+f6>)^)k);q|(jhj@SjK%J&h!+xeCP=Z)fp}Fj;d4&~x;TT_NDn(J zWfIi$s)$R@a}|GRxity9k!wREq80HyOF0l0Pah(KoDahq5g*yvsbUjD$ol9IJt_gX z>i)d2Z$;0*Q`n@fFS2KQQqL6#<@9I-dk-!m`V~_rPuqZm>Un?~m{+P4s@D;{*Z)2O zJV$?<{VMoc-vlzD{W)vk-lNRKh#HaZ5IJQT|GP{?PV#0hRBIkT%c|_ZM@v*%E;|Gq zCQ1St?5wlzOy3|5e-rX2m7|oA2-MPsC%`(O!{$)vH=uO%#)ry2p=kcW}nWgQGzi?mdo za{?r)Q^jIh1S1{xRd%e`Q<`(+*V$v!4hCg4z4-@MTSv&6k~xD@!R0J6#;($5@sj${ z0jN&kq)>}L%Do2QNrJt%SCC7d#`CCv4Bg(WKkQ8{H#c>X%{(d3i%1w~&Ou9B8_ zY7^1#st<8 literal 0 HcmV?d00001 diff --git a/metar-images/mist.gif b/metar-images/mist.gif new file mode 100644 index 0000000000000000000000000000000000000000..db178315be86bb7261c76362c4a7432515e517cc GIT binary patch literal 10773 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 literal 0 HcmV?d00001 diff --git a/metar-images/nbkn.jpg b/metar-images/nbkn.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0b4bbddc931ce3ac531b172b8b4a06fcd00780cb GIT binary patch literal 1273 zcmex=swfrpt9=ptr82787ROdDC}zUY-ToVYyFHInz%3NE(;#oIGa zs81_e%u>vDCXMOqm5fUl-__rf`y2ImmZkN~#icPJMK@CJ@FjmdAz^cjUq>Kxfp)2R zK`5twwUE%cm>kW<#_f{liqG5o#cY*Ycj-b{*zr(RQI*e2RotrD+LRt?d=jrtKD9Gd z(q@yx*Q;wpstgAmhm*!CtB* zF`sxIh8P}S5jcOr1xfcK=FzpwmfiJ?*1B+I@!|sor_5)Zp2}`5xm)94>OsWVy zzouK?91l-1=Q_1&_E{U@pwq$*))_$#3wjKt8xPk?Fr4mbGLcg1I-KlfyX8yCrbDm$ zJ9eM0pVqv^#@;h~-QE1SV@5_7`+qJ7JZ>ZCd2CzXQ=M*>VBx^()i$HGq?0 zc5zvE*tQ)k-ghPRVoYl1YxT;xDGaNoscztqlldahb$rd@*|{#c+_|5&HQ(y{a9UdL zS=i5Lhw@ixeRAiw@hT!2Vkuea|*fL4(sQbwGG|=yU*-aDfu-iqM zGb6*xpX_2Y37hry^sdm*KU;)nvtH8{xxK8Uey6>nzt; zmP!4c3Tx*mOy4A3UYem`&LxqQI>~qU?028d8mvy6nv}d&t~ZP>I{xf}L)ME0i+7rb z-0iL`uiW-RDk>xQeW-MZ-)X5oYj#iFA~e6W;MCn&5-O82%Dx(#z1`o}6zHG(aDTC< zD2w2?GrL1qDZjcPnzf*{`0k6uG-cZ*Mi~Nke$A4-^K1I?PZx^*UR2dPH^2SmX~(!b oo$vY2Kf6%5uHjexqx$U*pX3tK=leBfXT9tb+S7MlaKZnZ0EI^O=l}o! literal 0 HcmV?d00001 diff --git a/metar-images/nfew.gif b/metar-images/nfew.gif new file mode 100644 index 0000000000000000000000000000000000000000..ac834e82c73aadc6fde716147e41ae040232ab8c GIT binary patch literal 6877 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 literal 0 HcmV?d00001 diff --git a/metar-images/nfew.jpg b/metar-images/nfew.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bba1d84fcd38cac726b1caa8949cb7225c838b7e GIT binary patch literal 1320 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 hIZ+s&g*)frQ__0@j45T0jd69qs06S&;E0q8M literal 0 HcmV?d00001 diff --git a/metar-images/nfg.jpg b/metar-images/nfg.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bf17736327ede36d1ddb1a84409d2e509a109449 GIT binary patch literal 764 zcmex=MGn5vW*@MM#m=FwilvP*_A% zN!iG0;=+v=Kd=Qo1nLlHWMD=yi-7^CA0#0N3=vcrMnR$fw-|VU>X`(Y1sUua(x2An zO1;raR><9dm0cmzWb4bNtNTyhUaD8~=zP|qB1Y}=`uCq^!&ytok)FUxQ*$Yg#*#0|N( zzluykGbWaJW_X`V*jLtaS~Bs-al?9*l#g@LKKxWF)47yp`^L~mmC53!-?d9;%^rE? z$~tYC+uL;Kb;YvP+XZ90w|#WbdH*f))rQ~F-AUV&Yg!3AHI3> z=H0t@A3l8e`0?YXPoKVg`SSJa*YDrI|NQy$_wV0-{`~p>|3BDsqr_+k;0po8pDaM> z{|q`HMW8&vz;T6vkweB~!-9j&9NcLhFB+OUM3m(ecpfM(bYK$5V%fNGVFJ6HOPS7= zjsq-{6b#q|L==uFIWp@`P*}LI=mFbw7IB%0lFAHzEix%$9}5bWxU$-(Jp16efmvX& zaNr3QrGpQA=ZL2$S$_PyfOW0jE~%CUrEHEX^fWVS4KHZkY7ySDPNCv!I_E;sBSJnG zoS*SARtQ`72)O)+i)^C^-L3ERoR-AObjgTqAj;<6cb!KxtYtgd^sBrvP#IX@+>)!`1r~! zjXu7b6ARWbu!jn#2t0V`>Lo7A7a_BoVQn+3>ho83Pj6p;e}4lrx17(84+k0;tN|7# Bkca>P literal 0 HcmV?d00001 diff --git a/metar-images/night_heavy_rain.gif b/metar-images/night_heavy_rain.gif new file mode 100644 index 0000000000000000000000000000000000000000..e9ba2586fe532a25f846bf66cd1862184287a3ee GIT binary patch literal 1067 zcmZ?wbhEHblw^=(XlGzBH8r)cu&}YQadL8UcX#*l^78lh4-O6v2?>dgj*gFyPfkuw zNlD4b$jHsjEiNuDDJiM0uCA%6X>V`u=;-L}?VUV%@{}o4X3Utec=6)p%a^ZMv10xD z^&2*9*uH)HjvYJp@83WF&EEqD4jegh+=g*(NeEIT?8#kUjdGg}Li#KoHeEj(F z%a<=de*F0V|3AYh7!3jXhJfNv7NCXy8FWC_g7O3d$A1P!4jGOHS2j)#)tronixj(f z`IQO+9yTpFz$xHnlB2PxkyTt;X+nmF(;@b537edlmrl$q(|AQAVi+bXH}`5vE!(i* zpi--lfon$s=RwA1VKG*x1r1G$FDx{WRFSo4Z0KGd5V>fAf$1S8Ud!w}k&O+mm)K>q z)-hBvE@Wa%)AdT}6kXQI?75arG-|TLB?i;^hg=vPo*m%e{g!r@BgvtQkB{wDtY*bh zCKf)4T@nTp7+W_aWlu8D2{_EevVvV@N6v$T4BR?q>sACLta^KiJxtx=f?_5|<99{`qhIo<4p0 z^5x4E|0AHRJ0^7H4<|NsAkZ5t&Lnl{K`gk8x|~JXkuYgQ>mGtxcFp`0$YMXWa9xx z4sHKaQ*J(NaAYzro>vkX(BL;$j!8p-W8uN`Go{#SPCQ6ZIJa0$RG~mY>2X6Nk5WR5 z*5tzhP22(dR=%KCtW{Z^37=Bia-4<6G;#a>>~k8YCQI W;8AW{{o~!E)-GxDIv)!K25SJ4qkm5T literal 0 HcmV?d00001 diff --git a/metar-images/night_partly_cloudy.gif b/metar-images/night_partly_cloudy.gif new file mode 100644 index 0000000000000000000000000000000000000000..70789675ce3975d884a26610ea6da4c3cd0d4b6f GIT binary patch literal 1060 zcmZ?wbhEHblw^=(XlDQcW@ct~c6M%VZXO;Uetv#2F)?v*aR~_tSy@>*IXMjt4J|D# z9UUEgeSIS%BU4jT3kwTtYinCuTL%XRH#awTcXtmD4}X9E;NakpkdVm8$mrx+S=yk=GNBM?(XiMo}S*` z-bs@t&6zW2!GZ-#mMmGZV#UgpD_5;rwRY{=4I4IW+_-Vqu3h{0?>~C<=*g2OPoF-0 z_Uzen=gwWcc=7V(%QtV{ymjl=ojZ3PK79D($&(i^Uc7tv?!$)g)|M~Oh|NsABua6QVJp>egvH*kNKZ6b^AV7J7f#W{|BZrK~h6M+kIk@vY zZX96hmeP|^;F+MZ(1D4+!GQD9LIqA`zb>6E9SUtCYF2ClA{UM*IWk)=@%Xv0NP%NI zi>S-QlgbQ!ElMeNhJ^)7j5btI~Eg7G}@^$h1os1;beAxaWW-qI<#I(q=cY+*p z98MA&f4t}8@+c5ciMhFkomX|<2^EP&u8+?Z*NU83wa}E6Z@%Gz1q_QjZ>s9+iRdhF z;+i7I&f|1~VYYMIb|z+>4UDZPxEPriDy1kqWa*QV<}#_}GJAOS-2-+uMivHZ07TW| A$p8QV literal 0 HcmV?d00001 diff --git a/metar-images/night_rain.gif b/metar-images/night_rain.gif new file mode 100644 index 0000000000000000000000000000000000000000..d8aa5b34ce9ecbf657fc3b970c686782de2b1a44 GIT binary patch literal 986 zcmZ?wbhEHblw^=(XlDQcQ&Uq53kwGa2RAo24-XH2fB)d%;E<4z=;-M9`1quxr1bRk z?Ck8^+}y&#!ph3Z?(Xj1-rh-*CQY9{ea@UY3l=O`vSi8HwQDzQ*sy>9{`qhIo<4p0 z^5x4E|0AHRJ0^7H4<|NsAkZ5t&B3|E+uH=I7`0nVA@@0kWTjRsaA1 literal 0 HcmV?d00001 diff --git a/metar-images/night_sleet.gif b/metar-images/night_sleet.gif new file mode 100644 index 0000000000000000000000000000000000000000..6d281fa653095f70de7b9a287ef4898a4354bb7e GIT binary patch literal 972 zcmZ?wbhEHblw^=(XlDQc1qB5a6%`E)4ILdF0|SGAfPjRAgp`z&oSdBH%a`B3fB*UO z=dWMCe*gac=g*(NfB*jf|9`N)QDQU%hI|Mp{$v6A;Xi{8$S0sY!N9SSfssSTW5a@j z%}mT1JOYYL&TV|+NJImd}a z7NwnT)l~MHlQHp`SG#UJSFfdDn%{Jz;64$_l9gVIIP7mZjROJtUIT+Y9C_e zSI}S(NL29JerhC{-^`F?G)&LMmV@3b~ literal 0 HcmV?d00001 diff --git a/metar-images/night_snow.gif b/metar-images/night_snow.gif new file mode 100644 index 0000000000000000000000000000000000000000..8bd5ae3d6809b21637131cd232b06b9c6ed727d8 GIT binary patch literal 925 zcmZ?wbhEHblw^=(XlDR{|NsAk=}}@d1V&s4DE?#t`uRVD4#?-AJi)+G#lXlRVUTpNRYE)JiiW_W!_5++aZfaio*d{=7d5)lacRNH9y#B> z7SGMkocpzsPfd9#lqzFjxZsMh-nF literal 0 HcmV?d00001 diff --git a/metar-images/night_tstorm.gif b/metar-images/night_tstorm.gif new file mode 100644 index 0000000000000000000000000000000000000000..1ccefad1d8f0c5544a7ef080095e332d14c30105 GIT binary patch literal 1106 zcmZ?wbhEHblw^=(XlDQcQ&Uq53kw??8wUpmCnqO2H#c{8cP}rmprD}O;NXyuknr&E z=;-L!*x2~^_=JRn#KgqpYAFG`uh5}=|2Bw$Ngo;uJuyNzY?c2BS*s){({{8dc{QbYF_y6Ih|Bu!jIB?*| zks~KgoH%{@^!fAWFJHcVz(PGu71@YK4#$=ocQ?#<#n{9>$Jp>&gMle??@Z5G2O=6j9AsE$ z6k^vpE2yJs30vAXiH(cj_X$eys)!m)Uf;J**&{|r=m6tEKCzfS3CAV+oJV~NL@a`s z4?Cl(NZ~u)yt-3{$aBS)atuuWwHNpQO*g&rn_Y{-N;V=^1jrI}Uf2&Y7P- jFX8ve$ulSC@0UC9``@>T?kzQcE?%Es!@wsZz+epk;I9b1 literal 0 HcmV?d00001 diff --git a/metar-images/novc.gif b/metar-images/novc.gif new file mode 100644 index 0000000000000000000000000000000000000000..cbf1a1f503770c77f16889bc8334d7889a5fabe4 GIT binary patch literal 5947 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 S`9FSp|MutmU+J@()Bgg45Ew%M literal 0 HcmV?d00001 diff --git a/metar-images/novc.jpg b/metar-images/novc.jpg new file mode 100644 index 0000000000000000000000000000000000000000..52c5e5ec6d28ff63249bd69487480749ef0049f6 GIT binary patch literal 811 zcmex=^lOiET&UP@Y7ModgWM?qOlT~kX_QeM|USHnP6LsJ7}2qQZ?I~NC+Fc+7w zhLo6;2Fc+60R}-11}g@0W=25#gXxw_9yfKH9lK=>)n-M$^AoXTw7To)XV!Pdr0hcu@9)NQ87f&ZyelR7{Jhim zZ)MBbYI&jKWbBRu!B?3!omZT|#sPe}-GUN?t}WOpBVr7TnbFRGi);#aW!(Cb=N#>eMIkSIpipu+@o(JekT; zomj&CgxO)+bS5wJ*gO_Far?Wh6_+OnXt93K5Z$*U#bMR`qb$+W%g;}$G-2G<`BatZ z$*0Okjjf%@58YRM%V5^bn6gPo+JyD;($s>>hAy(RxP@YmedsUxX*-KWZHoBmug@B% zZj0?YBG5iZ_%6e}5WyWS4DRf*7ku~4ImD<^{G={JH72X`+9N}Uw^xLhu>O59ncX^k zvxBzx(|)ceU0eaa2WB(`6gOp9{aSRwBmEZ_YwNEi^Ey7=i+=2|Ze!VWG3kJ}Nsj6w za%SH`-43d5yvwTct>M(eW|rR<^ov)loPAmA!RPrR(o#DNWv_EB;S*Qr;+&ijd`Ai Pc-;yhGPoO1|NkZc8wUzr literal 0 HcmV?d00001 diff --git a/metar-images/nra.gif b/metar-images/nra.gif new file mode 100644 index 0000000000000000000000000000000000000000..8fb6924161fb209658ee52e964983172dd69a91c GIT binary patch literal 12576 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

3m@{sI(fnYU}Es8UZDoasD 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 Tsp*GEsJ5={7pa@aAB_DC6Zj!0 literal 0 HcmV?d00001 diff --git a/metar-images/nsct.gif b/metar-images/nsct.gif new file mode 100644 index 0000000000000000000000000000000000000000..924faf928e2d6f2eb015c0a2c5ada7509cfcdee9 GIT binary patch literal 8295 zcmeHs`(ILN`z|aFf)F91f=5scEp61aJdLwJL2w*JGgHe##8c%A8CsSWAetr?Dk+u@ zYGQ}U87(dAt@jJ&v6@~rvviuWGCPb-+StLS!*^NVz4y##K70QK`&!R)KMx-kzpQm} zU)Oy@Mz2@tJCyn!rT(J6_A~UF z+Lqc{jRu;vdey>c(Lh@bgik@EQfc%mO|43!Q7%N468c63;Zsm4l`4%=rBW_jp8>7A zc0p6A+69GOp8>7gwn5u%5I%)%o40NLjO5M9p8>52$qAnkoe=#QVbNg_K7}xL7&|(Q z4dGK@`}_NcErbO?tEZ=bm?yOLguq@1p01zZNq6;kb*0mx2}QamG@%c4I+eOGA<&6b zDscf )Y2%mRoo3LwC~Wk*LKm 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 literal 0 HcmV?d00001 diff --git a/metar-images/nscttra.gif b/metar-images/nscttra.gif new file mode 100644 index 0000000000000000000000000000000000000000..8ff3c3b2f3e2187371bfc8238cc06cba33c323aa GIT binary patch literal 9029 zcmb_>XH-*b*KJ54g^+|0s`LO7dgwKUfOH8(Q9!9G3Mx{RrnFEE5SpMOhNi#~K?DUw zrAqG+IldNK%_wV2Ly#KX31Dc$iY@1wLmkdon!LeZGw zru_W;+I*M%{E|@?EG&OuBu%M^6?8q{AvLR^Di3!2T5n~JTt;RIJ69_?ql3xJXEK@B zmW%oky)ZDFbP$;k{xQob{@Gd`g-F@ZTA4xc{QAY1*Ax`5Lj^wU>O&$9gjF4wuE zef`7EoYM05_xJM;3O*s7f0$Tw1W7uXsu_6utUrH-o4lt-kcUT@n@57Dhrfn@o~MUL z%wZufceBa^02h~YChkc=hoNWb8ZIvWUM^1FhtV!B9!efrE_>x>s zaP%=pP%Wgx4EYo-PKa9sniwB6F*bEDL=z0?zMA|*T?YewWhtX$XcHfET^LcvR7Zzs zK$H;CaUrOaq&2Jv1UsTSOoc!ssLB(57wVu47_DX{FHez|SCf~QSCQwJmlGjMgH0s) z5%Ok8d7^}*sf3iegrvN?G%DRnM^hWbxA$9q3k*R6cmVa^XMVTI z-a$ars*y!KyFCdetm+lHYXAI76u9z+&4aS;tKzz68jb$&esTPbS%#EtLq%VnigThv zUqhvRo|^e^3}Ic~HloMK_)|gFLT|y=9G~l{iMu`F#j6$aTuAnvzytn2?cF(nje3V8 zyQZBxXz2;nu`gHLn@*5!zIpCNkoQf1!eN-^`LVV6slttu^IPjy^g2Cvzawc+0bhVE zN?EZF_vI=ZQN5lg6*SGVZ>xoag zbsj&Ihtdjeo;)14Yg;dQ&in6*`pAVrz>PPk-=PXg3G@P}*0j!&K?I+%sEL5o?+wL?WMF@lW1xk@cERRK8Q

odTnIsKqJ?*PPxIgFTX#Til4sBMn$_JB+ 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 literal 0 HcmV?d00001 diff --git a/metar-images/nshra.gif b/metar-images/nshra.gif new file mode 100644 index 0000000000000000000000000000000000000000..7ff1872b42127ee69346cdd66f05b63c7b93691e GIT binary patch literal 15034 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 literal 0 HcmV?d00001 diff --git a/metar-images/nskc.jpg b/metar-images/nskc.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0fdc7891dddfb983993f3c57561c13119f5743bd GIT binary patch literal 1776 zcmbV}c~sL!9>9M&NkW7K2u86)5>h~*$c;gZTmeDkYAGfw3M5ECB60-eSmlzGDn~FN zw4xkAP*D=YDX%3E5L~PcB4BK+5|KmEV3kIok4?J!-1qjcwx4-3Z{E!JJM;a_Y)o%F z1uy~BeN+Gh0s;P-25dYAya5PUi*|%)fWo0#5O6pQjzpkPNCXmzLhGYZx_Y`uCb%-a7 z9P%pa5hO361Q#Y#nLEa$70zrlUW6YMQ4h+UzhMI&-1IQFVxgFG&TvEue7vY72Ohdbar+3 z^bQP4hlcNrjNTo8F!6A5YWk7<*^Kh}?2Ebig~jE!zrK6F@|*g@s@4kxK>nlk(d_@c zuo^EgRP&@dS}zbdL(?HxD9p?rZr~ZJ6Me#v=#Ymn@~Ws8N{}SSFcmH)MTRmqcX~!% z)~fws_UFX%|CZTDvHy9=0W<`p`8)^~@Br5Pf?{B*=id`3dbJPs<$f}=$YiWB5`?{Y zqvE&g%{KV_qAqGT)1)A7@)Gy`9=oq5ik_4`Q#;X_9i69XgHF8s<$;P(D;CndDV>E! zTOKvr8v+QJNw!N95#^UzpB^dMb05rO?{m3M#+gjZRe37H`hh#8$|)1dp8G3~tW=+G zorBN!v!UF_OX}psqQiW%?(M(6U#)zmuO@p89&+!mDqp8gIWOeU(_=pw`nf9QddR`C zMZEVm2Emn`eDDIJ;522bpCI;-B!#b>QVXx;I6S;D^k#Z@Pupug`c!-;-&?BoNaK@8 z!jU;#L}#NLJlA5)j6_cqwtiE6^upNpo&^a@p{5GS;Bj&n#uE}RA+JUi+<18+!Ejz~ z`};aAsQ!l^vgt?pNw(fiajbxX*Jt}?ke@zI&W$^vD-qBdFF*JA^c3Hg(ykn)4=Is)sd5P zYRuQjy?qr+9RC4h%Yd3mxzX&so*!ktMx&I&(3e>*MFei#L&E0GS>$`AbvNtf385WQ z0p|6ZxBjgdM=LtFAkd`H5+3-O@uduM(JNP>ejVJv&h2^H)u)WSa>tjnDDqEsebzIZ z{06hmccv&<)ef|OkuOeU>~uGi#Lu2RUlAN~*PnQ$#wz8P5Ra%F=M4bnr8ZOs7p>;b zm31WE)0GP81HH|4Rm0)Cxo{<K$_*8}5id8iG!ydahzTo5z8M5=&5ui}LvAVt(UgbwP+q@v3_D zScE~KZQtZ|yR^0J>6L&YJa^7-uR6A)A6<+VM1mb#fHqt9DZK-eeuK4a0i%_PifViR zE`v&M@2>K{>uWqx(-S$u*~_WUVec9#BSFvU+Rp={&f+Ho(fDrPtC`tD@)l99{qbm4 z+8c|o(!h~WX{dQc05P+U>ElT1EsQ08y%U%BNdDrVSFSC}6$4R;l#7b>Wx6Dur`SK< zD}e^0?ZMLWilMF4Z)Bmky#Oev=fP};SloAV>7rez!q~d-B*vOg^a-Om1n?k$|MpUZ zbF7bQrFBN z)-6lBX&9NAKZ$>uHeut9U^sa39M1J`Yut72Hk&FTL1$zEKmOK@DxH_eO4{c=B~1+_ zv9~*lZFodcqo^2vL=R;8PHuVGFQ`>r8GIPLV2b&v_ASZ$e#^_pXDj^DGs|o^*V^~X f#@hQ|hlOuTv5xvj^A@jLxG`B!mu)0Zxbf)U$iMC} literal 0 HcmV?d00001 diff --git a/metar-images/nsn.gif b/metar-images/nsn.gif new file mode 100644 index 0000000000000000000000000000000000000000..96b144c599f225c4756c657006a37632a26039a2 GIT binary patch literal 10936 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 Ybjm_G>)C~c3a|Gs7Amd4qPF(`0T4G;F8}}l literal 0 HcmV?d00001 diff --git a/metar-images/nsn.jpg b/metar-images/nsn.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e086e6c062da8c7754c679a47b917ec2a11ddf25 GIT binary patch literal 1275 zcmex=#1MjYwPfd&qSH3QM`f+l2)H2s) zxd)dZD%f{73uNZrk*T>BIuHm%5r&p&j>GobOz!EcjLRch!SaUW#u| zd{}<#>i1~7$+4YN&8G3W6@FyMVow)H%Cg?mrYA0OLD}fge+H}Qzaphx9y$3o%)8my zk1$6qx_!xT%P!tme2ZTf`Yu?h+q6``F7Q>|oU2@)U&rz;{POF~x5xmV<%u4%^Y~Yq zb7W4I^VE`G!eANY72aUHLsR`!%hvYvk4wJ4?nzfU7SlH2kJ&pf#h+YSk;R;xceW;K zsxvdJo*edR)l2*6&1Ok#WW1H}(DQxlIhWS$GOMdOj=lOMQ>C(5tdfa(N zlOnuka|NGMn6gkMMYy5XHLH6%PreKPD{248FK1@-+eV*5lIlW1xVNOxaIqe0xd|8D{ zlXkQoHovOb_F&smmi_a)GaUU7Ey=liYJb(UvbjOi=Um*M7WK@v>4(}K=F5v)ma0yA z=@E8Mh|luCs^obq=6SrivfDrH)wLGB+2OMhhnjnhVzoH^Z2eXE*K!*y`@Mgvk!?@rx~UryJfm&ONqYGlhx2U*zw->g@p&+QN^kFwUCkq$3%7|J>A&7}*a{dj^?( z`L!y1`i)u*#of&_pUjyr>>uZF@X@O1zxh>6PlY(2^;b(=7wc8~^E6i1bC!x}+X;p# u6Tg33b9cR9(2S1@q^<==O)Z;fI?YOV*Tbl2_NOP8`o!(?uL@!Re-i*^d;28- literal 0 HcmV?d00001 diff --git a/metar-images/nsvrtsra.gif b/metar-images/nsvrtsra.gif new file mode 100644 index 0000000000000000000000000000000000000000..4215230ad132bc7dd1a45e97377e0e027aa72862 GIT binary patch literal 8189 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 literal 0 HcmV?d00001 diff --git a/metar-images/nsvrtsra.jpg b/metar-images/nsvrtsra.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2a249335f9f072cb825cf3919516bca4fa62cf49 GIT binary patch literal 1602 zcmb7;dpOg39LK-E{kGpOA={)@Ziz?{s*}6Th)sB03Q3L-Cq|l-u2iRl(nv~D%G#7` z&D>KbPCba+b15>4N<}93ovrhn{y*>M`M#g;=Xt+BukTm#S~36>ncEoK00cqsG&~J} zq!-WuN;*Q2%uzC-VVPslXc&!P5aj2<;&BKTk3|sN5*(f&lk_IHgdisyWRQPXQ5YD; z5U>dLXXSsHAONBxs z0Q<8eP0#>CM6e|CY9kyCucT?bY>lgbBu81x#x3sjJL%FYND76aUq}F8GztL_1}hD9 zh_V*}2FCnXfKbw$D8tb({*h8%9Os*)2gpeYC?ZS*)?l(G^vHAVjccx1hcqW>w+b6w zmahVHo^suLJj1V=$7tr;KQg<`yfN;(&pGu%9q1R_&j_q&u%jlOw%Dm}+$o}RL!PQv zn~o{ltNp<^axjbs>5XSB&x`KZrkk!{Tx2yA_tnwRkC;<@C5mXnpDuWDcDENer8@F? zj+|88=I&+s6v^`u%=X#b9Kbp7)7sbjWkd7H=-9laGh1{&bskoVJsL2*MUUp3W4hQf z-xMD&Z1ToVX%^JAD1W&gF|5e=-ji{W71WhZY9`NWx$2tJ_4}(+teJ4&ZNGZl8gjdx zg%hk!!7-6zYvXksR9!6XcpFY`?Rm9G1J%}L}H>w z*{OT}?xBRTUpwh_&HC%MyF6#D89lI|;W}dOw=R+FRE)6;zio1dyg&#Tb>d$yKbEGy z;hEk(^N&9DHVgpIxeqEd)u`#tgz8eMc(l+yBH(Sp4D&3!x#MeX+r6p!fChcb2sZ~c zkBqc3V`0n(*L2oc&WC2=Tdu=CK1qfDF}c)0jB^L@{7$>Qz1x%p`C$j)CX#&M)zPWM z`)_P@6z@E{&w3|HIA8p7h0v+QzVt>)U~!wgiJ*)ZOT(l2S&Ogl`viF*CHjepyVM2L z^s%z@)4|@?;vl51Ua#$QSdP=y#ihMG z?`RYyoF242+n}l{GSX3Fn4Vrd&hc*CZ}d33izPa7{&7{Ktxv%)@@nGP$?O`Y+L@@G z&qvapT@$?7NG=-d8JeRnVK4BTd*T*Sz3<(foV&-{JV<7_s6^u&>Nbnsu<{J~jbNQ%aab(uQgLlL8nB_#+3qy)QIYMI%ajm8qX!QfM zv7|-uIUxyz) zsooUw*4Lw>@{VZV%J5dDek{an6YI(;I29CTb)S+i6C`Of8LrGL<|4q! zcp3euOL=kjc*1AZ8-2M`!&bWuHgMN7-n%!b+NPd)YFX)aa&T@!%fv4xbambD`L?3+ zh5dJH-|1M1c?Fe7Cd%^tdSlhx_HJEk(y92Y!TnysL~Fh!W35QjerAQRHk+H@YDl`= zv`;a89G+U)A8)^N qH2PUUTD~eNtVLyrN2uVmvU~eAxyEJF15vbjMVq-peG(8X>HY_@gq&;u literal 0 HcmV?d00001 diff --git a/metar-images/ntsra.gif b/metar-images/ntsra.gif new file mode 100644 index 0000000000000000000000000000000000000000..c1c7d7484cf9f6158d671293f0e2ae42d33250e5 GIT binary patch literal 11622 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 literal 0 HcmV?d00001 diff --git a/metar-images/ntsra.jpg b/metar-images/ntsra.jpg new file mode 100644 index 0000000000000000000000000000000000000000..afdcf4c5865c9f461fcadfc332c2f5fcc16f4308 GIT binary patch literal 1671 zcmb7Ac~sM97X5ztWoMC)V3DmMh#(MIgjkhDP*$N~-)$#hSO<}%&M1s59hE7g7$gCi zAd3iuAP~yhS~fu#0!SLdmLQu5Rq9f(5DPXFI?I`V=f3mZ^WJ&y-uKR@m{BYO4KFuO zHvmBp@K6R&$iQiUP?iw1$A~>3;XOtnkuVaCLZg3s7#tRj!C}y7tO^!~--9w!Rl%$7 z6?-QCk|IzrjKX8knBPYJFH-aZ0v4PA$6$y85CjM&K#BpN2LOap9tQpk3_zi=I3xrs zyH*+if)OZXVE#PZ?#OCf0)9kgK-^i?VqIuL*X{6BU;DNs7@ z?V=C>0s$eF{r@b35CA41l~zPQ2FdxYLJCxsS_A@{j0^2Yid zGd}C)eWSGZ;N^?%U2%pXm@gfzvL+%s9}M@@=~A;;sv(#)^TLpcDOoo@S;+%jJM1~} z-8q)ioLxdEu$cKv`W*N86?tf4(^;3G-`8`OnD0)v z+ozfDKUe>7)tJ`fU>#*|>mNIr@Ygz;Jb%EUahP3wUbTYovM19udxgtvj1Dif^oT#4 zI^US}UBo$cLR~sN@_|p;tWds2QbdRUz7$6&l4IDzZisNBxT*dABhuDF$V0zc`#1rn5?3 ziC?O9^B#x5mz<4{9S&-m*%}x{+#kuGPBSJH4fA`7O1;0OAuSB-pOYfoGwXvPuRDOu}ohMaE5?eh}`oXJ>k5+&?W$nN^ zpOe=WCRYzixE*c&w(jJ8$7=2y%5LG0U)w-M@HN$}FqMX){SCbfxa>va!< zg10_dzZKx)#_xCbv;BUY@0b(4`whC-pecag&5OHf9e1^&Yu*!|x-JOesVp>ZURX}i zdrN%AHI1V+^zx$h9tYeL@h3`lcO|+p5&4D< JTTBU37yoKv)pWFk>FC0VH7Jg-j zzcSo1*k|>NNN{b|!w)0h?wh%l`Z~t`;^xkeBTZk=#hf3SGEQT?b)Tfwz<6!XTvwr#Xs=K@#byq+OYn024~s-g+#c&EU! zGugs0d-vvJ;qvy9gLSzb|9L{AEHS8FvzkJgnhW$`RbTf_yvIfnTa)}bjK>msx6bFQ z+iw)W$~>*c!|L`lO!+J?cgnGr2Isqo2E$p;YTsUW``t-(C!p%>EOLdb*zg literal 0 HcmV?d00001 diff --git a/metar-images/nwind.jpg b/metar-images/nwind.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a2952dbcea26e43235571872b6dd96253f0a362a GIT binary patch literal 2141 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

    jP#Gll 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 literal 0 HcmV?d00001 diff --git a/metar-images/ra.jpg b/metar-images/ra.jpg new file mode 100644 index 0000000000000000000000000000000000000000..822cb22ed5abf5f8de04707553f4789cbf00b17c GIT binary patch literal 1839 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
      jP#Gll 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 literal 0 HcmV?d00001 diff --git a/metar-images/ra1.jpg b/metar-images/ra1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bf8d7fc788999927a88cd5ee3d2e27195d461ccf GIT binary patch literal 1650 zcmb7;dpOez7{`CxZ~R6!CX11@%B9f_Jk*K<&zTxNt5PmN_P zTjn6QE;|ZwI=VZ4|ywqK?3%G4G3EUz%eio1CzG{h5!IS%5Q%HB2-i%BpjxukT+{7 zo(JIw6$A_c{&NC@D|8H?3Tfj>$mMIc1nKOgFu7RE)I4gfMB%`}066&HH~;`)iU5VQ z76ZT)X^5XP3=UvGZTuD;5+w++hRT$`0yGpV90OtiC!nAcymvXZein@`s%D4}V#&65 zzmM%EHB4V(1!;a^^8F*zPE=9O?dK)spZL|W;p~1xiGFtl1906ro|Aak5X1)NRTR=! zKV9!9ow~Yu-pj=EtN!Z#V{iLZZ>}fV-V;VIZC$ZZ;($d;)0lZ8BA4nl4T&6Ytm<>e z8S|qUha~oIx8KpR@OfA;HliU1?6)Faj*N&te_|7@tuy^^#st&)&1Tv)!onH~@HNNQ zmKVRRBx6ZiI1w0jj00KnIyQ}#S5DSS$JtSn^%kB;`Vcmov?8%hCF;I}4F}%t!WvI{ zA3ie8OFWtE`{C+`Zzi(eYYKHPx?ml8Y%I?E+L|t)(X}BlD4s#?>5XUly+v{87e$=` zZ|W`@EbkgI@>!Z{p5hUJiG>9_sVF|DL(O#5@m3VslLGJUFlI>E#Ild6xIiD;;=0h~ zxj{Kh&z6-v1%i4?SL+*-9KU56NtU{f-_qrP{*)%G-S_;_YZ)v71fiMXn;bXi zZZeNvmzZ*3nrMms?V>@*U~~R;g9`@vMU{=ECAOw{zT=i>A0+Pw6lSxqz+wv!U^Q^o@KPmFDGc(4NKY*Jv?+S=#6T2!~};^Kn!#ry6LV?+)XbB6VCD~2l0h~`NYTm_$VB^-Z^ zy^>%Zfn+{oQIS%?W0ub46JxB;0!wmU{nor)iJYE}|Tmo3cM1KPzpU z7#iDjA)x41{zK;&F8xeG-lL4d3`Pth&d5G#?iYz1IR0+Pc6dYMgTxYhGu{D~9--1# zqC$EDY;#p}Y^b(6=S0!1>`Ra}onyF<4xi1E1q!y^NyJfFoP@o`Zs9Zo(;{xDA&=UySt-6#qT*Nd~|&F(d`Fi*1MTCFX@@)4@>I&%?oYs**AjO ze#7c3{_k{^aCIFe*b>rHao{?4q)1my)RfF;4 z(Wm@{-PcKX4PBEV4`w6R>g=nC!PExnf|G9Sr$UF?oyUXCX}BrJ0L{BUau>@_dl$6K zapv&Eprf7)PNS{MqN&lm5K3WJL=9J1t?53s$ck!{34CHb=IQy>6|w9uyu&O{ab1=j zY+m2Lws3JBaRniLc&sDys@tWuW&-5;U~_A)kG_cVSI36-p7I0}aWJQoZ}+}epVU+l zo-}B6znfLR5$A!FifouN8yC7wRY}}B4)5|6Y{G?k6De}3b1&)^>T#N8>>lQ)`B4s8 uw{(V)lK64Kv0ldIC;FJTu4ijwL|uC)xkSJBT;5BKT_LOS_BW literal 0 HcmV?d00001 diff --git a/metar-images/readme-graphics.txt b/metar-images/readme-graphics.txt new file mode 100644 index 0000000..afed085 --- /dev/null +++ b/metar-images/readme-graphics.txt @@ -0,0 +1,33 @@ +readme.txt for the Icon set for AJAX conditions, trends and wind direction arrows. +---------------------------------------------------------------------------------- +The wind arrows are from Ken True at Saratoga-weather.org + +Feel free to replace them with any .gif set of 16 direction arrows with size of +height="14", width="14" transparent background GIFs. + +The trend arrows with transparent background are from Johnny at http://www.wetlaufer.com/wx/ + +The conditions Icons are from Larry (anole) at http://weather.anolecomputer.com/ from his excellent +PHP Weather Sticker script and are used with his permission. + +Note: if you merge this icon set into a different directory, be sure to change the setting + +var imagedir = './ajax-images'; // place for wind arrows, rising/falling arrows, etc. + +assignment in the ajaxWDwx.js script to point to the new directory relative to the current page and +without a trailing '/'. Failure to set this correctly will result in broken images for wind, trend and +current summary icon. + + + +Ken True, 14-Dec-2006 http://saratoga-weather.org/scripts.php + +Addition 07-Nov-2007 +wr-*.gif : new wind-rose graphics 58x58px + +*.jpg : new conditions graphics 58x55px from NOAA forecast images + +Addition 01-Oct-2011 + +Conditions icons in animated .gif format from Paolo at http://www.meteotreviglio.com/ +Included with his kind permission. \ No newline at end of file diff --git a/metar-images/rising.gif b/metar-images/rising.gif new file mode 100644 index 0000000000000000000000000000000000000000..50b9b33c2824c17a92c280a180eff9471fc3d2b3 GIT binary patch literal 54 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 bH)dHjpEl;$?q;HS&cP_r+ntgk&f)(6y=*x1 literal 0 HcmV?d00001 diff --git a/metar-images/sct.jpg b/metar-images/sct.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4f813f811f1876b9ec64b321408ed80ae3c93734 GIT binary patch literal 1333 zcmb7;e>l?#9LK-k{bJQHTYjWA+qANaOd?{ke$KNCA(u#MjX8>;u!Jr=6=Kt(#?|%f zs9Doud8{M9X7eNK%8>k6(Q4_(?Yif9vg5hu>7V=S-k(2T&*$}io3y5Jz$$PDV+R0& zAh2uU0MiJt6@bHFa2OO0hrtmDIKtclX>Mj_j$VdZVu3|3$70YJjEx=M!NwM6i@`Xo zUWs!gkVvHEE6C1dqBEXIA}&fm1Oj1hW^RQ0Vn`j_=bL~T5zEWRG2jeP7J}ChJj@Z2!e*90e`^TzU~wE zun@Y`m(0D6N>yLLmuIf7H>vQ=e^B`Tbi{VmI*fKXK#xGT6;>kHxlXtW2#k~)U zm88GL!Y@TESqo)c^W3}0EfUd*6?I6XZ1!-vc~;8vg@uyw208t?s=d@bvi!3&+|{oC zY{I?<+_F%5bVuGMic$R$hEaX3LXfC_ypRCa#qD|1`}5o$GCJP$rCquV=jZhLlPU;R{# ziXjcdi#>XmGM`ls1|D~xb~>IpcQ;DDoaISnr^4A|?d-qW&u3{i#pe|jyjhR`Fe4Gz z-pIOU@a-Eqa&G4F{>mesA5YaGzq&E}ohAi$WU>m**_TGw!Dhc(_gi^KAFnNdN!Ne{ zJUl{Ds8;?K(QP}?!IcwMVHnZQG5x8@C8=^LS=@KxK$*z({f zs`;v}cwIdwhb)M4z|p+i1Rj~w_h=y(H6Ap{P6aDeT-;-|{?DaUic1q;ToT^*OFXWnHc$=kk-T!UK$Yhuru;HlddEm%9@@}*)dytsjfxW zrjKdDYsd6u+pzlaAX_89!u#t5N6kiWFYOn>{s4UNA0yo1?Z}k8JmsC5AB8H9y)!Zt zZHgQBu+;0`fkK0Ge&xF}mQyC+#!ac_J$BvG7d`JjX4EF=-xJ3e7saB{s4a#9&8plK zMG4~T>-Y98BIVG-Oy4e|0#ylkb+GpukXXA9e@kb>y zfxe<&QNqNz-&sli`?duVM_=5CaJ{EG;Fi5EgDl?gpnH9;RWtX6B{f$!RQn;n#U(Tg z$Kel;L{`=%Zk11Z_a%4H#$U1X1VajPBsoq-O=2cAF~1aJH;1v3{mkYHN0-EQ7!+@x z^C`t>i!j6*T3LzyHJjJ2dZ6~ybQ=Rs#7_u0@uagGJ8VO_ zS?}FNGg1uYUJ55p2(X*_Y!AHtzWHZWHdB|d-@6?-P_qDVBrlEfT D2%;-+ literal 0 HcmV?d00001 diff --git a/metar-images/scttsra.gif b/metar-images/scttsra.gif new file mode 100644 index 0000000000000000000000000000000000000000..214ed22f7832329bd69e3e01ded57997428347e9 GIT binary patch literal 9917 zcmcJUXrYYs%a*n`&~Y$;#w7^M9VtGjq=QoOkEl@BQz(uKRmmx2LyEwqjg7tjF%|f2+(|JFdGfmK&X_{+(s*R#S=(>jV=s7$ z7us_#%|E}=Ry=Wi{bI+%kxxw{itocaYDN@_5$HF$&*0$5)sdf_Bi9E91|JUo{%P2` zWaMYv@CU`9fnreQ(a^Ckg9bJ7QL%hb-k*DQP;piMZlZT*$tfRX~Aw|d}H*2~&Z+ATUQ;NOTK07BdR3q~FDJkq! z6n1`Xm0W3kC~j@-e9+ojB7NT^X_~kfB)^v_Zk2v&cIdn>EPD7selNMb5)}9!-zT;Z$ zxwAEo%W9g=*RwiK$%#t&;|ta!h2c#l2TMw?j}`cql$0F0GJf-7TwlTd+ofSw&u1PeADPP{ED1DA zii?EBH)jMEpE9vUMb~~Qm7P7CF(L?%&5IWp|C_KEaD5RYcr#T!km(fqdP?1FONBo9VOLq++Q6t z%H&?_Kjy~eXJ_$_aJfaBvZdJq`*W$g%ToQac;0)s_0jywq?9U7YOLtQ))Oa_Pn^j1 zN^jf5Z3;S7wfA_=-sHo{$F?LM<{wRTPdaLucqsW;-0rZ$Mbu;B;KVG_(bnLDSN88e zv2#CvLtMGfeqnU{b5`qg1 zj9yU!;uWd^?jgYpI?J7GV+T?K008)JV2C9YG1KkbZ??|^fmvr=Cw5~ zJ@zxAjlzYZp2wM9fyGY83_d>h9I;}>jpKZbEe9S|S{1(#wwXQEA=-+P=1@odFI{l0 z+jr6ltdgI1Y*Sluq=b_RRRWGW{1*H%%q)3M5+6L{6GB8HX8o&2ZA#4dZr;7)!tN0r z9a~wH2RAgH(}AQB=pC|IzlZA|kM|TR@0OX-bL)58S#-VWM2mH?&lJB%AZR@sT_7M9b@p~Nvn(4@ znEcZ?({xB9ez3&x&{&57j_Y+S*JvqPr1JXI{}#_ z(LNE*Ne8dp7N?}W>0xU}J0e&H%(bt_O{OPZx}nTbezXCS8G1B+0;&-qcq)O~C7y#3 z%zmeA^IdN@>}`24$p~TQ$+^=8J@W0VTS}*^F#$nHh{qzLUm5>qvv~r7 znE3LQYgfj-Fl8m}ce60VC!k|2>tWHSZSYG9<90Q7Y$Q{2vwSMhwGBMwZFEU~^o`gK zjIk&y!%b?MvEsYZP196B$n_tm37~zJn)4YtzN4s4%a3t{zUKPy;~n=7Hs^a)+4d$F z=#|AprfXesvLAGO8D}5RG+%{kzhKiSZpUmMjcWsheCW+>{K&sm+k6mK`00Uw?ZInl zXtWP-T}c!Mx-QRQ0uA)SpK&#|JK{5-I(j$=B}+2T(VU;2@^k$Np7OB!HjSxwij%X! zdi9QrLXzNRekM`(aBv1puj)pO|9Z1>cg;h5dq^1Tn{HvvI-aT?O!$*2D;1u zro3HelHPRV{g%^I)X8yWUsbSTMF?g~$o9H)y(3^F4=m;bT~)hLya)lIXf!TzKg}rH zIJRoIM?a>jqE|O%F7hkh8>bQO8`~5^?#-FQd#JV2Na?npW|h+5gk_PBNhw$ZW?2dIX@l%*3a_9zjfA#nunHP=#`ax-;TecTVin_<~{74q@ z?5sdKF|puvrzUibo4}jGusrk~vB2kZttuDASldx1-6JSNK42@`n9;MmpWv0WVeRT< zkrLgkUCU6;cTltp)2}w;9C0ZiON&V9ic`M&3s@)aeq^54a++420H_v!PDw+|MZEIj zS&pG|jcnctECGCLL|e8oc|P|{sJrV}eBO@bG>uG}2VO(uVlczj#N(LGf8?t@rVa6I zy$Pn-;&f*_ajxjVl=(qY7OlEMjU$$7Xoz^Bi8!Slxc1kQxWez0G*!#-wDAH`me-|8 z%_4CWGCy8m?MGKCYh)sJb9q4{?CbX67yK|>9$xm6ZPToWXSc`|`KEbas(a(p+6 zm55=RzJ_wrEDdwv{@LrdjiD~1dpFgDJ*|AezZKzN5!(KHNMXT|Te~;h^6$Pmaz)%! z^N?u~-g#l<-uz+J zD4oK@JfmgqUf=h8@c5q%WyqR6x*Dke34b^M46p#0{vG}b_}}55TA*eTE)$oxXQBu` zRAciSJ}RgH8OA%dCbS}OP(q+GbG#L^Q7F1es~5pxgR@Z!XQK_($mj<*@;ez z?ta6Q4QQ{Ay-)th`)-@p2Dj1})JQ4^=hzOx+|nsq%htFnuBKppVf6? zX#|gH!9r~jjgc7^e^Bcx3rD%7nGSn|g57WdK0l9+HR>*A9)WH8)&7m4i(ll;sgm+=Ep+j$4I z`A8%BbHQAm<)@cMa=gMz0s!fA=X&%XhLmNk9}8#tQ?B)Uigff7M#~LJiHm)tuji!s z>*gBm;l>IXo&{YOz7PoB?1u(oUsWFV^C}7r^&%@==^n}m{)CKbR(a+L4I-DP0YXKj z>+}eHmPBdihh#ZGgNbTe!_}ckboDuNTPnao0Od+(mIQcJc|+P>y1o3)JKCjFVIj1C zOTY?X@-GPp{~>_`NqZ{X)8h;x?#-flBmih`ct@eBdUvWV)Xk}La$9FVI^3xC zb;}+F&B>=}rs{gCmr!WloNLgUN`n6B{I#~2648=SYOb*-=OQ-@e$5%km%>Hjd|7y9Q-w^Dfk64s=h=Q>8?iDt%Zpxg8>yGFYLFS(1Chlk;4^lx zqI)&FpYXiZq7v!7b_#584{a!xJG~)(&M{lPu~F)0sBT>m;QS?qAi`es^XhZF4hxYH zqDLB#5C<74!$d1;N|jk;b_GFyyd=u7okewYXtW2>=%B0%Rg25L>+HQ*K?<3$Ogds8_|IT&3DQdKvbldNGT{)SRk=aj{wXPiGv zF!n`~1HU59NT99iS2?u|)6lv@4726mS2o+y#izBPBn2v%XI;%y!|1V7;kT{Kglw(jE0d5PZ_V>fZPw7+zGZ^V z=m$S8{3I;c_TDy_)KTE7C}&wtJ|IXTXW?+Vj-v7AKQ5JV{d_$ zncqPdrXoT<>)cmzFKKD%Tl?C)*DqY5S6g(h(AX_0hkk<`##rs#*giG>VMpQ3>g%re zGj{28-|43#flx^#nU#HO=XmqIzGs7a;?%b#zETQS67VJIvQ)4-U5(izrnzd)rdgYH`)>ETo zIc6LO_fgRo=JRdOQ@8`RYH5N#3*VJs?{!9O*`O(SLtKWI`O7^z=Xjw6v_+CeVu0?3 z7rY#Q^Q3q#Pth?xfV|y;L3-Sk6b^3aT3!^;%!*LydoAa1BJ)oz!RlCS5E<@Jy4=u7 zH7|*CQ+78CL1D}7sAux^dRC(k9h*2#Q{K|w!BR0E7r9|bOUFg3Ew^vpsDt89KpIqQ z*!*g_PNP)qsZpXd{kcxZFLxnYE}Q-lX$XK801sI6FHOM|@MM-%F{9m6&$HaT6fYNr49r>}PSA$MDywX-)$Lr48`EKkLXwkM` zU~yG1i%gn)4YRsu2mj7MiHPe8j((nQ(Q5-=_5;vn*HAZN0IQmkIe@^541(QRse_s$OWsE$GOH+33RDrrwqSumS|>#Ou!L70Z_o<40o+e|F<+2|Bi zv}sEg>mPsgAKx4O>yLo7fBF7D2W>m^{F3&o!_E70&njd+->~b^!;n6rS)uy5?5>Gmp7JyV~wc`via;Q{O(*A zE$B8~vkE-O!U6gx`RU9#`=CUHyZ#PMZ929`S)DWm?1ia}_{$P@f^b!PHqClK@H2!n{(ib0d* z`FLN88z_60e*MdQzWF=sIRnCZFJK1a7XL8PwH(gxgjX3}~(CI?9G^z7M&jTExb zM6I+Q;m|84qZ|%25BECWK~Pjk5BUX`Xb+a;UDOAzAux+71izQ!DJCJD2lR|ss{VRy zZ5(E^5fI<47oAUjHoFiYP=pS15jxk72`$+g3B#5j9qpki3ZZ$u+l_bVNFPdhVn@%F zh&k~dU)VjG#c>Jr1iMaEKj#Cz!=|sgVG#O%OpX6dJ%3M)f2jvO@L%f5N&fy8L3E3S zl;^IhC-NV|LTh4~ks#jjAeFh|p1kXi%hgxv!;+n(PjJ56ZPlT4uIzbp{LALtMeSN# zY3j$atY4nlSZ+y^_TOQA{shUb>g+$ClbLs!nlisMpHqAtr%3A|#Yj8K|BljNs ztnKBo__(p#-fs{u`nTL9=i0Z3I&am2hEimp+>1j;XE@s`p4mLTK=4nB`7WP*ZJTDP zXGF7`JD-<&L41bnSkR?ru=Uht`SieV?PyHp6BG=;l@k2^rB+dNrFWrzcXEp2ht|hS z=9y8)KcqG8>5%N3lUf@&?)5ctO=9r_A6vg7WpV{+-sU2~LOX2-Ov4LTjra^F-5^%< zs+rBPx@Z=zjo#+bw1xf@AlyhsC`3KUA|6Nr`eU>#KIb8}Hp^MYick{N?6*~XF+SrO z)nikHdcs5rLkm6AfjuH+18)jHn_ORw_j7Fi(5z~A6~#c2gy9pt>*-}>B7|_7?yHN` zuFqb#-JF+AlL4l@EV`=6a>DcQsazAU`*vQ0WAcg~M&UTO@1i2a&2LSdOgcc@Rf6La z_AWn`9+LcgoMHQb8S|F*xH(N=qga~HLs?dHfGQB=M6U{8&v(kl{Z1%Q&2hGBm9y;y z95)m+J)xiUiW5Jq(;535sO+v;_d8Mnh&20F=H;X$X1zj6_gxMUO?UwH*Q9r(RqG?ua@x~6dS0XMzhPh zvgO_D8@zO@pA2I0ZS~;cg%u1jw%FLWL#j93Zi+JIADVScp!oiQT?cfMISTq7>G?ih z2X}6sEvVsT;%fGCO+)k5q6=Vtn|3!zoDTbJ`1QzKh?Q@h#^7ih?1i@8F0k9T;yu4! z*gjNrS+f00o|a`)an{K-qwlmX?OffjOr>7zi@c7;z3u6}bJkux+Pr>hm?#aXKNt$? zQgL0LlH!7C=-;*UZ2&daV~Q%jVe} z3#_B>C{IH(i7~yJd_7FBJJ7sbb^TN&{=XPNB`v<6bnUa(G<9Qmd=FheG~P`aX~6_z zw;FXQx#@=o&0JVhBOzRjGg#$<_>p98+!1Nko=Yk9+W%N~|F5X||9#}}7G+;y&(T<(;U)Gp{lE&CI*^*KK!GYm-zSm2bAnx4FJBz02~4Frewd&p)$r z7CVKP!k=Dht$*kJ$f;A=bk^xC@x=xe;I``g#?7^^2}6nJ-)MQ}80v?G?TQ-lEQ4h< zjlFtoFGtjPoL|W@f(__4+WS?MMFMMr2nQbGwtVYmkJ}rbOsP}YGv|;MM8~tN^2t4; z59uRDr>p9J8fG2fe@|>UrlQrRy>VRPh72;}4r;EV+yEnrJ>R7PRI1Bze)p1*n+i&w zmr(-|q2spi{^B`x>qk9=6N33XT#8i%!sd)-BUA6JJcxlzpe?9l%Te>RX?ny7mT`0Vq^IfQaidjdkCIiAL7iL%dVk9%-agE(@d8R=daMP@tXcS8ya>}N@@LD1-I^N9%l z2dZ9?#KRYvCE}i0vPtA>{Ur0U?cS}Xr`%z}A{Mw%T&2iqLXuGmP5>00(g z54T-}dansFdr}ot364zYaS~b3Bi)qU+^e2|+5nKv-Ur&IFPn08VLG9{Pxn9N3Q%bl zN0qO(n{UK(xx7mH5cgm+ZbD|vC0-Og_7xofkjLX~xjVWUdfLyMKAruN@^a!qY3J&nK)w^pjh)?*bEL@igS7Sm$N6ajg8>mN z3^~dhN7X3xjT(M-NR`Kvf;Gb&e#U9XDL`H*%8*>Vr~VOCNS~$=q96dNU@6JgNX4Uu z)a4EgV&fpLz6*O+n3iF9fH(>AO@7Hqqi>`Hbzly`h+W{FmC?P{ zMBwuJ=W}fS7*}L?;A1~X{Y(_Gn+mXmS#*G7D2*+pR#Fm_tw;NHdd&A}F6Ns1IifQ# z`{EcLgpp9tFk-tV7>pwP)fqdvwqLXTG)|VA`pu2I!KsdQV5`x;>m|p;cD;<{U{7Ok zR*<`vLNJ`Zt~(ZJVX0t|d+<@%Ne{TmvY2l@8=KI-p*v14R|_Yac;Z3uO)>+bYQ=)n zr%|4&1+Y_FX$^;kR)Xyl0zI5RG24UCnXr%^lRDS>oZd6URu#+ZOt&6#_BaQk6_TO^ zgk3H|135Nc9U#-oEp3Uzb!H7J^s1DFKwM5snh@{6tV=i8x|1wY^=5Xoo1N-c0A#uY z!UZp@C#b}1e4bxaj^4>*8g~h0oN=)B-_AGP*wK#MJ{0F=f7Z;cpSmY_QaoO|d_|y@ z+-?>)F39bN?x4>0HtZ$@%XU=_btixL4gI-DZvbzL&B(_Jz|pq}#X5 z*+@W!A!7_Z3-gwxGS~g-)SOnH#x+pus+3K=_H^`IiL6dqcq1_b?OYE2{%NKis(ziA zI0{s!Ujr%u#8s5HR9oOgQGUEQOCoqlYcmfGDO0Kf<+pI&KYITVX$PIu-ivzokXetA z8qaRVnla;MW)cY@sYqq!-DNQo zT59kaeDh8uOA)6y{O#_SW^>SGSG3zM?*~UgnB=sN&2$jxD1>|A&GRD%9m7Seio{b(j4W_gNj)CUtCUAE2zr|sQU?0#~KBUfNQALBUa_;GqseLd(E8>PBD4)V8aIJcOW2})~|i?sF& zd4aAU8$r>@D~%YTI;eF%PY2u?@2Q;}8Z1?6J;3O;-*_B2NnOS%tK{x4D(EF-#!Yk~ zH&y|2iAHQ3OLcuej=xhOl&j)5>ILU%D{yn_S~cKy|BNoIeV0Zq$td%1-oG|J!1cUlfX-J(q~R-@suT#XaAkRbvN96x}Kf)(Ye|Dw03 zW|O}hEz{khISElEPP5y|&;HJbW{Dh0ug0PB&xC9jR4eAn{njURVc^E;vO0I5c1xQZ zln4g;Qbv*v=b5|yT!gQl#_DCn`k5c<4)Z0L9>W~sVxThoTp78&x*6S0ddKn`#@=bc zcUx3fNA(e##gh%?{DK3rH3OPPbgj*wC3aTeo*yhsale>n7(|TjdnyB*=rt$k)~i@; z7sm56J@ee$p*zGR5yG1_%|no1a=6xYvUr*G-DO4(HJ|xqp@+&@o>Eq4B%;zV5=4+x zW4~!Wc$-#w9Ng4}mf&GuijC?s&FIkR)83Ex&QZ5#a?*(mgwj1#0=*97PG72%BDbO# z{n}x;scyaf5^0ydHUDd%5}Hkxp+NU&9SgU&Pcu|OofTkpQwh0CYkfEuh6U=2H~=^* z3#Ca$DM7#LzOsXU2A(%&pnfBya^Ps9WQN8r%3JZU7ApcVM&FgOFT@zIumWPt;?kp} z8>U-3AOQp}ND&Eaa)^P|+N&_I*V{yi;|P637Wy{IO(bGrepp6&gvaOZ^zum8+FNb{ zRcaT~CUh>qylH^{cM>pGy#JE~^#(pAqoRBoQS(1ZaA`FOu9e5q*dXpnTEw?K^M(~` z)s$TM^>w@23i0M+>~DFhenQNy89iCdcz&t@7%B>_pQv_W8U$oH+P#wid{vE{1?U-S zS$K<_(#&9sQwL*=Ek;9bY)%V59r|Wr=>0>e0UPF5^oTv2deBw-C7bo>VN?Un*lkkD zYgb{D7(Q zrti;gZmu9?x0WR}Pi+L8HCYA`QeBg0_<)xCKK59Rb`8soHDHy@p&xs0fd8=tJOa)G0 z{Irb_#BSXqsL$>uF{{-+1eiisRxKsM{9S;Z4d?AoFWYw;A6~UD+Mms7)BKA7RDs{* zOmtvNKl|see=k2ihv8=Z4H5Q~nAM%3m0eQb4?|VAsP@8(^RNse6~CgAEGJD40br(-CEF zh=|H{Kz@|CZ+o{wSj`y0#3$;G7?8W}xk(MU@sSp~lp26CW7#VNW!}zXUQarxnVOa& zT-paqnBm=)$Nn2$tQwT87^k^Gt<*y@%-^*fR>x}0OL|NXY4)iYyKbGdw`h*N(oapb zT7Z%ZiEOF5)mu~!jjzX8WVi|^yAhn0x>b%SssBQ)j`Qy^EE+Y+G<3mAJ=N=qL=x&Q zL`Pbs+I$=X=Gs3eus%{fRqyZ&q_xSb;1Cwi0!D>uFqDH((_Dmh4;w;u2h>Bz8GiM> z#Pk#{0(WY;p&#O!$Z^yqRc@3|k>x+-Dp!i0@eK!J>mXJofC>mXniAiR4bYoY2j$Sv zyr~+@#C^tkFkX~(m{P~E%BHlnQ;QpMjC@5)tF@b=*^cR^TNBq4031+qQa{xg*8&J- z%?)9o#>9=^biR$dhObq}w`+OJ3MY5Rad`q;3&!5GthujwDx(~PM&vjPv5*c|gHYFi jvowI`+D^OfOV%$DsCvMpC}%$3n1W|`VGB3_fXn{^X=ywH literal 0 HcmV?d00001 diff --git a/metar-images/scttsra.jpg b/metar-images/scttsra.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1feecb6f61734159de184ec5531b6d403aaaac6f GIT binary patch literal 1750 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 T2S)xxm~}Fq+$a9n{sR9GKYG-a literal 0 HcmV?d00001 diff --git a/metar-images/shra.jpg b/metar-images/shra.jpg new file mode 100644 index 0000000000000000000000000000000000000000..412afc83693a2109fda6849d933ac1aeac124c82 GIT binary patch literal 1576 zcmbV}cTm%37{`BEkc43Z1QE_6BU(W~fixn&-*;j`+VM)|BgQkpv(zo1ONmA z0j2^2_>+JU009dn^bmodB2b~=A|fym1RRM(z!3d;BGJ!0)s)Jg6wd?IRHh&q?Aq=h)7$ziz@rcXy2k|!Bq^a zUSMnnH&t~mlW!xCvis!@$YT#5`TnSyF75~X$y29|jL#8FOwG(~?d%;Kot#~+T=gK5 zJiUJQ4+spR+z1Z26B!kKHzqdje$s>FhbfO9r)KBm=H(X@78O_5)YjEEG(Ky3*}-_# z`MRt7&Cu}3=-BwX_Y)uH<`)*1mVf)W!u-tI+TLOBa`uE=AOP|w);F?$aG?cUV5s0p zMTJ}-Fh#H+XednSgou=ZwWzzFw6gXsxQrn^tLgZQtmrPYRk?`V4Nw5q4)9KH_uE~=zus5bN?iIB<#pWWoiFY7)x zm?SPa4g1c!iaOO)Ht2-s)a+ksEN;-CjYv+s>{p<0^0g(VGUC*O)MKo{D(ux%rbS}R z;Kt{tjR1*NUeO^RT~cAxs#L9?wsa+tHP$k*>szPdq)O@ZA=;9Ub7upytB!4{b1u*L z7v++6{RU(lkJJ=Qjnfq~W0|%LE$uhTj`t0J9PL`=SyCbtm|F3g=57~V)QorCTMe3d zoC-tg%^7i=Sj@DKuTP#GXku*P>8Vb*cv(VDo?X&T(57qa)>z#$xE^6OnG?MIx&XIv z?EKl$SEsGk9?7>Q1k&&UYd;~wWEbb1NVfxSv=4;5soyo5?J9S0#6Rw6?Rks(=-YSj9DWy5!hs1JzRlQ~3y38)grB-L7dJjanvD{4VX}Z($ z5@h@5N}lk686(~v?uF&E=aw#uC#R{_+7_6m?TC!t0X{HR`p$W3s#_hL;n>Xzo6*6U z%pG<1J@2`I2{cOL8tt~F6JP0VoQTG@^hHWWg=p%#Y#%L?^j-;&RgzL(o7bu{X`u4d zif`OBzz(D+M_NrA8mv#JZ58jZVwV~?{hX`BFEjq!MQ^Zq zrELGY2mhE4ta78ssOjn8Dn5|g!~Ll#rz&v10$ zjaJp2y?rAOf1!3Hmf5FXZ0BuvPn1qEo1x3RJ;gGIB;Hw^FB{7T-mb_|=NVK%gBq-H e`XZV3NHY=*(}>@*cJ}Hm%KS8FoRM9{fB!r9=){-+ literal 0 HcmV?d00001 diff --git a/metar-images/shra2.gif b/metar-images/shra2.gif new file mode 100644 index 0000000000000000000000000000000000000000..912c275a951a27c106ed493ad402d841da0a98a9 GIT binary patch literal 15599 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 T2S)xxm~}Fq+$a9n{sR9GKYG-a literal 0 HcmV?d00001 diff --git a/metar-images/shra2.jpg b/metar-images/shra2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..69fe76b267d0452fefa0e32ccc152a866e1dfe29 GIT binary patch literal 1580 zcmbV}c{tR09LIlini*nd92=S_#7d8iWK5Qj$x&(Cveim*t#TiOose>b5OPiHD97eD z&J9J5k|X0TVq6*bG@*vsncaQb=h?q@_x*jopXc*@zn|;%{c=aR?*X(4(U=H;Kp?<~ zw*c-qU;seCeDN)WCny}s7Xl84!I20Q3W-1>Q9>d@C_!OCBytaCkFW?DjX|S?u%cMB zD9=api-7o<5GaC|h!#W&@=pJwxGew%0T2L92#agTO&AF}1M79E6;H#WQj9 z{xx~^E8gKql*BiCC8ZP&DJp%dd`#oGCSHqRaLSN)+Q`_%!qUpx#@6nF<5j0?&MvNQ zKE8hb0f9l}h+C1j??gq%BqiTZNlkl@o{^iE|LAc+VNr2qRW+@qwywV6d28E?_Kwc3 zmv08>gG0k3qhnLkjG5WF`GpUQ>l>_(>`$9p+n@PdAOP|w)>pEBaA9~{U?}fN1^8Sb zZ~$*ZFi_Zmqj0PqNx;EN^q^W8LQFp~r{Wn>PThP>{EBx!N<#kFl)^e6?GLhl2NwRn z$i9O8%{2xHK|s9EgJ1w%U|Cyp9nLVTvDKa*lkDtTGS;Xn2{8?-9vY>{%I@nB%QWV= zcls_XyGMLs&Oi!)Wc#GR%de{fRSsp?r^5-M^p()2=G}&!a7)+A>3J-sM0Ky^WQFSf z&3XJ?EbPWO$LMJ-D5S`CUfL_-;Uk;=6>Zh2LgAzuuq&QrH^RU#BIdV44;K!wSB3T@ z>|{fogbkEHVO$`%jA=nCo2e(H`cfpflGtqqM)yTlwOUFiP3anTq_f?m7tNCz$?l8< zVYMjg3At*=xj5vG+r}b+_*mB~U^a1VpVAI2$Zv2nGA^fR$iTmXD2R7t=a#GZ+K)#% z?v%}TaFpdHD54!3xxbBC6omFfUY~#YiI5#e(OT{k9Tq;x2`hcv(Oy1c`^v*5s+b}F zBWuNsvP<)nkg)EmUABSNGpiZmL$>1!RP(f0@30+KD(6>bMuJ6BujBr?FXso#F1gTW zvYg`kbW%zjf0^jLT~F6n^+e)JGLJ~>1!3Jg^J^|OLJL&c^D&K-CxNPZttI6T;$u}J z({vbk-MBNw{)X)jeFC0Oh}1L~#nmKg40k1}&k#qnIUNA&!$mLpPaML8)pEXdrQ<-B z^FDICh(`33nHaN4mQtOsW^mocGxb!9!}xVF7f=p}4N;&>r(2b=GlSjjL$)2_owQa= zg5z%vXPSHT43MRZ-Nta|G8v7gNmp*Bjp-~3WgNb@wwvbhe%uR3txWT-o%B1SIZwTB zjcwIGw{}6QU1~pM>IP~n!tx%nWVfdk;@fi5y-($5NhYTFwPKWtRprU}@478;pFtN> zALbp~kTq@F%TT!!Gt|`Yv2^5atL5D~9Q0Z(Rbiql&fL^Dh_)F)6+1$ic9r=)Hv#Ii z`h(7+DSL^!*0=9oryHMl(hYd?RIx3oq}njQ-cG%xojfca;2DQk8hvq5%hdmsoAL>% z3`+FsM?t@88qLyBnkY@XprgEgsJJdxxgg%1nmTJoXQK$@;j>eNW~x3)T1zfP$5WQj z1rkdSQir70w==ft<#KWxjE+0^Inu;?m*@O~@i=&Lsli@FxBc0R&C%LsQg$gY;OgmGmOj)(>zTYW~Q|R_F$*V}77Qu1>m&x+e-J~^O!K~z}G}{g&PoA#- z6d51u0k@`ZUa7TX!$F;do literal 0 HcmV?d00001 diff --git a/metar-images/skc.gif b/metar-images/skc.gif new file mode 100644 index 0000000000000000000000000000000000000000..71dcaaa9ff537469318e551b88316c06e756cdbe GIT binary patch literal 8158 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 literal 0 HcmV?d00001 diff --git a/metar-images/skc.jpg b/metar-images/skc.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6ebbbf0b89fba520368cc415ae299b864945dddf GIT binary patch literal 1167 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 literal 0 HcmV?d00001 diff --git a/metar-images/sn.jpg b/metar-images/sn.jpg new file mode 100644 index 0000000000000000000000000000000000000000..74119b93f1d9c129e313166cd864052fca013592 GIT binary patch literal 1196 zcmex=sR_JHd(x-wIJs!9v)SCzYU#|fPmba_Y?0C` z`>*_GIQ2Dgxp=^l0NGf}%exk5x`&EAf7^Z-#9lspqc)8@~n%|q8RgZ3%c#XphD#>o`abAg>b`wlR=Cm8wHlmiB99l}a(ge5_sF!2>r8!y`dQT% zXEz1TkGfzYYxV5I8dWKU0Ktnp|VJi|tR;r8gy$^R}7mYfkknP2=5u zzf1JPa&N2lfbVCIcz&9HCu3>R>?!H05zHsP1H*6gnv&Z)BzrDybmekskX>TlWW>%s zC+Kg_rCYvto7{T8ZF(2n+{WthyUG3D_D^4qf7x(-*JKx~(^1hkDrbH zuRg}c=XD$x`fk>7W$HPO=W{B5DhynMmX?CnZ}KqkY0o6i}& zKAhfMu6}>kVdV*%(@m~k*c)v(apj-04`)5oZ7j>bJ$H|WeGJ!%QyV(nj{n;g>t;74 zz02aXr<{J-zBh8^dFsdH6&-ATUrXC|F5KktYW3jkT_L-gB$Y26X75v0%+a&;SK+UU z@0`5#%i7r+S+4s@TU)MEd%NJDZ*+a4?rgs23iGsHThE`o_uZ-{{&`w&y*~N6Xhh8J z^I$e*opWuv?8IkF`Swgse6*B7?yNbV=4a>W4t|}J?mc5Q&z(~^d4BxY{|uV)o}VutpmhBaYhCPCMFj~25SJyItL8^ literal 0 HcmV?d00001 diff --git a/metar-images/tsra.gif b/metar-images/tsra.gif new file mode 100644 index 0000000000000000000000000000000000000000..a09b6ac23c836717caa8df66d839fe85a31be60b GIT binary patch literal 11564 zcmch7XH-)OyKXv3NJt^{mOu~!2%#w;B_W}TbQK*OX#yf>6jVf1Qs@CfQBhGs6%{og zI5?sv^eO=v1Z5Nj9b|B%si=Wm{La1Wd}p1z?)i83%8$MF&#dQt+WUHVx!c)?Zv{92 zz5)R6-@lhHZ2R%|?sspi7p8fyUj4Z^&3ZRg()a4q>RYOO2D11n;M;56v9Yn|&n07H zPoIvBO^h}_9{Xo@B<1x`-P#yrIn@9z#(&62YFBcB>nIvaWY_X1ws{^k1Z(XZD@ckkBRzTJHL_U((eNAKR{ z*4=u1r~Y!;%_lY2o0l&!Z{PO0c{94^`lXthn(CU{CD)&1T_3%5%eJ_t`BM4F>x+A@ zT<2xhh)>mw7S>#n6(PP97)UOpUM*{QRvcDVR(7?lru<6Dbb<3ovFF87apt9wjI!TK zE;fn_!|KkTo6a#Qy_lVR=}AdR$+1h)l9FrUBGa}!pKO7ovhYCig{I7c=7Z;3`T6B* zr@>`~epid^GWoaXPwVjcB^PtKyu3<2pMN^P;$(KiP>L-lZx1({wVN;I@d~1|e~Zb! z&ExS{IRY;4^r5V(^laPR=?$+F6dO;toKCrL>g27I6n^UI)2XLaKTkMR}~l?&HPICmUkouB69N4;@N$N~(;D z;{_e6JrsB7VC?A=(K~};@(&%{8X1}Bbm&^-&*zZEp{lKsCBN)F^vmAJ6T2LI_h$XF zXYa53jL4C~T_K74L$;gkEeZ@g5E!^O#Y@Y_Cve9OZ*T9t-rkYhy`8OmPP({7@1q&G zx`y~TZ*p>S+2-i&Ue0N5@i64@XenhQU}O z5fnuv5{b}V2ZBg)MPIkzAO_vv&B~k#1_A&8(l-bc1CRsEHr@e0#{>YE1AuUCPmxf< zg)8fti9G_?Ahf=BnP)>~XRbQsaIE@KZg&BZk)!R^7}Y~aT}`s-4V>vazuBoWc!C%` za5>C|64$cHZLrij{Kd+6Kxal)SQI7b#7$+3gI#0esPBohTy&W4)xgmkH|_?djx7ME zA$)xiEeM$~0q8b6uz#COhJj7>dU5xB!30eUoQ*R znYb9mCD@fsjiZzpU&z@&NI`72C}|n<3C0T&bw8Pj(Qd9H#A?>ek5D8D)-H^ ztU4^}x@fznh;r-9=Aa9AZKL`*IK{4*xvnen6Gb&Wh!q&L$VA=`JKQw?j(L>zM^fKz zJ)_GiRIMJ6CiAp?UD~4G#AMebJE*%!Jf8F7AfB&8@ zmbFX;R2lV(&=%k{WeVa?MebVv?$q}%%L3+vn?(P!Bx!y&;vA3g3DNrtj}0)UR} z$^x6&jjX;^v{>(r*kN;>a3xOf;lfhBW$Ho%%HnlNRld`gS}w@}r|2b{~I+?(H}^ zI~i-1GCQo$dpSu<CTtN-@&-D=&vF7#GGMVHy)Xi$OkkEvqYv1I{>&3t%<@C*2Et1E)gc$2HN zrKJ0@txMG}j109n+OZwf-&z6{x8zOYpW5E`uV~YJcg>^N15--!(iUNt0Le+jVc6E$ z@#&A|DcI$wTW_QV_Ugn0H)d+p+gNpA_XWGcNPGZ2@PJ9`5=W~!4f?rHj5MZlG@}82 zU@{IwpRH6o*}_m;kRt6$E0jajUC~xRq!$FFn$nW9va5&_=qXgH7ehVm7OAGAGeDNK z6X6lg|F$N?=dJQ|Q2`vhOsG;l<*F@@VFEnCm@ng zHQuG=O?$E{ULRYK3{^CdLjB2ad6Y@L6vs-A=Trn%bpehh(;@UxSG>OuQ`3AH6&@^v zn2EWjlVT{H%s{C0bl^j98E!u91b5z`=8YI2ZZ8d)4X5jzT}0sU6-Z&AXbPBCFU+d)uo3{EG9mPdBSc9lEhC!Nj#LPt!<;L39K7R3KI+5XvQzZ* zu*nF(um=cL5^j*8Sp`rd{+HNDIRi^34F1%TVmsWgpA+Kr;J=3K#NF2ktN!7JTO0|bBqECI&<(hND`Uz)+z zf-E`oh$@#WjezNkK~qQYB1Z?0c^ zyj+hT#(z~A>W6d_jAH%?t~OV)l>GCJ;e;6KD*ThUf7DbC)@ZCO`Q>%AqRZE& z-31A@5{0d63^MgfYYJ?r;dqwP9y2~);aX)(fo}UV{DfeRQMK9e^kKw{9~V=Ut@jSJ z?)dRFW@@t*G&U@~h3!xDiH2Q3EXRgDNVhqGdj)}GbWJXyHp@q9YPv8c$zik)iACYd zw4-6+DMXgwiW;jm93KKWs~yplGz?War;T^lsud2mq0aRLz(^&uhDlmEZ_1t0j3Pr# zmMC*jf(U5HV}UwpMKU}m zzqLsUN;#N{hwE#`vbuET*f;K*%WYP~#BOctJQXMWl4t5Lf{<+@M%~+?VnBt%4URgx z@)a~?xK1*DRDv{D_EyU#tgL}~WD9s@|5>@Cz*F-GkCOpQSeJOJ%i%=>E}HO;K5|vO zwWn||p4>?$nOXT<0Nr4L6b-1@8jLIXJ|2e8^$F_4P-P6Tc{j5NZ(dbLfzlPJf_9XF zXLcJ-%(oh}&@QdHMX3*=?`JBK7rK>{`2rqXUN)6$lI3;9xNdmefCfsF6$7C#IE@By zF71~BAhJj?Ja|(S01QwJw_pI_#5CA;6j`jQM;5ulz*;3~usiQfu&_PM)Vm7uP@3xl zxgd?xrJy6=J%j`Z!MzGQ!gzG;d2u6MImAaWV68Ue`c!RVAdztog+|I@5A|VVxK}RksW}io?d-$^q-~AS3IQqT@w4NKWjeP1ZzK1_Yfb<=<*+6&pUqo`=Z}+bjC#4!Iue& zg@)U+AkNC3hqdVel_R0QH+jEo{cGN8DC1&of!(PbjW55%^zZuZ^f%*vIrnrNEBa(a zrO&D5=$()MT9r*)Tf@AnJ_m)oSNNd7-+tm_8Mnaxe#_REPOGu)ue2@_+EKRkC`O+4 zo!I39Q>UabpgTq?R50*wiR!dyOS=GPOhDmD@EpjT19*8X`%i7bbz|rG0dC zsh7qz!$Y*6dEyE$#f}}zLD-K^W$Af}EBXlP$p|os$6D%iEA(9Oqd;ziA^i%Ink4Eq z#tz=*4le+3lfwEp3JCT1aHdv42T+lOvu^^LhMO%FQ2g-nZx}4t>)3!wE~*#_Blm=J z)tPaiIaLqxPu;E49|rHzwnkH_n!e~Nkgujy&mOAo&EUh$x7j!Bwda%sHkz$& zj*?siDash`2csn?A*awyF?WRy$3Z`2xd$w-FphnEal_zizV4G`$hSq)%=kU^ccWv8 z5Cx?-nii?iYm?naUOS)p@*={i2R(7`z)-}8;b$K2U5?57NIIoAl`rkcayXE?+u~I~ z%IcS^hq~$}AI71-R{Z$RulqfD@zqd+56zw zO3&t(=PUgj4`npM3mYKgbqA%pd`cJS@GO`Xb0tlK=MQpAlk+S3$u%~NtiyrWC2v(L zc!R6%m6FQsR(pIzu9)o`)TwUbxFS|Bg@6=E7!{Kp;9oisH4Jg(`JVb zN5j>peNyl|OMEp1brZMK&4~$Eh0WX6unGzlQ}>=}WwAcH7|5&xU zUF-{+u)72B_=US{4fk!vE!c*tiH3x>P?k_}n$9H{ZjF~#WnxRp17Q!cml0XdCFzfP zROm4N6=r$m{GaRyuo5*=o`>jg!&k6bS*@{E{W)TVXy0>h4K8xZiMMuoodAMCge@to z673azpK3pFjZfeq@6IP^3Ke=ZC`UQ-(XT$u9~fSrl(01TdAX!|i(55zbjR8xEem`7 zDyYA7j+S}e2$`fKTV`er9ao>n;kt~9;5MF=8o>06#HvnqZ#c|75NRr{W9y-aE8*_M z(g7$4%}tu>BA3fX-N}mU3s$%7NI+NH;1GXjB@(Oz_EYPDn zk0l9rBk3mN!w8BUQ*@C=$I>&+7dD&=rG?ohK-NkvvpMp#g-D3`ygwd}V@@$k>qT$1 z={9zd4x`!lJMw);NP8%QCJchMv@+>)U;wtS*VZ zIZMlV+I#T23mZ9GSL`mN(24aqaSVMP=F43D9i`y8dIUZ55FH5oA6OB=@%m{Z{+$)0 z2WlIpUEFkyOccF}NP3(eZ(o9ke{mmoYW*|C^Dr^(Twmy8@_7E#9ro&iN>sP6@LKMe z=Hibb9 zg##PB*|t3Q?V-ohe4pm}QW_?A-jP$JHKb0EA)axNvzsw*A4&fsa4dxit^ zeCsRrGqh#{U}{BJE39@n1ej^=w!RD?v41MR4=0TCQmw#KA?y1$EcQU?hS^AH zovY6(_OTi?y6zfVufA_WIRW!e)iNGmjk6%J?9dBWi$0#O1>2!xuqj8 z_rj7u)4I*R2PHH$kVCJ<^NebcHh1znChwExr3E5O_I0F2^;s4*Q~MJW+o?BAIo1o^ znc7Gmh`YQXx_Z$Y&G3A_&f9lZRX;C0qD`i|THuK}mu+tiUE_w@aB9HLepKT0`&q1@@r za8Ggox9+)FM1d|YxA8-Hb0~aL)Ykl_;yj(EE0Z4*a(uJ=CZ)p$-MKGa!oJsk`}P+H zq-8FL7%scAT_HP*`Hh3bw@xcG8*ymVl22`NTT(QQZwVto%XsV#vUI_yP02%a z%!iCiNCT_G*Y5#Mt5Ej_U7*M&I?^{Jq+G3=Z-uroXDyK6pgn+Ln187RrUdq4E1G79 zHSQGHZB%kN?G~adp;T0vYvlAhfJ?L4G>%2{_yO-}2RaruaE5A`eUy90Mg! zZhNg{EGuqPi?8mH!dMVVrvXps<$-0Df_VG`7ZwqE&i{mURkD(gL7@8&3%k`*XrxW9 z6zMQsJsaC3A<9`J8T>%z=MkVzE$giTia7oTVR$AuyA2l2m!y+Z90^|PNusu!G@IFg zE*Bf}c&t`7AW{KpUN@Dd#+#+X;k5PTIQ0Uvmso6JDLxwsx`BnOwdY%6wd3nRC@M9T z2!aQI0y2ujlp5cY$*wEp%W@tLp)F5S8 zOV5H2*IGYm(5dDQQ?! z&?Bwk*W+L`o~d4JQz|VDM~#F*2tp}S^QtsC4Hz*AV5%2l$!_G*jDrFsw`sN-tiZe3 zjsxo~u$51Q6!!2SH4BprS{So$+(jvrHVK976LCvRAHNu`1-pqrDD70iO9jIE&3K4o zY+sFHpSvkm;h`!Sgc@=02O=jZK6^2+#4_ z<&!t^$JG9ZvGTdRdk3~BJQ4os^W;G=f0t-a%9ezq$3MQXG7nu3PnnXARtCJ(KPtBX zkg-OrzyDd>{8e$UQ{qKHZ-sulw2F4OsFX@#j<{@X9$oq=!pglgif5afc5|yf7Lc9# zb;#aphL(;#<=EC~(6JGt(Z}H24*m90{X!_%i|zqGKI@9bK0#UU(AzX4;G%C37l-t_ ztJ%OTeorzAyFtb6FwoDOF?EJhNu#cipeXWu40!WK&gi!>3KON{(4NB?NZbuTx-ta? zQLuS7Tj_Bbw2#(?^A)545x>CMeU_tT93bqNm?#BPh##b|{hpSvLJ%+Etb?z1mQ$tLcpZhts2}M4(;6) z!sM#xyZrEjz|>iEm9t5o3xKZ4IH=O@o*be!mwGxtD?!R$82(qa0Cu8E@Rm_m;e&=Z z{9)RBC0d)3f)7m!F_wWl8f*U{k);3!?IzA^gpSDc4Gw)6i(={fV&Ud1dBSPfyGQ@k znEb5f{!7cu(NaRLK;1W7HB8x+0FNH*$W@O)m%s`!8!hwZ^~5E=VNVVkUIfut)XOKx z!}=Ub1BpHyynN5Vx1;Tv#Sp&+Gxd)IG#|5GGdkNq>Ipi-GUi|4{3Rir@kXxLE!6c8 zpeR+l?|zr0!q&>QE8he&H+)^$_>N((zn_S}N5=LU`&XLn=}UTLQ|fxD>$W+%ap$;r zZsOc^!l~5$%y_yx=ttD%QhaT1P$=S#hU1|{P3KJq>!TP*pTU8#^@BGLJ(!vbQdP(t zYkGgZ(z!b6_l^dumS^YUubly_EjH8K8o(ztH-|3K2mC1x;e^%~hrB_Na(NI*RZO1@ zOLK=YipT@|Ue8(e{qA$hX#hGt-zGbvcBN3R(V<9ZuYE4CxX!E^NCKUayfB|zXzZf2 zYJVwk`aG$ky7gV%vY%Nz>nnz^1z|&EgW1JsyD`z{Urx$ft5EiHCC}b$`#x?EU?yJ( z%BNL#;QQ5PfR+&nX5Q1eRudsre6zDu zKK6^u?}IgKH>wUgP1V2QDaXxvMQ&SNxaXJueZIZG;fx@&U5#olfBxL)0X9g{(k}Sk z(6)uyASFska`uq3eBf9+Ixaq9(C$qrBgg7Dp7oI9v>2~omI5c6(kUhSbe$(t`qJ$@ z;xc;c;&`$7mLBaaPg16g-l@kgdDD%tmC-skF*`QAxv~?s*P=Z>$UP7}OX_v$Al~a& zLo=;8r;f7G95a)RoSHU1wKHp=Jivs6uboUKRZ=3PF0Hi<7a(qI} zwCdWS<3r`B?pe^W!X&~Cd^9yBuRA7GiW!B4n$7kUX@3f=2t302ly6?Nl` zW(Aq*x-);ODOv1jViPPOmK*%!^^>2P=wmRqS%I78PAUtA@*pho^yKv-&?zk&CAS16 zuR{8KBWCom%088&bX`8d(iKl-QPW9$stXqTR12KFDKLWwsX#9%XCWU`Vb+rnXyB>` z4z-wV6)FbEi2wvD9A@0Q18L%aO-^*>ZYdQw%I$QqB{9`tER7iJ=|=fA1^`PAL+^PL37D=sB>_36aTYiJdg|(irxS=PXpoJi z!y8~Ji-5y26=ni}`e=Is2reONhky*Xek(xCi;3p521c2UY!y^=Nfkt56wup8C@VS- zM!^3)M*TOo;`%BfVde?i&RH{*K~486 zHn*-78!s8ssaxcfh&oYF4tmp8o_0&dyC*yaHZm&vnb0cl5Ml8{lvzw?21Dg7k>X$T z2geR;VhbPr`$=tN@w)Y1>5C`6;BChPqY8t|OQDulCMkpnAEW)Kv;5j+#lds?$Lu~- zQRc-k-)m^cN$K;6a!T1$625q7)VKVHs!ayt!^OCn^~LYq?!pleC|us}zDg*sJ@QR7 z4~8m~TKJRW_AdX>%O8_pKv%E$1=(_FN9)r3Ewx(W<*CQNzvbzNOoL82$@g;$2hHCt z3aoMr7hcv|*s)R(lhThbeIG}?xoC*9jMxDxtVU3tt`%Q)KqZI<%!i!7#7OlA)om`y zN|1aTdB`#$L7sMRuO44i(Q92)nCNXg6}-G7?#t{n9?-uKIpk7=UM|d8G`#S!ZQr_UGl^ech2Wm zP&>O?kzvsl95m$oeVkF}EZ^Wu5ciD2m=981dP+g%XzGo8y zH4M_NZk^g#0@7A!THQWiH1^J#vZuCaR^ksV^sySCz6!%FVuUPww?T(-KpW5w&^N_i;V5bwCddVCe&9<>+q;d>JT}N+R_uz{9JK_YR{2!< zygUcDxeL|&wuV6`*I;{%0_TnWHw-7W4Q>{k*6E@UjLR_#GEVEngTGzf#W0!o{6YhiNgb;Hg z1aK3JtDG#vCcxWVAi^{NnWi|YrMQ-+V3kz|h-!U!4XJ8}1&YL20>0-%NEl>lCkAd> z(zg59ZkGxQ4JfYzXdI6q3IOwLm>LVXuux?1Y3CHLh@Z6L<}Nmv)F7DF-0yeC(L|R;jSDZ!p1pt=P<~J!iIb$3E(4g38)Sj z*@O{E==rp6Ml?@B;aimf=@{2blT7@7Gtqt}Cj!;1t-XRf$9D5s|&Lv5JIo|Kac*7ePlZjE*i%QMA$Cwf+>=JBbkV!*1A~`l8EO zZvMUP+mSkP5c3z^o#_VXI}LHH*lu=sp$RIkNf=bWTV?UVcs3@F%U@so09JX= zcw*Ov@3=W%UTdoXb=cFJ5&W`x%-Gc|)Up$%ts>f z?L#j8GDZ$>f9n=$G*ly~)OL8a%_HWjdb{Ew(8r$_NTbRdH$@9UZ(PZbxdY}sQC_`j z`%A+&;x6s$E0_Q6k=}H>#4S|%Zu?lRUf?7vxwqkwY&3F};}F3#`yaHBNXK`MLB94k zKUVs3KBwL5IucjM_RRS--#+AQK35fG?@N#Zl=h?k_=^@NuL!NNhJLQ{ zY|Ji?x(2T;?|I5fTmK>`KXqK@O=oGGk&1u}jYcv87e2b=1x8m>d-U(hmIuogTc4q} zd^YB08C;4w*5z_K^bJCl5q8ww@G^vxt%0ps$cD&8oLnz?>d5%{{Wes03VhUcFc{qI znys6GWp39#D*XPFtOC2q&o;_bY$;?3gNDkM)5z^D4L#HfR4`(50mK!l2tKt@aW>ag z781m?_MCi^u%A&6YvoTa1T1508K|UwgV2p*1w4pt)u(tI)sFOXM6UF>Y@|GY^;nSz zWdtQ{1iap0OMm_LjcW%2S?8gFsi(hoZ#$@P!4I)1nCfqoOO#t8ZGFJ{{u+e<`c`K5 zP3bdY+_dYTE*i2R$xMo32i>?ko|{F-kY7q+cPY+NSYSv+vL7ONilLaI$7u&5Z6Z7s z)W)gb8?Nbf2#~Fq>K15g)g3WuyBSdcSDFU7HAPU0F`-M`!|%asB>-Ty35-4k5#`e{HhFCTrYJ)+~x~2UU1VUR8K^!uP18gNh$$D*IEo1|kJkF+v3LY7}Why90=>L?hV%28z PbL>cpstR~4VB7x!yLH4v literal 0 HcmV?d00001 diff --git a/metar-images/tsra.jpg b/metar-images/tsra.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ce0c1fa4c5dfc9f55b9114fbce66dcd40fd6cba4 GIT binary patch literal 1869 zcmbV}cU03!9>6F35=fz>Pz0=mCWtP@rG_rjIclUX3yZXk6hn{j1OWwB3`&(IMZtpS z0wTo)Q9w#$jY|R;4+1RJ5|$21Htg=(d++|byU)CtH*evp{ z3|I>q;J*bH0210`Z-fNEh2eW3g@qBqC?pzC0EBQb2nXZ80EYm8Aq3U#75o=4 zAqb8T7D1xW7(qZY76=LM7J@?v1RO4iz985Ka2x`EMAJ-|;QXzKLX@P|Mfxoy(frXf zDVNtgMeTs-R1{iTW}mE_lCp~GQ8k^DU+e1W8(3JLvN~;TW9#bX?m<4|=@s~0(AnUS z(6IB=nAo`Zgv7K<=^2@quVm$2zmZ>1SX5k6Rb5ki`%Yc`-5(p9njg13X>IF%{-US1 z?`8i0^UW_KEcWQwICpA#=GWP|`Gv*h-&R)F);Bh{w)ebX0QytwZ?pgK!U?>D;DRR= z+4F)4#R)ougCmY;3ggY3MZS$9C}>?oN}AJeJ$i;BYP;~H0-|4|r4@C!O3Qm{f0+Gu zVyXX^+23OS_8JGG5KQoS5Du7tn9j>H>23}0V`fI?X%6)R-G-4i??oPvA2X>v`3jNW zguxHDB(J?5yL~e#BSTXDNp}um?c~n>nnH_7H}B&M(&g$;LPlRno%szzZCJ5ko(L)v zWlv)DeU^P@i|Y(2N(G92#?Aj6?xl8QpIECl}2lbbHgEL|dko_`grZuL7)~hDNUMt~T-`1M&efP?^ zMRi(VDrtR(p;xN+y&cfIXIeOmR}Llyma8^I1R-h}3An8dkseC24J+94EWI&ZPv!H9 z-w)hed5#XoxUtU5DZ=|uE`$yQF^dzp|RQ zpfqI-0%C(7n)#}K$^S=&8aZc@O_*xG91vQ4d8Po3((jWcuAF@CFc96S8)ZFx@`G7z zfvU_Wy)OOvq0wFQVs2{$!P7fCiP~ED@ojH^=dmHvt)y#_rfbjxZzeUw$ZopKOWJ5WxV54{CLW@YIWLF(wpN>kZL<_TE{oYso;ky zjVkj!lya>gp*FRV86P@1mJf8d3Fd`Oh1#)XJ|I5bymx!BnkLRPGHh^c4EHF+P1py? z=IxtH06rDY^c+4w&=?Qz<2hT=puVWe-^uY(X|mLZZ{%pMaly-{J((Te0qpU!O&UX1 ztQ3u@jIZpS2v{<4NFR%GzEKXiRwqNgq{CGtVd;4_on3u1bN_3C~;@Zf`OWP={l zS!eEh4Vqa}_&r7ng|_~qfuVkudHRjAo@jlrT0i0KKz8B{U!vq$7TOg|zlt?7Vlqlk z>=?Re4o8pl_cLDn>*tCE52_Z~rO7|i^7RTIP^6nn@!1vbyY^HihSH&>^KVT;NPcWb z7F9x+H0TqSEW->)-JNgHeHmyDNXxw`a?3|&I7oc^fyx%6bBC`bx9-0XK9UlKHR1Z( zs4Vw$m#ktx_Ca|`?5jO|a1iWB%r+0ErnF@nM15SFX_uGYz(|^*dM~Knf0@vlYs5>* Nml{*4@6F|p{SGdRH0J;S literal 0 HcmV?d00001 diff --git a/metar-images/wind.gif b/metar-images/wind.gif new file mode 100644 index 0000000000000000000000000000000000000000..a3943a7864786346b83fb308178fd374c0253924 GIT binary patch literal 6271 zcmZ9QdpuMB-jp4TOCZz0yhKZz%l@UAom-{U0q(D zTUzGMf1Fxao1OdoY7TrixA1jhVrpXI&D7U7Q&XJb{>~||b7HDpKIhp*5FX!NR=DNn)jg5UbZx%KVlr%mqtRKBz zGeBz?pw*918;7Zl@0r(cQX2=Vs~ahe!^;KPoPtwjw`#uUQ7%{0?^Ij|FC3*+b<(Ps z)an6h^$S`xy}bN6rFvlSQbA2IlTmo1xV)TJ-asv9g6R=Y@(OAS8&k{alyWAuyzxv$ zXF*{rm=f?c`3SYJu`i8ADWp>it1smjPzoC_(eBYMRzIdvZ&T}f5|hAFzLX2qRND1X z(&P9`(CEw2J4;foH&T+as6~aTl=&kE!N~2+r)c$Ou9T2+dygJn z3w3OXjyxB4Y2m>3=ELz|p#EM;IrT)^t;mQKfBT`Joi(9nm;KBOB2%93-`l)Dyelx2 z8hMl&N@@4ox#GUX_b6@E)u7Jr(5j1eZct>(-jmZVRy}UJ$6Q=IBBj)`W5()`*rOb5nrX7Bx-3cOcDz<3~TW^;=%TY@-od9f; zo?q18+g`Y}{(#GcN}o4F&+0W@3eC^7Z*Y%K?!JuQwN^G?nk2u`>k(QwS)1uzur;w4 zj~RoDVn!C2&hJ}iUS3*%VQHUJkbRopBD*?tDpX8d?x6nxX>+wyB&M^i?ydFKS4L(s zaqKM*Umf&U58e@I;Q{!n;WhbufM=$kdLHA0F7v@uq#o{jpaURl1B6BEt>l*r>nKUa zVbYA*gr}XdP$&S<78+BIy1lmiUcsP=$>L5eElf7oLad>d7axc^ogUgWf;Dm)0#Cf} zx?<&oPLnzTZ1t8k&bLL^q@F(L|45zEU2rW8f{-v}XKma3?3fKBM1{8B^Nh*6We-7D zbRbj^Yl(lhWvaMEhz|JL3&2Zdhh>k70d| zcz)$I&G>?Tf?`r$c9Mnc?b~sDd_;W39`}Nk30J?t(QUXdtvShp@^)W(QmnV$zjo#k zdpvWqMnADtD80Q_ZQGVLFFu*JU=KUdJsP}xk*_m3~d(GS#UF>s99))|YtP5XsPd{Yw z$$#W<__z28z0mN%pr;PeuPt|{n|K_o*`n8U*uOk_$h&Wg$xw7ma?EhpoLR^6TPaZV z&Pe=oqr2>6P_!SBxIED<;zh-*PSCs$uTJJ2+;c)fY?a)uTb!)7HeGh{@Y;tm3n}FP zZj&Sc2NVFcU$+Sq_2J$%~LU(1;UO)9KIFR}f7_3kW@27T;s)>7aMOZyNg+ z7qi{L;Q3M+g_RBcc5h}$ycvhj;7a>IU{g⪻s1Q*enG-Z&9vjEklj@JjJ#!a<2nE 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 U5I--TfL8PfaL`Agk$}bj0q?{mQ2+n{ literal 0 HcmV?d00001 diff --git a/metar-images/wind.jpg b/metar-images/wind.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a9834efdbc1d422f5956f8595d5b98a556e1c635 GIT binary patch literal 1940 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 literal 0 HcmV?d00001 diff --git a/metar-images/windyrain.jpg b/metar-images/windyrain.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a54c8e6f7bd32285556fd15be99786d411d5716d GIT binary patch literal 2285 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 Vb-z8&5xD$7FJ*qX=tS7o@L$ry3zz@^ literal 0 HcmV?d00001 From 3f110a3a802cba3ccbc851e10fc08468c74d7ef4 Mon Sep 17 00:00:00 2001 From: Rick Boatright Date: Wed, 25 Jan 2017 18:02:29 -0600 Subject: [PATCH 04/17] add metar images part 2 --- metar-images/WNW.gif | Bin 0 -> 906 bytes metar-images/WSW.gif | Bin 0 -> 901 bytes metar-images/wr-E.gif | Bin 0 -> 1514 bytes metar-images/wr-E.png | Bin 0 -> 2891 bytes metar-images/wr-ENE.gif | Bin 0 -> 1998 bytes metar-images/wr-ENE.png | Bin 0 -> 3041 bytes metar-images/wr-ESE.gif | Bin 0 -> 1995 bytes metar-images/wr-ESE.png | Bin 0 -> 3081 bytes metar-images/wr-N.gif | Bin 0 -> 1548 bytes metar-images/wr-N.png | Bin 0 -> 2935 bytes metar-images/wr-NE.gif | Bin 0 -> 2023 bytes metar-images/wr-NE.png | Bin 0 -> 3076 bytes metar-images/wr-NNE.gif | Bin 0 -> 2034 bytes metar-images/wr-NNE.png | Bin 0 -> 3079 bytes metar-images/wr-NNW.gif | Bin 0 -> 2024 bytes metar-images/wr-NNW.png | Bin 0 -> 3093 bytes metar-images/wr-NW.gif | Bin 0 -> 2019 bytes metar-images/wr-NW.png | Bin 0 -> 3131 bytes metar-images/wr-S.gif | Bin 0 -> 1545 bytes metar-images/wr-S.png | Bin 0 -> 2894 bytes metar-images/wr-SE.gif | Bin 0 -> 2024 bytes metar-images/wr-SE.png | Bin 0 -> 3056 bytes metar-images/wr-SSE.gif | Bin 0 -> 2026 bytes metar-images/wr-SSE.png | Bin 0 -> 3066 bytes metar-images/wr-SSW.gif | Bin 0 -> 2020 bytes metar-images/wr-SSW.png | Bin 0 -> 3088 bytes metar-images/wr-SW.gif | Bin 0 -> 2009 bytes metar-images/wr-SW.png | Bin 0 -> 3063 bytes metar-images/wr-W.gif | Bin 0 -> 1504 bytes metar-images/wr-W.png | Bin 0 -> 2957 bytes metar-images/wr-WNW.gif | Bin 0 -> 1993 bytes metar-images/wr-WNW.png | Bin 0 -> 3098 bytes metar-images/wr-WSW.gif | Bin 0 -> 1998 bytes metar-images/wr-WSW.png | Bin 0 -> 3064 bytes metar-images/wr-animation.gif | Bin 0 -> 30083 bytes metar-images/wr-calm.gif | Bin 0 -> 1229 bytes metar-images/wr-calm.png | Bin 0 -> 2769 bytes 37 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 metar-images/WNW.gif create mode 100644 metar-images/WSW.gif create mode 100644 metar-images/wr-E.gif create mode 100644 metar-images/wr-E.png create mode 100644 metar-images/wr-ENE.gif create mode 100644 metar-images/wr-ENE.png create mode 100644 metar-images/wr-ESE.gif create mode 100644 metar-images/wr-ESE.png create mode 100644 metar-images/wr-N.gif create mode 100644 metar-images/wr-N.png create mode 100644 metar-images/wr-NE.gif create mode 100644 metar-images/wr-NE.png create mode 100644 metar-images/wr-NNE.gif create mode 100644 metar-images/wr-NNE.png create mode 100644 metar-images/wr-NNW.gif create mode 100644 metar-images/wr-NNW.png create mode 100644 metar-images/wr-NW.gif create mode 100644 metar-images/wr-NW.png create mode 100644 metar-images/wr-S.gif create mode 100644 metar-images/wr-S.png create mode 100644 metar-images/wr-SE.gif create mode 100644 metar-images/wr-SE.png create mode 100644 metar-images/wr-SSE.gif create mode 100644 metar-images/wr-SSE.png create mode 100644 metar-images/wr-SSW.gif create mode 100644 metar-images/wr-SSW.png create mode 100644 metar-images/wr-SW.gif create mode 100644 metar-images/wr-SW.png create mode 100644 metar-images/wr-W.gif create mode 100644 metar-images/wr-W.png create mode 100644 metar-images/wr-WNW.gif create mode 100644 metar-images/wr-WNW.png create mode 100644 metar-images/wr-WSW.gif create mode 100644 metar-images/wr-WSW.png create mode 100644 metar-images/wr-animation.gif create mode 100644 metar-images/wr-calm.gif create mode 100644 metar-images/wr-calm.png diff --git a/metar-images/WNW.gif b/metar-images/WNW.gif new file mode 100644 index 0000000000000000000000000000000000000000..a155e3af3d6e7978db4edb7c450651344f304a5b GIT binary patch literal 906 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 literal 0 HcmV?d00001 diff --git a/metar-images/wr-ENE.gif b/metar-images/wr-ENE.gif new file mode 100644 index 0000000000000000000000000000000000000000..d8e815e1502c201671348471b4886164456ce9bc GIT binary patch literal 1998 zcmeH`|5wuY9>?FnM}&ePB^5&jMRQ8bFX*(914Ger9qS@7haJC=ZjPFIxn{}?2+SN) zOft1ko^<4CT}J37kJTqH)JHSNX-%0|%Pn=@tUFIvyPlODXV?7?_s9GC;dRdIm&bWN zUgtc;ndwQ%1-rm5umAvrh4eZ-dIuGyiY(n0bE*jTp~1xphfY5~H;;B(;3y6|lrb1;J!$D{esEDc7k% z+C*~SL9JJg<8h)m(_YR{wz3< zfwr36{SG*o!3bm^HmkZ;ZQY1esd5x5&`#KqD@SV8D=!w^HYiWTNov!maEY>*$gSAJWuB=UHPJenWP(rA=OCCF8) zYJ*>?vTn#0E2e**hC5+o5J5U&>tVU0R&8uFF1}bqZC3Xn0!OeNrApEkl6x41<9L=7 zzIA_=`z8X1vaL2NQm5x|Inxs!Xd>C^tVn6IVl)t>{`xK4NsrO5pYSxZj_CGlg zsS3|(!xz|0W##y*L+K~xW!D?dE#~}{n^>JTIf6YCQ$I3H{>ppdZ_1bx zzs*J%sJN{A^@q!!-IBd2N+6D&yDOmzPA4q~s7#NKE!`tpd{35!4NgT07e-sRKb)#n z*OdPoyS`q}^jOl5J}xcDweQ8&oZ9r{%)N!f>H~}v6aFLHQVFH|_PYr$rE;6AKd9o# z4;U9?IQ+B|t9|AogjFM#bj-Re%%6fA^9<+d#L6Ac0E~&HA!3;T7kFHi?M=`^eFjX~ zCD0;M+?WUoGPGqg=u#*~T)uFS1 zOM%lCQ1n%}vpjLer6(I`Sj_EcJ`hr<93hGig0u1dQ30U_8b@}7`^^=yihyIV=ft7F znxB(bm8XT()YnyWxJ2gfnx>|~N55W(`+&yTo~jtekV({;j4eQMAXYAoc>PPj?nc)y ztt<2$f}yJ4m&^h_j#{^!@~Pq6mKMX6{B^&gN&CgASlUYvOl2?Rc}Zh^@JDvCRsi6M zbWtErr5(wWC1l8n7^4s-7HY^XwQ7?=0)X!Mz#=w$2 zp!U0e%v9LBwv1B_UGJ%R^fNj0$@9sJC9V%=i%Qz*{^J*(rdoDSQpM3ppQ3Z?huU8~ zyq4s7(|Gi^BCK!wY)xeH-I~Jjz){h@FQ_zUMPQj1cQs>A+I`%s*I(cMo+SSBPw^yW zlx(15=a5%#GNtSi{`vxaM1QSf=1Z^qc%f%2o@eg*s$4nH`p)&w<7}%Pq=NC?b>IHe zd-ieDC$_QR#jF_2c&1zMz@&NaM$hh&8z184?H|PUg;P#GXGwjW+uoC+Sd253YF{Gw zOfH8ifyO6^3I!rBnn+#RX=u#A4DDm>1sWVUdw$%jhnP6t6`c>CI(#02!2ACN*K^X; literal 0 HcmV?d00001 diff --git a/metar-images/wr-ENE.png b/metar-images/wr-ENE.png new file mode 100644 index 0000000000000000000000000000000000000000..7d1246b335bbfe6907e81c157e9a9fc6903019b0 GIT binary patch literal 3041 zcmV<73m)`|P)Hg5+raC zH2ILWK@s#r+I%S-pm3tXZR$7)V#`2~07~G-2qNVrvI|otE3Ifzr1;S8a^Lf~w;yI_ zJY15JC_an`{R4xUxpU{<^Ph9>x#ylc@c-CVsP^&9CS{qoM4~-HKx!2*I?DEisJ0)S zM34dgc%S$(STR#z$I3n2tbDU?!crfEJOi^aY)Ha51nn{w?M zQ7NS{KR^F;y=e zdm<$-TJ7iu*? zlyGpZX1oK2V|NihG7to$B|NoV>CFsjRu}=p@NTk(jQLoo;IZlNTSe8X1k?_ZLsl?)$GgJ!&y5Ie7Qn?&T zDKx{ddwP1_H!(5s!|lqvZPWEUFIFy>Uy@Q$=oxwVSq4tyWoCSz&Z^bX~cw6t(l`DZlzE#^50L zeDH(BvRQ=Z(YkU4*LA5(O|dpP$-t>o?^#Kuo&f%1Pl&$p#vA`4r3}YqRFg`nTapC0 zdi5%+tE&tS4w6VD01#4A{>3j?{lO2=(`hmfKTNIBz@3_+Iyp)C+&NH+>cxv7B~&W( z-hcm>_l&4*+wbr6jNm(yN~N-{u9T8esYE)R#xzZUa2!f0Sy)(LY-|io2%JKJ#nY$3 zb;&&R5L!IWjTc{}J~@fIyu3k<%IqvlKl#a#D}}fAr^~q^ypC*7Z({B83ADK*T1HG`ZVV9GI};kV|tp> z%P(&&h!B|BEVYFN8qMY>fxp{TqRnRWBf)hL$p|6Pb)9;>zUe!IgM-Y@&f>Z*v6$~W zEX%?$3}4IFucKam8DoAP0B?C2uS0_(7Q^iB1|Xizl09{b!N(rM$Y!b4YL9N0=+nSg zfjxHPJnh$;JWUX9=5NqFN~B5g#w2U9}cZRYcyDR@kQ#>(}>RZg+NOt z(GMITee4)Rk3NcF7-UYIpd}@`VbE%|&@}BtRK`v455SkAL<16sws>JpDb*h>2m*sf zqp`&+zV?QPhfzu~KR?f^c%FxD+f3&3WD^Mv-g6ILwTkX}wAR*8l?usZ61UMn zm?qhGz00?RjVO2A4+2Y3qTrkFFuvxV2R;rw(tdV%vsMGo8$bv_e}6xHeSMV6Wm4_% z4Sc6HJw46n=xAuxg{xN?A0H>y4jhiX;~m7~aiW5me#2z5Szr5_wiQX(I7UMU5G8sE zcu)KKyKTaM*uI}rO4Wg`C^1dbFijKNj<)R+?ru*B0m+LOFETVVL^_>jX=#c6{(giI z%*@O%K0b~RBAkMvP=ML~SXz5w9>8%NX`1G5BSp6yqu^__3pfJ&5;%@O?En-sOBDth zjP~?m7>3N{a-}T=h#_l&GFGE8^^!E1Nw4PxYSe6wA zC642SD<#);-L9^#f837j+afwTI(kjl^>0Kn>g$d~B5_NyLI{5ys%_o1VHn|}TuO=K zIMix2TCG;FVtVDi`|jITf^6G4qlt-$&jL%q7mlu80uxRqlUsV?Tfwp{QmIsE@~u{j zQmI6%)$#?_w3206f4SXuw@uVEO*ffL{*kWhb}%Q}w!JPPZJH*TOy;&sIe=jpq|@op zT)`)~wzd|{_tuliz_ZZ{ZLK>|Cf zeZw$9GY#Geti*8~N+mxQXf~T9lS#X;ukW89eDJ}~--*0C+GLuVn)+O$(fEp#G8PaG zLb>Qx18~zZ8BMZDDY0#vdc7VsSG%vT@AS!&C;#G3W!>>^+Vu4FhbooIGfJtHQVPQ` zLV~7gB7_J@MuUOQz`(X`gb-oi5s(C`eSLjjKYsl9-|j@tUD-CAo}PZFUax;kDRm?u z3t*Zij^l*an;~#&LBs=u-qkeC70a^zI+x3Rd#5t)+D33bpYI0#$#I-Nb6wXm3`OM{)*GoqUy_4wnDKexQR{IKVF8C}=cUVr`dS5{Y7Kf{|jtGfdKg`Y5($IoE= zH_&3^(&~2}4Sb?UB4r1GvA0H?y~8{{(SPGEBp1aK_`k3Qzs8*ho_tFs+Cv-!z6eb5 zCgG=V`o>*=kKz;ExB>b*j=v%D7YqK@hr&1Ky9x?_%izbr_woP4R`_Yjy9!?feub|= j2Y;L6Yi!*5+Y|gB;86Do|5B1B00000NkvXXu0mjffsNHF literal 0 HcmV?d00001 diff --git a/metar-images/wr-ESE.gif b/metar-images/wr-ESE.gif new file mode 100644 index 0000000000000000000000000000000000000000..4e8e977d88ad6f49e2e363e43c6cf4c0c0017f15 GIT binary patch literal 1995 zcmeIx>sJ$Z8VB%Sk|Bu@AS7Jn5)uOnMg%sC5hLXi?iZ4=cdT5BU4IV0|Ir!~{Ui2WpZCvsp3n0= zPiA(8XuCWSB!VXZKx7Ek!je=8ahpI*D3T#TSiaa0W~fkLT6lhL-WV<5^Z1Gb3g?v5 z+-*d57vUz97{<&86i9;5*kyE%5#~BI)?rwBwIqxe`m%hBb{8RGA?iA{d2f;Vsu?NB z!*Ahuw-FyS6Sr`4wbDLeN8^Pv4`+}hG17}L+!=-r13rWit?=T)qA^}5h!!ZTl}MS) zei?N-?8F(v%70hHiDFr)%oxeX`w;srJg*?nK1N_B6it;N>qGEX7>O3lOgRY?iXBj( z2|}dHI5S4zjVJI9L&*A&6OAXZG8uN&Y|hEUs+DM|45C7CD=f*75Mu;-8Abekv0==( z25*JuznkYr@)Z>d=RcfSml3~=+J`W6g#t+w8@r9p2|Kn%K4Vz=X-SwM^!4{G+FOM1 z`056=xm0EzG^06r_y|sP8HqLW2yS=SXCBReBE+os+ zZ`0A)(XzXiZ~)$gl9ujUOzE)qwppq0r782QHz{P6u9+J@&)}3EPMhLSd_?0c$U6r% z*gu9iw_W|?kp&3*OX7moxU1tyO8adhU?Zn2a)o^qXI`Mpt9u92N%%{t^GzNjZ@si)zVci5zU|1x9PE_ z^+ES^dMt8Cs-rNOfa5xRJyoTG3f(jfuAeRzd)!zHWjkrIN6U5$xRIdm}AsE z3`fdziLuj{1qv7t8Jw8M#-#^8qxHjw5~nlWHnv6uUy>%xrv)48q9)e?yps(6aAYZS z|ND0;5V}-fPE$#X!WY^b^yeU7zLQJ!mOHHy&((B|JS{&W6rz9{BF+aSt!?M`b#u5W zOlr(d_MlIK6uO(yXO!$w7!LW=LUUA~%)mO=9`ZA;hOGqsPXqMYI8fK1v9__p3AxEa zUo5xcCH7oNSX*9l1}~SP8VxF+OsuS?{9*$%?IM>Bwjf6z_}$GuW^Jq27n10kWrbV6 zC|LxVfnt3*rHZt9;)>S=m6c3^m^=!QW>H<Z|2rG{Zlm1<+Os3UJnln7#5>2vF{ebm0?#9%-B|U|5ce*w*-GG z{Gt8y^M?nKDI}R3!%Tr&)%`m}PoPWLXO%O$RJV)$-lATLt(&ZSv7$-3#AV2{J_+-w zl6#rmUAffq4V+O4HQqRoucBH$Ch)5C;XkrX+WW{u`_?#ekmPltK6S%`XVD^J6uRyT zh+ZfZb=gM!t{-DsevXJ&+bH{7(oP0sb>D8$dQr2+J1`Q+pH23lVGCJ{f@F%cN0EMusd-C`y7yvPyAqf=Ekz*C>&QD%Y_evj)J6-oK8W^V Rt+i;}^IrgUIg1H){13@G!`=V@ literal 0 HcmV?d00001 diff --git a/metar-images/wr-ESE.png b/metar-images/wr-ESE.png new file mode 100644 index 0000000000000000000000000000000000000000..38a89fbc010f908c44aac2932425881cb5d1f9d4 GIT binary patch literal 3081 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 XNR=^kl}Loh00000NkvXXu0mjfNL~~1 literal 0 HcmV?d00001 diff --git a/metar-images/wr-N.gif b/metar-images/wr-N.gif new file mode 100644 index 0000000000000000000000000000000000000000..dd3b7da7c960a5951baacd438d42c81a5d22d0f4 GIT binary patch literal 1548 zcmcJM`&W{80LH(-3o4-?zFt!D1|k}D%CsR;LnXB`BXwRmOpTl~)+r-TE!GghD@qz8 zQ8H9CGb%G;Z3oQ@b(*qf9nvmVR_2_uGG~`)@N6bvf*Sxp zNJu7?aiTbuev7_Yui6%`CBhTWCd^V9#h)U`5g5CSwmUXip-5G$(yyh@&&`L1gu+BP zIWgHfXtlKIMFk?gT4n7q8~8j$g~HHbFl6ww-X!zSW^KLJSRle-ar!9E%=8RBm@dp0 zjy)J#_-BE|Wbrb1wn3|^L>8YAZ|%1j+w@vblCeTzHW{_cuFWixCrNxvY*ecZ`9cT- z$x39L7>?zJMZerkh}XKo6O$9>5*dX`5#$PtCZlb{rc$f)A))i{=0i7z!ftSKO0xBq z)qKGqDij%W1d3{f;etU+rI>rn+D5IhP=s^B8J4%bnxU_y3-<}f9*-?7F0eMUczm91 z8En)pEiHlnGk$+V2mrDG{gdR=C%|q|k|iyc$xBMh$}1`rasZ;F%G9bK)MZLyVAhF~ zjg3mMLJL%<&nT44ZThzMi>1mWKfWL_3&$Z4I5e&=q_EQdnLni~t z+z1W_$BCelV~5q5sTm_2SIngU$UP3Z;c;0efy$xY!@a<4o*Es!_j%?kc><{}mLtdR zwYO@#N{fo3g^z$Vym?DwSa32){Z}?vg>v0xre}8w%H30ktLxH&l#wc@;2F)(SB^5g zFJ)_@Zg#-ydc~TRjP*d;=Put+Xq=jDetPp%1Wl1vh-@#frK~qk5e6_l)rtE)++0^X zQQN+Y{P;nEWY4YIMHIv1>eIVp3cpoix<}{pHS+fD5Bj88Rs3H9V0~Qn+%vR7vtggd zxUTMXwgpz_rLW$}zi&aoL#LXC;~t|cT5%rZv-@-V&Rie}yE#{0qDcoET7;PgCP#3z zI!Qpak7>AL6Z?&CY7^dPs7dFvNk<`OZ-^9T*f}a*XVSL(CGqT{H`E9n&pO z@!d$SA!0!ot_!h@CSGSeKYWIt2f-3NekTs$S8(o9-Z+^~d)gwEask_g3M5cqnsu?o z2^GPfLf{d>DcOjyws(C11=W{`(K9{iB-X}<|fS+5HdK&hbayXyAg4Op&C0cDH1D8cwjg-j7b^$<>G@$`Q5?Oa3 zeq%#DCR`M}WuW~?)}Jn*E9TA@{P?hEJ{wAUgcW zXcO!O^)`KLdby5xXFKlwpaX=o+q`mCpHPyX|xoxB5X$?Ve9j|x)8W$1j@L}qeFts)ga!XOV^Cv#Kqf|!^ z_TQm4CEzz!s#W)icD>XZU*wBS@kO#x@c_1nJ>$U zV0aw@%V7Im3-FVzzG?sF;S>Kn0MNo1iTWNp1P~D3zMaI+?SY$jO|e}@vpca<=T9Oy iV?JyzE(dH^Q7_V=%t2OW&xWETD9}Hq% literal 0 HcmV?d00001 diff --git a/metar-images/wr-N.png b/metar-images/wr-N.png new file mode 100644 index 0000000000000000000000000000000000000000..c68a58513de0eec5009d1c3074726180d0a69ca0 GIT binary patch literal 2935 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 literal 0 HcmV?d00001 diff --git a/metar-images/wr-NE.gif b/metar-images/wr-NE.gif new file mode 100644 index 0000000000000000000000000000000000000000..8fbd13892d4cf71098c9ae368114ad3d8451dc9b GIT binary patch literal 2023 zcmeH``%{y58pXd!-rO+NaE};Cg5e@$tze|6ER&EBKrzcD5y(WAO9(AZU7!&tg_J;~ zG)ANlz|j{Mm{-Tew-PW_22&=u;WBR4vKR!N3==Iy#k31HQ0X$b^pDuz_WXRFIp_1t zoa9td+>wH#;3#+j0EC5f4LaL>n=ny`^dU&15ccs~e7wmyU%!iFO`ixW0Q zp#sU2*oMr;Hlt(4ffgz(oksJJ+4IH&$8zlt?A#cx^N!hEq4x9flVnQZ<7t*Aow`B| z>kXEE6b`1lm)(d=ZX310mtos26prDdr7DUS#h^DhCTwUwYHl-fA~~v3mGi07b``da zST=v#L=xg15A5+r<{hSSgvE#VyRU71^7u$NnmlBx>60d z7%baRA#C^0Zulx}zl9<(T=N+fWhceZVnA=9oC6%y8I^OvX&JR_Zf!aq+T#=A5lyYF z#bDMOY?onVn=wz0iqnt-95hdEAGN%D_YVAD|H}`sHXsZDdcgTTO_0K2UDGXVzV21smi^zD8ThP1D zeg$H*xtNn-V%Yb)oYf8AC0k@xb3oFQa_!8uz>iz4SxE*Oxv+nVnL+3uPbgo{`BvZI zmfmE?)+EhOHc+BtOvjsd+(mT}N$iyAnUYV&f`~5JwWv82Q_$#H{$vID_tTiq7amLF z18y2Zn$+yJ{E6>-u)>kJJejEJ)m{DC)eBL4?Ztf>Srk*jJaLhc&PvvN+;m%dh}KV{ zrWYr7vkp~8STmXDF*pj>Fq&I**RU`eO>*6?JH|MOS8b(V>iyxfPR_oG{FnOM-)kSi z|5PstzPLwD_!S>rO|?yIyr4v6;0ekb_;!5bcsPdOJeI%|X_woA^h^NojYzzv# zl~bTSC%Zgstfkh)$5kmzRKTQM>cZnfjQ~SSQSnH=-6yLuc7Kr9QPddb zkka%+v*&9*z*Ma81=z?_q)GhN>Cu&mo#)m>nJIu9-MRxfzi!`KbYYxXhrH32;)CCU zz39+T?riRr1l!+(9GXZf0hn1hP*P@0K7E!vxA(p5>HPbZ5bYV?E0nuOgx}@WBWpk0 zp{9}ns+|;qm7dF`QtIo5jtaRp62oIs8|W1}ZxJ}D<8v5A|B?=zz(0xR`IZ9HK;W1x z)LIudT$b#6z@<&b{Jw)X6j4t`mzsgLLb)pGA|`wLVr5}_*Vy?q2_5tDy{lmx6^`W3JG0GUa7qqzbq z!&Y&H*3LETjX==XU&vw^Y zFwn}3J7%q?>@Ny%4Gw&ya0$HU3NbFnpAvo<`bSR9r#$aB_V@KX-+0%Z!5 zhMys>rHU(9QAVF1KLtVGWH9SjFI-=0=wSZLzfi>`FvH5s~ z#uhvV^`UA&jJnay4jjUMM;7kb^OP;<1c0c^G`?5P&jhX7sGcE~jKm8LPCS==3JIs1 miW5Vu!DP9(i#FKkUv1UaVt!#_rmSAqO%Qc{H57vZ$Nmdsy3uL? literal 0 HcmV?d00001 diff --git a/metar-images/wr-NE.png b/metar-images/wr-NE.png new file mode 100644 index 0000000000000000000000000000000000000000..1d5e72d7024d37d42be68f1649cf6dd355af8a43 GIT binary patch literal 3076 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 P$x=IGzw99pz#sn$?!EB& literal 0 HcmV?d00001 diff --git a/metar-images/wr-NNE.png b/metar-images/wr-NNE.png new file mode 100644 index 0000000000000000000000000000000000000000..6c507cb1dbd663e0b6056ccbcde1e09e0acb61f8 GIT binary patch literal 3079 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 V9XH-_-OB&~002ovPDHLkV1l;@00aO4 literal 0 HcmV?d00001 diff --git a/metar-images/wr-NNW.gif b/metar-images/wr-NNW.gif new file mode 100644 index 0000000000000000000000000000000000000000..497c18b59bd669982df48ab9d305bde3ef43bcc9 GIT binary patch literal 2024 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 literal 0 HcmV?d00001 diff --git a/metar-images/wr-NW.gif b/metar-images/wr-NW.gif new file mode 100644 index 0000000000000000000000000000000000000000..652b550f3d8cd504cb607c6a661af2c94f38ebb6 GIT binary patch literal 2019 zcmeH``%_bQ8pgj#P6&h)2nmP~%f*PGkxQGU+=?LtB9&6=Mg%5Yf>~PHh@cn)&4wf% z7{rXrC0N-8Hen77(j!GSBGNN7!EmXKNZITKH;YGMfjYFsZpwgCT>4M!Py77(&NH9q zd1hW=W=4F1BoQQn6#yV21Z!d2xXs|pM7j~#M>2aig1nQ(jpHsoT{2Y2%v#tG#aVmg zG!K~_a}IVGTXaHXA2wrUQhlo)>qcBZxsa4(`+d71jExqEu~t3PmuVZt%<^iqAFV!D zjhqk(G6YB*7aPUIMPgg664AnI&(^Reo%4~C6UA|iVP=(*My2VRbdKF5fh@EevGt?L zDapvLJ&J=3nGJt5Y`@rc>{1SK?4uZZLZmO1I_DgmLmY8|*gSxu83L@!zzSqx@@l0@ zDJ_$_eps_z)!F+|$PI!UVB4h4;Lk*Q5m|){&CW_rOkP@ELO+sWy9M9ix)z+~VYB0J z4t6+Olq+%!nf2H7STEw*aG`vGea3DGXQQQ3+ciDYpK03-T&qL}&}w-#k}Jx}&O#EC zu`x_qDqZ_w4ZEsyE;zYwaIxJ|UNqfRonsgMIt%SZ1bhLyYuP;wn+;ut?VWAp5XUiN zw~t|HuE;)szIycv{9pgW1wywV0s!@Z^DFb$p8)PVz|(_uY|v=EsyRv!NIIX|MYpfcCKg7dE>D~!If*20z)5<;MPBJv~nr$c2oP>$Gz`>-u{fjg`HXc3crJQ+I#V@Vau9; zSdG~KLNflfJLzn&ecDJkU-&?gbj7OHP#tW>JKiIF_b-gEOV}lqVLUa1R_gnSiuW?U z>Dx?wOvJv^jRaC+!CGF3<-y(`@s^$9UzFSNi=Wl`t`4?JEb4$Wk7OUlmib)%vBFvX z@T_ucZLzeE+(s_w^Et*km9yub-^b=E>z;pozsID?R&MM)Q#!5bq9%%a(x^%L4I6_d zRSP{Uq)&twH=nG)rPHAY@yyC(<2`S?X0@pNz@$3Niy$>UZcYnZ$^Rgr542G^v$rh1 z+V#OHzxPJoddiSGX9eK!XevL@OMQ^{f#K`nzh{<+(JL;wvJ#-#p>$RGUbKm6Op7jLEW(GK0 zuG#Mf8|g$+EKVnN?kJjD$X<~rnkOj&xiCDpvxVskgftfc$d^P@d8Z|K2F1@j%Xd$* zZwY8Mcr%$S@rpEovYHn@L1OrDKQ90n8>k?}@-3Boe}bjhqVoi=QDQ7=BC{k38T0LG z&wKa4K9~r^NGu)5WM%#SzN+aMPcu+ShA#%K;r3wg_?iSxE0Gz!`T3UUnN_-9(?obiFUPAqa$r3pU{xj^*I%l;bs+k} zMb&1}z@*f)SYjc*CHa#~y7-mH?&58W(3e02Id9YY=$ z{_ie5%Um=?`v<7|n?F9kIYGnuq0^~!Jm zA<_S5p!04hL3ztk$3Xyrr${b literal 0 HcmV?d00001 diff --git a/metar-images/wr-NW.png b/metar-images/wr-NW.png new file mode 100644 index 0000000000000000000000000000000000000000..86c6c9333720e28a79a1875d23b3a7a72f2be905 GIT binary patch literal 3131 zcmV-B48-$^P)$~7={a=w%I-4Qi4HG?g z^ytCVefKRb6bf%ymesEuU#{U7UZ7?Fe(rqoNn~5wHQP~2;d$Q5vbkh3`CGlcy~l1; z&J8awu5HV)?|%20li&HyH!~l8__61@{q^tD2M;p;^Pf}r z-HmnmGO=yjFmpNPj~zp_x5J%x;y6xdrmpK^+cu_YQZAQKN+G302;Xf4TDEN)UDr`c z3CD3BK79D_u~%Px^-QC3H*C5xk@VL763fcWN~DKiPv6Z;%eIxXL_LN>Qm)$mjD^tJSbv2thO&4d<*7A~HWe|N8j&cvquxH>}a; zo_p@=l}hDtA`w!%cO%nj%2QJ~3kxXM#VM7r3I$5%&Y`MRU&u;@)Zie*;~}v?b1Pxn zHm>W2+O5BoQW%C2w{5%c$dMy&H6nLI8g*SawY0eSXQ8=DN!tStaOcxc6S?CKz}KuY zP0X`rsZLB_U%G^O_AG^yClSEX(h?UgT)1jKmSs_?RD1z74Z|?dGz}?bpxw`(Idf)c z%ZOgQc<~=R&x_O%Usp5hVQOlMOePZ&Sr3+FVcRyI=Y@_7KuU?{d9qk6zT8N^4H30W z^N^LzGJW(YQ*XabX>=4-trBkO!eC9KuIaVqaE?&II-o1M^D(Zki^sSPV_m@H`JGC6;BOXeflZZ z)D(_VXb(Mv+1H2dy7cz;hUV&d9%Ex;?AWn`WHPx-yPBra(a{mczX57y{LsL_!2i^W zT7bp125Y58cK~~9zYlOF%`pkABC2WHvOruZ#Y{HKF}n9t1?^Ya_7@_%&b# z=ms9FBYIs37IyH>D;kX=gg_e{M0p<5XU-6<#kLoJ*uH%`$z+mjHcLlG2SNzO$H(dG>+`pEkqB!c z7_5~fZQJ$?!}z4G==ZtC90gya&A@Kp7%+&x>;RnCG;PlFyk7|_2csJZu@(x20;O6s z)Ya8RTU#5h>xRoqI-N!c!RY8Hp69V^*DjLDQaWbX~`F-7tK!EQ?~XNFtFS7K_o-(?c$oqgX7inuk)#@Y%L)B9RED zX<}Ix(P;EPRuDb3;`t1<0H~p@$MEoQQ3#O;5?R40E2YTi^UJjDI1a^PkyI+REa`Rp z_;Ct_0xc~q?Ay0*S^L3Y)LTe0nG84IL3YA4O`4jTJi{<{4GavNzaH5e+Pz3Ae^@V6 z03k#exzyFAt*vd@G9iSZr>6%^)7Y_N$Ex;qU0+5ru!ewS5SYYbFo$cGV)85{G)p}COFuo1)OG+tB)5LKcr@6WLZyJ%k zA)bsj#J257;4pMu53>Mp<&?}cO-$3ob=_s!mr{mi8hjI2 ziEY~~EcmfNwOS<}k6Y<<`tSGe-~SgIk@toUnTCgl|GZMEyySUaBp@1ua`i_IusVFJ zN04L-ysKqdl*{FMbG6dx^uHW9aNrL&D(elOrj3n_eW6$^9#Kjqf^2(0&@c>t=TakC z9}KJv3@pn+2oVMz0ZCvfold_pI5_xMHzMbzoR5x;jeWLUF2Amn+8vMuf4^wkcKCZO z1Wql8c!1Em8ip|!i^cwAU|`_Q84uWf`$8XxU{kx9i#H5tV5?NP6J;7KkhUaPe;4XEjZ0cU{-fbv@ijc%EkoAw1wCA;iA}KiDh{uEdrRT?2_H zo_OMo+1c3#T-QzMy1sb&^y&9=x!em}$ywbNcnd$Hn8D9rd;plN-dg>iM+Kkg?z*yW zp!e2@vvtVe6a6-~A-Q@yh5r}U;IDBX15e*liM9~kz>B~zR|p@z>KC^Gp2a6RdyD1R zbo?n0t9#yyPqcJv#MwG1{3C<^2L28IpV$gNEqPnvMc|kC8np3`IbLS<(chNfe*rm6 V3qg#GXN3R&002ovPDHLkV1fy-BX$4) literal 0 HcmV?d00001 diff --git a/metar-images/wr-S.gif b/metar-images/wr-S.gif new file mode 100644 index 0000000000000000000000000000000000000000..27062113a0c989a7f2b65cc3b9685b28ee35adcc GIT binary patch literal 1545 zcmcJM|5K880LMQMJeXe)L4nM#z|b_Q%x^O#1AWj^TB7(ReDsicm5R+AYi@HL(qo#D zT9RFkoG#9}j+}L5T}LK_U0+zChsx5GYphziP8*h$v(+E5_wVo5`*ruu*qWZWu`~%J zf$IRkI2co5NGf76TXa9@H0g-em+E}zWV6^t6;>uIGn_YI`|IpucFi%3ZXL(t9piAKf1q9jOll%4hE^XcZIzx>@ zFF|297(0j|>4@dJMc1p-(y7izPIfrkcn~YwS!NhCsNYLY*fkv*T}+(or7JEWj!LJB z^TpOXR!gtW(4kT6Q&@+L+V_ZUf)O=VRT=8BM5Uyc1Vvu*?yR|a4M;0QS#6bQj_QyFlAEC!dyG! zEIm5G(_7Kyx%UoZ0)lbb%r$Hmh=REK;G}cYEFZvg;%wx3854GQRfPze@KIdGXKi(@ zte>($1rY}+Gy5a|xZbn&NZ!(6*80TZDcQI)1CES}=;_|4$_7e5Hc-N=3+=f+LP6E= zwXYG%j1n()H|0~j3<3?`Y0tUEWP)yt)(!^D8IC?0!965;Ku}vG=L@_^nrurOWUrnQ zJ(4b;W~F07CeM2-0H2cGcIHyuH>;#0yYq=6UX!7!?HWC(tB_7vV{RN{6f&au^xQH? zxnfrWIk#M-xzT~A8>&r5MaJO=hkSONmZ>tkm7{PlgU4IR0>cLokhh^YpJcPCph!ph zlnn3hPZSOdDin7_(b|kd0w|ie1&cFj z+=hFJVvl%Dbeh*DN2iJ`hHWd0L_%b=zE#-P=S%cF55Q`yhX4{W$h3)IvQ){7>=l(h zo5aIu9=B=n!&_1auSz0bY)CENmesdQK#dg_orN~(l#hXA8M-LW!M=K!)>9vuVD}zO zl~;Osl|}e%jays#YgG8mI8BfokP@(4tgfD_O`q>52;|Zy)`x2sXchGOQU$em>YfD`U}&o+ zmUzrZwhy2tDj`q!68>ew7sXY6$qp&-uN8H_GFPtiGZ#qX+muj(^qTpKkSuC&%XTjO z1-<2EACuy_jCcx%JH3&T;FufFPDX}Em0=>6WjiyljfaLVU9sHt@Q|h2`pTE93G|!M zgY;D^ANa_SI%bStCS@;}9|^^^Y_6dEF2Lvo-0^=|WM?
\n"; } -mysql_free_result($result); +((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); ?> diff --git a/footer.php b/footer.php index fb5289c..37bcbcb 100644 --- a/footer.php +++ b/footer.php @@ -1,22 +1,22 @@ -\n"; -echo "
\n"; +echo " \n"; echo " \n"; // display links in top left of each page // @@ -258,11 +117,11 @@ if ($show_display_name == "yes") { $query = "select displayname from " . $db_prefix . "employees where disabled <> '1' and empfullname <> 'admin' order by displayname"; - $emp_name_result = mysql_query($query); + $emp_name_result = mysqli_query($GLOBALS["___mysqli_ston"], $query); echo " \n"; - mysql_free_result($emp_name_result); + ((mysqli_free_result($emp_name_result) || (is_object($emp_name_result) && (get_class($emp_name_result) == "mysqli_result"))) ? true : false); echo " \n"; } else { $query = "select empfullname from " . $db_prefix . "employees where disabled <> '1' and empfullname <> 'admin' order by empfullname"; - $emp_name_result = mysql_query($query); + $emp_name_result = mysqli_query($GLOBALS["___mysqli_ston"], $query); echo " \n"; - mysql_free_result($emp_name_result); + ((mysqli_free_result($emp_name_result) || (is_object($emp_name_result) && (get_class($emp_name_result) == "mysqli_result"))) ? true : false); echo " \n"; } @@ -316,17 +175,17 @@ // query to populate dropdown with punchlist items // $query = "select punchitems from " . $db_prefix . "punchlist"; -$punchlist_result = mysql_query($query); +$punchlist_result = mysqli_query($GLOBALS["___mysqli_ston"], $query); echo " \n"; -mysql_free_result($punchlist_result); +((mysqli_free_result($punchlist_result) || (is_object($punchlist_result) && (get_class($punchlist_result) == "mysqli_result"))) ? true : false); echo " \n"; echo " \n"; @@ -349,33 +208,15 @@ class=misc_items style='padding-left:0px;padding-right:0px;' tabindex=5>\n"; -if ($display_weather == "yes") { - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; - - if ($humidity == 'None') { - echo " \n"; - } else { - echo " \n"; - } - echo " \n"; - echo " \n"; - echo " \n"; - echo " \n"; +if ($display_weather == 'yes') { + echo ''; } -echo " \n"; + + echo "
Notes:
Weather Conditions:
$city
Currently: $temp°
Feels Like: $feelslike°
Skies: $cloud_cover
Wind: $wind_dir $wind$mph
Humidity: $humidity
Humidity: $humidity%
Visibility: $visibility
Last Updated: $time
'; + include 'sidebar-metar-display.php'; + echo '
s9C`MM(l;`wGO>JQN7 zipHQXRf}``m(@)Wpw4Xu2{`yB;K8-h;mkz_D6BCY*DJ3t3hf&HisCF1GzSn XCwqqF!(su-6F`zFp?|Kh$RPPYsBBrH literal 0 HcmV?d00001 diff --git a/metar-images/wr-S.png b/metar-images/wr-S.png new file mode 100644 index 0000000000000000000000000000000000000000..6396440f51dfb30f295d32e342ac15668f74d581 GIT binary patch literal 2894 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 as@mxm&prxOz$vn$k!yzftyBv5(|-Z8ti<&I literal 0 HcmV?d00001 diff --git a/metar-images/wr-SE.png b/metar-images/wr-SE.png new file mode 100644 index 0000000000000000000000000000000000000000..bae545ef26a45bf3982a4126ca3efe9d2787e86c GIT binary patch literal 3056 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 CQq`LP literal 0 HcmV?d00001 diff --git a/metar-images/wr-SSE.png b/metar-images/wr-SSE.png new file mode 100644 index 0000000000000000000000000000000000000000..31965b7ea32527e84b8da65ee081f5ce6d9bab8e GIT binary patch literal 3066 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 IM6N<$f;QJHQ2+n{ literal 0 HcmV?d00001 diff --git a/metar-images/wr-SSW.gif b/metar-images/wr-SSW.gif new file mode 100644 index 0000000000000000000000000000000000000000..24a71bce534886bcc29850e90b1768c4c70d338b GIT binary patch literal 2020 zcmeH|{ZmtS7RJ9xZU`@d00}QjcnKR2X+Ur@C^RquLa4|pFo>XmMF zSQ14g7?irq136S(*|j-&~+9opqL%SHogx(0K1av8pi{JeZqs|qd1m)1*- zO)?}a+d7QFAxvz*h}KGGre{odOx7V2lE77;QzOwFY{;~+zCm@T;=>qfKvm5$ya!pB zU*JS@B*!Es=f-B4bsUGkfQ@}9FNr5QBr?#R zCaq|_6dyFgNjy|2*jQOM^&rfxOj)zc)Fgu=*~ViM$Mg)6!qZ+*!}U_g1yZ%D1VRCJ z7lWNS^dPW512dqG-yCSA*!qi=9my6~ij9LtZ4wXv8ApTy?G^3v$}%^B%kXF97v!7H zsnJ6sX@eBmmu+>LgtPHJbmrNN$%&c7Q(sUcJGr(CmV zXLo3k5)ppKWHO)&uNOG697(OjG-$N`jKkMpUJ6g-gmq%Za?l2;saa;MmArrd9{hj) zw***g5CH%!;QVRxXD5K`CfM%A{HR}NQM%HjMPvP80EnR!p0&R_Lq$vcLC0O{&b&w? z2<)!%xqFwWp~tGzC)wklQ$lw(wdntXe+h+7+RbB;`(XP0s--phZ&*xWn}5dCQp@Cx zfZ~b8?=#eal(Iosr*|=oCZC-zymjvK!hvtN2~8P4P)6M1xAiBrdE7=tXz2+u z`bPTvi->>e`aAnhZSU=UJ6JnAaP+&aDZkqBs~NF+L!xEvRryHa?^&_gYuTT{|3#Ip<`DQYOr1J*e^v>Z^A#c zT`b=}bh_dBxL?&~SFQ)0WS{qnX8gVD^p8t(hdGB+PWS9vzWwcJXYC&;#Otr0-s&e; zzx^lW5$jBHgUhMusdl0NIqw%C4Y%5_JadctN5qy2&-IqHx(d|We8#rsLpVtSM~f<& zzCwfw{MHj;O6-|b>U8QW__X^8ANze-7bR^`)RB?8RQ;%4BZRstk0OERt@)Fw zn_Mu_8cHX4Lsf+}H;bv^JM;KDGTM)LB_ZuXkYkHFA};7%((+}lfE)xSvV`4bRJq6_ z-cHD%Hg|Tm5ajk;;g($&R%e@D6hEJbdp%WSq+s@NW;j46`bdYvwy_NND{?U3gP87m zaOlu3b9s5<#~)u$7XM=LpfM&s@&r=WmeSM4BA6wj)~TQdN8_)0(qd7k$Adh@4p3%Z zn(+TrHQ3gCR>+6QB~1RX-`H9mA!OUY!IskVyC;0p0>C0M;v^Bc1lGlKSao!}`NV_t zK)DENgmlW`<2_$Tfnejq^q`CG31y>*=T`bGsu%^e@7^B%{5vA&<}#D z*Aq3YG;xrfLQOThzmCY(D@Yyhd;+P;lS(&@!!qh~hIUgPI#%;} zvCLl7I=eTP?ImJea+j}&??paRidZO?MV#*w;|6NJH?+bC;36C%qdpMUVUogdQMQX zWD)FL9dT8gp$Kmmp6h>dh%5E3Hcp!FXvyNR_pnCko~>{@6Xj7csJl&Ah>YKnl195-c~l} zehIv=w8wB)eUD%o(6@0jJaA0m->4&JYW~o8R+GTB2|`Gzg{Co%d6Y(K_>}|U`<-uj z;q9LDSlD)8;|F9F`NToMhjyR%LChrG3(sQ(@YN)^;U^W4(+;^3DdNX_RZuBuhk2OJ L2f>{X1U~#P9oO<6 literal 0 HcmV?d00001 diff --git a/metar-images/wr-SSW.png b/metar-images/wr-SSW.png new file mode 100644 index 0000000000000000000000000000000000000000..aa191c609a19dd7b73cbd5f9253a0a4355111ef9 GIT binary patch literal 3088 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 literal 0 HcmV?d00001 diff --git a/metar-images/wr-SW.png b/metar-images/wr-SW.png new file mode 100644 index 0000000000000000000000000000000000000000..45ce24e6cf5dfb48c6702ee3bae6bae5ccdbe856 GIT binary patch literal 3063 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 D1rMC- literal 0 HcmV?d00001 diff --git a/metar-images/wr-WNW.gif b/metar-images/wr-WNW.gif new file mode 100644 index 0000000000000000000000000000000000000000..5fa1c33b02b73fc33faa72c6e9b2cbc17742532b GIT binary patch literal 1993 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 literal 0 HcmV?d00001 diff --git a/metar-images/wr-WSW.gif b/metar-images/wr-WSW.gif new file mode 100644 index 0000000000000000000000000000000000000000..732d2a86f314bafd2be7e0cf99c098ac3fac65c4 GIT binary patch literal 1998 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 a*(|cYksfSLAhuCKBnP6;8YXN`c>e=)5?=cN literal 0 HcmV?d00001 diff --git a/metar-images/wr-calm.gif b/metar-images/wr-calm.gif new file mode 100644 index 0000000000000000000000000000000000000000..e9886d2611624f62e8444fe26a1326eb75ba2e9e GIT binary patch literal 1229 zcmV;;1Ty`YG7=Icp3BUyloD4 zDI^HUF|Z)P9P}<(n>P>H9UTR@RkM~Lhed-IGh7r=t(t^+GE~7?0Bm9c2?qyWB&gA# z2y52N$-wdO6}uGWR;E;NBjx@|j>YKF6M2TluV*q2`pkhMfC`lc1<*4o0RtRS(x_pa z&{9E!02f%!P+*au1WXiV=sL6FsKS*3B7{JYA;Sz58VN-BKvpGCOlS3-p>WC=Mgar@ z#2~05tbiE-BEZdowA7La04C%C&$Xh|^I zr8;GfPypa!#uNY@zF|_CW5U-Pp>N#Si{Ju^{{eh}*Fl9{vce-mz%alEEdb!&3AtGU z4?z>e@WBK#j8$O-G5)AfR|X;6upL3A(1IRp=nPSV0S?#zgAD*gP|_vwl$FDHEFmxf z3Oj0)gO4eFV+nf5xxfK74nSZ40XtLx0146nvm16f&hT4(c##KHZpCPTU=J_?kirX3 zh=2n)#;~GjORB1_2 z*HhTsLBqJ_O!bUFP_c%T1RnaD;vy7$M6R;t*>lp5D&$bWE(??+6h)>O<4yu1Oelh2 zyR=2mr2lXUP)r<|n~V@TBzv>Vv)Ce&34^ zu|NPLY%l@`)^^>53jlcFzy=`9V0IM{h$#dGWxuV22LK#EligKJkO%+_kid5nB?M5z r6Cn&z?doyPrq literal 0 HcmV?d00001 diff --git a/metar-images/wr-calm.png b/metar-images/wr-calm.png new file mode 100644 index 0000000000000000000000000000000000000000..53edbf2e631c994e5953f6b27b6e6c197d4feb21 GIT binary patch literal 2769 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 Date: Wed, 25 Jan 2017 18:05:00 -0600 Subject: [PATCH 05/17] Mysql to Mysqli function fixes. --- display.php | 4 +- footer.php | 44 +++++------ functions.php | 4 +- header.php | 12 +-- index.php | 6 +- login.php | 4 +- login_reports.php | 4 +- logout.php | 34 ++++---- metar-display.php | 118 ++++++++++++++++++++++++++++ resetcookie.php | 12 +-- timeclock.php | 16 ++-- topmain.php | 196 +++++++++++++++++++++++----------------------- tzoffset.php | 60 +++++++------- 13 files changed, 316 insertions(+), 198 deletions(-) create mode 100644 metar-display.php diff --git a/display.php b/display.php index d33b8a4..c0ca298 100644 --- a/display.php +++ b/display.php @@ -3,7 +3,7 @@ $row_count = 0; $page_count = 0; -while ($row = mysql_fetch_array($result)) { +while ($row = mysqli_fetch_array($result)) { $display_stamp = "" . $row["timestamp"] . ""; $time = date($timefmt, $display_stamp); @@ -130,5 +130,5 @@ echo "
Powered by Apache ± MySql - ±"; - -if ($email == "none") { - echo " PHP"; -} else { - echo " PHP • $email"; -} - -echo " • $app_name $app_version
\n"; -echo " \n"; -echo " \n"; -echo "\n"; -echo "\n"; -echo "\n"; -?> +Powered by Apache ± MySql + ±"; + +if ($email == "none") { + echo " PHP"; +} else { + echo " PHP • $email"; +} + +echo " • $app_name $app_version\n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo "\n"; +echo "\n"; +echo "\n"; +?> diff --git a/functions.php b/functions.php index 781ff04..d37b2fa 100644 --- a/functions.php +++ b/functions.php @@ -84,9 +84,9 @@ function secsToHours($secs, $round_time) { function disabled_acct($get_user) { $query = "select empfullname, disabled from employees where empfullname = '" . addslashes($get_user) . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { if ("" . $row["disabled"] . "" == 1) { echo "\n"; diff --git a/header.php b/header.php index c3692aa..5aaffef 100644 --- a/header.php +++ b/header.php @@ -30,16 +30,16 @@ // connect to db anc check for correct db version // -@ $db = mysql_pconnect($db_hostname, $db_username, $db_password); +@ $db = ($GLOBALS["___mysqli_ston"] = mysqli_connect($db_hostname, $db_username, $db_password)); if (!$db) { echo "Error: Could not connect to the database. Please try again later."; exit; } -mysql_select_db($db_name); +mysqli_select_db($GLOBALS["___mysqli_ston"], $db_name); $table = "dbversion"; -$result = mysql_query("SHOW TABLES LIKE '" . $db_prefix . $table . "'"); -@$rows = mysql_num_rows($result); +$result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW TABLES LIKE '" . $db_prefix . $table . "'"); +@$rows = mysqli_num_rows($result); if ($rows == "1") { $dbexists = "1"; @@ -47,8 +47,8 @@ $dbexists = "0"; } -$db_version_result = mysql_query("select * from " . $db_prefix . "dbversion"); -while (@$row = mysql_fetch_array($db_version_result)) { +$db_version_result = mysqli_query($GLOBALS["___mysqli_ston"], "select * from " . $db_prefix . "dbversion"); +while (@$row = mysqli_fetch_array($db_version_result)) { @$my_dbversion = "" . $row["dbversion"] . ""; } diff --git a/index.php b/index.php index add5457..ec6b9f0 100644 --- a/index.php +++ b/index.php @@ -1,3 +1,3 @@ - + diff --git a/login.php b/login.php index 9556af5..c9da725 100644 --- a/login.php +++ b/login.php @@ -14,9 +14,9 @@ $query = "select empfullname, employee_passwd, admin, time_admin from " . $db_prefix . "employees where empfullname = '" . $login_userid . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $admin_username = "" . $row['empfullname'] . ""; $admin_password = "" . $row['employee_passwd'] . ""; diff --git a/login_reports.php b/login_reports.php index d4163f7..d51ae73 100644 --- a/login_reports.php +++ b/login_reports.php @@ -14,9 +14,9 @@ $query = "select empfullname, employee_passwd, reports from " . $db_prefix . "employees where empfullname = '" . $login_userid . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $reports_username = "" . $row['empfullname'] . ""; $reports_password = "" . $row['employee_passwd'] . ""; diff --git a/logout.php b/logout.php index af77605..171cb99 100644 --- a/logout.php +++ b/logout.php @@ -1,17 +1,17 @@ - window.location.href = 'index.php';"; -?> + window.location.href = 'index.php';"; +?> diff --git a/metar-display.php b/metar-display.php new file mode 100644 index 0000000..60b8950 --- /dev/null +++ b/metar-display.php @@ -0,0 +1,118 @@ + + + + +Local Weather + + + + + + +\n"; +# end of utility functions +?> + +Metar display script from Saratoga-Weather.org

\n"; + } else { + print "

Sorry.. include-metar-display.php not found

\n"; + } +?> + + + \ No newline at end of file diff --git a/resetcookie.php b/resetcookie.php index 69ff361..4185583 100644 --- a/resetcookie.php +++ b/resetcookie.php @@ -1,6 +1,6 @@ -\n"; -echo "\n"; -echo "\n"; -?> +\n"; +echo "\n"; +echo "\n"; +?> diff --git a/timeclock.php b/timeclock.php index 3cbbe6a..ad02a79 100644 --- a/timeclock.php +++ b/timeclock.php @@ -69,7 +69,7 @@ and " . $db_prefix . "info.`inout` = " . $db_prefix . "punchlist.punchitems and ((" . $db_prefix . "info.timestamp < '" . $a . "') and (" . $db_prefix . "info.timestamp >= '" . $b . "')) and " . $db_prefix . "employees.disabled <> '1' and " . $db_prefix . "employees.empfullname <> 'admin' order by `$sortcolumn` $sortdirection"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($display_current_users == "yes") && ($display_office != "all") && ($display_group == "all")) { $current_users_date = strtotime(date($datefmt)); @@ -84,7 +84,7 @@ and ((" . $db_prefix . "info.timestamp < '" . $a . "') and (" . $db_prefix . "info.timestamp >= '" . $b . "')) and " . $db_prefix . "employees.disabled <> '1' and " . $db_prefix . "employees.empfullname <> 'admin' order by `$sortcolumn` $sortdirection"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($display_current_users == "yes") && ($display_office == "all") && ($display_group != "all")) { $current_users_date = strtotime(date($datefmt)); @@ -99,7 +99,7 @@ and ((" . $db_prefix . "info.timestamp < '" . $a . "') and (" . $db_prefix . "info.timestamp >= '" . $b . "')) and " . $db_prefix . "employees.disabled <> '1' and " . $db_prefix . "employees.empfullname <> 'admin' order by `$sortcolumn` $sortdirection"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($display_current_users == "yes") && ($display_office != "all") && ($display_group != "all")) { $current_users_date = strtotime(date($datefmt)); @@ -115,7 +115,7 @@ and (" . $db_prefix . "info.timestamp >= '" . $b . "')) and " . $db_prefix . "employees.disabled <> '1' and " . $db_prefix . "employees.empfullname <> 'admin' order by `$sortcolumn` $sortdirection"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($display_current_users == "no") && ($display_office == "all") && ($display_group == "all")) { $query = "select " . $db_prefix . "info.*, " . $db_prefix . "employees.*, " . $db_prefix . "punchlist.* @@ -124,7 +124,7 @@ and " . $db_prefix . "info.`inout` = " . $db_prefix . "punchlist.punchitems and " . $db_prefix . "employees.disabled <> '1' and " . $db_prefix . "employees.empfullname <> 'admin' order by `$sortcolumn` $sortdirection"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($display_current_users == "no") && ($display_office != "all") && ($display_group == "all")) { $query = "select " . $db_prefix . "info.*, " . $db_prefix . "employees.*, " . $db_prefix . "punchlist.* @@ -133,7 +133,7 @@ and " . $db_prefix . "info.`inout` = " . $db_prefix . "punchlist.punchitems and " . $db_prefix . "employees.office = '" . $display_office . "' and " . $db_prefix . "employees.disabled <> '1' and " . $db_prefix . "employees.empfullname <> 'admin' order by `$sortcolumn` $sortdirection"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($display_current_users == "no") && ($display_office == "all") && ($display_group != "all")) { $query = "select " . $db_prefix . "info.*, " . $db_prefix . "employees.*, " . $db_prefix . "punchlist.* @@ -142,7 +142,7 @@ and " . $db_prefix . "info.`inout` = " . $db_prefix . "punchlist.punchitems and " . $db_prefix . "employees.groups = '" . $display_group . "' and " . $db_prefix . "employees.disabled <> '1' and " . $db_prefix . "employees.empfullname <> 'admin' order by `$sortcolumn` $sortdirection"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($display_current_users == "no") && ($display_office != "all") && ($display_group != "all")) { $query = "select " . $db_prefix . "info.*, " . $db_prefix . "employees.*, " . $db_prefix . "punchlist.* @@ -152,7 +152,7 @@ and " . $db_prefix . "employees.groups = '" . $display_group . "' and " . $db_prefix . "employees.disabled <> '1' and " . $db_prefix . "employees.empfullname <> 'admin' order by `$sortcolumn` $sortdirection"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } $time = time(); diff --git a/topmain.php b/topmain.php index f88b31f..18670c7 100644 --- a/topmain.php +++ b/topmain.php @@ -1,98 +1,98 @@ -\n"; -echo " "; - -// display the logo in top left of each page. This will be $logo you setup in config.inc.php. // -// It will also link you back to your index page. // - -if ($logo == "none") { - echo " \n"; -} else { - echo "\n"; -} - -// if db is out of date, report it here // - -if (($dbexists <> "1") || (@$my_dbversion <> $dbversion)) { - echo " \n"; -} - -// display a 'reset cookie' message if $use_client_tz = "yes" // - -if ($date_link == "none") { - - if ($use_client_tz == "yes") { - echo " \n"; - } - - echo " \n"; - } - - echo " \n"; -echo "

***Your database is out of date.***
-    Upgrade it via the admin section.

-

If the times below appear to be an hour off, click here to reset.
- If that doesn't work, restart your web browser and reset again.

"; - -} else { - - if ($use_client_tz == "yes") { - echo " -

If the times below appear to be an hour off, click here to reset.
- If that doesn't work, restart your web browser and reset again.

"; -} - -// display today's date in top right of each page. This will link to $date_link you setup in config.inc.php. // - -$todaydate = date('F j, Y'); -echo "$todaydate  
\n"; - -// display the topbar // - -echo "\n"; -echo " \n"; - -if (isset($_SESSION['valid_user'])) { - $logged_in_user = $_SESSION['valid_user']; - echo " \n"; - echo " \n"; -} else if (isset($_SESSION['time_admin_valid_user'])) { - $logged_in_user = $_SESSION['time_admin_valid_user']; - echo " \n"; - echo " \n"; -} else if (isset($_SESSION['valid_reports_user'])) { - $logged_in_user = $_SESSION['valid_reports_user']; - echo " \n"; - echo " \n"; -} - -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; - -if ($use_reports_password == "yes") { - echo " \n"; -} elseif ($use_reports_password == "no") { - echo " \n"; -} - -echo " \n"; -echo " \n"; - -if ((isset($_SESSION['valid_user'])) || (isset($_SESSION['valid_reports_user'])) || (isset($_SESSION['time_admin_valid_user']))) { - echo " \n"; - echo " \n"; -} - -echo "
logged in as: $logged_in_userlogged in as: $logged_in_userlogged in as: $logged_in_user   - Home     - Administration    Reports  Reports    Punchclock    - Logout  
\n"; -?> +\n"; +echo " "; + +// display the logo in top left of each page. This will be $logo you setup in config.inc.php. // +// It will also link you back to your index page. // + +if ($logo == "none") { + echo " \n"; +} else { + echo "\n"; +} + +// if db is out of date, report it here // + +if (($dbexists <> "1") || (@$my_dbversion <> $dbversion)) { + echo "

***Your database is out of date.***
+    Upgrade it via the admin section.

\n"; +} + +// display a 'reset cookie' message if $use_client_tz = "yes" // + +if ($date_link == "none") { + + if ($use_client_tz == "yes") { + echo " +

If the times below appear to be an hour off, click here to reset.
+ If that doesn't work, restart your web browser and reset again.

\n"; + } + + echo " "; + +} else { + + if ($use_client_tz == "yes") { + echo " +

If the times below appear to be an hour off, click here to reset.
+ If that doesn't work, restart your web browser and reset again.

\n"; + } + + echo " "; +} + +// display today's date in top right of each page. This will link to $date_link you setup in config.inc.php. // + +$todaydate = date('F j, Y'); +echo "$todaydate  \n"; +echo "\n"; + +// display the topbar // + +echo "\n"; +echo " \n"; + +if (isset($_SESSION['valid_user'])) { + $logged_in_user = $_SESSION['valid_user']; + echo " \n"; + echo " \n"; +} else if (isset($_SESSION['time_admin_valid_user'])) { + $logged_in_user = $_SESSION['time_admin_valid_user']; + echo " \n"; + echo " \n"; +} else if (isset($_SESSION['valid_reports_user'])) { + $logged_in_user = $_SESSION['valid_reports_user']; + echo " \n"; + echo " \n"; +} + +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; + +if ($use_reports_password == "yes") { + echo " \n"; +} elseif ($use_reports_password == "no") { + echo " \n"; +} + +echo " \n"; +echo " \n"; + +if ((isset($_SESSION['valid_user'])) || (isset($_SESSION['valid_reports_user'])) || (isset($_SESSION['time_admin_valid_user']))) { + echo " \n"; + echo " \n"; +} + +echo "
logged in as: $logged_in_userlogged in as: $logged_in_userlogged in as: $logged_in_user   + Home     + Administration    Reports  Reports    Punchclock    + Logout  
\n"; +?> diff --git a/tzoffset.php b/tzoffset.php index 935be76..6aed76f 100644 --- a/tzoffset.php +++ b/tzoffset.php @@ -1,30 +1,30 @@ - - - - + + + + From baccca77278669b64ca19647faf2468a28c92efd Mon Sep 17 00:00:00 2001 From: Rick Boatright Date: Wed, 25 Jan 2017 18:06:14 -0600 Subject: [PATCH 06/17] remove phpweather.php --- phpweather.php | 600 ------------------------------------------------- 1 file changed, 600 deletions(-) delete mode 100644 phpweather.php diff --git a/phpweather.php b/phpweather.php deleted file mode 100644 index 29a46ad..0000000 --- a/phpweather.php +++ /dev/null @@ -1,600 +0,0 @@ - 'Clear', - 'CLR' => 'Clear', - 'VV' => 'Vertical Visibility', - 'FEW' => 'Partly Cloudy', - 'SCT' => 'Scattered Clouds', - 'BKN' => 'Partly Cloudy', - 'OVC' => 'Overcast'); - -/* Offset in hours to add to the time of a report. If all your times - * are 2 hours off, then set this to -2. */ -$weather_offset = 0; - -/* Make a connection to the MySQL database: */ -if (mysql_pconnect($db_hostname, $db_username, $db_password)) { - mysql_select_db($db_name); -} else { - echo "

Unable to connect to MySQL database!

"; -} - -function store_speed($value, $windunit, &$meterspersec, &$knots, &$milesperhour) { - /* - * Helper function to convert and store speed based on unit. - * &$meterspersec, &$knots and &$milesperhour are passed on - * reference - */ - if ($windunit == 'KT') { - /* The windspeed measured in knots: */ - $knots = number_format($value); - /* The windspeed measured in meters per second, rounded to one - * decimal place: */ - $meterspersec = number_format($value * 0.51444, 1); - /* The windspeed measured in miles per hour, rounded to one - * decimal place: */ - $milesperhour = number_format($value * 1.1507695060844667, 1); - } elseif ($windunit == 'MPS') { - /* The windspeed measured in meters per second: */ - $meterspersec = number_format($value); - /* The windspeed measured in knots, rounded to one decimal - * place: */ - $knots = number_format($value / 0.51444, 1); - /* The windspeed measured in miles per hour, rounded to one - * decimal place: */ - $milesperhour = number_format($value / 0.51444 * 1.1507695060844667, 1); - } elseif ($windunit == 'KMH') { - /* The windspeed measured in kilometers per hour: */ - $meterspersec = number_format($value * 1000 / 3600, 1); - $knots = number_format($value * 1000 / 3600 / 0.51444, 1); - /* The windspeed measured in miles per hour, rounded to one - * decimal place: */ - $milesperhour = number_format($knots * 1.1507695060844667, 1); - } -} - -function get_metar($station, $always_use_cache = 0) { - /* - * Looks in the database, and fetches a new metar is nesceary. If - * $always_use_cache is true, then it ignores the timestamp of the - * METAR and just returns it. - * - * You should pass a ICAO station identifier, eg. 'EKYT' for - * Aalborg, Denmark. - */ - - global $conn, $dbmMetar, $dbmTimestamp, $db_prefix; - - $query = "SELECT metar, UNIX_TIMESTAMP(timestamp) FROM " . $db_prefix . "metars WHERE station = '$station'"; - $result = mysql_query($query); - @$metar_rows = mysql_num_rows($result); /* this suppresses a php error message if the metars db has not yet been created. */ - if (isset($metar_rows)) { /* found station */ - list($metar, $timestamp) = mysql_fetch_row($result); - } - - if (isset($metar)) { /* found station */ - if ($always_use_cache || $timestamp > time() - 3600) { - /* We have asked explicit for a cached metar, or the metar is - * still fresh. */ - return $metar; - } else { - /* We looked in the cache, but the metar was too old. */ - return fetch_metar($station, 0); - } - } else { - /* The station is new - we fetch a new METAR */ - return fetch_metar($station, 1); - } -} - -function fetch_metar($station, $new) { - /* - * Fetches a new METER from weather.noaa.gov. If the $new variable - * is true, the metar is inserted, else it will replace the old - * metar. The new METAR is returned. - */ - global $conn, $dbmMetar, $dbmTimestamp; - - $metar = ''; - $station = strtoupper($station); - - /* We use the @ notation, because it might fail. */ - $file = @file('http://weather.noaa.gov/pub/data/' . - "observations/metar/stations/$station.TXT"); - - /* Here we test to see if we actually got a METAR. */ - if (is_array($file)) { - $date = trim($file[0]); - $metar = trim($file[1]); - for ($i = 2; $i < count($file); $i++) { - $metar .= ' ' . trim($file[i]); - } - - /* The date is in the form 2000/10/09 14:50 UTC. This seperates - the different parts. */ - $date_parts = explode(':', strtr($date, '/ ', '::')); - $date_unixtime = gmmktime($date_parts[3], $date_parts[4], - 0, $date_parts[1], $date_parts[2], - $date_parts[0]); - - if (!ereg('[0-9]{6}Z', $metar)) { - /* Some reports dont even have a time-part, so we insert the - * current time. This might not be the time of the report, but - * it was broken anyway :-) */ - $metar = gmdate('dHi', $date_unixtime) . 'Z ' . $metar; - } - - if ($date_unixtime < (time() - 3300)) { - /* The timestamp in the metar is more than 55 minutes old. We - * adjust the timestamp, so that we won't try to fetch a new - * METAR within the next 5 minutes. After 5 minutes, the - * timestamp will again be more than 1 hour old. */ - $date_unixtime = time() - 3300; - } - - } else { - /* If we end up here, it means that there was no file, we then set - * the metar to and empty string. We set the date to time() - 3000 - * to give the server 10 minutes of peace. If the file is - * unavailable, we don't want to stress the server. */ - $metar = ''; - $date_unixtime = time() - 3000; - } - - /* It might seam strange, that we make a local date, but MySQL - * expects a local when we insert the METAR. */ - $date = date('Y/m/d H:i', $date_unixtime); - - if ($new) { - /* Insert the new record */ - $query = "INSERT INTO " . $db_prefix . "metars SET station = '$station', " . - "metar = '$metar', timestamp = '$date'"; - } else { - /* Update the old record */ - $query = "UPDATE " . $db_prefix . "metars SET metar = '$metar', " . - "timestamp = '$date' WHERE station = '$station'"; - } - mysql_query($query); - - return $metar; -} - -function process_metar($metar) { - /* This function decodes a raw METAR. The result is an associative - * array with entries like 'temp_c', 'visibility_miles' etc. */ - - global $strings, $wind_dir_text_short_array, $wind_dir_text_array, - $cloud_condition_array, $weather_array, $weather_offset; - - $temp_visibility_miles = ''; - $cloud_layers = 0; - $decoded_metar['remarks'] = ''; - $decoded_metar['weather'] = ''; - - $cloud_coverage = array('SKC' => '0', - 'CLR' => '0', - 'VV' => '8/8', - 'FEW' => '1/8 - 2/8', - 'SCT' => '3/8 - 4/8', - 'BKN' => '5/8 - 7/8', - 'OVC' => '8/8'); - - $decoded_metar['metar'] = $metar; - $parts = split('[ ]+', $metar); - $num_parts = count($parts); - for ($i = 0; $i < $num_parts; $i++) { - $part = $parts[$i]; - - if (ereg('RMK|TEMPO|BECMG', $part)) { - /* The rest of the METAR is either a remark or temporary - * information. We skip the rest of the METAR. */ - $decoded_metar['remarks'] .= ' ' . $part; - break; - } elseif ($part == 'METAR') { - /* - * Type of Report: METAR - */ - $decoded_metar['type'] = 'METAR'; - } elseif ($part == 'SPECI') { - /* - * Type of Report: SPECI - */ - $decoded_metar['type'] = 'SPECI'; - } elseif (ereg('^[A-Z]{4}$', $part) && !isset($decoded_metar['station'])) { - /* - * Station Identifier - */ - $decoded_metar['station'] = $part; - } elseif (ereg('([0-9]{2})([0-9]{2})([0-9]{2})Z', $part, $regs)) { - /* - * Date and Time of Report - * We return a standard Unix UTC/GMT timestamp suitable for - * gmdate() - */ - $decoded_metar['time'] = gmmktime($regs[2] + $weather_offset, $regs[3], 0, - gmdate('m'), $regs[1], gmdate('Y')); - } elseif (ereg('(AUTO|COR|RTD|CC[A-Z]|RR[A-Z])', $part, $regs)) { - /* - * Report Modifier: AUTO, COR, CCx or RRx - */ - $decoded_metar['report_mod'] = $regs[1]; - } elseif (ereg('([0-9]{3}|VRB)([0-9]{2,3}).*(KT|MPS|KMH)', $part, $regs)) { - /* Wind Group */ - $windunit = $regs[3]; /* do ereg in two parts to retrieve unit first */ - /* now do ereg to get the actual values */ - ereg("([0-9]{3}|VRB)([0-9]{2,3})(G([0-9]{2,3})?$windunit)", $part, $regs); - if ($regs[1] == 'VRB') { - $decoded_metar['wind_deg'] = $strings['wind_vrb_long']; - $decoded_metar['wind_dir_text'] = $strings['wind_vrb_long']; - $decoded_metar['wind_dir_text_short'] = $strings['wind_vrb_short']; - } else { - $decoded_metar['wind_deg'] = $regs[1]; - $decoded_metar['wind_dir_text'] = - $wind_dir_text_array[intval(round($regs[1] / 22.5))]; - $decoded_metar['wind_dir_text_short'] = - $wind_dir_text_short_array[intval(round($regs[1] / 22.5))]; - } - store_speed($regs[2], - $windunit, - $decoded_metar['wind_meters_per_second'], - $decoded_metar['wind_knots'], - $decoded_metar['wind_miles_per_hour']); - - if (isset($regs[4])) { - /* We have a report with information about the gust. First we - have the gust measured in knots: */ - store_speed($regs[4], $windunit, - $decoded_metar['wind_gust_meters_per_second'], - $decoded_metar['wind_gust_knots'], - $decoded_metar['wind_gust_miles_per_hour']); - } - } elseif (ereg('^([0-9]{3})V([0-9]{3})$', $part, $regs)) { - /* - * Variable wind-direction - */ - $decoded_metar['wind_var_beg'] = $regs[1]; - $decoded_metar['wind_var_end'] = $regs[2]; - } elseif ($part == 9999) { - /* A strange value. When you look at other pages you see it - interpreted like this (where I use > to signify 'Greater - than'): */ - $decoded_metar['visibility_miles'] = '>6.2'; - $decoded_metar['visibility_km'] = '>10'; - } elseif (ereg('^([0-9]{4})$', $part, $regs)) { - /* - * Visibility in meters (4 digits only) - */ - $decoded_metar['visibility_km'] = number_format($regs[1] / 1000, 1); - $decoded_metar['visibility_miles'] = - number_format(($regs[1] / 1000) / 1.609344, 1); - } elseif (ereg('^[0-9]$', $part)) { - /* - * Temp Visibility Group, single digit followed by space - */ - $temp_visibility_miles = $part; - } elseif (ereg('^M?(([0-9]?)[ ]?([0-9])(/?)([0-9]*))SM$', - $temp_visibility_miles . ' ' . - $parts[$i], $regs) - ) { - /* - * Visibility Group - */ - if ($regs[4] == '/') { - $vis_miles = $regs[2] + $regs[3] / $regs[5]; - } else { - $vis_miles = $regs[1]; - } - if ($regs[0][0] == 'M') { - /* The visibility measured in miles, prefixed with < to - indicate 'Less than' */ - $decoded_metar['visibility_miles'] = - '<' . number_format($vis_miles, 1); - /* The visibility measured in kilometers. The value is rounded - to one decimal place, prefixed with < to indicate 'Less - than' */ - $decoded_metar['visibility_km'] = - '<' . number_format($vis_miles * 1.609344, 1); - } else { - /* The visibility measured in mile.s */ - $decoded_metar['visibility_miles'] = number_format($vis_miles, 1); - /* The visibility measured in kilometers, rounded to one - decimal place. */ - $decoded_metar['visibility_km'] = - number_format($vis_miles * 1.609344, 1); - } - } elseif ($part == 'CAVOK') { - /* CAVOK: Used when the visibility is greather than 10 - kilometers, the lowest cloud-base is at 5000 feet and there - is no significant weather. */ - $decoded_metar['visibility_km'] = '>10'; - $decoded_metar['visibility_miles'] = '>6.2'; - $decoded_metar['cloud_layer1_condition'] = 'CAVOK'; - } elseif (ereg('^R([0-9][0-9][RLC]?)/([MP]?[0-9]{4})V?(P?[0-9]{4})?F?T?$', $part, $regs)) { - $decoded_metar['runway_nr'] = $regs[1]; - if ($regs[3]) { - /* We have both min and max visibility. */ - $prefix = ''; - if ($regs[2][0] == 'M') { - /* Less than. */ - $prefix = '<'; - $regs[2] = substr($regs[2], 1); - } - $decoded_metar['runway_vis_min_ft'] = $prefix . number_format($regs[2]); - $decoded_metar['runway_vis_min_meter'] = $prefix . number_format($regs[2] * 0.3048); - - $prefix = ''; - if ($regs[3][0] == 'P') { - /* Greather than. */ - $prefix = '>'; - $regs[3] = substr($regs[3], 1); - } - $decoded_metar['runway_vis_max_ft'] = $prefix . number_format($regs[3]); - $decoded_metar['runway_vis_max_meter'] = $prefix . number_format($regs[3] * 0.3048); - - } else { - /* We only have a single visibility. */ - $prefix = ''; - if ($regs[2][0] == 'M') { - $prefix = '<'; - $regs[2] = substr($regs[2], 1); - } elseif ($regs[2][0] == 'P') { - $prefix = '>'; - $regs[2] = substr($regs[2], 1); - } - $decoded_metar['runway_vis_ft'] = $prefix . number_format($regs[2]); - $decoded_metar['runway_vis_meter'] = $prefix . number_format($regs[2] * 0.3048); - } - } elseif (ereg('^(-|\+|VC)?(TS|SH|FZ|BL|DR|MI|BC|PR|RA|DZ|SN|SG|GR|' . - 'GS|PE|IC|UP|BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS)+$', - $part) - ) { - /* - * Current weather-group - */ - if ($part[0] == '-') { - /* A light phenomenon */ - $decoded_metar['weather'] .= $strings['light']; - $part = substr($part, 1); - } elseif ($part[0] == '+') { - /* A heavy phenomenon */ - $decoded_metar['weather'] .= $strings['heavy']; - $part = substr($part, 1); - } elseif ($part[0] . $part[1] == 'VC') { - /* Proximity Qualifier */ - $decoded_metar['weather'] .= $strings['nearby']; - $part = substr($part, 2); - } else { - /* no intensity code => moderate phenomenon */ - $decoded_metar['weather'] .= $strings['moderate']; - } - - while ($bite = substr($part, 0, 2)) { - /* Now we take the first two letters and determine what they - mean. We append this to the variable so that we gradually - build up a phrase. */ - $decoded_metar['weather'] .= $weather_array[$bite]; - /* Here we chop off the two first letters, so that we can take - a new bite at top of the while-loop. */ - $part = substr($part, 2); - } - } elseif (ereg('(SKC|CLR)', $part, $regs)) { - /* - * Cloud-layer-group. - * There can be up to three of these groups, so we store them as - * cloud_layer1, cloud_layer2 and cloud_layer3. - */ - $cloud_layers++; - /* Again we have to translate the code-characters to a - meaningful string. */ - $decoded_metar['cloud_layer' . $cloud_layers . '_condition'] = - $cloud_condition_array[$regs[1]]; - $decoded_metar['cloud_layer' . $cloud_layers . '_coverage'] = - $cloud_coverage[$regs[1]]; - } elseif (ereg('^(VV|FEW|SCT|BKN|OVC)([0-9]{3})(CB|TCU)?$', - $part, $regs) - ) { - /* We have found (another) a cloud-layer-group. There can be up - to three of these groups, so we store them as cloud_layer1, - cloud_layer2 and cloud_layer3. */ - $cloud_layers++; - /* Again we have to translate the code-characters to a - meaningful string. */ - if ($regs[1] == 'OVC') { - $clouds_str_temp = ''; - } else { - $clouds_str_temp = $strings['clouds']; - } - if ($regs[3] == 'CB') { - /* cumulonimbus (CB) clouds were observed. */ - $decoded_metar['cloud_layer' . $cloud_layers . '_condition'] = - $cloud_condition_array[$regs[1]] . $strings['clouds_cb']; - } elseif ($regs[3] == 'TCU') { - /* towering cumulus (TCU) clouds were observed. */ - $decoded_metar['cloud_layer' . $cloud_layers . '_condition'] = - $cloud_condition_array[$regs[1]] . $strings['clouds_tcu']; - } else { - $decoded_metar['cloud_layer' . $cloud_layers . '_condition'] = - $cloud_condition_array[$regs[1]] . $clouds_str_temp; - } - $decoded_metar['cloud_layer' . $cloud_layers . '_coverage'] = - $cloud_coverage[$regs[1]]; - $decoded_metar['cloud_layer' . $cloud_layers . '_altitude_ft'] = - $regs[2] * 100; - $decoded_metar['cloud_layer' . $cloud_layers . '_altitude_m'] = - round($regs[2] * 30.48); - } elseif (ereg('^(M?[0-9]{2})/(M?[0-9]{2})?$', $part, $regs)) { - /* - * Temperature/Dew Point Group - * The temperature and dew-point measured in Celsius. - */ - $decoded_metar['temp_c'] = number_format(strtr($regs[1], 'M', '-')); - $decoded_metar['dew_c'] = number_format(strtr($regs[2], 'M', '-')); - /* The temperature and dew-point measured in Fahrenheit, rounded - to the nearest degree. */ - $decoded_metar['temp_f'] = round(strtr($regs[1], 'M', '-') * (9 / 5) + 32); - $decoded_metar['dew_f'] = round(strtr($regs[2], 'M', '-') * (9 / 5) + 32); - } elseif (ereg('A([0-9]{4})', $part, $regs)) { - /* - * Altimeter - * The pressure measured in inHg - */ - $decoded_metar['altimeter_inhg'] = number_format($regs[1] / 100, 2); - /* The pressure measured in mmHg, hPa and atm */ - $decoded_metar['altimeter_mmhg'] = number_format($regs[1] * 0.254, 1); - $decoded_metar['altimeter_hpa'] = number_format($regs[1] * 0.33863881578947); - $decoded_metar['altimeter_atm'] = number_format($regs[1] * 3.3421052631579e-4, 3); - } elseif (ereg('Q([0-9]{4})', $part, $regs)) { - /* - * Altimeter - * This is strange, the specification doesnt say anything about - * the Qxxxx-form, but it's in the METARs. - */ - /* The pressure measured in hPa */ - $decoded_metar['altimeter_hpa'] = number_format($regs[1]); - /* The pressure measured in mmHg, inHg and atm */ - $decoded_metar['altimeter_mmhg'] = number_format($regs[1] * 0.7500616827, 1); - $decoded_metar['altimeter_inhg'] = number_format($regs[1] * 0.0295299875, 2); - $decoded_metar['altimeter_atm'] = number_format($regs[1] * 9.869232667e-4, 3); - } elseif (ereg('^T([0-9]{4})([0-9]{4})', $part, $regs)) { - /* - * Temperature/Dew Point Group, coded to tenth of degree. - * The temperature and dew-point measured in Celsius. - */ - store_temp($regs[1], $decoded_metar, 'temp_c', 'temp_f'); - store_temp($regs[2], $decoded_metar, 'dew_c', 'dew_f'); - } elseif (ereg('^T([0-9]{4}$)', $part, $regs)) { - store_temp($regs[1], $decoded_metar, 'temp_c', 'temp_f'); - } elseif (ereg('^1([0-9]{4}$)', $part, $regs)) { - /* - * 6 hour maximum temperature Celsius, coded to tenth of degree - */ - store_temp($regs[1], $decoded_metar, 'temp_max6h_c', 'temp_max6h_f'); - } elseif (ereg('^2([0-9]{4}$)', $part, $regs)) { - /* - * 6 hour minimum temperature Celsius, coded to tenth of degree - */ - store_temp($regs[1], $decoded_metar, 'temp_min6h_c', 'temp_min6h_f'); - } elseif (ereg('^4([0-9]{4})([0-9]{4})$', $part, $regs)) { - /* - * 24 hour maximum and minimum temperature Celsius, coded to - * tenth of degree - */ - store_temp($regs[1], $decoded_metar, 'temp_max24h_c', 'temp_max24h_f'); - store_temp($regs[2], $decoded_metar, 'temp_min24h_c', 'temp_min24h_f'); - } elseif (ereg('^P([0-9]{4})', $part, $regs)) { - /* - * Precipitation during last hour in hundredths of an inch - * (store as inches) - */ - $decoded_metar['precip_in'] = number_format($regs[1] / 100, 2); - $decoded_metar['precip_mm'] = number_format($regs[1] * 0.254, 2); - } elseif (ereg('^6([0-9]{4})', $part, $regs)) { - /* - * Precipitation during last 3 or 6 hours in hundredths of an - * inch (store as inches) - */ - $decoded_metar['precip_6h_in'] = number_format($regs[1] / 100, 2); - $decoded_metar['precip_6h_mm'] = number_format($regs[1] * 0.254, 2); - } elseif (ereg('^7([0-9]{4})', $part, $regs)) { - /* - * Precipitation during last 24 hours in hundredths of an inch - * (store as inches) - */ - $decoded_metar['precip_24h_in'] = number_format($regs[1] / 100, 2); - $decoded_metar['precip_24h_mm'] = number_format($regs[1] * 0.254, 2); - } elseif (ereg('^4/([0-9]{3})', $part, $regs)) { - /* - * Snow depth in inches - */ - $decoded_metar['snow_in'] = number_format($regs[1]); - $decoded_metar['snow_mm'] = number_format($regs[1] * 25.4); - } else { - /* - * If we couldn't match the group, we assume that it was a - * remark. - */ - $decoded_metar['remarks'] .= ' ' . $part; - } - } - /* - * Relative humidity - */ - $decoded_metar['rel_humidity'] = number_format(pow(10, - (1779.75 * ($decoded_metar['dew_c'] - $decoded_metar['temp_c']) / - ((237.3 + $decoded_metar['dew_c']) * (237.3 + $decoded_metar['temp_c'])) - + 2)), 1); - - /* - * Humidity index - */ - $e = 6.112 * pow(10, 7.5 * $decoded_metar['temp_c'] - / (237.7 + $decoded_metar['temp_c'])) - * $decoded_metar['rel_humidity'] / 100; - $decoded_metar['humidex_c'] = - number_format($decoded_metar['temp_c'] + 5 / 9 * ($e - 10), 1); - $decoded_metar['humidex_f'] = - number_format($decoded_metar['humidex_c'] * 9 / 5 + 32, 1); - - /* - * Windchill. - * - * This is only appropriate if temp < 40f and windspeed > 3 mph - */ - if ($decoded_metar['temp_f'] <= '40' && - $decoded_metar['wind_miles_per_hour'] > '3' - ) { - $decoded_metar['windchill_f'] = - number_format(35.74 + 0.6215 * $decoded_metar['temp_f'] - - 35.75 * pow((float)$decoded_metar['wind_miles_per_hour'], 0.16) + - 0.4275 * $decoded_metar['temp_f'] * - pow((float)$decoded_metar['wind_miles_per_hour'], 0.16)); - $decoded_metar['windchill_c'] = - number_format(13.112 + 0.6215 * $decoded_metar['temp_c'] - - 13.37 * pow(($decoded_metar['wind_miles_per_hour'] / 1.609), 0.16) + - 0.3965 * $decoded_metar['temp_c'] * - pow(($decoded_metar['wind_miles_per_hour'] / 1.609), 0.16)); - } - - return $decoded_metar; -} - -?> \ No newline at end of file From e75652d5d5d1790eddf261d67c6056f6ebae9166 Mon Sep 17 00:00:00 2001 From: Rick Boatright Date: Wed, 25 Jan 2017 18:09:07 -0600 Subject: [PATCH 07/17] mysql to mysqli, fix isset() problems lots of non-initialized variable causing warnings -- fixed. All mysql calls fixed. --- punchclock/class.Timecard.php | 22 +- punchclock/config.inc.php | 250 +- punchclock/css/jquery.suggest.css | 62 +- punchclock/css/nyroModal.css | 238 +- punchclock/css/punchclock.css | 870 +-- punchclock/entry.ajax.php | 30 +- punchclock/entry.php | 24 +- punchclock/entry_status.php | 122 +- punchclock/export.php | 14 +- punchclock/export_display.php | 78 +- punchclock/footer.php | 26 +- punchclock/footer_timeclock.php | 20 +- punchclock/header.php | 118 +- punchclock/header_reports.php | 56 +- punchclock/header_timeclock.php | 46 +- punchclock/index.php | 18 +- punchclock/lib.common.php | 75 +- punchclock/lib.select.php | 4 +- punchclock/lib.timecard.php | 2 +- punchclock/login.php | 362 +- punchclock/menu.php | 6 +- punchclock/password.ajax.php | 6 +- punchclock/password.php | 2 +- punchclock/punchclock.php | 6 +- punchclock/punchclock_display.php | 12 +- punchclock/scripts/dragtable.js | 1076 ++-- punchclock/scripts/jquery-1.4.1.min.js | 5330 ++++++++-------- punchclock/scripts/jquery-1.4.2.min.js | 5442 ++++++++--------- .../scripts/jquery.nyroModal-1.6.2.min.js | 1970 +++--- .../scripts/jquery.scrollTo-1.3.3-min.js | 148 +- punchclock/scripts/jquery.suggest.js | 628 +- punchclock/scripts/punchclock.js | 244 +- punchclock/scripts/resize_window.js | 32 +- punchclock/scripts/sorttable.js | 1022 ++-- punchclock/scripts/textrange.js | 216 +- punchclock/setup_timeclock.php | 12 +- punchclock/suggest.ajax.php | 12 +- punchclock/time.php | 148 +- punchclock/timecard.ajax.php | 4 +- punchclock/timecard.php | 190 +- 40 files changed, 9485 insertions(+), 9458 deletions(-) diff --git a/punchclock/class.Timecard.php b/punchclock/class.Timecard.php index 7060bb7..15e5d85 100644 --- a/punchclock/class.Timecard.php +++ b/punchclock/class.Timecard.php @@ -75,11 +75,11 @@ function walk($onBefore = null, $onEveryRow = null, $onAfter = null) { if ($this->begin_local_timestamp < $local_timestamp) { // Get previous record to timecard to see if employee is already signed in at beginning of the period. - $result = mysql_query($this->_query_prev_record($begin_utm_timestamp)) - or trigger_error('Timecard->walk: no previous result: ' . mysql_error(), E_USER_WARNING); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $this->_query_prev_record($begin_utm_timestamp)) + or trigger_error('Timecard->walk: no previous result: ' . mysqli_error($GLOBALS["___mysqli_ston"]), E_USER_WARNING); - if ($result && mysql_num_rows($result) > 0) { - $this->row = mysql_fetch_array($result); + if ($result && mysqli_num_rows($result) > 0) { + $this->row = mysqli_fetch_array($result); if ($this->row['in_or_out'] == 1) { $row_count++; @@ -92,17 +92,17 @@ function walk($onBefore = null, $onEveryRow = null, $onAfter = null) { if ($onBefore) $onBefore($this); } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); } } // Get timecard entries. $query = $this->_query($begin_utm_timestamp, $end_utm_timestamp); - $result = mysql_query($query) - or trigger_error('Timecard->walk: no result: ' . mysql_error(), E_USER_WARNING); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query) + or trigger_error('Timecard->walk: no result: ' . mysqli_error($GLOBALS["___mysqli_ston"]), E_USER_WARNING); // Process timecard entries. - while (($this->next_row = mysql_fetch_array($result))) { + while (($this->next_row = mysqli_fetch_array($result))) { $row_count++; $this->end_time = local_timestamp($this->next_row['timestamp']); // normalize timestamp to local time if ($row_count == 1) { @@ -181,7 +181,7 @@ function walk($onBefore = null, $onEveryRow = null, $onAfter = null) { $onAfter($this); } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); return array($row_count, $this->total_hours, $this->overtime_hours, $this->today_hours); } @@ -190,7 +190,7 @@ function walk($onBefore = null, $onEveryRow = null, $onAfter = null) { function _query($begin_utm_timestamp, $end_utm_timestamp) { // Find records on an employee's timecard global $db_prefix, $default_in_or_out; - $q_empfullname = mysql_real_escape_string($this->empfullname); + $q_empfullname = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $this->empfullname); return <<empfullname); + $q_empfullname = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $this->empfullname); return << + diff --git a/punchclock/css/jquery.suggest.css b/punchclock/css/jquery.suggest.css index ebf8480..6dd8f7b 100644 --- a/punchclock/css/jquery.suggest.css +++ b/punchclock/css/jquery.suggest.css @@ -1,31 +1,31 @@ - -.ac_results { - border: 1px solid gray; - background-color: white; - padding: 0; - margin: 0; - list-style: none; - position: absolute; - z-index: 10000; - display: none; - - min-width: 170px; -} - -.ac_results li { - padding: 2px 5px; - white-space: nowrap; - color: #101010; - text-align: left; -} - -.ac_over { - cursor: pointer; - background-color: #F0F0B8; -} - -.ac_match { - text-decoration: underline; - color: black; -} - + +.ac_results { + border: 1px solid gray; + background-color: white; + padding: 0; + margin: 0; + list-style: none; + position: absolute; + z-index: 10000; + display: none; + + min-width: 170px; +} + +.ac_results li { + padding: 2px 5px; + white-space: nowrap; + color: #101010; + text-align: left; +} + +.ac_over { + cursor: pointer; + background-color: #F0F0B8; +} + +.ac_match { + text-decoration: underline; + color: black; +} + diff --git a/punchclock/css/nyroModal.css b/punchclock/css/nyroModal.css index 5d98267..7deaf4f 100644 --- a/punchclock/css/nyroModal.css +++ b/punchclock/css/nyroModal.css @@ -1,119 +1,119 @@ -div#nyroModalFull { - font-size: 12px; - color: #777; -} - -div#nyroModalLoading { - border: 4px solid #777; - width: 150px; - height: 150px; - text-indent: -9999em; - background: #fff url(../images/nyroModal/ajaxLoader.gif) no-repeat; - background-position: center; -} - -div#nyroModalLoading.error { - border: 4px solid #f66; - line-height: 20px; - padding: 20px; - width: 300px; - height: 100px; - text-indent: 0; - background: #fff; -} - -div#nyroModalWrapper { - background: #fff; - border: 4px solid #777; -} - -a#closeBut { - position: absolute; - display: block; - top: -13px; - right: -13px; - width: 12px; - height: 12px; - text-indent: -9999em; - background: url(../images/nyroModal/close.gif) no-repeat; - outline: 0; -} - -h1#nyroModalTitle { - margin: -34px 0px 0px 0px; - padding: 2px 0px 3px 6px; - color: #ddd; - background-color: #748771; -} - -div#nyroModalContent { - overflow: auto; -} - -div.wrapper div#nyroModalContent { - padding: 5px; -} - -div.wrapperImg div#nyroModalContent { - position: relative; - overflow: hidden; - text-align: center; -} - -div.wrapperImg img { - vertical-align: baseline; -} - -div.wrapperImg div#nyroModalContent div { - position: absolute; - bottom: 0; - left: 0; - background: black; - padding: 10px; - margin: 10px; - border: 1px white dotted; - overflow: hidden; - opacity: 0.2; - filter: alpha(opacity=20); -} - -div.wrapperImg div#nyroModalContent div:hover { - opacity: 0.5; - filter: alpha(opacity=50); - cursor: help; -} - -a.nyroModalPrev, a.nyroModalNext { - z-index: 105; - outline: none; - position: absolute; - top: 0; - height: 100%; - width: 40%; - cursor: pointer; - text-indent: -9999em; - background: left 20% no-repeat; - background-image: url(data:image/gif;base64,AAAA); /* Trick IE6 */ -} - -div.wrapperSwf a.nyroModalPrev, div.wrapperSwf a.nyroModalNext, div.wrapper a.nyroModalPrev, div.wrapper a.nyroModalNext { - height: 60%; - width: 20%; -} - -a.nyroModalPrev { - left: 0; -} - -a.nyroModalPrev:hover { - background-image: url(../images/nyroModal/prev.gif); -} - -a.nyroModalNext { - right: 0; - background-position: right 20%; -} - -a.nyroModalNext:hover { - background-image: url(../images/nyroModal/next.gif); -} +div#nyroModalFull { + font-size: 12px; + color: #777; +} + +div#nyroModalLoading { + border: 4px solid #777; + width: 150px; + height: 150px; + text-indent: -9999em; + background: #fff url(../images/nyroModal/ajaxLoader.gif) no-repeat; + background-position: center; +} + +div#nyroModalLoading.error { + border: 4px solid #f66; + line-height: 20px; + padding: 20px; + width: 300px; + height: 100px; + text-indent: 0; + background: #fff; +} + +div#nyroModalWrapper { + background: #fff; + border: 4px solid #777; +} + +a#closeBut { + position: absolute; + display: block; + top: -13px; + right: -13px; + width: 12px; + height: 12px; + text-indent: -9999em; + background: url(../images/nyroModal/close.gif) no-repeat; + outline: 0; +} + +h1#nyroModalTitle { + margin: -34px 0px 0px 0px; + padding: 2px 0px 3px 6px; + color: #ddd; + background-color: #748771; +} + +div#nyroModalContent { + overflow: auto; +} + +div.wrapper div#nyroModalContent { + padding: 5px; +} + +div.wrapperImg div#nyroModalContent { + position: relative; + overflow: hidden; + text-align: center; +} + +div.wrapperImg img { + vertical-align: baseline; +} + +div.wrapperImg div#nyroModalContent div { + position: absolute; + bottom: 0; + left: 0; + background: black; + padding: 10px; + margin: 10px; + border: 1px white dotted; + overflow: hidden; + opacity: 0.2; + filter: alpha(opacity=20); +} + +div.wrapperImg div#nyroModalContent div:hover { + opacity: 0.5; + filter: alpha(opacity=50); + cursor: help; +} + +a.nyroModalPrev, a.nyroModalNext { + z-index: 105; + outline: none; + position: absolute; + top: 0; + height: 100%; + width: 40%; + cursor: pointer; + text-indent: -9999em; + background: left 20% no-repeat; + background-image: url(data:image/gif;base64,AAAA); /* Trick IE6 */ +} + +div.wrapperSwf a.nyroModalPrev, div.wrapperSwf a.nyroModalNext, div.wrapper a.nyroModalPrev, div.wrapper a.nyroModalNext { + height: 60%; + width: 20%; +} + +a.nyroModalPrev { + left: 0; +} + +a.nyroModalPrev:hover { + background-image: url(../images/nyroModal/prev.gif); +} + +a.nyroModalNext { + right: 0; + background-position: right 20%; +} + +a.nyroModalNext:hover { + background-image: url(../images/nyroModal/next.gif); +} diff --git a/punchclock/css/punchclock.css b/punchclock/css/punchclock.css index 7e529a9..418510f 100644 --- a/punchclock/css/punchclock.css +++ b/punchclock/css/punchclock.css @@ -1,435 +1,435 @@ -/* - * Punchclock styles - */ - -body, td, th { - font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; - font-size: 11px; -} - -body { - color: #222; - background-color: #FFF; - margin: 0px; - padding: 0px; -} - -a:hover { - font-size: inherit; - text-decoration: underline; -} - -img { - border: 0; -} - -.page { - margin: 8px; - border: solid #748771 1px; - background-color: #FCFCFF; - color: #222; -} - -.content { - max-width: 760px; - margin: 0px auto; -} - -.footer { - height: 24px; - clear: both; -} - -.message { - color: #090; - margin: 16px 16px 4px; - font-size: 13px; - padding: 6px 6px 6px 30px; - border: solid #BBB 1px; - background: url(../../images/icons/accept.png) no-repeat 5px 6px; -} - -.error { - color: #F00; - margin: 16px 16px 4px; - font-size: 13px; - padding: 6px 6px 6px 30px; - border: solid #BBB 1px; - background: url(../../images/icons/cancel.png) no-repeat 5px 6px; -} - -tr.odd { - background-color: #EFEFEF; -} - -tr.even { - background-color: #FBFBFB; -} - -table.emp_list { - margin-top: 12px; -} - -table.emp_list thead { - line-height: 28px; - background-color: inherit; - margin-bottom: 12px; -} - -table.emp_list thead th { - font-size: 11px; - padding: 2px 10px 0px; - white-space: nowrap; - border-bottom: solid #CCC 1px; -} - -table.emp_list thead th a { - color: #27408b; -} - -table.emp_list tbody { - overflow-y: auto; - overflow-x: hidden; -} - -/* scroll the body of the table */ -table.emp_list tbody tr:hover { - color: #000; - background-color: #FFD; -} - -table.emp_list tbody td { - font-size: 11px; - padding: 8px 10px; - cursor: pointer; - white-space: nowrap; - overflow: hidden; -} - -table.emp_list tbody td a { - color: #27408b; - text-decoration: none; -} - -table.emp_list tbody td a:hover { - text-decoration: underline; - color: #853d27; -} - -.export { - max-width: 600px; -} - -.export h2 { - margin: 2px 6px; - text-align: center; -} - -.export h3 { - margin: 18px 6px 6px; - padding: 0; -} - -.export h4 { - margin: 6px 6px; - padding: 0; -} - -.export p { - margin: 3px 6px; - padding: 0; - font-size: 11px; -} - -.export .select-buttons { - margin-top: 18px; -} - -.export .select-button { - margin-right: 12px; - padding: 6px; - border: solid inherit 1px; -} - -table.export_items { -} - -table.export_items thead { - line-height: 28px; - background-color: inherit; - margin-bottom: 12px; -} - -table.export_items thead th { - font-size: 11px; - padding: 2px 10px 0px; - white-space: nowrap; - border-bottom: solid #CCC 1px; - cursor: default; -} - -table.export_items thead th a { - color: #27408b; -} - -table.export_items tbody { - overflow-y: auto; - overflow-x: hidden; -} - -/* scroll the body of the table */ -table.export_items tbody tr:hover { - color: #000; - background-color: #FFD; -} - -table.export_items tbody td { - font-size: 11px; - padding: 8px 10px; - cursor: default; - white-space: nowrap; - overflow: hidden; -} - -table.export_items tbody td a { - color: #27408b; - text-decoration: none; -} - -table.export_items tbody td a:hover { - text-decoration: underline; - color: #853d27; -} - -#sorttable_sortfwdind { - font-size: 15px; - font-weight: normal; -} - -#sorttable_sortrevind { - font-size: 15px; - font-weight: normal; -} - -.options { - margin: 12px 0px 0px 6px; -} - -.options a:link, .options a:active, .options a:visited { - text-decoration: none; - padding-left: 13px; - background: url(../images/right.gif) left center no-repeat; -} - -.options a.open:link, .options a.open:active, .options a.open:visited { - padding-left: 13px; - background: url(../images/down.gif) left center no-repeat; -} - -#options { - border: solid #CCC 1px; - padding: 6px; -} - -#timeclock { - clear: both; - text-align: center; - font-size: 20px; - margin-top: 10px; -} - -#message { - font-size: 11px; - text-align: center; - color: #000; - background-color: #FC0; - width: 27ex; - padding: 1px; - margin: 0px auto; - z-index: 1; - visibility: visible; -} - -#entry #message { - visibility: hidden; -} - -#office { - float: left; - width: 33%; - font-size: 12px; - font-weight: normal; - margin: 0; - padding: 3px; -} - -#entry_form { - margin: 16px; -} - -#employee_entry_form { - clear: both; - max-width: 450px; - margin: 16px; -} - -#password_entry_form { - clear: both; - margin: 16px; -} - -#password_change_form { - margin: 16px; -} - -#password_change_form p { - margin: 3px 16px 3px 32px; -} - -#select_offices { - float: left; -} - -#select_groups { - float: right; -} - -#printer_friendly { - font-size: 11px; - margin-left: 6px; -} - -.punch-in, .punch-out { - font-size: 14px; - font-weight: normal; - float: left; -} - -#entry .punch-in, #entry .punch-out { - float: none; -} - -/* for mobile safari */ -.hours-summary { - float: right; - margin: 10px 12px 0px 0px; -} - -.hours-summary th { - text-align: right; -} - -.hours-summary td { - text-align: right; -} - -.refresh-link { - float: right; - margin-right: 10px; - font-weight: normal; -} - -.buttons { - float: left; - margin-top: 30px; - margin-left: 10px; -} - -#nyroModalWrapper .buttons { - margin-left: 0; -} - -.timecard { - max-width: 600px; -} - -.timecard h2 { - margin: 2px 6px; - text-align: center; -} - -.timecard h3 { - margin: 6px 6px; - padding: 0; -} - -.timecard h4 { - margin: 6px 6px; - padding: 0; -} - -.timecard p { - margin: 3px 6px; - padding: 0; - font-size: 11px; -} - -.timecard_list { - margin: 12px 0px; -} - -.timecard_list td { - padding: 4px 6px; -} - -.timecard_list th { - padding: 4px 6px; - border-bottom: solid #CCC 1px; -} - -.timecard_list .hrs { - border-left: solid #CCC 1px; -} - -.timecard_list .ovt { -} - -.timecard_list .total { -} - -.timecard_list .notes { - border-left: solid #CCC 1px; - min-width: 16ex; -} - -.timecard_list .total_row td { - border-top: solid #CCC 1px; - font-weight: bold; -} - -.timecard_list .total_row .hrs { - border-left: solid #FFF 1px; - border-top: solid #CCC 1px; -} - -.timecard_list .total_row .ovt { - border-top: solid #CCC 1px; -} - -.timecard_list .total_row .total { - border-top: solid #CCC 1px; -} - -.timecard_list .total_row .notes { - border-left: solid #FFF 1px; -} - -.nav-buttons { - float: right; - margin-top: 4px; - margin-right: 4px; -} - -.nav-buttons a { - margin: 0px; - padding: 0px; -} - -.totals { - margin-top: 9px; -} - -.tip { - margin-left: 12px; - color: #999; -} +/* + * Punchclock styles + */ + +body, td, th { + font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; +} + +body { + color: #222; + background-color: #FFF; + margin: 0px; + padding: 0px; +} + +a:hover { + font-size: inherit; + text-decoration: underline; +} + +img { + border: 0; +} + +.page { + margin: 8px; + border: solid #748771 1px; + background-color: #FCFCFF; + color: #222; +} + +.content { + max-width: 760px; + margin: 0px auto; +} + +.footer { + height: 24px; + clear: both; +} + +.message { + color: #090; + margin: 16px 16px 4px; + font-size: 13px; + padding: 6px 6px 6px 30px; + border: solid #BBB 1px; + background: url(../../images/icons/accept.png) no-repeat 5px 6px; +} + +.error { + color: #F00; + margin: 16px 16px 4px; + font-size: 13px; + padding: 6px 6px 6px 30px; + border: solid #BBB 1px; + background: url(../../images/icons/cancel.png) no-repeat 5px 6px; +} + +tr.odd { + background-color: #EFEFEF; +} + +tr.even { + background-color: #FBFBFB; +} + +table.emp_list { + margin-top: 12px; +} + +table.emp_list thead { + line-height: 28px; + background-color: inherit; + margin-bottom: 12px; +} + +table.emp_list thead th { + font-size: 11px; + padding: 2px 10px 0px; + white-space: nowrap; + border-bottom: solid #CCC 1px; +} + +table.emp_list thead th a { + color: #27408b; +} + +table.emp_list tbody { + overflow-y: auto; + overflow-x: hidden; +} + +/* scroll the body of the table */ +table.emp_list tbody tr:hover { + color: #000; + background-color: #FFD; +} + +table.emp_list tbody td { + font-size: 11px; + padding: 8px 10px; + cursor: pointer; + white-space: nowrap; + overflow: hidden; +} + +table.emp_list tbody td a { + color: #27408b; + text-decoration: none; +} + +table.emp_list tbody td a:hover { + text-decoration: underline; + color: #853d27; +} + +.export { + max-width: 600px; +} + +.export h2 { + margin: 2px 6px; + text-align: center; +} + +.export h3 { + margin: 18px 6px 6px; + padding: 0; +} + +.export h4 { + margin: 6px 6px; + padding: 0; +} + +.export p { + margin: 3px 6px; + padding: 0; + font-size: 11px; +} + +.export .select-buttons { + margin-top: 18px; +} + +.export .select-button { + margin-right: 12px; + padding: 6px; + border: solid inherit 1px; +} + +table.export_items { +} + +table.export_items thead { + line-height: 28px; + background-color: inherit; + margin-bottom: 12px; +} + +table.export_items thead th { + font-size: 11px; + padding: 2px 10px 0px; + white-space: nowrap; + border-bottom: solid #CCC 1px; + cursor: default; +} + +table.export_items thead th a { + color: #27408b; +} + +table.export_items tbody { + overflow-y: auto; + overflow-x: hidden; +} + +/* scroll the body of the table */ +table.export_items tbody tr:hover { + color: #000; + background-color: #FFD; +} + +table.export_items tbody td { + font-size: 11px; + padding: 8px 10px; + cursor: default; + white-space: nowrap; + overflow: hidden; +} + +table.export_items tbody td a { + color: #27408b; + text-decoration: none; +} + +table.export_items tbody td a:hover { + text-decoration: underline; + color: #853d27; +} + +#sorttable_sortfwdind { + font-size: 15px; + font-weight: normal; +} + +#sorttable_sortrevind { + font-size: 15px; + font-weight: normal; +} + +.options { + margin: 12px 0px 0px 6px; +} + +.options a:link, .options a:active, .options a:visited { + text-decoration: none; + padding-left: 13px; + background: url(../images/right.gif) left center no-repeat; +} + +.options a.open:link, .options a.open:active, .options a.open:visited { + padding-left: 13px; + background: url(../images/down.gif) left center no-repeat; +} + +#options { + border: solid #CCC 1px; + padding: 6px; +} + +#timeclock { + clear: both; + text-align: center; + font-size: 20px; + margin-top: 10px; +} + +#message { + font-size: 11px; + text-align: center; + color: #000; + background-color: #FC0; + width: 27ex; + padding: 1px; + margin: 0px auto; + z-index: 1; + visibility: visible; +} + +#entry #message { + visibility: hidden; +} + +#office { + float: left; + width: 33%; + font-size: 12px; + font-weight: normal; + margin: 0; + padding: 3px; +} + +#entry_form { + margin: 16px; +} + +#employee_entry_form { + clear: both; + max-width: 450px; + margin: 16px; +} + +#password_entry_form { + clear: both; + margin: 16px; +} + +#password_change_form { + margin: 16px; +} + +#password_change_form p { + margin: 3px 16px 3px 32px; +} + +#select_offices { + float: left; +} + +#select_groups { + float: right; +} + +#printer_friendly { + font-size: 11px; + margin-left: 6px; +} + +.punch-in, .punch-out { + font-size: 14px; + font-weight: normal; + float: left; +} + +#entry .punch-in, #entry .punch-out { + float: none; +} + +/* for mobile safari */ +.hours-summary { + float: right; + margin: 10px 12px 0px 0px; +} + +.hours-summary th { + text-align: right; +} + +.hours-summary td { + text-align: right; +} + +.refresh-link { + float: right; + margin-right: 10px; + font-weight: normal; +} + +.buttons { + float: left; + margin-top: 30px; + margin-left: 10px; +} + +#nyroModalWrapper .buttons { + margin-left: 0; +} + +.timecard { + max-width: 600px; +} + +.timecard h2 { + margin: 2px 6px; + text-align: center; +} + +.timecard h3 { + margin: 6px 6px; + padding: 0; +} + +.timecard h4 { + margin: 6px 6px; + padding: 0; +} + +.timecard p { + margin: 3px 6px; + padding: 0; + font-size: 11px; +} + +.timecard_list { + margin: 12px 0px; +} + +.timecard_list td { + padding: 4px 6px; +} + +.timecard_list th { + padding: 4px 6px; + border-bottom: solid #CCC 1px; +} + +.timecard_list .hrs { + border-left: solid #CCC 1px; +} + +.timecard_list .ovt { +} + +.timecard_list .total { +} + +.timecard_list .notes { + border-left: solid #CCC 1px; + min-width: 16ex; +} + +.timecard_list .total_row td { + border-top: solid #CCC 1px; + font-weight: bold; +} + +.timecard_list .total_row .hrs { + border-left: solid #FFF 1px; + border-top: solid #CCC 1px; +} + +.timecard_list .total_row .ovt { + border-top: solid #CCC 1px; +} + +.timecard_list .total_row .total { + border-top: solid #CCC 1px; +} + +.timecard_list .total_row .notes { + border-left: solid #FFF 1px; +} + +.nav-buttons { + float: right; + margin-top: 4px; + margin-right: 4px; +} + +.nav-buttons a { + margin: 0px; + padding: 0px; +} + +.totals { + margin-top: 9px; +} + +.tip { + margin-left: 12px; + color: #999; +} diff --git a/punchclock/entry.ajax.php b/punchclock/entry.ajax.php index e239fae..ec7f827 100644 --- a/punchclock/entry.ajax.php +++ b/punchclock/entry.ajax.php @@ -13,12 +13,12 @@ require_once 'lib.common.php'; require_once 'lib.timecard.php'; require_once "$TIMECLOCK_PATH/functions.php"; -turn_off_magic_quotes(); +//turn_off_magic_quotes(); // Connect to db. -$db = mysql_connect($db_hostname, $db_username, $db_password) +$db = ($GLOBALS["___mysqli_ston"] = mysqli_connect($db_hostname, $db_username, $db_password)) or die("Could not connect to the database."); -mysql_select_db($db_name); +mysqli_select_db($GLOBALS["___mysqli_ston"], $db_name); // Parse arguments. $emp = isset($_GET['emp']) ? $_GET['emp'] : null; @@ -49,19 +49,19 @@ // Post employee time. $inout = $_POST['inout']; - $q_inout = mysql_real_escape_string($inout); + $q_inout = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $inout); $h_inout = htmlentities($inout); $notes = isset($_POST['notes']) ? $_POST['notes'] : ''; - $q_notes = mysql_real_escape_string($notes); + $q_notes = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $notes); $h_notes = htmlentities($notes); - $q_empfullname = mysql_real_escape_string($empfullname); + $q_empfullname = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $empfullname); // Validate and get inout display color. $query = "select color from " . $db_prefix . "punchlist where punchitems = '$q_inout'"; - $punchlist_result = mysql_query($query); - $inout_color = mysql_result($punchlist_result, 0, 0); + $punchlist_result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + $inout_color = mysqli_result($punchlist_result, 0, 0); if (!$inout_color) { #print error_msg("In/Out Status is not in the database."); trigger_error('In/Out Status is not in the database.', E_USER_WARNING); @@ -83,11 +83,11 @@ where empfullname = '$q_empfullname' End_Of_SQL; - if (mysql_query($insert_query)) { - mysql_query($update_query) - or trigger_error('punchclock: cannot update tstamp in employee record. ' . mysql_error(), E_USER_WARNING); + if (mysqli_query($GLOBALS["___mysqli_ston"], $insert_query)) { + mysqli_query($GLOBALS["___mysqli_ston"], $update_query) + or trigger_error('punchclock: cannot update tstamp in employee record. ' . mysqli_error($GLOBALS["___mysqli_ston"]), E_USER_WARNING); } else { - trigger_error('punchclock: cannot insert timestamp into info record. ' . mysql_error(), E_USER_WARNING); + trigger_error('punchclock: cannot insert timestamp into info record. ' . mysqli_error($GLOBALS["___mysqli_ston"]), E_USER_WARNING); } // Update display line on punchclock list and close form. @@ -258,8 +258,8 @@ // query to produce buttons for punchlist items // $query = "select punchitems,color,in_or_out from " . $db_prefix . "punchlist order by in_or_out desc, color, punchitems"; - $punchlist_result = mysql_query($query); - while ($row = mysql_fetch_array($punchlist_result)) { + $punchlist_result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($punchlist_result)) { $punchclass = $row['in_or_out'] ? 'punch-in' : 'punch-out'; ## Note: nyroModel plays with submit buttons so the following does not work. ## The value of the submit button is not passed to the server. As a workaround @@ -267,7 +267,7 @@ ##echo "\n"; echo "\n"; } - mysql_free_result($punchlist_result); + ((mysqli_free_result($punchlist_result) || (is_object($punchlist_result) && (get_class($punchlist_result) == "mysqli_result"))) ? true : false); ?> diff --git a/punchclock/entry.php b/punchclock/entry.php index 5612268..2632e00 100644 --- a/punchclock/entry.php +++ b/punchclock/entry.php @@ -66,19 +66,19 @@ // Post employee time. $inout = $_POST['inout']; - $q_inout = mysql_real_escape_string($inout); + $q_inout = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $inout); $h_inout = htmlentities($inout); $notes = isset($_POST['notes']) ? $_POST['notes'] : ''; - $q_notes = mysql_real_escape_string($notes); + $q_notes = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $notes); $h_notes = htmlentities($notes); - $q_empfullname = mysql_real_escape_string($empfullname); + $q_empfullname = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $empfullname); // Validate and get inout display color. $query = "select color from " . $db_prefix . "punchlist where punchitems = '$q_inout'"; - $punchlist_result = mysql_query($query); - $inout_color = mysql_result($punchlist_result, 0, 0); + $punchlist_result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + $inout_color = mysqli_result($punchlist_result, 0, 0); if (!$inout_color) { #print error_msg("In/Out Status is not in the database."); trigger_error('In/Out Status is not in the database.', E_USER_WARNING); @@ -101,11 +101,11 @@ where empfullname = '$q_empfullname' End_Of_SQL; - if (mysql_query($insert_query)) { - mysql_query($update_query) - or trigger_error('entry: cannot update tstamp in employee record. ' . mysql_error(), E_USER_WARNING); + if (mysqli_query($GLOBALS["___mysqli_ston"], $insert_query)) { + mysqli_query($GLOBALS["___mysqli_ston"], $update_query) + or trigger_error('entry: cannot update tstamp in employee record. ' . mysqli_error($GLOBALS["___mysqli_ston"]), E_USER_WARNING); } else { - trigger_error('entry: cannot insert timestamp into info record. ' . mysql_error(), E_USER_WARNING); + trigger_error('entry: cannot insert timestamp into info record. ' . mysqli_error($GLOBALS["___mysqli_ston"]), E_USER_WARNING); } # Uncomment next to display success message. The entry status display also shows last punch-in/out. @@ -212,12 +212,12 @@ // query to produce buttons for the punchlist items // $query = "select punchitems,color,in_or_out from " . $db_prefix . "punchlist order by in_or_out desc, color, punchitems"; - $punchlist_result = mysql_query($query); - while ($row = mysql_fetch_array($punchlist_result)) { + $punchlist_result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($punchlist_result)) { $punchclass = $row['in_or_out'] ? 'punch-in' : 'punch-out'; echo "\n"; } - mysql_free_result($punchlist_result); + ((mysqli_free_result($punchlist_result) || (is_object($punchlist_result) && (get_class($punchlist_result) == "mysqli_result"))) ? true : false); ?> diff --git a/punchclock/entry_status.php b/punchclock/entry_status.php index 33391c7..bd4f989 100644 --- a/punchclock/entry_status.php +++ b/punchclock/entry_status.php @@ -1,61 +1,61 @@ - - - - - - - - - - - - - - - - - - - - -
In/OutTimeDateHrsNote
+ + + + + + + + + + + + + + + + + + + + +
In/OutTimeDateHrsNote
diff --git a/punchclock/export.php b/punchclock/export.php index ef778ea..32467be 100644 --- a/punchclock/export.php +++ b/punchclock/export.php @@ -198,13 +198,13 @@ $office_name = isset($_POST['office_name']) ? $_POST['office_name'] : null; // Program options. -$c_reg_ot = bool($_POST['c_reg_ot']); -$c_inout = bool($_POST['c_inout']); -$c_date = bool($_POST['c_date']); -$c_employee = bool($_POST['c_employee']); -$c_name = bool($_POST['c_name']); -$c_group = bool($_POST['c_group']); -$c_office = bool($_POST['c_office']); +$c_reg_ot = isset($_POST['c_reg_ot']) ? bool($_POST['c_reg_ot']) : null; +$c_inout = isset($_POST['c_inout']) ? bool($_POST['c_inout']) : null; +$c_date = isset($_POST['c_date']) ? bool($_POST['c_date']) : null; +$c_employee = isset($_POST['c_employee']) ? bool($_POST['c_employee']) : null; +$c_name = isset($_POST['c_name']) ? bool($_POST['c_name']) : null; +$c_group = isset($_POST['c_group']) ? bool($_POST['c_group']) : null; +$c_office = isset($_POST['c_office']) ? bool($_POST['c_office']) : null; //////////////////////////////////////// $PAGE_TITLE = "Export - $title"; diff --git a/punchclock/export_display.php b/punchclock/export_display.php index d71ae03..bb107f6 100644 --- a/punchclock/export_display.php +++ b/punchclock/export_display.php @@ -17,9 +17,9 @@ $begin_utm_timestamp = utm_timestamp($begin_local_timestamp); $end_utm_timestamp = utm_timestamp($end_local_timestamp); -$employee_clause = $user_name == 'All' ? '' : " and {$db_prefix}employees.empfullname = '" . mysql_real_escape_string($user_name) . "'\n"; -$office_clause = $office_name == 'All' ? '' : " and {$db_prefix}employees.office = '" . mysql_real_escape_string($office_name) . "'\n"; -$groups_clause = $group_name == 'All' ? '' : " and {$db_prefix}employees.groups = '" . mysql_real_escape_string($group_name) . "'\n"; +$employee_clause = $user_name == 'All' ? '' : " and {$db_prefix}employees.empfullname = '" . mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $user_name) . "'\n"; +$office_clause = $office_name == 'All' ? '' : " and {$db_prefix}employees.office = '" . mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $office_name) . "'\n"; +$groups_clause = $group_name == 'All' ? '' : " and {$db_prefix}employees.groups = '" . mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $group_name) . "'\n"; // Select employees whose timecards need to be scanned. $query = <<walk(null, record_hours, null); + list($timecard_row_count, $total_hours, $overtime_hours) = $tc->walk(null, 'record_hours', null); $begin = $end; } @@ -83,8 +83,8 @@ {$group_by_clause}{$order_by_clause} End_Of_SQL; -$result = mysql_query($query) -or trigger_error("export_display: Cannot select hours. " . mysql_error(), E_USER_WARNING); +$result = mysqli_query($GLOBALS["___mysqli_ston"], $query) +or trigger_error("export_display: Cannot select hours. " . mysqli_error($GLOBALS["___mysqli_ston"]), E_USER_WARNING); // Print export page header. $begin_date = date('l F j, Y', $begin_local_timestamp); @@ -140,7 +140,7 @@ // Build export table html. $row_count = 0; -while ($row = mysql_fetch_array($result)) { +while ($row = mysqli_fetch_array($result)) { if ($row_count == 0) { // Table header @@ -184,11 +184,23 @@ $hours = sprintf("%01.02f", $row['sum_hours']); $reg_ot = $row['reg_ot'] == 'O' ? 'OT' : 'Reg'; - $h_inout = htmlentities($row['inout']); - $h_color = $row['color'] ? htmlentities($row['color']) : 'inherit'; + if (isset($row['inout'])) { + $h_inout = htmlentities($row['inout']); + } else { + $h_inout = ''; + } + if (isset($row['color'])) { + $h_color = $row['color'] ? htmlentities($row['color']) : 'inherit'; + } else { + $h_color = 'inherit'; + } $date = $row['hours_date']; $h_empfullname = htmlentities($row['empfullname']); - $h_name = htmlentities($row['displayname']); + if (isset($row['displayname'])) { + $h_name = htmlentities($row['displayname']); + } else { + $h_name = ''; + } $h_groups = htmlentities($row['groups']); $h_office = htmlentities($row['office']); @@ -236,7 +248,7 @@ End_Of_HTML; -mysql_free_result($result); +((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); //////////////////////////////////////// function setup_record_hours() { @@ -254,9 +266,9 @@ function setup_record_hours() { `office` varchar(50) ) End_Of_SQL; - mysql_query("DROP TABLE IF EXISTS t_computed_hours"); - mysql_query($sql) - or trigger_error("export_display: Cannot create temporary table t_computed_hours. " . mysql_error(), E_USER_WARNING); + mysqli_query($GLOBALS["___mysqli_ston"], "DROP TABLE IF EXISTS t_computed_hours"); + mysqli_query($GLOBALS["___mysqli_ston"], $sql) + or trigger_error("export_display: Cannot create temporary table t_computed_hours. " . mysqli_error($GLOBALS["___mysqli_ston"]), E_USER_WARNING); } function record_hours($tc) { @@ -288,38 +300,38 @@ function record_hours($tc) { if (round($hours, 3) > 0) { $reg_ot = 'R'; - $q_inout = mysql_real_escape_string($tc->row['inout']); - $q_color = mysql_real_escape_string($tc->row['color']); - $q_employee = mysql_real_escape_string($tc->row['fullname']); - $q_name = mysql_real_escape_string($tc->row['displayname']); - $q_group = mysql_real_escape_string($tc->row['groups']); - $q_office = mysql_real_escape_string($tc->row['office']); + $q_inout = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $tc->row['inout']); + $q_color = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $tc->row['color']); + $q_employee = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $tc->row['fullname']); + $q_name = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $tc->row['displayname']); + $q_group = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $tc->row['groups']); + $q_office = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $tc->row['office']); #$date = date('Y-m-d H:i',$start_time); ## debug $date = date('Y-m-d', $start_time); $sql = << 0) { $reg_ot = 'O'; - $q_inout = mysql_real_escape_string($tc->row['inout']); - $q_color = mysql_real_escape_string($tc->row['color']); - $q_employee = mysql_real_escape_string($tc->row['fullname']); - $q_name = mysql_real_escape_string($tc->row['displayname']); - $q_group = mysql_real_escape_string($tc->row['groups']); - $q_office = mysql_real_escape_string($tc->row['office']); + $q_inout = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $tc->row['inout']); + $q_color = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $tc->row['color']); + $q_employee = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $tc->row['fullname']); + $q_name = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $tc->row['displayname']); + $q_group = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $tc->row['groups']); + $q_office = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $tc->row['office']); #$date = date('Y-m-d H:i',$start_time); ## debug $date = date('Y-m-d', $start_time); $sql = << - - - - - - - + + + + + + + + diff --git a/punchclock/footer_timeclock.php b/punchclock/footer_timeclock.php index 398321d..43cbed0 100644 --- a/punchclock/footer_timeclock.php +++ b/punchclock/footer_timeclock.php @@ -1,10 +1,10 @@ - - + + diff --git a/punchclock/header.php b/punchclock/header.php index 1657d8f..fd4dbf9 100644 --- a/punchclock/header.php +++ b/punchclock/header.php @@ -1,59 +1,59 @@ -\n"; // puts IE6 in quirks mode -?> - - - - - <?php echo $PAGE_TITLE; ?> - - 0) - echo "$PAGE_META\n"; ?> - - - - - - 0) - echo "$PAGE_STYLE\n"; ?> - - - 0) - echo "$PAGE_SCRIPT\n"; ?> - - 0) - echo " id=\"$PAGE_BODY_ID\""; ?>> -
- - - - 0) - echo "$PAGE_CONTENT_HEADER\n"; ?> -
+\n"; // puts IE6 in quirks mode +?> + + + + + <?php echo $PAGE_TITLE; ?> + + 0) + echo "$PAGE_META\n"; ?> + + + + + + 0) + echo "$PAGE_STYLE\n"; ?> + + + 0) + echo "$PAGE_SCRIPT\n"; ?> + + 0) + echo " id=\"$PAGE_BODY_ID\""; ?>> +
+ + + + 0) + echo "$PAGE_CONTENT_HEADER\n"; ?> +
diff --git a/punchclock/header_reports.php b/punchclock/header_reports.php index 09faea8..3f5d799 100644 --- a/punchclock/header_reports.php +++ b/punchclock/header_reports.php @@ -1,28 +1,28 @@ -)/', "$1\n$PAGE_TITLE", $header); - -print $header; -?> +)/', "$1\n$PAGE_TITLE", $header); + +print $header; +?> diff --git a/punchclock/header_timeclock.php b/punchclock/header_timeclock.php index 1a86621..f371980 100644 --- a/punchclock/header_timeclock.php +++ b/punchclock/header_timeclock.php @@ -1,23 +1,23 @@ - + diff --git a/punchclock/index.php b/punchclock/index.php index 45aaa50..af9a588 100644 --- a/punchclock/index.php +++ b/punchclock/index.php @@ -1,9 +1,9 @@ - + diff --git a/punchclock/lib.common.php b/punchclock/lib.common.php index 3d850ed..06135ea 100644 --- a/punchclock/lib.common.php +++ b/punchclock/lib.common.php @@ -5,6 +5,19 @@ require_once 'config.inc.php'; +//////////////////////////////////////// +function mysqli_result($res,$row=0,$col=0){ + $numrows = mysqli_num_rows($res); + if ($numrows && $row <= ($numrows-1) && $row >=0){ + mysqli_data_seek($res,$row); + $resrow = (is_numeric($col)) ? mysqli_fetch_row($res) : mysqli_fetch_assoc($res); + if (isset($resrow[$col])){ + return $resrow[$col]; + } + } + return false; +} + //////////////////////////////////////// function make_id($empfullname) { // Make an DOM ID string from the employee id @@ -22,19 +35,19 @@ function lookup_employee($empfullname) { // Return valid empfullname or null global $db_prefix; $name = null; - $q_empfullname = mysql_real_escape_string($empfullname); - $result = mysql_query("SELECT empfullname FROM {$db_prefix}employees WHERE empfullname = '$q_empfullname'"); - if (!$result || mysql_num_rows($result) == 0) { + $q_empfullname = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $empfullname); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SELECT empfullname FROM {$db_prefix}employees WHERE empfullname = '$q_empfullname'"); + if (!$result || mysqli_num_rows($result) == 0) { // Check if displayname was entered. - $q_empfullname = mysql_real_escape_string(strtolower($empfullname)); - $result = mysql_query("SELECT empfullname FROM {$db_prefix}employees WHERE lower(displayname) = '$q_empfullname'") - or trigger_error('lookup_employee: no result: ' . mysql_error(), E_USER_WARNING); + $q_empfullname = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], strtolower($empfullname)); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SELECT empfullname FROM {$db_prefix}employees WHERE lower(displayname) = '$q_empfullname'") + or trigger_error('lookup_employee: no result: ' . mysqli_error($GLOBALS["___mysqli_ston"]), E_USER_WARNING); } - if ($result && mysql_num_rows($result) == 1) { - $name = mysql_result($result, 0, 0); + if ($result && mysqli_num_rows($result) == 1) { + $name = mysqli_result($result, 0, 0); } if ($result) - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); return $name; } @@ -42,15 +55,15 @@ function lookup_employee($empfullname) { //////////////////////////////////////// function get_employee_name($empfullname) { global $db_prefix; - $q_empfullname = mysql_real_escape_string($empfullname); - $result = mysql_query("SELECT displayname FROM {$db_prefix}employees WHERE empfullname = '$q_empfullname'"); + $q_empfullname = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $empfullname); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SELECT displayname FROM {$db_prefix}employees WHERE empfullname = '$q_empfullname'"); if (!$result) { - trigger_error('get_employee_name: no result: ' . mysql_error(), E_USER_WARNING); + trigger_error('get_employee_name: no result: ' . mysqli_error($GLOBALS["___mysqli_ston"]), E_USER_WARNING); return false; } - $name = mysql_result($result, 0, 0); - mysql_free_result($result); + $name = mysqli_result($result, 0, 0); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); return $name; } @@ -58,15 +71,15 @@ function get_employee_name($empfullname) { //////////////////////////////////////// function get_employee_password($empfullname) { global $db_prefix; - $q_empfullname = mysql_real_escape_string($empfullname); - $result = mysql_query("SELECT employee_passwd FROM {$db_prefix}employees WHERE empfullname = '$q_empfullname'"); + $q_empfullname = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $empfullname); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SELECT employee_passwd FROM {$db_prefix}employees WHERE empfullname = '$q_empfullname'"); if (!$result) { - trigger_error('get_employee_password: no result: ' . mysql_error(), E_USER_WARNING); + trigger_error('get_employee_password: no result: ' . mysqli_error($GLOBALS["___mysqli_ston"]), E_USER_WARNING); return false; } - $password = mysql_result($result, 0, 0); - mysql_free_result($result); + $password = mysqli_result($result, 0, 0); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); return $password; } @@ -86,15 +99,15 @@ function is_valid_password($empfullname, $password) { function save_employee_password($empfullname, $new_password) { global $db_prefix; $password = crypt($new_password, 'xy'); - $q_empfullname = mysql_real_escape_string($empfullname); - $q_password = mysql_real_escape_string($password); - $result = mysql_query("UPDATE {$db_prefix}employees SET employee_passwd = '$q_password' WHERE empfullname = '$q_empfullname'"); + $q_empfullname = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $empfullname); + $q_password = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $password); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "UPDATE {$db_prefix}employees SET employee_passwd = '$q_password' WHERE empfullname = '$q_empfullname'"); if (!$result) { - trigger_error('save_employee_password: cannot save new password: ' . mysql_error(), E_USER_WARNING); + trigger_error('save_employee_password: cannot save new password: ' . mysqli_error($GLOBALS["___mysqli_ston"]), E_USER_WARNING); return false; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); return true; } @@ -104,7 +117,7 @@ function get_employee_status($empfullname) { // Get employee's current punch-in/out status and time. // Return array of in/out(1/0), punch code, timestamp, and notes. global $db_prefix; - $q_empfullname = mysql_real_escape_string($empfullname); + $q_empfullname = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $empfullname); $query = << '1' and employees.empfullname = '$q_empfullname' End_Of_SQL; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); if (!$result) { - trigger_error('get_employee_status: no result: ' . mysql_error(), E_USER_WARNING); + trigger_error('get_employee_status: no result: ' . mysqli_error($GLOBALS["___mysqli_ston"]), E_USER_WARNING); return false; } - $row = mysql_fetch_assoc($result); - mysql_free_result($result); + $row = mysqli_fetch_assoc($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); return array($row['in_or_out'], $row['color'], $row['inout'], $row['timestamp'], $row['notes']); } @@ -310,9 +323,9 @@ function turn_off_magic_quotes() { remove_magic_quotes($_POST); remove_magic_quotes($_COOKIE); remove_magic_quotes($_REQUEST); - ini_set('magic_quotes_gpc', 0); + //ini_set('magic_quotes_gpc', 0); } - set_magic_quotes_runtime(0); + //set_magic_quotes_runtime(0); } function remove_magic_quotes(&$array) { diff --git a/punchclock/lib.select.php b/punchclock/lib.select.php index cc972be..9b131be 100644 --- a/punchclock/lib.select.php +++ b/punchclock/lib.select.php @@ -33,8 +33,8 @@ function select_options($arg, $val = null) { return _select_options_arr($arg, $lookup); $html = ''; // initialize return string $db = isset($GLOBALS['db']) ? $GLOBALS['db'] : null; - $result = mysql_query($arg, $db); - while ($row = mysql_fetch_row($result)) { + $result = mysqli_query( $db, $arg); + while ($row = mysqli_fetch_row($result)) { if (count($row) < 2) $row[1] = $row[0]; $selected = isset($lookup[$row[0]]) ? ' selected="selected"' : ''; diff --git a/punchclock/lib.timecard.php b/punchclock/lib.timecard.php index dec50e9..abe5a9a 100644 --- a/punchclock/lib.timecard.php +++ b/punchclock/lib.timecard.php @@ -161,7 +161,7 @@ function print_footer($tc) { // Print timecard. $tc = new Timecard($empfullname, $begin_local_timestamp, $end_local_timestamp); - list($row_count, $total_hours, $overtime_hours, $today_hours) = $tc->walk(print_header, print_row, print_footer); + list($row_count, $total_hours, $overtime_hours, $today_hours) = $tc->walk('print_header', 'print_row', 'print_footer'); if ($row_count <= 0) print error_msg("No records were found."); diff --git a/punchclock/login.php b/punchclock/login.php index 20f5222..0ca3015 100644 --- a/punchclock/login.php +++ b/punchclock/login.php @@ -1,181 +1,181 @@ - -End_Of_HTML; - - $PAGE_SCRIPT = << - -End_Of_HTML; - - include 'header.php'; - if ($msg) - print msg($msg); - if ($error_msg) - print error_msg($error_msg); - print << -
- - - - - - - - - -
   Enter your name -
Employee Name: -  *
 
* required 
- - - -
-
-
- -End_Of_HTML; - - include 'footer.php'; - exit; -} - -//////////////////////////////////////// -if ($use_passwd == 'yes') { - $authenticated = isset($_SESSION['authenticated']) ? ($_SESSION['authenticated'] == $empfullname) : false; - - if ((!$authenticated) && (isset($_SESSION['time_admin_valid_user']) || isset($_SESSION['valid_user']))) { - // Allow time administrators and system administrators to bypass the password screen. - $_SESSION['authenticated'] = $empfullname; - $authenticated = true; - } - - if (!$authenticated && $password) { - - // Validate password - if (is_valid_password($empfullname, $password)) { - $_SESSION['authenticated'] = $empfullname; - $authenticated = true; - } else { - $error_msg .= "Password is incorrect. Please try again.\n"; - } - } - - if (!$authenticated) { - $u_empfullname = rawurlencode($empfullname); - $h_empfullname = htmlentities($empfullname); - $h_name_header = $show_display_name == 'yes' ? htmlentities(get_employee_name($empfullname)) : $h_empfullname; - - // Security: make sure no one is already authenticated before displaying password screen. - unset($_SESSION['authenticated']); - - // Authenticate employee - $PAGE_TITLE = "Login - $title"; - $PAGE_SCRIPT = <<$(function(){ $('form input:first').focus(); }); -End_Of_HTML; - include 'header.php'; - if ($msg) - print msg($msg); - if ($error_msg) - print error_msg($error_msg); - print << -
- - - - - - - - - - - -
   Enter your password -
$h_name_header
Password: -  *
- Forgot your password -    - Change your password
 
* required 
- - - -
- -
-
-End_Of_HTML; - include 'footer.php'; - exit; - } -} - -//////////////////////////////////////// -// Successful login -$_SESSION['authenticated'] = $empfullname; -$return_url = preg_replace('/\bemp(fullname)?=.*?&(.*)$/', '$2', $return_url); // remove possible emp= from url -$return_url .= (preg_match('/[?]/', $return_url) ? '&' : '?') . "emp=" . rawurlencode($empfullname); // add emp= argument to url -exit_next($return_url); -?> + +End_Of_HTML; + + $PAGE_SCRIPT = << + +End_Of_HTML; + + include 'header.php'; + if ($msg) + print msg($msg); + if ($error_msg) + print error_msg($error_msg); + print << +
+ + + + + + + + + +
   Enter your name +
Employee Name: +  *
 
* required 
+ + + +
+
+
+ +End_Of_HTML; + + include 'footer.php'; + exit; +} + +//////////////////////////////////////// +if ($use_passwd == 'yes') { + $authenticated = isset($_SESSION['authenticated']) ? ($_SESSION['authenticated'] == $empfullname) : false; + + if ((!$authenticated) && (isset($_SESSION['time_admin_valid_user']) || isset($_SESSION['valid_user']))) { + // Allow time administrators and system administrators to bypass the password screen. + $_SESSION['authenticated'] = $empfullname; + $authenticated = true; + } + + if (!$authenticated && $password) { + + // Validate password + if (is_valid_password($empfullname, $password)) { + $_SESSION['authenticated'] = $empfullname; + $authenticated = true; + } else { + $error_msg .= "Password is incorrect. Please try again.\n"; + } + } + + if (!$authenticated) { + $u_empfullname = rawurlencode($empfullname); + $h_empfullname = htmlentities($empfullname); + $h_name_header = $show_display_name == 'yes' ? htmlentities(get_employee_name($empfullname)) : $h_empfullname; + + // Security: make sure no one is already authenticated before displaying password screen. + unset($_SESSION['authenticated']); + + // Authenticate employee + $PAGE_TITLE = "Login - $title"; + $PAGE_SCRIPT = <<$(function(){ $('form input:first').focus(); }); +End_Of_HTML; + include 'header.php'; + if ($msg) + print msg($msg); + if ($error_msg) + print error_msg($error_msg); + print << +
+ + + + + + + + + + + +
   Enter your password +
$h_name_header
Password: +  *
+ Forgot your password +    + Change your password
 
* required 
+ + + +
+ +
+
+End_Of_HTML; + include 'footer.php'; + exit; + } +} + +//////////////////////////////////////// +// Successful login +$_SESSION['authenticated'] = $empfullname; +$return_url = preg_replace('/\bemp(fullname)?=.*?&(.*)$/', '$2', $return_url); // remove possible emp= from url +$return_url .= (preg_match('/[?]/', $return_url) ? '&' : '?') . "emp=" . rawurlencode($empfullname); // add emp= argument to url +exit_next($return_url); +?> diff --git a/punchclock/menu.php b/punchclock/menu.php index af5a4a5..06d4895 100644 --- a/punchclock/menu.php +++ b/punchclock/menu.php @@ -34,10 +34,10 @@ Please re-enter and confirm your new password."); diff --git a/punchclock/password.php b/punchclock/password.php index ea8ffd6..1199dbf 100644 --- a/punchclock/password.php +++ b/punchclock/password.php @@ -61,7 +61,7 @@ $_SESSION['login_msg'] = "Your password has been changed.\n"; exit_next($return_url); } else { - print error_msg("Cannot save your new password. " . mysql_error()); + print error_msg("Cannot save your new password. " . mysqli_error($GLOBALS["___mysqli_ston"])); } } else { print error_msg("Your new password and the confirm password do not match.
Please re-enter and confirm your new password."); diff --git a/punchclock/punchclock.php b/punchclock/punchclock.php index 9e36435..52db2d7 100644 --- a/punchclock/punchclock.php +++ b/punchclock/punchclock.php @@ -29,7 +29,7 @@ if (isset($_REQUEST['office'])) { $office = $_REQUEST['office']; $h_office = htmlentities($office); - $q_office = mysql_real_escape_string($office); + $q_office = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $office); $u_office = rawurlencode($office); $display_office = $office ? $office : 'all'; // override config option @@ -39,10 +39,12 @@ if (isset($_REQUEST['group'])) { $group = $_REQUEST['group']; $h_group = htmlentities($group); - $q_group = mysql_real_escape_string($group); + $q_group = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $group); $u_group = rawurlencode($group); $display_group = $group ? $group : 'all'; // override config option +} else { + $group = ''; } if ($punchclock_select_offices == "yes") { diff --git a/punchclock/punchclock_display.php b/punchclock/punchclock_display.php index 8af53cf..2ca698c 100644 --- a/punchclock/punchclock_display.php +++ b/punchclock/punchclock_display.php @@ -13,8 +13,8 @@ $sortdirection = 'asc'; // Construct query -$office_clause = $display_office == 'all' ? '' : " and {$db_prefix}employees.office = '" . mysql_real_escape_string($display_office) . "'\n"; -$groups_clause = $display_group == 'all' ? '' : " and {$db_prefix}employees.groups = '" . mysql_real_escape_string($display_group) . "'\n"; +$office_clause = $display_office == 'all' ? '' : " and {$db_prefix}employees.office = '" . mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $display_office) . "'\n"; +$groups_clause = $display_group == 'all' ? '' : " and {$db_prefix}employees.groups = '" . mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $display_group) . "'\n"; $query = << diff --git a/punchclock/scripts/dragtable.js b/punchclock/scripts/dragtable.js index 9d07b17..fe11994 100644 --- a/punchclock/scripts/dragtable.js +++ b/punchclock/scripts/dragtable.js @@ -1,538 +1,538 @@ -/* - dragtable v1.0 - June 26, 2008 - Dan Vanderkam, http://danvk.org/dragtable/ - http://code.google.com/p/dragtable/ - - Instructions: - - Download this file - - Add to your HTML. - - Add class="draggable" to any table you might like to reorder. - - Drag the headers around to reorder them. - - This is code was based on: - - Stuart Langridge's SortTable (kryogenix.org/code/browser/sorttable) - - Mike Hall's draggable class (http://www.brainjar.com/dhtml/drag/) - - A discussion of permuting table columns on comp.lang.javascript - - Licensed under the MIT license. - */ - -// Here's the notice from Mike Hall's draggable script: -//***************************************************************************** -// Do not remove this notice. -// -// Copyright 2001 by Mike Hall. -// See http://www.brainjar.com for terms of use. -//***************************************************************************** -dragtable = { - // How far should the mouse move before it's considered a drag, not a click? - dragRadius2: 100, - setMinDragDistance: function (x) { - dragtable.dragRadius2 = x * x; - }, - - // How long should cookies persist? (in days) - cookieDays: 365, - setCookieDays: function (x) { - dragtable.cookieDays = x; - }, - - // Determine browser and version. - // TODO: eliminate browser sniffing except where it's really necessary. - Browser: function () { - var ua, s, i; - - this.isIE = false; - this.isNS = false; - this.version = null; - ua = navigator.userAgent; - - s = "MSIE"; - if ((i = ua.indexOf(s)) >= 0) { - this.isIE = true; - this.version = parseFloat(ua.substr(i + s.length)); - return; - } - - s = "Netscape6/"; - if ((i = ua.indexOf(s)) >= 0) { - this.isNS = true; - this.version = parseFloat(ua.substr(i + s.length)); - return; - } - - // Treat any other "Gecko" browser as NS 6.1. - s = "Gecko"; - if ((i = ua.indexOf(s)) >= 0) { - this.isNS = true; - this.version = 6.1; - return; - } - }, - browser: null, - - // Detect all draggable tables and attach handlers to their headers. - init: function () { - // Don't initialize twice - if (arguments.callee.done) return; - arguments.callee.done = true; - if (_dgtimer) clearInterval(_dgtimer); - if (!document.createElement || !document.getElementsByTagName) return; - - dragtable.dragObj.zIndex = 0; - dragtable.browser = new dragtable.Browser(); - forEach(document.getElementsByTagName('table'), function (table) { - if (table.className.search(/\bdraggable\b/) != -1) { - dragtable.makeDraggable(table); - } - }); - }, - - // The thead business is taken straight from sorttable. - makeDraggable: function (table) { - if (table.getElementsByTagName('thead').length == 0) { - the = document.createElement('thead'); - the.appendChild(table.rows[0]); - table.insertBefore(the, table.firstChild); - } - - // Safari doesn't support table.tHead, sigh - if (table.tHead == null) { - table.tHead = table.getElementsByTagName('thead')[0]; - } - - var headers = table.tHead.rows[0].cells; - for (var i = 0; i < headers.length; i++) { - headers[i].onmousedown = dragtable.dragStart; - } - - // Replay reorderings from cookies if there are any. - if (dragtable.cookiesEnabled() && table.id && - table.className.search(/\bforget-ordering\b/) == -1) { - dragtable.replayDrags(table); - } - }, - - // Global object to hold drag information. - dragObj: new Object(), - - // Climb up the DOM until there's a tag that matches. - findUp: function (elt, tag) { - do { - if (elt.nodeName && elt.nodeName.search(tag) != -1) - return elt; - } while (elt = elt.parentNode); - return null; - }, - - // clone an element, copying its style and class. - fullCopy: function (elt, deep) { - var new_elt = elt.cloneNode(deep); - new_elt.className = elt.className; - forEach(elt.style, - function (value, key, object) { - if (value == null) return; - if (typeof(value) == "string" && value.length == 0) return; - - new_elt.style[key] = elt.style[key]; - }); - return new_elt; - }, - - eventPosition: function (event) { - var x, y; - if (dragtable.browser.isIE) { - x = window.event.clientX + document.documentElement.scrollLeft - + document.body.scrollLeft; - y = window.event.clientY + document.documentElement.scrollTop - + document.body.scrollTop; - return {x: x, y: y}; - } - return {x: event.pageX, y: event.pageY}; - }, - - // Determine the position of this element on the page. Many thanks to Magnus - // Kristiansen for help making this work with "position: fixed" elements. - absolutePosition: function (elt, stopAtRelative) { - var ex = 0, ey = 0; - do { - var curStyle = dragtable.browser.isIE ? elt.currentStyle - : window.getComputedStyle(elt, ''); - var supportFixed = !(dragtable.browser.isIE && - dragtable.browser.version < 7); - if (stopAtRelative && curStyle.position == 'relative') { - break; - } else if (supportFixed && curStyle.position == 'fixed') { - // Get the fixed el's offset - ex += parseInt(curStyle.left, 10); - ey += parseInt(curStyle.top, 10); - // Compensate for scrolling - ex += document.body.scrollLeft; - ey += document.body.scrollTop; - // End the loop - break; - } else { - ex += elt.offsetLeft; - ey += elt.offsetTop; - } - } while (elt = elt.offsetParent); - return {x: ex, y: ey}; - }, - - // MouseDown handler -- sets up the appropriate mousemove/mouseup handlers - // and fills in the global dragtable.dragObj object. - dragStart: function (event, id) { - var el; - var x, y; - var dragObj = dragtable.dragObj; - - var browser = dragtable.browser; - if (browser.isIE) - dragObj.origNode = window.event.srcElement; - else - dragObj.origNode = event.target; - var pos = dragtable.eventPosition(event); - - // Drag the entire table cell, not just the element that was clicked. - dragObj.origNode = dragtable.findUp(dragObj.origNode, /T[DH]/); - - // Since a column header can't be dragged directly, duplicate its contents - // in a div and drag that instead. - // TODO: I can assume a tHead... - var table = dragtable.findUp(dragObj.origNode, "TABLE"); - dragObj.table = table; - dragObj.startCol = dragtable.findColumn(table, pos.x); - if (dragObj.startCol == -1) return; - - var new_elt = dragtable.fullCopy(table, false); - new_elt.style.margin = '0'; - - // Copy the entire column - var copySectionColumn = function (sec, col) { - var new_sec = dragtable.fullCopy(sec, false); - forEach(sec.rows, function (row) { - var cell = row.cells[col]; - var new_tr = dragtable.fullCopy(row, false); - if (row.offsetHeight) new_tr.style.height = row.offsetHeight + "px"; - var new_td = dragtable.fullCopy(cell, true); - if (cell.offsetWidth) new_td.style.width = cell.offsetWidth + "px"; - new_tr.appendChild(new_td); - new_sec.appendChild(new_tr); - }); - return new_sec; - }; - - // First the heading - if (table.tHead) { - new_elt.appendChild(copySectionColumn(table.tHead, dragObj.startCol)); - } - forEach(table.tBodies, function (tb) { - new_elt.appendChild(copySectionColumn(tb, dragObj.startCol)); - }); - if (table.tFoot) { - new_elt.appendChild(copySectionColumn(table.tFoot, dragObj.startCol)); - } - - var obj_pos = dragtable.absolutePosition(dragObj.origNode, true); - new_elt.style.position = "absolute"; - new_elt.style.left = obj_pos.x + "px"; - new_elt.style.top = obj_pos.y + "px"; - new_elt.style.width = dragObj.origNode.offsetWidth + "px"; - new_elt.style.height = dragObj.origNode.offsetHeight + "px"; - new_elt.style.opacity = 0.7; - - // Hold off adding the element until this is clearly a drag. - dragObj.addedNode = false; - dragObj.tableContainer = dragObj.table.parentNode || document.body; - dragObj.elNode = new_elt; - - // Save starting positions of cursor and element. - dragObj.cursorStartX = pos.x; - dragObj.cursorStartY = pos.y; - dragObj.elStartLeft = parseInt(dragObj.elNode.style.left, 10); - dragObj.elStartTop = parseInt(dragObj.elNode.style.top, 10); - - if (isNaN(dragObj.elStartLeft)) dragObj.elStartLeft = 0; - if (isNaN(dragObj.elStartTop)) dragObj.elStartTop = 0; - - // Update element's z-index. - dragObj.elNode.style.zIndex = ++dragObj.zIndex; - - // Capture mousemove and mouseup events on the page. - if (browser.isIE) { - document.attachEvent("onmousemove", dragtable.dragMove); - document.attachEvent("onmouseup", dragtable.dragEnd); - window.event.cancelBubble = true; - window.event.returnValue = false; - } else { - document.addEventListener("mousemove", dragtable.dragMove, true); - document.addEventListener("mouseup", dragtable.dragEnd, true); - event.preventDefault(); - } - }, - - // Move the floating column header with the mouse - // TODO: Reorder columns as the mouse moves for a more interactive feel. - dragMove: function (event) { - var x, y; - var dragObj = dragtable.dragObj; - - // Get cursor position with respect to the page. - var pos = dragtable.eventPosition(event); - - var dx = dragObj.cursorStartX - pos.x; - var dy = dragObj.cursorStartY - pos.y; - if (!dragObj.addedNode && dx * dx + dy * dy > dragtable.dragRadius2) { - dragObj.tableContainer.insertBefore(dragObj.elNode, dragObj.table); - dragObj.addedNode = true; - } - - // Move drag element by the same amount the cursor has moved. - var style = dragObj.elNode.style; - style.left = (dragObj.elStartLeft + pos.x - dragObj.cursorStartX) + "px"; - style.top = (dragObj.elStartTop + pos.y - dragObj.cursorStartY) + "px"; - - if (dragtable.browser.isIE) { - window.event.cancelBubble = true; - window.event.returnValue = false; - } else { - event.preventDefault(); - } - }, - - // Stop capturing mousemove and mouseup events. - // Determine which (if any) column we're over and shuffle the table. - dragEnd: function (event) { - if (dragtable.browser.isIE) { - document.detachEvent("onmousemove", dragtable.dragMove); - document.detachEvent("onmouseup", dragtable.dragEnd); - } else { - document.removeEventListener("mousemove", dragtable.dragMove, true); - document.removeEventListener("mouseup", dragtable.dragEnd, true); - } - - // If the floating header wasn't added, the mouse didn't move far enough. - var dragObj = dragtable.dragObj; - if (!dragObj.addedNode) { - return; - } - dragObj.tableContainer.removeChild(dragObj.elNode); - - // Determine whether the drag ended over the table, and over which column. - var pos = dragtable.eventPosition(event); - var table_pos = dragtable.absolutePosition(dragObj.table); - if (pos.y < table_pos.y || - pos.y > table_pos.y + dragObj.table.offsetHeight) { - return; - } - var targetCol = dragtable.findColumn(dragObj.table, pos.x); - if (targetCol != -1 && targetCol != dragObj.startCol) { - dragtable.moveColumn(dragObj.table, dragObj.startCol, targetCol); - if (dragObj.table.id && dragtable.cookiesEnabled() && - dragObj.table.className.search(/\bforget-ordering\b/) == -1) { - dragtable.rememberDrag(dragObj.table.id, dragObj.startCol, targetCol); - } - } - }, - - // Which column does the x value fall inside of? x should include scrollLeft. - findColumn: function (table, x) { - var header = table.tHead.rows[0].cells; - for (var i = 0; i < header.length; i++) { - //var left = header[i].offsetLeft; - var pos = dragtable.absolutePosition(header[i]); - //if (left <= x && x <= left + header[i].offsetWidth) { - if (pos.x <= x && x <= pos.x + header[i].offsetWidth) { - return i; - } - } - return -1; - }, - - // Move a column of table from start index to finish index. - // Based on the "Swapping table columns" discussion on comp.lang.javascript. - // Assumes there are columns at sIdx and fIdx - moveColumn: function (table, sIdx, fIdx) { - var row, cA; - var i = table.rows.length; - while (i--) { - row = table.rows[i] - var x = row.removeChild(row.cells[sIdx]); - if (fIdx < row.cells.length) { - row.insertBefore(x, row.cells[fIdx]); - } else { - row.appendChild(x); - } - } - - // For whatever reason, sorttable tracks column indices this way. - // Without a manual update, clicking one column will sort on another. - var headrow = table.tHead.rows[0].cells; - for (var i = 0; i < headrow.length; i++) { - headrow[i].sorttable_columnindex = i; - } - }, - - // Are cookies enabled? We should not attempt to set cookies on a local file. - cookiesEnabled: function () { - return (window.location.protocol != 'file:') && navigator.cookieEnabled; - }, - - // Store a column swap in a cookie for posterity. - rememberDrag: function (id, a, b) { - var cookieName = "dragtable-" + id; - var prev = dragtable.readCookie(cookieName); - var new_val = ""; - if (prev) new_val = prev + ","; - new_val += a + "/" + b; - dragtable.createCookie(cookieName, new_val, dragtable.cookieDays); - }, - - // Replay all column swaps for a table. - replayDrags: function (table) { - if (!dragtable.cookiesEnabled()) return; - var dragstr = dragtable.readCookie("dragtable-" + table.id); - if (!dragstr) return; - var drags = dragstr.split(','); - for (var i = 0; i < drags.length; i++) { - var pair = drags[i].split("/"); - if (pair.length != 2) continue; - var a = parseInt(pair[0]); - var b = parseInt(pair[1]); - if (isNaN(a) || isNaN(b)) continue; - dragtable.moveColumn(table, a, b); - } - }, - - // Cookie functions based on http://www.quirksmode.org/js/cookies.html - // Cookies won't work for local files. - cookiesEnabled: function () { - return (window.location.protocol != 'file:') && navigator.cookieEnabled; - }, - - createCookie: function (name, value, days) { - if (days) { - var date = new Date(); - date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); - var expires = "; expires=" + date.toGMTString(); - } - else var expires = ""; - - var path = document.location.pathname; - document.cookie = name + "=" + value + expires + "; path=" + path - }, - - readCookie: function (name) { - var nameEQ = name + "="; - var ca = document.cookie.split(';'); - for (var i = 0; i < ca.length; i++) { - var c = ca[i]; - while (c.charAt(0) == ' ') c = c.substring(1, c.length); - if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); - } - return null; - }, - - eraseCookie: function (name) { - dragtable.createCookie(name, "", -1); - } - -} - -/* ****************************************************************** - Supporting functions: bundled here to avoid depending on a library - ****************************************************************** */ - -// Dean Edwards/Matthias Miller/John Resig -// has a hook for dragtable.init already been added? (see below) -var dgListenOnLoad = false; - -/* for Mozilla/Opera9 */ -if (document.addEventListener) { - dgListenOnLoad = true; - document.addEventListener("DOMContentLoaded", dragtable.init, false); -} - -/* for Internet Explorer */ -/*@cc_on @*/ -/*@if (@_win32) - dgListenOnLoad = true; - document.write(" to your HTML. + - Add class="draggable" to any table you might like to reorder. + - Drag the headers around to reorder them. + + This is code was based on: + - Stuart Langridge's SortTable (kryogenix.org/code/browser/sorttable) + - Mike Hall's draggable class (http://www.brainjar.com/dhtml/drag/) + - A discussion of permuting table columns on comp.lang.javascript + + Licensed under the MIT license. + */ + +// Here's the notice from Mike Hall's draggable script: +//***************************************************************************** +// Do not remove this notice. +// +// Copyright 2001 by Mike Hall. +// See http://www.brainjar.com for terms of use. +//***************************************************************************** +dragtable = { + // How far should the mouse move before it's considered a drag, not a click? + dragRadius2: 100, + setMinDragDistance: function (x) { + dragtable.dragRadius2 = x * x; + }, + + // How long should cookies persist? (in days) + cookieDays: 365, + setCookieDays: function (x) { + dragtable.cookieDays = x; + }, + + // Determine browser and version. + // TODO: eliminate browser sniffing except where it's really necessary. + Browser: function () { + var ua, s, i; + + this.isIE = false; + this.isNS = false; + this.version = null; + ua = navigator.userAgent; + + s = "MSIE"; + if ((i = ua.indexOf(s)) >= 0) { + this.isIE = true; + this.version = parseFloat(ua.substr(i + s.length)); + return; + } + + s = "Netscape6/"; + if ((i = ua.indexOf(s)) >= 0) { + this.isNS = true; + this.version = parseFloat(ua.substr(i + s.length)); + return; + } + + // Treat any other "Gecko" browser as NS 6.1. + s = "Gecko"; + if ((i = ua.indexOf(s)) >= 0) { + this.isNS = true; + this.version = 6.1; + return; + } + }, + browser: null, + + // Detect all draggable tables and attach handlers to their headers. + init: function () { + // Don't initialize twice + if (arguments.callee.done) return; + arguments.callee.done = true; + if (_dgtimer) clearInterval(_dgtimer); + if (!document.createElement || !document.getElementsByTagName) return; + + dragtable.dragObj.zIndex = 0; + dragtable.browser = new dragtable.Browser(); + forEach(document.getElementsByTagName('table'), function (table) { + if (table.className.search(/\bdraggable\b/) != -1) { + dragtable.makeDraggable(table); + } + }); + }, + + // The thead business is taken straight from sorttable. + makeDraggable: function (table) { + if (table.getElementsByTagName('thead').length == 0) { + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the, table.firstChild); + } + + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) { + table.tHead = table.getElementsByTagName('thead')[0]; + } + + var headers = table.tHead.rows[0].cells; + for (var i = 0; i < headers.length; i++) { + headers[i].onmousedown = dragtable.dragStart; + } + + // Replay reorderings from cookies if there are any. + if (dragtable.cookiesEnabled() && table.id && + table.className.search(/\bforget-ordering\b/) == -1) { + dragtable.replayDrags(table); + } + }, + + // Global object to hold drag information. + dragObj: new Object(), + + // Climb up the DOM until there's a tag that matches. + findUp: function (elt, tag) { + do { + if (elt.nodeName && elt.nodeName.search(tag) != -1) + return elt; + } while (elt = elt.parentNode); + return null; + }, + + // clone an element, copying its style and class. + fullCopy: function (elt, deep) { + var new_elt = elt.cloneNode(deep); + new_elt.className = elt.className; + forEach(elt.style, + function (value, key, object) { + if (value == null) return; + if (typeof(value) == "string" && value.length == 0) return; + + new_elt.style[key] = elt.style[key]; + }); + return new_elt; + }, + + eventPosition: function (event) { + var x, y; + if (dragtable.browser.isIE) { + x = window.event.clientX + document.documentElement.scrollLeft + + document.body.scrollLeft; + y = window.event.clientY + document.documentElement.scrollTop + + document.body.scrollTop; + return {x: x, y: y}; + } + return {x: event.pageX, y: event.pageY}; + }, + + // Determine the position of this element on the page. Many thanks to Magnus + // Kristiansen for help making this work with "position: fixed" elements. + absolutePosition: function (elt, stopAtRelative) { + var ex = 0, ey = 0; + do { + var curStyle = dragtable.browser.isIE ? elt.currentStyle + : window.getComputedStyle(elt, ''); + var supportFixed = !(dragtable.browser.isIE && + dragtable.browser.version < 7); + if (stopAtRelative && curStyle.position == 'relative') { + break; + } else if (supportFixed && curStyle.position == 'fixed') { + // Get the fixed el's offset + ex += parseInt(curStyle.left, 10); + ey += parseInt(curStyle.top, 10); + // Compensate for scrolling + ex += document.body.scrollLeft; + ey += document.body.scrollTop; + // End the loop + break; + } else { + ex += elt.offsetLeft; + ey += elt.offsetTop; + } + } while (elt = elt.offsetParent); + return {x: ex, y: ey}; + }, + + // MouseDown handler -- sets up the appropriate mousemove/mouseup handlers + // and fills in the global dragtable.dragObj object. + dragStart: function (event, id) { + var el; + var x, y; + var dragObj = dragtable.dragObj; + + var browser = dragtable.browser; + if (browser.isIE) + dragObj.origNode = window.event.srcElement; + else + dragObj.origNode = event.target; + var pos = dragtable.eventPosition(event); + + // Drag the entire table cell, not just the element that was clicked. + dragObj.origNode = dragtable.findUp(dragObj.origNode, /T[DH]/); + + // Since a column header can't be dragged directly, duplicate its contents + // in a div and drag that instead. + // TODO: I can assume a tHead... + var table = dragtable.findUp(dragObj.origNode, "TABLE"); + dragObj.table = table; + dragObj.startCol = dragtable.findColumn(table, pos.x); + if (dragObj.startCol == -1) return; + + var new_elt = dragtable.fullCopy(table, false); + new_elt.style.margin = '0'; + + // Copy the entire column + var copySectionColumn = function (sec, col) { + var new_sec = dragtable.fullCopy(sec, false); + forEach(sec.rows, function (row) { + var cell = row.cells[col]; + var new_tr = dragtable.fullCopy(row, false); + if (row.offsetHeight) new_tr.style.height = row.offsetHeight + "px"; + var new_td = dragtable.fullCopy(cell, true); + if (cell.offsetWidth) new_td.style.width = cell.offsetWidth + "px"; + new_tr.appendChild(new_td); + new_sec.appendChild(new_tr); + }); + return new_sec; + }; + + // First the heading + if (table.tHead) { + new_elt.appendChild(copySectionColumn(table.tHead, dragObj.startCol)); + } + forEach(table.tBodies, function (tb) { + new_elt.appendChild(copySectionColumn(tb, dragObj.startCol)); + }); + if (table.tFoot) { + new_elt.appendChild(copySectionColumn(table.tFoot, dragObj.startCol)); + } + + var obj_pos = dragtable.absolutePosition(dragObj.origNode, true); + new_elt.style.position = "absolute"; + new_elt.style.left = obj_pos.x + "px"; + new_elt.style.top = obj_pos.y + "px"; + new_elt.style.width = dragObj.origNode.offsetWidth + "px"; + new_elt.style.height = dragObj.origNode.offsetHeight + "px"; + new_elt.style.opacity = 0.7; + + // Hold off adding the element until this is clearly a drag. + dragObj.addedNode = false; + dragObj.tableContainer = dragObj.table.parentNode || document.body; + dragObj.elNode = new_elt; + + // Save starting positions of cursor and element. + dragObj.cursorStartX = pos.x; + dragObj.cursorStartY = pos.y; + dragObj.elStartLeft = parseInt(dragObj.elNode.style.left, 10); + dragObj.elStartTop = parseInt(dragObj.elNode.style.top, 10); + + if (isNaN(dragObj.elStartLeft)) dragObj.elStartLeft = 0; + if (isNaN(dragObj.elStartTop)) dragObj.elStartTop = 0; + + // Update element's z-index. + dragObj.elNode.style.zIndex = ++dragObj.zIndex; + + // Capture mousemove and mouseup events on the page. + if (browser.isIE) { + document.attachEvent("onmousemove", dragtable.dragMove); + document.attachEvent("onmouseup", dragtable.dragEnd); + window.event.cancelBubble = true; + window.event.returnValue = false; + } else { + document.addEventListener("mousemove", dragtable.dragMove, true); + document.addEventListener("mouseup", dragtable.dragEnd, true); + event.preventDefault(); + } + }, + + // Move the floating column header with the mouse + // TODO: Reorder columns as the mouse moves for a more interactive feel. + dragMove: function (event) { + var x, y; + var dragObj = dragtable.dragObj; + + // Get cursor position with respect to the page. + var pos = dragtable.eventPosition(event); + + var dx = dragObj.cursorStartX - pos.x; + var dy = dragObj.cursorStartY - pos.y; + if (!dragObj.addedNode && dx * dx + dy * dy > dragtable.dragRadius2) { + dragObj.tableContainer.insertBefore(dragObj.elNode, dragObj.table); + dragObj.addedNode = true; + } + + // Move drag element by the same amount the cursor has moved. + var style = dragObj.elNode.style; + style.left = (dragObj.elStartLeft + pos.x - dragObj.cursorStartX) + "px"; + style.top = (dragObj.elStartTop + pos.y - dragObj.cursorStartY) + "px"; + + if (dragtable.browser.isIE) { + window.event.cancelBubble = true; + window.event.returnValue = false; + } else { + event.preventDefault(); + } + }, + + // Stop capturing mousemove and mouseup events. + // Determine which (if any) column we're over and shuffle the table. + dragEnd: function (event) { + if (dragtable.browser.isIE) { + document.detachEvent("onmousemove", dragtable.dragMove); + document.detachEvent("onmouseup", dragtable.dragEnd); + } else { + document.removeEventListener("mousemove", dragtable.dragMove, true); + document.removeEventListener("mouseup", dragtable.dragEnd, true); + } + + // If the floating header wasn't added, the mouse didn't move far enough. + var dragObj = dragtable.dragObj; + if (!dragObj.addedNode) { + return; + } + dragObj.tableContainer.removeChild(dragObj.elNode); + + // Determine whether the drag ended over the table, and over which column. + var pos = dragtable.eventPosition(event); + var table_pos = dragtable.absolutePosition(dragObj.table); + if (pos.y < table_pos.y || + pos.y > table_pos.y + dragObj.table.offsetHeight) { + return; + } + var targetCol = dragtable.findColumn(dragObj.table, pos.x); + if (targetCol != -1 && targetCol != dragObj.startCol) { + dragtable.moveColumn(dragObj.table, dragObj.startCol, targetCol); + if (dragObj.table.id && dragtable.cookiesEnabled() && + dragObj.table.className.search(/\bforget-ordering\b/) == -1) { + dragtable.rememberDrag(dragObj.table.id, dragObj.startCol, targetCol); + } + } + }, + + // Which column does the x value fall inside of? x should include scrollLeft. + findColumn: function (table, x) { + var header = table.tHead.rows[0].cells; + for (var i = 0; i < header.length; i++) { + //var left = header[i].offsetLeft; + var pos = dragtable.absolutePosition(header[i]); + //if (left <= x && x <= left + header[i].offsetWidth) { + if (pos.x <= x && x <= pos.x + header[i].offsetWidth) { + return i; + } + } + return -1; + }, + + // Move a column of table from start index to finish index. + // Based on the "Swapping table columns" discussion on comp.lang.javascript. + // Assumes there are columns at sIdx and fIdx + moveColumn: function (table, sIdx, fIdx) { + var row, cA; + var i = table.rows.length; + while (i--) { + row = table.rows[i] + var x = row.removeChild(row.cells[sIdx]); + if (fIdx < row.cells.length) { + row.insertBefore(x, row.cells[fIdx]); + } else { + row.appendChild(x); + } + } + + // For whatever reason, sorttable tracks column indices this way. + // Without a manual update, clicking one column will sort on another. + var headrow = table.tHead.rows[0].cells; + for (var i = 0; i < headrow.length; i++) { + headrow[i].sorttable_columnindex = i; + } + }, + + // Are cookies enabled? We should not attempt to set cookies on a local file. + cookiesEnabled: function () { + return (window.location.protocol != 'file:') && navigator.cookieEnabled; + }, + + // Store a column swap in a cookie for posterity. + rememberDrag: function (id, a, b) { + var cookieName = "dragtable-" + id; + var prev = dragtable.readCookie(cookieName); + var new_val = ""; + if (prev) new_val = prev + ","; + new_val += a + "/" + b; + dragtable.createCookie(cookieName, new_val, dragtable.cookieDays); + }, + + // Replay all column swaps for a table. + replayDrags: function (table) { + if (!dragtable.cookiesEnabled()) return; + var dragstr = dragtable.readCookie("dragtable-" + table.id); + if (!dragstr) return; + var drags = dragstr.split(','); + for (var i = 0; i < drags.length; i++) { + var pair = drags[i].split("/"); + if (pair.length != 2) continue; + var a = parseInt(pair[0]); + var b = parseInt(pair[1]); + if (isNaN(a) || isNaN(b)) continue; + dragtable.moveColumn(table, a, b); + } + }, + + // Cookie functions based on http://www.quirksmode.org/js/cookies.html + // Cookies won't work for local files. + cookiesEnabled: function () { + return (window.location.protocol != 'file:') && navigator.cookieEnabled; + }, + + createCookie: function (name, value, days) { + if (days) { + var date = new Date(); + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + var expires = "; expires=" + date.toGMTString(); + } + else var expires = ""; + + var path = document.location.pathname; + document.cookie = name + "=" + value + expires + "; path=" + path + }, + + readCookie: function (name) { + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + for (var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) == ' ') c = c.substring(1, c.length); + if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); + } + return null; + }, + + eraseCookie: function (name) { + dragtable.createCookie(name, "", -1); + } + +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig +// has a hook for dragtable.init already been added? (see below) +var dgListenOnLoad = false; + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + dgListenOnLoad = true; + document.addEventListener("DOMContentLoaded", dragtable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + dgListenOnLoad = true; + document.write(" to your HTML - Add class="sortable" to any table you'd like to make sortable - Click on the headers to sort - - Thanks to many, many people for contributions and suggestions. - Licenced as X11: http://www.kryogenix.org/code/browser/licence.html - This basically means: do what you want with it. - */ - - -var stIsIE = /*@cc_on!@*/false; - -sorttable = { - init: function () { - // quit if this function has already been called - if (arguments.callee.done) return; - // flag this function so we don't do the same thing twice - arguments.callee.done = true; - // kill the timer - if (_timer) clearInterval(_timer); - - if (!document.createElement || !document.getElementsByTagName) return; - - sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; - - forEach(document.getElementsByTagName('table'), function (table) { - if (table.className.search(/\bsortable\b/) != -1) { - sorttable.makeSortable(table); - } - }); - - }, - - makeSortable: function (table) { - if (table.getElementsByTagName('thead').length == 0) { - // table doesn't have a tHead. Since it should have, create one and - // put the first table row in it. - the = document.createElement('thead'); - the.appendChild(table.rows[0]); - table.insertBefore(the, table.firstChild); - } - // Safari doesn't support table.tHead, sigh - if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; - - if (table.tHead.rows.length != 1) return; // can't cope with two header rows - - // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as - // "total" rows, for example). This is B&R, since what you're supposed - // to do is put them in a tfoot. So, if there are sortbottom rows, - // for backwards compatibility, move them to tfoot (creating it if needed). - sortbottomrows = []; - for (var i = 0; i < table.rows.length; i++) { - if (table.rows[i].className.search(/\bsortbottom\b/) != -1) { - sortbottomrows[sortbottomrows.length] = table.rows[i]; - } - } - if (sortbottomrows) { - if (table.tFoot == null) { - // table doesn't have a tfoot. Create one. - tfo = document.createElement('tfoot'); - table.appendChild(tfo); - } - for (var i = 0; i < sortbottomrows.length; i++) { - tfo.appendChild(sortbottomrows[i]); - } - delete sortbottomrows; - } - - // work through each column and calculate its type - headrow = table.tHead.rows[0].cells; - for (var i = 0; i < headrow.length; i++) { - // manually override the type with a sorttable_type attribute - if (!headrow[i].className.match(/\bsorttable_nosort\b/)) { // skip this col - mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/); - if (mtch) { - override = mtch[1]; - } - if (mtch && typeof sorttable["sort_" + override] == 'function') { - headrow[i].sorttable_sortfunction = sorttable["sort_" + override]; - } else { - headrow[i].sorttable_sortfunction = sorttable.guessType(table, i); - } - // make it clickable to sort - headrow[i].sorttable_columnindex = i; - headrow[i].sorttable_tbody = table.tBodies[0]; - dean_addEvent(headrow[i], "click", function (e) { - - if (this.className.search(/\bsorttable_sorted\b/) != -1) { - // if we're already sorted by this column, just - // reverse the table, which is quicker - sorttable.reverse(this.sorttable_tbody); - this.className = this.className.replace('sorttable_sorted', - 'sorttable_sorted_reverse'); - this.removeChild(document.getElementById('sorttable_sortfwdind')); - sortrevind = document.createElement('span'); - sortrevind.id = "sorttable_sortrevind"; - sortrevind.innerHTML = stIsIE ? ' 5' : ' ▴'; - this.appendChild(sortrevind); - return; - } - if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { - // if we're already sorted by this column in reverse, just - // re-reverse the table, which is quicker - sorttable.reverse(this.sorttable_tbody); - this.className = this.className.replace('sorttable_sorted_reverse', - 'sorttable_sorted'); - this.removeChild(document.getElementById('sorttable_sortrevind')); - sortfwdind = document.createElement('span'); - sortfwdind.id = "sorttable_sortfwdind"; - sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; - this.appendChild(sortfwdind); - return; - } - - // remove sorttable_sorted classes - theadrow = this.parentNode; - forEach(theadrow.childNodes, function (cell) { - if (cell.nodeType == 1) { // an element - cell.className = cell.className.replace('sorttable_sorted_reverse', ''); - cell.className = cell.className.replace('sorttable_sorted', ''); - } - }); - sortfwdind = document.getElementById('sorttable_sortfwdind'); - if (sortfwdind) { - sortfwdind.parentNode.removeChild(sortfwdind); - } - sortrevind = document.getElementById('sorttable_sortrevind'); - if (sortrevind) { - sortrevind.parentNode.removeChild(sortrevind); - } - - this.className += ' sorttable_sorted'; - sortfwdind = document.createElement('span'); - sortfwdind.id = "sorttable_sortfwdind"; - sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; - this.appendChild(sortfwdind); - - // build an array to sort. This is a Schwartzian transform thing, - // i.e., we "decorate" each row with the actual sort key, - // sort based on the sort keys, and then put the rows back in order - // which is a lot faster because you only do getInnerText once per row - row_array = []; - col = this.sorttable_columnindex; - rows = this.sorttable_tbody.rows; - for (var j = 0; j < rows.length; j++) { - row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]]; - } - /* If you want a stable sort, uncomment the following line */ - //sorttable.shaker_sort(row_array, this.sorttable_sortfunction); - /* and comment out this one */ - row_array.sort(this.sorttable_sortfunction); - - tb = this.sorttable_tbody; - for (var j = 0; j < row_array.length; j++) { - tb.appendChild(row_array[j][1]); - } - - delete row_array; - }); - } - } - }, - - guessType: function (table, column) { - // guess the type of a column based on its first non-blank row - sortfn = sorttable.sort_alpha; - for (var i = 0; i < table.tBodies[0].rows.length; i++) { - text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]); - if (text != '') { - if (text.match(/^-?[�$�]?[\d,.]+%?$/)) { - return sorttable.sort_numeric; - } - // check for a date: dd/mm/yyyy or dd/mm/yy - // can have / or . or - as separator - // can be mm/dd as well - possdate = text.match(sorttable.DATE_RE) - if (possdate) { - // looks like a date - first = parseInt(possdate[1]); - second = parseInt(possdate[2]); - if (first > 12) { - // definitely dd/mm - return sorttable.sort_ddmm; - } else if (second > 12) { - return sorttable.sort_mmdd; - } else { - // looks like a date, but we can't tell which, so assume - // that it's dd/mm (English imperialism!) and keep looking - sortfn = sorttable.sort_ddmm; - } - } - } - } - return sortfn; - }, - - getInnerText: function (node) { - // gets the text we want to use for sorting for a cell. - // strips leading and trailing whitespace. - // this is *not* a generic getInnerText function; it's special to sorttable. - // for example, you can override the cell text with a customkey attribute. - // it also gets .value for fields. - - hasInputs = (typeof node.getElementsByTagName == 'function') && - node.getElementsByTagName('input').length; - - if (node.getAttribute("sorttable_customkey") != null) { - return node.getAttribute("sorttable_customkey"); - } - else if (typeof node.textContent != 'undefined' && !hasInputs) { - return node.textContent.replace(/^\s+|\s+$/g, ''); - } - else if (typeof node.innerText != 'undefined' && !hasInputs) { - return node.innerText.replace(/^\s+|\s+$/g, ''); - } - else if (typeof node.text != 'undefined' && !hasInputs) { - return node.text.replace(/^\s+|\s+$/g, ''); - } - else { - switch (node.nodeType) { - case 3: - if (node.nodeName.toLowerCase() == 'input') { - return node.value.replace(/^\s+|\s+$/g, ''); - } - case 4: - return node.nodeValue.replace(/^\s+|\s+$/g, ''); - break; - case 1: - case 11: - var innerText = ''; - for (var i = 0; i < node.childNodes.length; i++) { - innerText += sorttable.getInnerText(node.childNodes[i]); - } - return innerText.replace(/^\s+|\s+$/g, ''); - break; - default: - return ''; - } - } - }, - - reverse: function (tbody) { - // reverse the rows in a tbody - newrows = []; - for (var i = 0; i < tbody.rows.length; i++) { - newrows[newrows.length] = tbody.rows[i]; - } - for (var i = newrows.length - 1; i >= 0; i--) { - tbody.appendChild(newrows[i]); - } - delete newrows; - }, - - /* sort functions - each sort function takes two parameters, a and b - you are comparing a[0] and b[0] */ - sort_numeric: function (a, b) { - aa = parseFloat(a[0].replace(/[^0-9.-]/g, '')); - if (isNaN(aa)) aa = 0; - bb = parseFloat(b[0].replace(/[^0-9.-]/g, '')); - if (isNaN(bb)) bb = 0; - return aa - bb; - }, - sort_alpha: function (a, b) { - if (a[0] == b[0]) return 0; - if (a[0] < b[0]) return -1; - return 1; - }, - sort_ddmm: function (a, b) { - mtch = a[0].match(sorttable.DATE_RE); - y = mtch[3]; - m = mtch[2]; - d = mtch[1]; - if (m.length == 1) m = '0' + m; - if (d.length == 1) d = '0' + d; - dt1 = y + m + d; - mtch = b[0].match(sorttable.DATE_RE); - y = mtch[3]; - m = mtch[2]; - d = mtch[1]; - if (m.length == 1) m = '0' + m; - if (d.length == 1) d = '0' + d; - dt2 = y + m + d; - if (dt1 == dt2) return 0; - if (dt1 < dt2) return -1; - return 1; - }, - sort_mmdd: function (a, b) { - mtch = a[0].match(sorttable.DATE_RE); - y = mtch[3]; - d = mtch[2]; - m = mtch[1]; - if (m.length == 1) m = '0' + m; - if (d.length == 1) d = '0' + d; - dt1 = y + m + d; - mtch = b[0].match(sorttable.DATE_RE); - y = mtch[3]; - d = mtch[2]; - m = mtch[1]; - if (m.length == 1) m = '0' + m; - if (d.length == 1) d = '0' + d; - dt2 = y + m + d; - if (dt1 == dt2) return 0; - if (dt1 < dt2) return -1; - return 1; - }, - - shaker_sort: function (list, comp_func) { - // A stable sort function to allow multi-level sorting of data - // see: http://en.wikipedia.org/wiki/Cocktail_sort - // thanks to Joseph Nahmias - var b = 0; - var t = list.length - 1; - var swap = true; - - while (swap) { - swap = false; - for (var i = b; i < t; ++i) { - if (comp_func(list[i], list[i + 1]) > 0) { - var q = list[i]; - list[i] = list[i + 1]; - list[i + 1] = q; - swap = true; - } - } // for - t--; - - if (!swap) break; - - for (var i = t; i > b; --i) { - if (comp_func(list[i], list[i - 1]) < 0) { - var q = list[i]; - list[i] = list[i - 1]; - list[i - 1] = q; - swap = true; - } - } // for - b++; - - } // while(swap) - } -} - -/* ****************************************************************** - Supporting functions: bundled here to avoid depending on a library - ****************************************************************** */ - -// Dean Edwards/Matthias Miller/John Resig - -/* for Mozilla/Opera9 */ -if (document.addEventListener) { - document.addEventListener("DOMContentLoaded", sorttable.init, false); -} - -/* for Internet Explorer */ -/*@cc_on @*/ -/*@if (@_win32) - document.write(" to your HTML + Add class="sortable" to any table you'd like to make sortable + Click on the headers to sort + + Thanks to many, many people for contributions and suggestions. + Licenced as X11: http://www.kryogenix.org/code/browser/licence.html + This basically means: do what you want with it. + */ + + +var stIsIE = /*@cc_on!@*/false; + +sorttable = { + init: function () { + // quit if this function has already been called + if (arguments.callee.done) return; + // flag this function so we don't do the same thing twice + arguments.callee.done = true; + // kill the timer + if (_timer) clearInterval(_timer); + + if (!document.createElement || !document.getElementsByTagName) return; + + sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; + + forEach(document.getElementsByTagName('table'), function (table) { + if (table.className.search(/\bsortable\b/) != -1) { + sorttable.makeSortable(table); + } + }); + + }, + + makeSortable: function (table) { + if (table.getElementsByTagName('thead').length == 0) { + // table doesn't have a tHead. Since it should have, create one and + // put the first table row in it. + the = document.createElement('thead'); + the.appendChild(table.rows[0]); + table.insertBefore(the, table.firstChild); + } + // Safari doesn't support table.tHead, sigh + if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; + + if (table.tHead.rows.length != 1) return; // can't cope with two header rows + + // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as + // "total" rows, for example). This is B&R, since what you're supposed + // to do is put them in a tfoot. So, if there are sortbottom rows, + // for backwards compatibility, move them to tfoot (creating it if needed). + sortbottomrows = []; + for (var i = 0; i < table.rows.length; i++) { + if (table.rows[i].className.search(/\bsortbottom\b/) != -1) { + sortbottomrows[sortbottomrows.length] = table.rows[i]; + } + } + if (sortbottomrows) { + if (table.tFoot == null) { + // table doesn't have a tfoot. Create one. + tfo = document.createElement('tfoot'); + table.appendChild(tfo); + } + for (var i = 0; i < sortbottomrows.length; i++) { + tfo.appendChild(sortbottomrows[i]); + } + delete sortbottomrows; + } + + // work through each column and calculate its type + headrow = table.tHead.rows[0].cells; + for (var i = 0; i < headrow.length; i++) { + // manually override the type with a sorttable_type attribute + if (!headrow[i].className.match(/\bsorttable_nosort\b/)) { // skip this col + mtch = headrow[i].className.match(/\bsorttable_([a-z0-9]+)\b/); + if (mtch) { + override = mtch[1]; + } + if (mtch && typeof sorttable["sort_" + override] == 'function') { + headrow[i].sorttable_sortfunction = sorttable["sort_" + override]; + } else { + headrow[i].sorttable_sortfunction = sorttable.guessType(table, i); + } + // make it clickable to sort + headrow[i].sorttable_columnindex = i; + headrow[i].sorttable_tbody = table.tBodies[0]; + dean_addEvent(headrow[i], "click", function (e) { + + if (this.className.search(/\bsorttable_sorted\b/) != -1) { + // if we're already sorted by this column, just + // reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted', + 'sorttable_sorted_reverse'); + this.removeChild(document.getElementById('sorttable_sortfwdind')); + sortrevind = document.createElement('span'); + sortrevind.id = "sorttable_sortrevind"; + sortrevind.innerHTML = stIsIE ? ' 5' : ' ▴'; + this.appendChild(sortrevind); + return; + } + if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { + // if we're already sorted by this column in reverse, just + // re-reverse the table, which is quicker + sorttable.reverse(this.sorttable_tbody); + this.className = this.className.replace('sorttable_sorted_reverse', + 'sorttable_sorted'); + this.removeChild(document.getElementById('sorttable_sortrevind')); + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + return; + } + + // remove sorttable_sorted classes + theadrow = this.parentNode; + forEach(theadrow.childNodes, function (cell) { + if (cell.nodeType == 1) { // an element + cell.className = cell.className.replace('sorttable_sorted_reverse', ''); + cell.className = cell.className.replace('sorttable_sorted', ''); + } + }); + sortfwdind = document.getElementById('sorttable_sortfwdind'); + if (sortfwdind) { + sortfwdind.parentNode.removeChild(sortfwdind); + } + sortrevind = document.getElementById('sorttable_sortrevind'); + if (sortrevind) { + sortrevind.parentNode.removeChild(sortrevind); + } + + this.className += ' sorttable_sorted'; + sortfwdind = document.createElement('span'); + sortfwdind.id = "sorttable_sortfwdind"; + sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; + this.appendChild(sortfwdind); + + // build an array to sort. This is a Schwartzian transform thing, + // i.e., we "decorate" each row with the actual sort key, + // sort based on the sort keys, and then put the rows back in order + // which is a lot faster because you only do getInnerText once per row + row_array = []; + col = this.sorttable_columnindex; + rows = this.sorttable_tbody.rows; + for (var j = 0; j < rows.length; j++) { + row_array[row_array.length] = [sorttable.getInnerText(rows[j].cells[col]), rows[j]]; + } + /* If you want a stable sort, uncomment the following line */ + //sorttable.shaker_sort(row_array, this.sorttable_sortfunction); + /* and comment out this one */ + row_array.sort(this.sorttable_sortfunction); + + tb = this.sorttable_tbody; + for (var j = 0; j < row_array.length; j++) { + tb.appendChild(row_array[j][1]); + } + + delete row_array; + }); + } + } + }, + + guessType: function (table, column) { + // guess the type of a column based on its first non-blank row + sortfn = sorttable.sort_alpha; + for (var i = 0; i < table.tBodies[0].rows.length; i++) { + text = sorttable.getInnerText(table.tBodies[0].rows[i].cells[column]); + if (text != '') { + if (text.match(/^-?[�$�]?[\d,.]+%?$/)) { + return sorttable.sort_numeric; + } + // check for a date: dd/mm/yyyy or dd/mm/yy + // can have / or . or - as separator + // can be mm/dd as well + possdate = text.match(sorttable.DATE_RE) + if (possdate) { + // looks like a date + first = parseInt(possdate[1]); + second = parseInt(possdate[2]); + if (first > 12) { + // definitely dd/mm + return sorttable.sort_ddmm; + } else if (second > 12) { + return sorttable.sort_mmdd; + } else { + // looks like a date, but we can't tell which, so assume + // that it's dd/mm (English imperialism!) and keep looking + sortfn = sorttable.sort_ddmm; + } + } + } + } + return sortfn; + }, + + getInnerText: function (node) { + // gets the text we want to use for sorting for a cell. + // strips leading and trailing whitespace. + // this is *not* a generic getInnerText function; it's special to sorttable. + // for example, you can override the cell text with a customkey attribute. + // it also gets .value for fields. + + hasInputs = (typeof node.getElementsByTagName == 'function') && + node.getElementsByTagName('input').length; + + if (node.getAttribute("sorttable_customkey") != null) { + return node.getAttribute("sorttable_customkey"); + } + else if (typeof node.textContent != 'undefined' && !hasInputs) { + return node.textContent.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.innerText != 'undefined' && !hasInputs) { + return node.innerText.replace(/^\s+|\s+$/g, ''); + } + else if (typeof node.text != 'undefined' && !hasInputs) { + return node.text.replace(/^\s+|\s+$/g, ''); + } + else { + switch (node.nodeType) { + case 3: + if (node.nodeName.toLowerCase() == 'input') { + return node.value.replace(/^\s+|\s+$/g, ''); + } + case 4: + return node.nodeValue.replace(/^\s+|\s+$/g, ''); + break; + case 1: + case 11: + var innerText = ''; + for (var i = 0; i < node.childNodes.length; i++) { + innerText += sorttable.getInnerText(node.childNodes[i]); + } + return innerText.replace(/^\s+|\s+$/g, ''); + break; + default: + return ''; + } + } + }, + + reverse: function (tbody) { + // reverse the rows in a tbody + newrows = []; + for (var i = 0; i < tbody.rows.length; i++) { + newrows[newrows.length] = tbody.rows[i]; + } + for (var i = newrows.length - 1; i >= 0; i--) { + tbody.appendChild(newrows[i]); + } + delete newrows; + }, + + /* sort functions + each sort function takes two parameters, a and b + you are comparing a[0] and b[0] */ + sort_numeric: function (a, b) { + aa = parseFloat(a[0].replace(/[^0-9.-]/g, '')); + if (isNaN(aa)) aa = 0; + bb = parseFloat(b[0].replace(/[^0-9.-]/g, '')); + if (isNaN(bb)) bb = 0; + return aa - bb; + }, + sort_alpha: function (a, b) { + if (a[0] == b[0]) return 0; + if (a[0] < b[0]) return -1; + return 1; + }, + sort_ddmm: function (a, b) { + mtch = a[0].match(sorttable.DATE_RE); + y = mtch[3]; + m = mtch[2]; + d = mtch[1]; + if (m.length == 1) m = '0' + m; + if (d.length == 1) d = '0' + d; + dt1 = y + m + d; + mtch = b[0].match(sorttable.DATE_RE); + y = mtch[3]; + m = mtch[2]; + d = mtch[1]; + if (m.length == 1) m = '0' + m; + if (d.length == 1) d = '0' + d; + dt2 = y + m + d; + if (dt1 == dt2) return 0; + if (dt1 < dt2) return -1; + return 1; + }, + sort_mmdd: function (a, b) { + mtch = a[0].match(sorttable.DATE_RE); + y = mtch[3]; + d = mtch[2]; + m = mtch[1]; + if (m.length == 1) m = '0' + m; + if (d.length == 1) d = '0' + d; + dt1 = y + m + d; + mtch = b[0].match(sorttable.DATE_RE); + y = mtch[3]; + d = mtch[2]; + m = mtch[1]; + if (m.length == 1) m = '0' + m; + if (d.length == 1) d = '0' + d; + dt2 = y + m + d; + if (dt1 == dt2) return 0; + if (dt1 < dt2) return -1; + return 1; + }, + + shaker_sort: function (list, comp_func) { + // A stable sort function to allow multi-level sorting of data + // see: http://en.wikipedia.org/wiki/Cocktail_sort + // thanks to Joseph Nahmias + var b = 0; + var t = list.length - 1; + var swap = true; + + while (swap) { + swap = false; + for (var i = b; i < t; ++i) { + if (comp_func(list[i], list[i + 1]) > 0) { + var q = list[i]; + list[i] = list[i + 1]; + list[i + 1] = q; + swap = true; + } + } // for + t--; + + if (!swap) break; + + for (var i = t; i > b; --i) { + if (comp_func(list[i], list[i - 1]) < 0) { + var q = list[i]; + list[i] = list[i - 1]; + list[i - 1] = q; + swap = true; + } + } // for + b++; + + } // while(swap) + } +} + +/* ****************************************************************** + Supporting functions: bundled here to avoid depending on a library + ****************************************************************** */ + +// Dean Edwards/Matthias Miller/John Resig + +/* for Mozilla/Opera9 */ +if (document.addEventListener) { + document.addEventListener("DOMContentLoaded", sorttable.init, false); +} + +/* for Internet Explorer */ +/*@cc_on @*/ +/*@if (@_win32) + document.write(" -End_Of_HTML; -?> +$timeclock + +End_Of_HTML; +?> diff --git a/punchclock/timecard.ajax.php b/punchclock/timecard.ajax.php index 59f2138..71d2e8e 100644 --- a/punchclock/timecard.ajax.php +++ b/punchclock/timecard.ajax.php @@ -39,9 +39,9 @@ $local_timestamp_in_week += $one_week; // Connect to db. -$db = mysql_connect($db_hostname, $db_username, $db_password) +$db = ($GLOBALS["___mysqli_ston"] = mysqli_connect($db_hostname, $db_username, $db_password)) or die("Could not connect to the database."); -mysql_select_db($db_name); +mysqli_select_db($GLOBALS["___mysqli_ston"], $db_name); $u_empfullname = rawurlencode($empfullname); diff --git a/punchclock/timecard.php b/punchclock/timecard.php index bfcd871..2207ee2 100644 --- a/punchclock/timecard.php +++ b/punchclock/timecard.php @@ -1,95 +1,95 @@ - -.nav-buttons { float:right; margin-top:8px; margin-right:8px; } -@media print { - .page { width:50%; min-width:400px; } - .buttons { display:none; } - .nav-buttons { display:none; } - .topmain_row_color { display:none; } - .misc_items { color:#222; } -} - -End_Of_HTML; -$PAGE_CONTENT_HEADER = << -PreviousNext - -End_Of_HTML; - -include 'header.php'; - -print timecard_html($empfullname, $local_timestamp_in_week); - -print << - - - -End_Of_HTML; - -include 'footer.php'; + +.nav-buttons { float:right; margin-top:8px; margin-right:8px; } +@media print { + .page { width:50%; min-width:400px; } + .buttons { display:none; } + .nav-buttons { display:none; } + .topmain_row_color { display:none; } + .misc_items { color:#222; } +} + +End_Of_HTML; +$PAGE_CONTENT_HEADER = << +PreviousNext + +End_Of_HTML; + +include 'header.php'; + +print timecard_html($empfullname, $local_timestamp_in_week); + +print << + + + +End_Of_HTML; + +include 'footer.php'; From d3d2cdf8588ccd3d353f7bea0dbd96e34089ae38 Mon Sep 17 00:00:00 2001 From: Rick Boatright Date: Wed, 25 Jan 2017 18:11:22 -0600 Subject: [PATCH 08/17] msql to mysqli --- admin/chngpasswd.php | 26 ++--- admin/dbupgrade.php | 158 +++++++++++++++--------------- admin/groupadmin.php | 8 +- admin/groupcreate.php | 24 ++--- admin/groupdelete.php | 40 ++++---- admin/groupedit.php | 124 +++++++++++------------ admin/header.admin.inc.php | 12 +-- admin/header.php | 24 ++--- admin/header_colorpick.php | 28 +++--- admin/header_date.php | 30 +++--- admin/header_get.php | 30 +++--- admin/header_get_sysedit.php | 30 +++--- admin/header_post.php | 30 +++--- admin/header_post_sysedit.php | 30 +++--- admin/index.php | 146 +++++++++++++-------------- admin/officeadmin.php | 12 +-- admin/officecreate.php | 16 +-- admin/officedelete.php | 44 ++++----- admin/officeedit.php | 64 ++++++------ admin/statusadmin.php | 4 +- admin/statuscreate.php | 6 +- admin/statusdelete.php | 10 +- admin/statusedit.php | 14 +-- admin/sysedit.php | 54 +++++----- admin/timeadd.php | 62 ++++++------ admin/timeadmin.php | 4 +- admin/timedelete.php | 56 +++++------ admin/timeedit.php | 54 +++++----- admin/topmain.php | 2 +- admin/useradmin.php | 20 ++-- admin/usercreate.php | 26 ++--- admin/userdelete.php | 34 +++---- admin/useredit.php | 34 +++---- admin/usersearch.php | 40 ++++---- reports/audit.php | 4 +- reports/get_csv.php | 68 ++++++------- reports/header.reports.inc.php | 12 +-- reports/header_get_reports.php | 32 +++--- reports/header_post_reports.php | 32 +++--- reports/index.php | 98 +++++++++--------- reports/timerpt.php | 54 +++++----- reports/topmain.php | 2 +- reports/total_hours.php | 64 +++++++----- scripts/dropdown_get.php | 18 ++-- scripts/dropdown_get_reports.php | 36 +++---- scripts/dropdown_get_sysedit.php | 24 ++--- scripts/dropdown_post.php | 18 ++-- scripts/dropdown_post_reports.php | 36 +++---- scripts/dropdown_post_sysedit.php | 24 ++--- templates/admin_index_tpl.php | 16 +-- 50 files changed, 921 insertions(+), 913 deletions(-) diff --git a/admin/chngpasswd.php b/admin/chngpasswd.php index 94097a2..4e8de83 100644 --- a/admin/chngpasswd.php +++ b/admin/chngpasswd.php @@ -102,11 +102,11 @@ $get_user = addslashes($get_user); $query = "select empfullname from " . $db_prefix . "employees where empfullname = '" . $get_user . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $username = stripslashes("" . $row['empfullname'] . ""); } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); if (!isset($username)) { echo "username is not defined for this user.\n"; exit; @@ -114,11 +114,11 @@ if (!empty($get_office)) { $query = "select * from " . $db_prefix . "offices where officename = '" . $get_office . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $getoffice = "" . $row['officename'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); } if (!isset($getoffice)) { echo "Office is not defined for this user. Go back and associate this user with an office.\n"; @@ -158,11 +158,11 @@ if (!empty($get_office)) { $query = "select * from " . $db_prefix . "offices where officename = '" . $get_office . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $getoffice = "" . $row['officename'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); } if (!isset($getoffice)) { echo "Office is not defined for this user. Go back and associate this user with an office.\n"; @@ -229,11 +229,11 @@ if (!empty($post_username)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $username = "" . $row['empfullname'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); if (!isset($username)) { echo "username is not defined for this user.\n"; exit; @@ -292,7 +292,7 @@ $post_username = addslashes($post_username); $query = "update " . $db_prefix . "employees set employee_passwd = ('" . $new_password . "') where empfullname = ('" . $post_username . "')"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); $post_username = stripslashes($post_username); diff --git a/admin/dbupgrade.php b/admin/dbupgrade.php index 7f051b7..6f7158d 100644 --- a/admin/dbupgrade.php +++ b/admin/dbupgrade.php @@ -77,8 +77,8 @@ // determine the privileges of the PHP Timeclock user // -$result = mysql_query("show grants for current_user()"); -while ($row = mysql_fetch_array($result)) { +$result = mysqli_query($GLOBALS["___mysqli_ston"], "show grants for current_user()"); +while ($row = mysqli_fetch_array($result)) { $abc = stripslashes("" . $row["0"] . ""); if (((preg_match("/\bgrant\b/i", $abc)) && (preg_match("/\bselect\b/i", $abc)) && (preg_match("/\binsert\b/i", $abc)) && (preg_match("/\bupdate\b/i", $abc)) && @@ -95,9 +95,9 @@ if ($request == 'GET') { $query_admin = "select empfullname from " . $db_prefix . "employees where empfullname = 'admin'"; - $result_admin = mysql_query($query_admin); + $result_admin = mysqli_query($GLOBALS["___mysqli_ston"], $query_admin); - while ($row = mysql_fetch_array($result_admin)) { + while ($row = mysqli_fetch_array($result_admin)) { $user_admin = "" . $row["empfullname"] . ""; } @@ -158,99 +158,99 @@ // employees table additions // $field = "employee_passwd"; - $result = mysql_query("SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); + @$rows = mysqli_num_rows($result); if (empty($rows)) { - $passwd_query = mysql_query("ALTER TABLE " . $db_prefix . "employees ADD $field VARCHAR(25) NOT NULL;"); + $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field VARCHAR(25) NOT NULL;"); echo " Added: $field field has been added to the employees table.\n"; $passed_or_not = "1"; } $field = "displayname"; - $result = mysql_query("SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); + @$rows = mysqli_num_rows($result); if (empty($rows)) { - $passwd_query = mysql_query("ALTER TABLE " . $db_prefix . "employees ADD $field VARCHAR(50) NOT NULL;"); + $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field VARCHAR(50) NOT NULL;"); echo " Added: $field field has been added to the employees table.\n"; $passed_or_not = "1"; } $field = "email"; - $result = mysql_query("SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); + @$rows = mysqli_num_rows($result); if (empty($rows)) { - $passwd_query = mysql_query("ALTER TABLE " . $db_prefix . "employees ADD $field VARCHAR(75) NOT NULL;"); + $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field VARCHAR(75) NOT NULL;"); echo " Added: $field field has been added to the employees table.\n"; $passed_or_not = "1"; } $field = "groups"; - $result = mysql_query("SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); + @$rows = mysqli_num_rows($result); if (empty($rows)) { - $passwd_query = mysql_query("ALTER TABLE " . $db_prefix . "employees ADD $field VARCHAR(50) NOT NULL;"); + $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field VARCHAR(50) NOT NULL;"); echo " Added: $field field has been added to the employees table.\n"; $passed_or_not = "1"; } $field = "office"; - $result = mysql_query("SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); + @$rows = mysqli_num_rows($result); if (empty($rows)) { - $passwd_query = mysql_query("ALTER TABLE " . $db_prefix . "employees ADD $field VARCHAR(50) NOT NULL;"); + $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field VARCHAR(50) NOT NULL;"); echo " Added: $field field has been added to the employees table.\n"; $passed_or_not = "1"; } $field = "admin"; - $result = mysql_query("SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); + @$rows = mysqli_num_rows($result); if (empty($rows)) { - $passwd_query = mysql_query("ALTER TABLE " . $db_prefix . "employees ADD $field TINYINT(1) NOT NULL default '0';"); + $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field TINYINT(1) NOT NULL default '0';"); echo " Added: $field field has been added to the employees table.\n"; $passed_or_not = "1"; } $field = "reports"; - $result = mysql_query("SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); + @$rows = mysqli_num_rows($result); if (empty($rows)) { - $passwd_query = mysql_query("ALTER TABLE " . $db_prefix . "employees ADD $field TINYINT(1) NOT NULL default '0';"); + $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field TINYINT(1) NOT NULL default '0';"); echo " Added: $field field has been added to the employees table.\n"; $passed_or_not = "1"; } $field = "time_admin"; - $result = mysql_query("SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); + @$rows = mysqli_num_rows($result); if (empty($rows)) { - $passwd_query = mysql_query("ALTER TABLE " . $db_prefix . "employees ADD $field TINYINT(1) NOT NULL default '0';"); + $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field TINYINT(1) NOT NULL default '0';"); echo " Added: $field field has been added to the employees table.\n"; $passed_or_not = "1"; } $field = "disabled"; - $result = mysql_query("SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); + @$rows = mysqli_num_rows($result); if (empty($rows)) { - $passwd_query = mysql_query("ALTER TABLE " . $db_prefix . "employees ADD $field TINYINT(1) NOT NULL default '0';"); + $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field TINYINT(1) NOT NULL default '0';"); echo " Added: $field field has been added to the employees table.\n"; $passed_or_not = "1"; @@ -258,36 +258,36 @@ // employees table changes // - $result = mysql_query("SHOW FIELDS FROM " . $db_prefix . "employees"); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW FIELDS FROM " . $db_prefix . "employees"); + while ($row = mysqli_fetch_array($result)) { $name = "" . $row["Field"] . ""; $type = "" . $row["Type"] . ""; $tmp_type = strtoupper($type); if (($name == 'empfullname') && ($type != 'varchar(50)')) { - $alter_result = mysql_query("ALTER TABLE " . $db_prefix . "employees CHANGE empfullname empfullname VARCHAR(50) NOT NULL"); + $alter_result = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees CHANGE empfullname empfullname VARCHAR(50) NOT NULL"); echo " Changed: $name field in employees table has been changed from type $tmp_type to type VARCHAR(50).\n"; $passed_or_not = "1"; } if (($name == 'tstamp') && ($type != 'bigint(14)')) { - $alter_result = mysql_query("ALTER TABLE " . $db_prefix . "employees CHANGE tstamp tstamp BIGINT(14) DEFAULT NULL"); + $alter_result = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees CHANGE tstamp tstamp BIGINT(14) DEFAULT NULL"); echo " Changed: $name field in employees table has been changed from type $tmp_type to type BIGINT(14).\n"; $emp_tstamp_count++; $passed_or_not = "1"; } } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); // info table additions // $field = "ipaddress"; - $result = mysql_query("SHOW fields from " . $db_prefix . "info LIKE '" . $field . "'"); - @$rows = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "info LIKE '" . $field . "'"); + @$rows = mysqli_num_rows($result); if (empty($rows)) { - $passwd_query = mysql_query("ALTER TABLE " . $db_prefix . "info ADD $field VARCHAR(39) NOT NULL;"); + $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "info ADD $field VARCHAR(39) NOT NULL;"); echo " Added: $field field has been added to the employees table.\n"; $passed_or_not = "1"; @@ -295,36 +295,36 @@ // info table changes // - $result = mysql_query("SHOW FIELDS FROM " . $db_prefix . "info"); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW FIELDS FROM " . $db_prefix . "info"); + while ($row = mysqli_fetch_array($result)) { $name = "" . $row["Field"] . ""; $type = "" . $row["Type"] . ""; $tmp_type = strtoupper($type); if (($name == 'inout') && ($type != 'varchar(50)')) { - $alter_result = mysql_query("ALTER TABLE " . $db_prefix . "info CHANGE `inout` `inout` VARCHAR(50) NOT NULL"); + $alter_result = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "info CHANGE `inout` `inout` VARCHAR(50) NOT NULL"); echo " Changed: $name field in info table has been changed from type $tmp_type to type VARCHAR(50).\n"; $passed_or_not = "1"; } if (($name == 'timestamp') && ($type != 'bigint(14)')) { - $alter_result = mysql_query("ALTER TABLE " . $db_prefix . "info CHANGE timestamp timestamp BIGINT(14) DEFAULT NULL"); + $alter_result = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "info CHANGE timestamp timestamp BIGINT(14) DEFAULT NULL"); echo " Changed: $name field in info table has been changed from type $tmp_type to type BIGINT(14).\n"; $info_timestamp_count++; $passed_or_not = "1"; } } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); // punchlist table additions // $field = "in_or_out"; - $result = mysql_query("SHOW fields from " . $db_prefix . "punchlist LIKE '" . $field . "'"); - $rows = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "punchlist LIKE '" . $field . "'"); + $rows = mysqli_num_rows($result); if (empty($rows)) { - $passwd_query = mysql_query("ALTER TABLE " . $db_prefix . "punchlist ADD $field TINYINT(1) NOT NULL default '0';"); + $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "punchlist ADD $field TINYINT(1) NOT NULL default '0';"); echo " Added: $field field has been added to the punchlist table.\n"; $passed_or_not = "1"; @@ -332,29 +332,29 @@ // punchlist table changes // - $result = mysql_query("SHOW FIELDS FROM " . $db_prefix . "punchlist"); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW FIELDS FROM " . $db_prefix . "punchlist"); + while ($row = mysqli_fetch_array($result)) { $name = "" . $row["Field"] . ""; $type = "" . $row["Type"] . ""; $tmp_type = strtoupper($type); if (($name == 'punchitems') && ($type != 'varchar(50)')) { - $alter_result = mysql_query("ALTER TABLE " . $db_prefix . "punchlist CHANGE punchitems punchitems VARCHAR(50) NOT NULL"); + $alter_result = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "punchlist CHANGE punchitems punchitems VARCHAR(50) NOT NULL"); echo " Changed: $name field in punchlist table has been changed from type $tmp_type to type VARCHAR(50).\n"; $passed_or_not = "1"; } } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); // add metars table // $table = "metars"; - $result = mysql_query("SHOW TABLES LIKE '" . $db_prefix . $table . "'"); - $rows = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW TABLES LIKE '" . $db_prefix . $table . "'"); + $rows = mysqli_num_rows($result); if (empty($rows)) { - $metars_query = mysql_query("CREATE TABLE " . $db_prefix . "metars (metar varchar(255) NOT NULL default '', + $metars_query = mysqli_query($GLOBALS["___mysqli_ston"], "CREATE TABLE " . $db_prefix . "metars (metar varchar(255) NOT NULL default '', timestamp timestamp(14) NOT NULL, station varchar(4) NOT NULL default '', PRIMARY KEY (station), UNIQUE KEY station (station)) TYPE=MyISAM;"); echo " AddedAdded: $table table has been added to the $db_name database.\n"; @@ -379,22 +379,22 @@ // dbversion table changes // $table = "dbversion"; - $result = mysql_query("SHOW TABLES LIKE '" . $db_prefix . $table . "'"); - $rows = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW TABLES LIKE '" . $db_prefix . $table . "'"); + $rows = mysqli_num_rows($result); if (!empty($rows)) { - $dbversion_result = mysql_query("select * from " . $db_prefix . "dbversion"); - while ($row = mysql_fetch_array($dbversion_result)) { + $dbversion_result = mysqli_query($GLOBALS["___mysqli_ston"], "select * from " . $db_prefix . "dbversion"); + while ($row = mysqli_fetch_array($dbversion_result)) { $tmp_dbversion = "" . $row["dbversion"] . ""; } if (!isset($tmp_dbversion)) { - $compare_result = mysql_query("INSERT INTO " . $db_prefix . "dbversion (dbversion) VALUES ('" . $dbversion . "');"); + $compare_result = mysqli_query($GLOBALS["___mysqli_ston"], "INSERT INTO " . $db_prefix . "dbversion (dbversion) VALUES ('" . $dbversion . "');"); echo " Changed: the version of the database is $dbversion.\n"; $passed_or_not = "1"; } elseif (@$tmp_dbversion != $dbversion) { $update_query = "update dbversion set " . $db_prefix . "dbversion = '" . $dbversion . "'"; - $update_result = mysql_query($update_query); + $update_result = mysqli_query($GLOBALS["___mysqli_ston"], $update_query); echo " Changed: the version of the database has been changed from $tmp_dbversion to $dbversion.\n"; $passed_or_not = "1"; @@ -404,11 +404,11 @@ // add offices table // $table = "offices"; - $result = mysql_query("SHOW TABLES LIKE '" . $db_prefix . $table . "'"); - $rows = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW TABLES LIKE '" . $db_prefix . $table . "'"); + $rows = mysqli_num_rows($result); if (empty($rows)) { - $metars_query = mysql_query("CREATE TABLE " . $db_prefix . "offices (officename varchar(50) NOT NULL default '', + $metars_query = mysqli_query($GLOBALS["___mysqli_ston"], "CREATE TABLE " . $db_prefix . "offices (officename varchar(50) NOT NULL default '', officeid int(10) NOT NULL auto_increment, PRIMARY KEY (officeid), UNIQUE KEY officeid (officeid)) TYPE=MyISAM;"); echo " AddedAddedConvertedConvertedParent Office:  *\n"; - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); echo " * required \n"; echo " \n"; @@ -166,12 +166,12 @@ if (!empty($select_office_name)) { $query = "select * from " . $db_prefix . "offices where officename = '" . $select_office_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $getoffice = "" . $row['officename'] . ""; $officeid = "" . $row['officeid'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); } if ((!isset($getoffice)) && ($select_office_name != '1')) { echo "Office is not defined for this user. Go back and associate this user with an office.\n"; @@ -181,9 +181,9 @@ // check for duplicate groupnames with matching officeids // $query = "select * from " . $db_prefix . "groups where groupname = '" . $post_groupname . "' and officeid = '" . @$officeid . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $tmp_groupname = "" . $row['groupname'] . ""; } @@ -255,14 +255,14 @@ // query to populate dropdown with parent offices // $query = "select * from " . $db_prefix . "offices order by officename asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); echo " Parent Office:  *\n"; - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); echo " * required \n"; echo " \n"; @@ -285,7 +285,7 @@ } else { $query = "insert into " . $db_prefix . "groups (groupname, officeid) values ('" . $post_groupname . "', '" . $officeid . "')"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); echo " \n"; echo "
diff --git a/admin/groupdelete.php b/admin/groupdelete.php index d0fcdd8..e6069d8 100644 --- a/admin/groupdelete.php +++ b/admin/groupdelete.php @@ -96,9 +96,9 @@ echo "
\n"; $query = "select * from " . $db_prefix . "groups, " . $db_prefix . "offices where officename = '" . $get_office . "' and groupname = '" . $get_group . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $officename = "" . $row['officename'] . ""; $officeid = "" . $row['officeid'] . ""; @@ -116,8 +116,8 @@ } $query2 = "select * from " . $db_prefix . "employees where office = '" . $get_office . "' and groups = '" . $get_group . "'"; - $result2 = mysql_query($query2); - @$user_cnt = mysql_num_rows($result2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); + @$user_cnt = mysqli_num_rows($result2); if ($user_cnt > 0) { echo " \n"; @@ -194,12 +194,12 @@ if ((!empty($post_officename)) || (!empty($post_officeid)) || ($office_name != 'no_office_users')) { $query = "select * from " . $db_prefix . "offices where officename = '" . $post_officename . "' and officeid = '" . $post_officeid . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $officename = "" . $row['officename'] . ""; $officeid = "" . $row['officeid'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); } if ((!isset($officename)) || (!isset($officeid))) { echo "Office name is not defined for this group.\n"; @@ -208,12 +208,12 @@ if ((!empty($post_groupname)) || (!empty($post_groupid)) || ($group_name != 'no_group_users')) { $query = "select * from " . $db_prefix . "groups where groupname = '" . $post_groupname . "' and groupid = '" . $post_groupid . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $groupname = "" . $row['groupname'] . ""; $groupid = "" . $row['groupid'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); } if ((!isset($groupname)) || (!isset($groupid))) { echo "Group name is not defined for this group.\n"; @@ -222,12 +222,12 @@ if (!empty($office_name)) { $query = "select * from " . $db_prefix . "offices where officename = '" . $office_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_officename = "" . $row['officename'] . ""; $tmp_officeid = "" . $row['officeid'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); if ((!isset($tmp_officename)) || (!isset($tmp_officeid))) { echo "Office name is not defined for this group.\n"; exit; @@ -236,12 +236,12 @@ if (!empty($group_name)) { $query = "select * from " . $db_prefix . "groups where groupname = '" . $group_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_groupname = "" . $row['groupname'] . ""; $tmp_groupid = "" . $row['groupid'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); if ((!isset($tmp_groupname)) || (!isset($tmp_groupid))) { echo "Group name is not defined for this group.\n"; exit; @@ -262,8 +262,8 @@ } $query = "select * from " . $db_prefix . "employees where office = '" . $post_officename . "' and groups = '" . $post_groupname . "'"; - $result = mysql_query($query); - @$tmp_user_cnt = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + @$tmp_user_cnt = mysqli_num_rows($result); if ($user_cnt != $tmp_user_cnt) { echo "Posted user count does not equal actual user count for this group.\n"; @@ -412,11 +412,11 @@ if ($user_cnt > '0') { $query4 = "update " . $db_prefix . "employees set office = ('" . $office_name . "'), groups = ('" . $group_name . "') where office = ('" . $post_officename . "') and groups = ('" . $post_groupname . "')"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); } $query5 = "delete from " . $db_prefix . "groups where groupid = '" . $post_groupid . "'"; - $result5 = mysql_query($query5); + $result5 = mysqli_query($GLOBALS["___mysqli_ston"], $query5); echo " \n"; diff --git a/admin/groupedit.php b/admin/groupedit.php index 6bf54b0..790cdd2 100644 --- a/admin/groupedit.php +++ b/admin/groupedit.php @@ -95,9 +95,9 @@ echo "
\n"; $query = "select * from " . $db_prefix . "groups, " . $db_prefix . "offices where officename = '" . $get_office . "' and groupname = '" . $get_group . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $officename = "" . $row['officename'] . ""; $officeid = "" . $row['officeid'] . ""; @@ -115,8 +115,8 @@ } $query2 = "select * from " . $db_prefix . "employees where office = '" . $get_office . "' and groups = '" . $get_group . "'"; - $result2 = mysql_query($query2); - @$user_cnt = mysql_num_rows($result2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); + @$user_cnt = mysqli_num_rows($result2); echo " \n"; echo "
Group Name:$post_groupname
\n"; @@ -134,12 +134,12 @@ $query3 = "select * from " . $db_prefix . "offices order by officename asc"; - $result3 = mysql_query($query3); + $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); echo "
New Parent Office:
\n"; - $user_count = mysql_query("select empfullname from " . $db_prefix . "employees where groups = ('" . $get_group . "') and office = ('" . $get_office . "') + $user_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where groups = ('" . $get_group . "') and office = ('" . $get_office . "') order by empfullname"); - @$user_count_rows = mysql_num_rows($user_count); + @$user_count_rows = mysqli_num_rows($user_count); - $admin_count = mysql_query("select empfullname from " . $db_prefix . "employees where admin = '1' and groups = ('" . $get_group . "') + $admin_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where admin = '1' and groups = ('" . $get_group . "') and office = ('" . $get_office . "')"); - @$admin_count_rows = mysql_num_rows($admin_count); + @$admin_count_rows = mysqli_num_rows($admin_count); - $time_admin_count = mysql_query("select empfullname from " . $db_prefix . "employees where time_admin = '1' and groups = ('" . $get_group . "') + $time_admin_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where time_admin = '1' and groups = ('" . $get_group . "') and office = ('" . $get_office . "')"); - @$time_admin_count_rows = mysql_num_rows($time_admin_count); + @$time_admin_count_rows = mysqli_num_rows($time_admin_count); - $reports_count = mysql_query("select empfullname from " . $db_prefix . "employees where reports = '1' and groups = ('" . $get_group . "') + $reports_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where reports = '1' and groups = ('" . $get_group . "') and office = ('" . $get_office . "')"); - @$reports_count_rows = mysql_num_rows($reports_count); + @$reports_count_rows = mysqli_num_rows($reports_count); if ($user_count_rows > '0') { @@ -207,9 +207,9 @@ $query = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees where groups = ('" . $get_group . "') and office = ('" . $get_office . "') order by empfullname"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $empfullname = stripslashes("" . $row['empfullname'] . ""); $displayname = stripslashes("" . $row['displayname'] . ""); @@ -300,11 +300,11 @@ if (!empty($get_office)) { $query = "select * from " . $db_prefix . "offices where officename = '" . $get_office . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $getoffice = "" . $row['officename'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); } if (!isset($getoffice)) { echo "Office is not defined for this user. Go back and associate this user with an office.\n"; @@ -313,11 +313,11 @@ if (!empty($get_group)) { $query = "select * from " . $db_prefix . "groups where groupname = '" . $get_group . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $getgroup = "" . $row['groupname'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); } if (!isset($getgroup)) { echo "Group is not defined for this user. Go back and associate this user with a group.\n"; @@ -326,12 +326,12 @@ if (!empty($post_officename)) { $query = "select * from " . $db_prefix . "offices where officename = '" . $post_officename . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $officename = "" . $row['officename'] . ""; $tmp_officeid = "" . $row['officeid'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); } if (!isset($officename)) { echo "Office name is not defined for this group.\n"; @@ -340,12 +340,12 @@ if (!empty($post_officeid)) { $query = "select * from " . $db_prefix . "offices where officeid = '" . $post_officeid . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $post_officeid = "" . $row['officeid'] . ""; $post_officeid = $tmp_officeid; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); if (!isset($post_officeid)) { echo "Office id is not defined for this group.\n"; exit; @@ -356,11 +356,11 @@ if (!empty($orig_officeid)) { $query = "select * from " . $db_prefix . "offices where officeid = '" . $orig_officeid . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $origofficeid = "" . $row['officeid'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); } if (!isset($origofficeid)) { echo "Office name is not defined for this group.\n"; @@ -369,11 +369,11 @@ if (!empty($post_groupid)) { $query = "select * from " . $db_prefix . "groups where groupid = '" . $post_groupid . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $groupid = "" . $row['groupid'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); } if (!isset($groupid)) { echo "Group id is not defined for this group.\n"; @@ -381,8 +381,8 @@ } $query = "select * from " . $db_prefix . "employees where office = '" . $get_office . "' and groups = '" . $get_group . "'"; - $result = mysql_query($query); - @$tmp_user_cnt = mysql_num_rows($result); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + @$tmp_user_cnt = mysqli_num_rows($result); if ($user_cnt != $tmp_user_cnt) { echo "Posted user count does not equal actual user count for this group.\n"; @@ -397,9 +397,9 @@ if (empty($string)) { $query = "select * from " . $db_prefix . "groups where groupname = '" . $post_groupname . "' and officeid = '" . $post_officeid . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $dupe = '1'; } } @@ -519,12 +519,12 @@ $query3 = "select * from " . $db_prefix . "offices order by officename asc"; - $result3 = mysql_query($query3); + $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); echo "
New Parent Office:
\n"; - $user_count = mysql_query("select empfullname from " . $db_prefix . "employees where groups = ('" . $get_group . "') and office = ('" . $get_office . "') + $user_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where groups = ('" . $get_group . "') and office = ('" . $get_office . "') order by empfullname"); - @$user_count_rows = mysql_num_rows($user_count); + @$user_count_rows = mysqli_num_rows($user_count); - $admin_count = mysql_query("select empfullname from " . $db_prefix . "employees where admin = '1' and groups = ('" . $get_group . "') + $admin_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where admin = '1' and groups = ('" . $get_group . "') and office = ('" . $get_office . "')"); - @$admin_count_rows = mysql_num_rows($admin_count); + @$admin_count_rows = mysqli_num_rows($admin_count); - $time_admin_count = mysql_query("select empfullname from " . $db_prefix . "employees where time_admin = '1' and groups = ('" . $get_group . "') + $time_admin_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where time_admin = '1' and groups = ('" . $get_group . "') and office = ('" . $get_office . "')"); - @$time_admin_count_rows = mysql_num_rows($time_admin_count); + @$time_admin_count_rows = mysqli_num_rows($time_admin_count); - $reports_count = mysql_query("select empfullname from " . $db_prefix . "employees where reports = '1' and groups = ('" . $get_group . "') + $reports_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where reports = '1' and groups = ('" . $get_group . "') and office = ('" . $get_office . "')"); - @$reports_count_rows = mysql_num_rows($reports_count); + @$reports_count_rows = mysqli_num_rows($reports_count); if ($user_count_rows > '0') { @@ -595,9 +595,9 @@ class=table_rows style='padding-left:20px;'>\n"; echo " \n"; @@ -705,21 +705,21 @@ class=table_rows style='padding-left:20px;'>\n"; - $user_count = mysql_query("select empfullname from " . $db_prefix . "employees where groups = ('" . $post_groupname . "') and office = ('" . $post_officename . "') + $user_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where groups = ('" . $post_groupname . "') and office = ('" . $post_officename . "') order by empfullname"); - @$user_count_rows = mysql_num_rows($user_count); + @$user_count_rows = mysqli_num_rows($user_count); - $admin_count = mysql_query("select empfullname from " . $db_prefix . "employees where admin = '1' and groups = ('" . $post_groupname . "') and + $admin_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where admin = '1' and groups = ('" . $post_groupname . "') and office = ('" . $post_officename . "')"); - @$admin_count_rows = mysql_num_rows($admin_count); + @$admin_count_rows = mysqli_num_rows($admin_count); - $time_admin_count = mysql_query("select empfullname from " . $db_prefix . "employees where time_admin = '1' and groups = ('" . $post_groupname . "') and + $time_admin_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where time_admin = '1' and groups = ('" . $post_groupname . "') and office = ('" . $post_officename . "')"); - @$time_admin_count_rows = mysql_num_rows($time_admin_count); + @$time_admin_count_rows = mysqli_num_rows($time_admin_count); - $reports_count = mysql_query("select empfullname from " . $db_prefix . "employees where reports = '1' and groups = ('" . $post_groupname . "') and + $reports_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where reports = '1' and groups = ('" . $post_groupname . "') and office = ('" . $post_officename . "')"); - @$reports_count_rows = mysql_num_rows($reports_count); + @$reports_count_rows = mysqli_num_rows($reports_count); if ($user_count_rows > '0') { @@ -750,9 +750,9 @@ class=table_rows style='padding-left:20px;'>\n"; -echo "\n"; -echo "\n"; -echo "\n"; - -setTimeZone(); - -echo "\n"; -?> +\n"; +echo "\n"; +echo "\n"; +echo "\n"; + +setTimeZone(); + +echo "\n"; +?> diff --git a/admin/header_colorpick.php b/admin/header_colorpick.php index 5ffda2e..9729b57 100644 --- a/admin/header_colorpick.php +++ b/admin/header_colorpick.php @@ -1,14 +1,14 @@ -\n"; -echo "\n"; -echo "\n"; -echo "\n"; -echo "\n"; -echo "\n"; - -setTimeZone(); - -echo "\n"; -?> +\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; + +setTimeZone(); + +echo "\n"; +?> diff --git a/admin/header_date.php b/admin/header_date.php index 8234e3c..4c6b546 100644 --- a/admin/header_date.php +++ b/admin/header_date.php @@ -1,15 +1,15 @@ -\n"; -echo "\n"; -echo "\n"; -echo "\n"; -echo "\n"; -echo "\n"; -echo "\n"; - -setTimeZone(); - -echo "\n"; -?> +\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; + +setTimeZone(); + +echo "\n"; +?> diff --git a/admin/header_get.php b/admin/header_get.php index 48c27f8..0e77f42 100644 --- a/admin/header_get.php +++ b/admin/header_get.php @@ -1,15 +1,15 @@ -\n"; -echo "\n"; -echo "\n"; -echo "\n"; -echo "\n"; -include '../scripts/dropdown_get.php'; -echo "\n"; - -setTimeZone(); - -echo "\n"; -?> +\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +include '../scripts/dropdown_get.php'; +echo "\n"; + +setTimeZone(); + +echo "\n"; +?> diff --git a/admin/header_get_sysedit.php b/admin/header_get_sysedit.php index 0fc9280..abc8296 100644 --- a/admin/header_get_sysedit.php +++ b/admin/header_get_sysedit.php @@ -1,15 +1,15 @@ -\n"; -echo "\n"; -echo "\n"; -echo "\n"; -echo "\n"; -include '../scripts/dropdown_get_sysedit.php'; -echo "\n"; - -setTimeZone(); - -echo "\n"; -?> +\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +include '../scripts/dropdown_get_sysedit.php'; +echo "\n"; + +setTimeZone(); + +echo "\n"; +?> diff --git a/admin/header_post.php b/admin/header_post.php index 416df1b..248f07a 100644 --- a/admin/header_post.php +++ b/admin/header_post.php @@ -1,15 +1,15 @@ -\n"; -echo "\n"; -echo "\n"; -echo "\n"; -echo "\n"; -include '../scripts/dropdown_post.php'; -echo "\n"; - -setTimeZone(); - -echo "\n"; -?> +\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +include '../scripts/dropdown_post.php'; +echo "\n"; + +setTimeZone(); + +echo "\n"; +?> diff --git a/admin/header_post_sysedit.php b/admin/header_post_sysedit.php index af69404..a67a7df 100644 --- a/admin/header_post_sysedit.php +++ b/admin/header_post_sysedit.php @@ -1,15 +1,15 @@ -\n"; -echo "\n"; -echo "\n"; -echo "\n"; -echo "\n"; -include '../scripts/dropdown_post_sysedit.php'; -echo "\n"; - -setTimeZone(); - -echo "\n"; -?> +\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +include '../scripts/dropdown_post_sysedit.php'; +echo "\n"; + +setTimeZone(); + +echo "\n"; +?> diff --git a/admin/index.php b/admin/index.php index 6bb8e74..5dadffa 100644 --- a/admin/index.php +++ b/admin/index.php @@ -1,73 +1,73 @@ -$title - Administration\n"; - -$self = $_SERVER['PHP_SELF']; -$request = $_SERVER['REQUEST_METHOD']; -$row_count = '0'; -$row_color = ($row_count % 2) ? $color2 : $color1; - -if (!isset($_SESSION['valid_user'])) { - - echo "\n"; - echo " \n"; - echo " \n"; - echo "
PHP Timeclock Administration
\n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo "
You are not presently logged in, or do not have permission to view this page.
Click here to login.

\n"; - exit; -} - -echo "\n"; -echo " \n"; -echo " \n"; -echo "
\n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo "
Users
User Summary   - User Summary
Create New User   - Create New User
User Search   - User Search
Offices
Office Summary   - Office Summary
Create New Office   - Create New Office
Groups
Group Summary   - Group Summary
Create New Group   - Create New Group
In/Out Status
Status Summary -   Status Summary
Create Status   - Create Status
Miscellaneous
Add/Edit/Delete Time -   Add/Edit/Delete Time
Edit System Settings -   Edit System Settings
Upgrade Database   Upgrade Database
\n"; -echo " \n"; -echo " \n"; -echo " \n"; + echo " \n"; echo "
\n"; - -include '../templates/admin_index_tpl.php'; -include '../footer.php'; -?> +$title - Administration\n"; + +$self = $_SERVER['PHP_SELF']; +$request = $_SERVER['REQUEST_METHOD']; +$row_count = '0'; +$row_color = ($row_count % 2) ? $color2 : $color1; + +if (!isset($_SESSION['valid_user'])) { + + echo "\n"; + echo " \n"; + echo " \n"; + echo "
PHP Timeclock Administration
\n"; + echo " \n"; + echo " \n"; + echo " \n"; + echo "
You are not presently logged in, or do not have permission to view this page.
Click here to login.

\n"; + exit; +} + +echo "\n"; +echo " \n"; +echo " \n"; +echo " \n"; } + echo " \n"; + echo " \n"; echo "
\n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo "
Users
User Summary   + User Summary
Create New User   + Create New User
User Search   + User Search
Offices
Office Summary   + Office Summary
Create New Office   + Create New Office
Groups
Group Summary   + Group Summary
Create New Group   + Create New Group
In/Out Status
Status Summary +   Status Summary
Create Status   + Create Status
Miscellaneous
Add/Edit/Delete Time +   Add/Edit/Delete Time
Edit System Settings +   Edit System Settings
Upgrade Database   Upgrade Database
\n"; +echo " \n"; +echo " \n"; +echo " \n"; -$user_count = mysql_query("select empfullname from " . $db_prefix . "employees +$user_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees order by empfullname"); -@$user_count_rows = mysql_num_rows($user_count); +@$user_count_rows = mysqli_num_rows($user_count); -$admin_count = mysql_query("select empfullname from " . $db_prefix . "employees where admin = '1'"); -@$admin_count_rows = mysql_num_rows($admin_count); +$admin_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where admin = '1'"); +@$admin_count_rows = mysqli_num_rows($admin_count); -$time_admin_count = mysql_query("select empfullname from " . $db_prefix . "employees where time_admin = '1'"); -@$time_admin_count_rows = mysql_num_rows($time_admin_count); +$time_admin_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where time_admin = '1'"); +@$time_admin_count_rows = mysqli_num_rows($time_admin_count); -$reports_count = mysql_query("select empfullname from " . $db_prefix . "employees where reports = '1'"); -@$reports_count_rows = mysql_num_rows($reports_count); +$reports_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where reports = '1'"); +@$reports_count_rows = mysqli_num_rows($reports_count); echo " \n"; - if (!empty($string)) { - $post_username = addslashes($post_username); - } - if (!empty($string2)) { - $displayname = addslashes($display_name); - } - echo " \n"; echo " \n"; echo " \n"; diff --git a/create_tables.sql b/create_tables.sql index eb524be..ed2e70d 100644 --- a/create_tables.sql +++ b/create_tables.sql @@ -1,41 +1,47 @@ -# if you would like to utilize a table prefix when creating these tables, be sure to reflect that in config.inc.php so the program -# will be aware of it. this option is $db_prefix. if you are unaware of what is meant by utilizing a 'table prefix', then please disregard. --- -------------------------------------------------------- +-- if you would like to utilize a table prefix when creating these tables, +-- be sure to reflect that in config.inc.php so the program will be aware +-- of it. this option is $db_prefix. if you are unaware of what is meant by +-- utilizing a 'table prefix', then please disregard. + +-- -------------------------------------------------------- -- -- Table structure for table `audit` -- CREATE TABLE `audit` ( - `modified_by_ip` varchar(39) COLLATE utf8_bin NOT NULL DEFAULT '', - `modified_by_user` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', - `modified_when` bigint(14) NOT NULL, + `modified_when` bigint(14), `modified_from` bigint(14) NOT NULL, `modified_to` bigint(14) NOT NULL, + `modified_by_ip` varchar(39) COLLATE utf8_bin NOT NULL DEFAULT '', + `modified_by_user` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', `modified_why` varchar(250) COLLATE utf8_bin NOT NULL DEFAULT '', `user_modified` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; --- -------------------------------------------------------- +CREATE INDEX audit_modified_when ON audit (modified_when); + +-- -------------------------------------------------------- -- -- Table structure for table `dbversion` -- CREATE TABLE `dbversion` ( - `dbversion` decimal(5,1) NOT NULL DEFAULT '0.0' + `dbversion` decimal(5,1) PRIMARY KEY ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; INSERT INTO dbversion VALUES ('1.4'); --- -------------------------------------------------------- + +-- -------------------------------------------------------- -- -- Table structure for table `employees` -- CREATE TABLE `employees` ( - `empfullname` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', + `empfullname` varchar(50) PRIMARY KEY COLLATE utf8_bin, `tstamp` bigint(14) DEFAULT NULL, `employee_passwd` varchar(25) COLLATE utf8_bin NOT NULL DEFAULT '', `displayname` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', @@ -48,20 +54,20 @@ CREATE TABLE `employees` ( `disabled` tinyint(1) NOT NULL DEFAULT '0' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; --- -------------------------------------------------------- +-- -------------------------------------------------------- -- -- Table structure for table `groups` -- CREATE TABLE `groups` ( + `groupid` int(10) AUTO_INCREMENT PRIMARY KEY, `groupname` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', - `groupid` int(10) NOT NULL, `officeid` int(10) NOT NULL DEFAULT '0' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; --- -------------------------------------------------------- +-- -------------------------------------------------------- -- -- Table structure for table `info` -- @@ -74,118 +80,53 @@ CREATE TABLE `info` ( `ipaddress` varchar(39) COLLATE utf8_bin NOT NULL DEFAULT '' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; --- -------------------------------------------------------- +CREATE INDEX info_fullname ON info (fullname); +CREATE INDEX info_timestamp ON info (`timestamp`); + +-- -------------------------------------------------------- -- -- Table structure for table `metars` -- CREATE TABLE `metars` ( + `station` varchar(4) PRIMARY KEY COLLATE utf8_bin, `metar` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '', - `timestamp` timestamp NOT NULL, - `station` varchar(4) COLLATE utf8_bin NOT NULL DEFAULT '' + `timestamp` timestamp NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; --- -------------------------------------------------------- +-- -------------------------------------------------------- -- -- Table structure for table `offices` -- CREATE TABLE `offices` ( - `officename` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', - `officeid` int(10) NOT NULL + `officeid` int(10) AUTO_INCREMENT PRIMARY KEY, + `officename` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '' ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; --- -------------------------------------------------------- +-- -------------------------------------------------------- -- -- Table structure for table `punchlist` -- CREATE TABLE `punchlist` ( - `punchitems` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', + `punchitems` varchar(50) PRIMARY KEY COLLATE utf8_bin, `color` varchar(7) COLLATE utf8_bin NOT NULL DEFAULT '', `in_or_out` tinyint(1) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; --- --- Indexes for dumped tables --- - --- --- Indexes for table `audit` --- -ALTER TABLE `audit` - ADD PRIMARY KEY (`modified_when`), - ADD UNIQUE KEY `modified_when` (`modified_when`); - --- --- Indexes for table `dbversion` --- -ALTER TABLE `dbversion` - ADD PRIMARY KEY (`dbversion`); - --- --- Indexes for table `employees` --- -ALTER TABLE `employees` - ADD PRIMARY KEY (`empfullname`); - --- --- Indexes for table `groups` --- -ALTER TABLE `groups` - ADD PRIMARY KEY (`groupid`); - --- --- Indexes for table `info` --- -ALTER TABLE `info` - ADD KEY `fullname` (`fullname`); - --- --- Indexes for table `metars` --- -ALTER TABLE `metars` - ADD PRIMARY KEY (`station`), - ADD UNIQUE KEY `station` (`station`); - --- --- Indexes for table `offices` --- -ALTER TABLE `offices` - ADD PRIMARY KEY (`officeid`); - --- --- Indexes for table `punchlist` --- -ALTER TABLE `punchlist` - ADD PRIMARY KEY (`punchitems`); +-- -------------------------------------------------------- -- --- AUTO_INCREMENT for dumped tables +-- Insert default data. Version, admin login, etc. -- --- --- AUTO_INCREMENT for table `groups` --- -ALTER TABLE `groups` - MODIFY `groupid` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3; --- --- AUTO_INCREMENT for table `offices` --- -ALTER TABLE `offices` - MODIFY `officeid` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2; - - -- - -- Insert default data. Version, admin login, etc. - -- - - INSERT INTO employees VALUES ('admin', NULL, 'xy.RY2HT1QTc2', 'administrator', '', '', '', 1, 1, 1, ''); - INSERT INTO dbversion VALUES ('1.4'); - INSERT INTO punchlist VALUES ('in', '#009900', 1); - INSERT INTO punchlist VALUES ('out', '#FF0000', 0); - INSERT INTO punchlist VALUES ('break', '#FF9900', 0); - INSERT INTO punchlist VALUES ('lunch', '#0000FF', 0); - \ No newline at end of file +INSERT INTO employees VALUES ('admin', NULL, 'xy.RY2HT1QTc2', 'administrator', '', '', '', 1, 1, 1, ''); +INSERT INTO dbversion VALUES ('1.4'); +INSERT INTO punchlist VALUES ('in', '#009900', 1); +INSERT INTO punchlist VALUES ('out', '#FF0000', 0); +INSERT INTO punchlist VALUES ('break', '#FF9900', 0); +INSERT INTO punchlist VALUES ('lunch', '#0000FF', 0); From 0e4937f9aa0ab2a4471d31f750b3201cbd083433 Mon Sep 17 00:00:00 2001 From: Dean Serenevy Date: Fri, 10 Mar 2017 13:54:34 -0500 Subject: [PATCH 16/17] Barcode clock-in Allow barcode clock-in. This required a few changes: - Add a punchnext field to punchlist table which specifies which punch status should be moved to when we scan our barcode. - Add a barcode UNIQUE field to the employees table. - Modify user search to accept barcodes: additionally, I removed the restriction of searching on only a single search term. Terms are now AND-ed together. - Create new configuration options "$barcode_clockin" and "$manual_clockin" which toggle the display of each login form on the main clock-in screen. Due to the creation of the "punchnext" property, the In/Out punch field no longer needs to be filled in even for normal punches (provided the "punchnext" fields have been populated by an administrator). The barcode entry is configured to not auto-complete and is automatically focused on page load, so any barcode scanner or card reader which emulates keyboard input should work fine. --- admin/dbupgrade.php | 2 + admin/statusadmin.php | 8 +- admin/statuscreate.php | 33 ++- admin/statusedit.php | 39 ++- admin/usercreate.php | 35 ++- admin/userdelete.php | 4 + admin/useredit.php | 14 +- admin/usersearch.php | 100 ++++---- config.inc.php | 18 ++ functions.php | 39 +++ leftmain.php | 278 ++++++++++----------- alter_tables.sql => sql/alter_tables.sql | 13 + create_tables.sql => sql/create_tables.sql | 4 +- sql/upgrade_v1.4-v2.0.sql | 5 + 14 files changed, 385 insertions(+), 207 deletions(-) rename alter_tables.sql => sql/alter_tables.sql (89%) rename create_tables.sql => sql/create_tables.sql (96%) create mode 100644 sql/upgrade_v1.4-v2.0.sql diff --git a/admin/dbupgrade.php b/admin/dbupgrade.php index 8ff4ca9..7e208af 100644 --- a/admin/dbupgrade.php +++ b/admin/dbupgrade.php @@ -253,6 +253,7 @@ function ensure_index($table, $field) { $changes_made += ensure_field("employees", "employee_passwd", "varchar(25)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); $changes_made += ensure_field("employees", "displayname", "varchar(50)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); $changes_made += ensure_field("employees", "email", "varchar(75)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); + $changes_made += ensure_field("employees", "barcode", "varchar(75)", "COLLATE utf8_bin UNIQUE"); $changes_made += ensure_field("employees", "groups", "varchar(50)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); $changes_made += ensure_field("employees", "office", "varchar(50)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); $changes_made += ensure_field("employees", "admin", "tinyint(1)", "NOT NULL DEFAULT '0'"); @@ -320,6 +321,7 @@ function ensure_index($table, $field) { $changes_made += ensure_table("punchlist", "punchitems varchar(50) PRIMARY KEY COLLATE utf8_bin"); $changes_made += ensure_field("punchlist", "punchitems", "varchar(50)", "PRIMARY KEY COLLATE utf8_bin"); + $changes_made += ensure_field("punchlist", "punchnext", "varchar(50)", "varchar(50) COLLATE utf8_bin NOT NULL DEFAULT ''"); $changes_made += ensure_field("punchlist", "color", "varchar(7)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); $changes_made += ensure_field("punchlist", "in_or_out", "tinyint(1)", "DEFAULT NULL"); diff --git a/admin/statusadmin.php b/admin/statusadmin.php index 3790aa0..90f92b2 100644 --- a/admin/statusadmin.php +++ b/admin/statusadmin.php @@ -72,7 +72,8 @@ echo "
\n"; + +include '../templates/admin_index_tpl.php'; +include '../footer.php'; +?> diff --git a/admin/officeadmin.php b/admin/officeadmin.php index 3a12d2b..1f8dc8c 100644 --- a/admin/officeadmin.php +++ b/admin/officeadmin.php @@ -81,17 +81,17 @@ $row_count = 0; $query = "select * from " . $db_prefix . "offices order by officename"; -$result = mysql_query($query); +$result = mysqli_query($GLOBALS["___mysqli_ston"], $query); -while ($row = mysql_fetch_array($result)) { +while ($row = mysqli_fetch_array($result)) { $query2 = "select office from " . $db_prefix . "employees where office = '" . $row['officename'] . "'"; - $result2 = mysql_query($query2); - @$user_cnt = mysql_num_rows($result2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); + @$user_cnt = mysqli_num_rows($result2); $query3 = "select * from " . $db_prefix . "groups where officeid = '" . $row['officeid'] . "'"; - $result3 = mysql_query($query3); - @$group_cnt = mysql_num_rows($result3); + $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); + @$group_cnt = mysqli_num_rows($result3); $row_count++; $row_color = ($row_count % 2) ? $color2 : $color1; diff --git a/admin/officecreate.php b/admin/officecreate.php index 37cc96e..54c3a64 100644 --- a/admin/officecreate.php +++ b/admin/officecreate.php @@ -156,9 +156,9 @@ // check for duplicate officenames // $query = "select * from " . $db_prefix . "offices where officename = '" . $post_officename . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $tmp_officename = "" . $row['officename'] . ""; } @@ -315,20 +315,20 @@ if ((@$empty_groupname != '1') && (@$evil_groupname != '1') && (@$groupname_array_cnt == @$unique_groupname_array_cnt)) { $query = "insert into " . $db_prefix . "offices (officename) values ('" . $post_officename . "')"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); $query2 = "select * from " . $db_prefix . "offices where officename = '" . $post_officename . "'"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); - while ($row = mysql_fetch_array($result2)) { + while ($row = mysqli_fetch_array($result2)) { $tmp_officeid = "" . $row['officeid'] . ""; } - mysql_free_result($result2); + ((mysqli_free_result($result2) || (is_object($result2) && (get_class($result2) == "mysqli_result"))) ? true : false); for ($x = 0; $x < $how_many; $x++) { $y = $x + 1; $query3 = "insert into " . $db_prefix . "groups (groupname, officeid) values ('" . $input_group_name[$y] . "', '" . $tmp_officeid . "')"; - $result3 = mysql_query($query3); + $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); } echo " \n"; @@ -431,7 +431,7 @@ class=table_rows colspan=2 width=80% style='padding-left:20px;'> if (!isset($how_many)) { $query = "insert into " . $db_prefix . "offices (officename) values ('" . $post_officename . "')"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); echo "
\n"; echo " \n"; diff --git a/admin/officedelete.php b/admin/officedelete.php index 890f224..e85e577 100644 --- a/admin/officedelete.php +++ b/admin/officedelete.php @@ -92,9 +92,9 @@ echo "
\n"; $query = "select * from " . $db_prefix . "offices where officename = '" . $get_office . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $officename = "" . $row['officename'] . ""; $officeid = "" . $row['officeid'] . ""; @@ -106,12 +106,12 @@ } $query2 = "select office from " . $db_prefix . "employees where office = '" . $get_office . "'"; - $result2 = mysql_query($query2); - @$user_cnt = mysql_num_rows($result2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); + @$user_cnt = mysqli_num_rows($result2); $query3 = "select * from " . $db_prefix . "groups where officeid = '" . $officeid . "'"; - $result3 = mysql_query($query3); - @$group_cnt = mysql_num_rows($result3); + $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); + @$group_cnt = mysqli_num_rows($result3); if ($user_cnt > 0) { echo "
\n"; @@ -208,12 +208,12 @@ class=table_rows width=80% style='padding-left:20px;'> 0) { $query4 = "update " . $db_prefix . "employees set office = ('" . $office_name . "'), groups = ('" . $group_name . "') where office = ('" . $post_officename . "')"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); } $query5 = "delete from " . $db_prefix . "offices where officeid = '" . $post_officeid . "'"; - $result5 = mysql_query($query5); + $result5 = mysqli_query($GLOBALS["___mysqli_ston"], $query5); $query6 = "delete from " . $db_prefix . "groups where officeid = '" . $post_officeid . "'"; - $result6 = mysql_query($query6); + $result6 = mysqli_query($GLOBALS["___mysqli_ston"], $query6); echo " \n"; diff --git a/admin/officeedit.php b/admin/officeedit.php index 5d83c15..5d52f8b 100644 --- a/admin/officeedit.php +++ b/admin/officeedit.php @@ -91,9 +91,9 @@ echo "
\n"; $query = "select * from " . $db_prefix . "offices where officename = '" . $get_office . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $officename = "" . $row['officename'] . ""; $officeid = "" . $row['officeid'] . ""; @@ -109,12 +109,12 @@ } $query2 = "select * from " . $db_prefix . "employees where office = '" . $get_office . "'"; - $result2 = mysql_query($query2); - @$user_cnt = mysql_num_rows($result2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); + @$user_cnt = mysqli_num_rows($result2); $query3 = "select * from " . $db_prefix . "groups where officeid = '" . $officeid . "'"; - $result3 = mysql_query($query3); - @$group_cnt = mysql_num_rows($result3); + $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); + @$group_cnt = mysqli_num_rows($result3); echo " \n"; echo "
Office Name:$post_officename
\n"; @@ -167,15 +167,15 @@ class=table_rows style='padding-left:20px;'>\n"; echo " \n"; @@ -534,15 +534,15 @@ class=table_rows style='padding-left:20px;'>\n"; echo " \n"; diff --git a/admin/statusdelete.php b/admin/statusdelete.php index 940247e..8bb841a 100644 --- a/admin/statusdelete.php +++ b/admin/statusdelete.php @@ -41,9 +41,9 @@ $get_status = $_GET['statusname']; $query = "select * from " . $db_prefix . "punchlist where punchitems = '" . $get_status . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $punchitem = "" . $row['punchitems'] . ""; $color = "" . $row['color'] . ""; @@ -146,9 +146,9 @@ } $query = "select * from " . $db_prefix . "punchlist where punchitems = '" . $post_statusname . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $punchitem = "" . $row['punchitems'] . ""; $color = "" . $row['color'] . ""; @@ -160,7 +160,7 @@ } $query2 = "delete from " . $db_prefix . "punchlist where punchitems = ('" . $post_statusname . "')"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); if ($post_in_out == '1') { $post_in_out = 'In'; diff --git a/admin/statusedit.php b/admin/statusedit.php index d41cfaa..059f204 100644 --- a/admin/statusedit.php +++ b/admin/statusedit.php @@ -41,9 +41,9 @@ $get_status = $_GET['statusname']; $query = "select * from " . $db_prefix . "punchlist where punchitems = '" . $get_status . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $punchitem = "" . $row['punchitems'] . ""; $color = "" . $row['color'] . ""; @@ -148,11 +148,11 @@ if (!empty($get_status)) { $query = "select * from " . $db_prefix . "punchlist where punchitems = '" . $get_status . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $getstatus = "" . $row['punchitems'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); if (!isset($getstatus)) { echo "Status is not defined.\n"; exit; @@ -319,10 +319,10 @@ $query = "update " . $db_prefix . "punchlist set punchitems = ('" . $post_statusname . "'), color = ('" . $post_color . "'), in_or_out = ('" . $create_status . "') where punchitems = ('" . $get_status . "')"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); $query2 = "update " . $db_prefix . "info set `inout` = ('" . $post_statusname . "') where `inout` = ('" . $get_status . "')"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); echo "
\n"; echo " \n"; diff --git a/admin/sysedit.php b/admin/sysedit.php index 1b2ece4..5fe05a8 100644 --- a/admin/sysedit.php +++ b/admin/sysedit.php @@ -343,7 +343,7 @@ echo " \n"; - echo " \n"; + echo " \n"; echo " - - + \n"; $row_count++; $row_color = ($row_count % 2) ? $color2 : $color1; @@ -1317,8 +1316,8 @@ class=table_rows width=80% align=left valign=top>\n"; - echo " \n"; + echo " \n"; echo " - - + \n"; $row_count++; $row_color = ($row_count % 2) ? $color2 : $color1; diff --git a/admin/timeadd.php b/admin/timeadd.php index 5077747..617b046 100644 --- a/admin/timeadd.php +++ b/admin/timeadd.php @@ -101,14 +101,14 @@ $get_user = addslashes($get_user); $query = "select * from " . $db_prefix . "employees where empfullname = '" . $get_user . "' order by empfullname"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $username = stripslashes("" . $row['empfullname'] . ""); $displayname = stripslashes("" . $row['displayname'] . ""); } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); $get_user = stripslashes($_GET['username']); @@ -148,18 +148,18 @@ // query to populate dropdown with statuses // $query2 = "select * from " . $db_prefix . "punchlist order by punchitems asc"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); echo " \n"; - mysql_free_result($result2); + ((mysqli_free_result($result2) || (is_object($result2) && (get_class($result2) == "mysqli_result"))) ? true : false); echo " \n"; @@ -196,8 +196,8 @@ if (!empty($get_user)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $get_user . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_get_user = "" . $row['empfullname'] . ""; } if (!isset($tmp_get_user)) { @@ -208,8 +208,8 @@ if (!empty($post_username)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_username = "" . $row['empfullname'] . ""; } if (!isset($tmp_username)) { @@ -220,8 +220,8 @@ if (!empty($post_displayname)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "' and displayname = '" . $post_displayname . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_post_displayname = "" . $row['displayname'] . ""; } if (!isset($tmp_post_displayname)) { @@ -234,13 +234,13 @@ if ($post_statusname != '1') { $query = "select * from " . $db_prefix . "punchlist where punchitems = '" . $post_statusname . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $punchitems = "" . $row['punchitems'] . ""; $color = "" . $row['color'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); if (!isset($punchitems)) { echo "Something is fishy here.\n"; exit; @@ -498,14 +498,14 @@ // query to populate dropdown with statuses // $query2 = "select * from " . $db_prefix . "punchlist order by punchitems asc"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); echo " \n"; - mysql_free_result($result2); + ((mysqli_free_result($result2) || (is_object($result2) && (get_class($result2) == "mysqli_result"))) ? true : false); echo " \n"; @@ -548,12 +548,12 @@ // check for duplicate time for $post_username $query = "select * from " . $db_prefix . "info where fullname = '" . $post_username . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); $post_username = stripslashes($post_username); $post_displayname = stripslashes($post_displayname); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $info_table_timestamp = "" . $row['timestamp'] . ""; if ($timestamp == $info_table_timestamp) { @@ -594,14 +594,14 @@ // query to populate dropdown with statuses // $query2 = "select * from " . $db_prefix . "punchlist order by punchitems asc"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); echo " \n"; - mysql_free_result($result2); + ((mysqli_free_result($result2) || (is_object($result2) && (get_class($result2) == "mysqli_result"))) ? true : false); echo " \n"; @@ -626,7 +626,7 @@ exit; } } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); // check to see if this would be the most recent time for $post_username. if so, run the update query for the employees table. @@ -634,16 +634,16 @@ $post_displayname = addslashes($post_displayname); $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $employees_table_timestamp = "" . $row['tstamp'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); if ($timestamp > $employees_table_timestamp) { $update_query = "update " . $db_prefix . "employees set tstamp = '" . $timestamp . "' where empfullname = '" . $post_username . "'"; - $update_result = mysql_query($update_query); + $update_result = mysqli_query($GLOBALS["___mysqli_ston"], $update_query); } // determine who the authenticated user is for audit log @@ -674,18 +674,18 @@ $query = "insert into " . $db_prefix . "info (fullname, `inout`, timestamp, notes) values ('" . $post_username . "', '" . $post_statusname . "', '" . $timestamp . "', '" . $post_notes . "')"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); // add the results to the audit table if (strtolower($ip_logging) == "yes") { $query2 = "insert into " . $db_prefix . "audit (modified_by_ip, modified_by_user, modified_when, modified_from, modified_to, modified_why, user_modified) values ('" . $connecting_ip . "', '" . $user . "', '" . $time_tz_stamp . "', '0', '" . $timestamp . "', '" . $post_why . "', '" . $post_username . "')"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); } else { $query2 = "insert into " . $db_prefix . "audit (modified_by_user, modified_when, modified_from, modified_to, modified_why, user_modified) values ('" . $user . "', '" . $time_tz_stamp . "', '0', '" . $timestamp . "', '" . $post_why . "', '" . $post_username . "')"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); } $post_username = stripslashes($post_username); diff --git a/admin/timeadmin.php b/admin/timeadmin.php index f25c6a9..777f740 100644 --- a/admin/timeadmin.php +++ b/admin/timeadmin.php @@ -86,9 +86,9 @@ $query = "select empfullname, displayname, email, groups, office, admin, reports, disabled from " . $db_prefix . "employees order by empfullname"; -$result = mysql_query($query); +$result = mysqli_query($GLOBALS["___mysqli_ston"], $query); -while ($row = mysql_fetch_array($result)) { +while ($row = mysqli_fetch_array($result)) { $empfullname = stripslashes("" . $row['empfullname'] . ""); $displayname = stripslashes("" . $row['displayname'] . ""); diff --git a/admin/timedelete.php b/admin/timedelete.php index c0b1d78..6847917 100644 --- a/admin/timedelete.php +++ b/admin/timedelete.php @@ -102,14 +102,14 @@ $get_user = addslashes($get_user); $query = "select * from " . $db_prefix . "employees where empfullname = '" . $get_user . "' order by empfullname"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $username = stripslashes("" . $row['empfullname'] . ""); $displayname = stripslashes("" . $row['displayname'] . ""); } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); $get_user = stripslashes($get_user); @@ -177,8 +177,8 @@ if (!empty($get_user)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $get_user . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_get_user = "" . $row['empfullname'] . ""; } if (!isset($tmp_get_user)) { @@ -189,8 +189,8 @@ if (!empty($post_username)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_username = "" . $row['empfullname'] . ""; } if (!isset($tmp_username)) { @@ -201,8 +201,8 @@ if (!empty($post_displayname)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "' and displayname = '" . $post_displayname . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_post_displayname = "" . $row['displayname'] . ""; } if (!isset($tmp_post_displayname)) { @@ -427,12 +427,12 @@ //if ((strlen($final_mysql_timestamp[$x]) != "10") || (!is_integer($final_mysql_timestamp[$x]))) {echo "Something is fishy here.\n"; exit;} $query_sel = "select * from " . $db_prefix . "punchlist where punchitems = '" . $final_inout[$x] . "'"; - $result_sel = mysql_query($query_sel); + $result_sel = mysqli_query($GLOBALS["___mysqli_ston"], $query_sel); - while ($row = mysql_fetch_array($result_sel)) { + while ($row = mysqli_fetch_array($result_sel)) { $punchitems = "" . $row['punchitems'] . ""; } - mysql_free_result($result_sel); + ((mysqli_free_result($result_sel) || (is_object($result_sel) && (get_class($result_sel) == "mysqli_result"))) ? true : false); if (!isset($punchitems)) { echo "Something is fishy here.\n"; exit; @@ -443,8 +443,8 @@ $query5 = "select * from " . $db_prefix . "info where (fullname = '" . $final_username[$x] . "') and (timestamp = '" . $final_mysql_timestamp[$x] . "') and (`inout` = '" . $final_inout[$x] . "') and (notes = '" . $final_notes[$x] . "')"; - $result5 = mysql_query($query5); - @$tmp_num_rows = mysql_num_rows($result5); + $result5 = mysqli_query($GLOBALS["___mysqli_ston"], $query5); + @$tmp_num_rows = mysqli_num_rows($result5); if ((isset($tmp_num_rows)) && (@$tmp_num_rows != '1')) { echo "Something is fishy here.\n"; @@ -470,9 +470,9 @@ //if (!get_magic_quotes_gpc()) {$final_username[$x] = addslashes($final_username[$x]);} $query = "select * from " . $db_prefix . "employees where empfullname = '" . $final_username[$x] . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $tmp_empfullname_1 = stripslashes("" . $row['empfullname'] . ""); $tmp_tstamp_1 = "" . $row['tstamp'] . ""; } @@ -482,9 +482,9 @@ if (($tmp_empfullname_1 == $tmp_tmp_username[$x]) && ($tmp_tstamp_1 == $final_mysql_timestamp[$x])) { $query2 = "select * from " . $db_prefix . "info where fullname = '" . $final_username[$x] . "' order by timestamp desc limit 1,1"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); - while ($row2 = mysql_fetch_array($result2)) { + while ($row2 = mysqli_fetch_array($result2)) { $tmp_empfullname_2 = stripslashes("" . $row2['fullname'] . ""); $tmp_empfullname_2 = addslashes($tmp_empfullname_2); $tmp_tstamp_2 = "" . $row2['timestamp'] . ""; @@ -492,24 +492,24 @@ $query3 = "update " . $db_prefix . "employees set empfullname = '" . $tmp_empfullname_2 . "', tstamp = '" . $tmp_tstamp_2 . "' where empfullname = '" . $tmp_empfullname_2 . "'"; - $result3 = mysql_query($query3); + $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); } // delete the time from the info table for $post_username $query4 = "delete from " . $db_prefix . "info where fullname = '" . $final_username[$x] . "' and timestamp = '" . $final_mysql_timestamp[$x] . "'"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); // add the results to the audit table if (strtolower($ip_logging) == "yes") { $query6 = "insert into " . $db_prefix . "audit (modified_by_ip, modified_by_user, modified_when, modified_from, modified_to, modified_why, user_modified) values ('" . $connecting_ip . "', '" . $user . "', '" . $time_tz_stamp . "', '" . $final_mysql_timestamp[$x] . "', '0', '" . $post_why . "', '" . $final_username[$x] . "')"; - $result6 = mysql_query($query6); + $result6 = mysqli_query($GLOBALS["___mysqli_ston"], $query6); } else { $query6 = "insert into " . $db_prefix . "audit (modified_by_user, modified_when, modified_from, modified_to, modified_why, user_modified) values ('" . $user . "', '" . $time_tz_stamp . "', '" . $final_mysql_timestamp[$x] . "', '0', '" . $post_why . "', '" . $final_username[$x] . "')"; - $result6 = mysql_query($query6); + $result6 = mysqli_query($GLOBALS["___mysqli_ston"], $query6); } echo " \n"; @@ -557,14 +557,14 @@ $query = "select * from " . $db_prefix . "info where (fullname = '" . $post_username . "') and ((timestamp < '" . $calc . "') and (timestamp >= '" . $timestamp . "')) order by timestamp asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); $username = array(); $inout = array(); $notes = array(); $mysql_timestamp = array(); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $time_set = '1'; $username[] = "" . $row['fullname'] . ""; @@ -572,7 +572,7 @@ $notes[] = "" . $row['notes'] . ""; $mysql_timestamp[] = "" . $row['timestamp'] . ""; } - $num_rows = mysql_num_rows($result); + $num_rows = mysqli_num_rows($result); $post_username = stripslashes($post_username); @@ -655,14 +655,14 @@ $query = "select * from " . $db_prefix . "info where (fullname = '" . $post_username . "') and ((timestamp < '" . $calc . "') and (timestamp >= '" . $timestamp . "')) order by timestamp asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); $username = array(); $inout = array(); $notes = array(); $mysql_timestamp = array(); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $time_set = '1'; $username[] = "" . $row['fullname'] . ""; @@ -670,7 +670,7 @@ $notes[] = "" . $row['notes'] . ""; $mysql_timestamp[] = "" . $row['timestamp'] . ""; } - $num_rows = mysql_num_rows($result); + $num_rows = mysqli_num_rows($result); } $post_username = stripslashes($post_username); diff --git a/admin/timeedit.php b/admin/timeedit.php index b10f39e..e322e43 100644 --- a/admin/timeedit.php +++ b/admin/timeedit.php @@ -101,14 +101,14 @@ $get_user = addslashes($get_user); $query = "select * from " . $db_prefix . "employees where empfullname = '" . $get_user . "' order by empfullname"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $username = stripslashes("" . $row['empfullname'] . ""); $displayname = stripslashes("" . $row['displayname'] . ""); } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); $get_user = stripslashes($get_user); echo " \n"; + echo "\n"; } // if db is out of date, report it here // diff --git a/admin/useradmin.php b/admin/useradmin.php index dc258fb..420f606 100644 --- a/admin/useradmin.php +++ b/admin/useradmin.php @@ -64,18 +64,18 @@ alt='Upgrade Database' />   Upgrade Database\n"; echo "
VARIABLE VALUE DESCRIPTION
MySql DB Settings
mysql DB Settings
db_hostname: $db_hostname This is the hostname for your @@ -971,9 +971,9 @@ class=table_rows width=80% align=left valign=top>all\n"; $query = "select DISTINCT(groupname) from groups order by groupname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { if ("" . $row['groupname'] . "" == $display_group) { echo " \n"; } else { @@ -1058,15 +1058,14 @@ class=table_rows width=80% align=left valign=top>metar:Sets the ICAO (International - Civil Aviation Organization) for your local airport. This is the unique four letter international ID for the airport. METAR - reports are created at roughly 4500 airports from around the world, so you probably live near one of them. The airports make a - report once or twice an hour, and these reports are stored at the National Weather Service and are publically available via HTTP - or FTP. Visit - https://pilotweb.nas.faa.gov/qryhtml/icao/ to find a corresponding ICAO near you. If 'display_weather' is set - to \"no\", this option is ignored. If 'display_weather' is set to \"yes\", you must provide an ICAO here. + $metarIf 'display_weather' is set + to \"no\", this option is ignored. If 'display_weather' is set to \"yes\", you have to set an WxList in config.inc.php.
+ The ICAO (International Civil Aviation Organization) for your weather location is defined in config.inc.php, not here.
+ You can configure the weather display to use reports created at any of roughly 4500 airports from around the world, + so you probably live near one of them. The reports are stored at the National Weather Service and are publically available via HTTP + or FTP.

Visit + https://pilotweb.nas.faa.gov/qryhtml/icao/ to find a corresponding ICAO near you.
VARIABLE VALUE DESCRIPTION
MySql DB Settings
mysql DB Settings
db_hostname: $db_hostname This is the hostname for your @@ -2324,9 +2323,9 @@ class=table_rows width=80% align=left valign=top> \n"; $query = "select DISTINCT(groupname) from groups order by groupname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { if ("" . $row['groupname'] . "" == $post_group_name) { echo " \n"; } else { @@ -2410,15 +2409,14 @@ class=table_rows width=80% align=left valign=top>metar:Sets the ICAO (International - Civil Aviation Organization) for your local airport. This is the unique four letter international ID for the airport. METAR - reports are created at roughly 4500 airports from around the world, so you probably live near one of them. The airports make a - report once or twice an hour, and these reports are stored at the National Weather Service and are publically available via HTTP - or FTP. Visit - https://pilotweb.nas.faa.gov/qryhtml/icao/ to find a corresponding ICAO near you. If 'display_weather' is set - to \"no\", this option is ignored. If 'display_weather' is set to \"yes\", you must provide an ICAO here. + $post_metarIf 'display_weather' is set + to \"no\", this option is ignored. If 'display_weather' is set to \"yes\", you have to set an WxList in config.inc.php.
+ The ICAO (International Civil Aviation Organization) for your weather location is defined in config.inc.php, not here.
+ You can configure the weather display to use reports created at any of roughly 4500 airports from around the world, + so you probably live near one of them. The reports are stored at the National Weather Service and are publically available via HTTP + or FTP.

Visit + https://pilotweb.nas.faa.gov/qryhtml/icao/ to find a corresponding ICAO near you.
Status:  *
Notes:
Status:  *
Notes:
Status:  *
Notes:
\n"; @@ -175,8 +175,8 @@ if (!empty($get_user)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $get_user . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_get_user = "" . $row['empfullname'] . ""; } if (!isset($tmp_get_user)) { @@ -187,8 +187,8 @@ if (!empty($post_username)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_username = "" . $row['empfullname'] . ""; } if (!isset($tmp_username)) { @@ -199,8 +199,8 @@ if (!empty($post_displayname)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "' and displayname = '" . $post_displayname . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_post_displayname = "" . $row['displayname'] . ""; } if (!isset($tmp_post_displayname)) { @@ -396,12 +396,12 @@ } $query_sel = "select * from " . $db_prefix . "punchlist where punchitems = '" . $final_inout[$x] . "'"; - $result_sel = mysql_query($query_sel); + $result_sel = mysqli_query($GLOBALS["___mysqli_ston"], $query_sel); - while ($row = mysql_fetch_array($result_sel)) { + while ($row = mysqli_fetch_array($result_sel)) { $punchitems = "" . $row['punchitems'] . ""; } - mysql_free_result($result_sel); + ((mysqli_free_result($result_sel) || (is_object($result_sel) && (get_class($result_sel) == "mysqli_result"))) ? true : false); if (!isset($punchitems)) { echo "Something is fishy here.\n"; exit; @@ -412,8 +412,8 @@ $query5 = "select * from " . $db_prefix . "info where (fullname = '" . $final_username[$x] . "') and (timestamp = '" . $final_mysql_timestamp[$x] . "') and (`inout` = '" . $final_inout[$x] . "')"; - $result5 = mysql_query($query5); - @$tmp_num_rows = mysql_num_rows($result5); + $result5 = mysqli_query($GLOBALS["___mysqli_ston"], $query5); + @$tmp_num_rows = mysqli_num_rows($result5); if ((isset($tmp_num_rows)) && (@$tmp_num_rows != '1')) { echo "Something is fishy here.\n"; @@ -607,9 +607,9 @@ $row_color = ($row_count % 2) ? $color1 : $color2; $query = "select * from " . $db_prefix . "employees where empfullname = '" . $final_username[$x] . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $tmp_tstamp = "" . $row['tstamp'] . ""; } @@ -626,29 +626,29 @@ if ($new_tstamp[$x] > $tmp_tstamp) { $query2 = "update " . $db_prefix . "employees set tstamp = '" . $new_tstamp[$x] . "' where empfullname = '" . $final_username[$x] . "'"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); } elseif ($new_tstamp[$x] < $tmp_tstamp) { $query2 = "select * from " . $db_prefix . "info where fullname = '" . $final_username[$x] . "' order by timestamp desc limit 1,1"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); - while ($row2 = mysql_fetch_array($result2)) { + while ($row2 = mysqli_fetch_array($result2)) { $tmp_tstamp_2 = "" . $row2['timestamp'] . ""; } if ($new_tstamp[$x] > @$tmp_tstamp_2) { $query2 = "update " . $db_prefix . "employees set tstamp = '" . $new_tstamp[$x] . "' where empfullname = '" . $final_username[$x] . "'"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); } elseif ($new_tstamp[$x] < @$tmp_tstamp_2) { $query2 = "update " . $db_prefix . "employees set tstamp = '" . $tmp_tstamp_2 . "' where empfullname = '" . $final_username[$x] . "'"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); } } $query3 = "update " . $db_prefix . "info set timestamp = '" . $new_tstamp[$x] . "' where ((fullname = '" . $final_username[$x] . "') and (`inout` = '" . $final_inout[$x] . "') and (timestamp = '" . $final_mysql_timestamp[$x] . "') and (notes = '" . $final_notes[$x] . "'))"; - $result3 = mysql_query($query3); + $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); // add the results to the audit table @@ -656,11 +656,11 @@ $query4 = "insert into " . $db_prefix . "audit (modified_by_ip, modified_by_user, modified_when, modified_from, modified_to, modified_why, user_modified) values ('" . $connecting_ip . "', '" . $user . "', '" . $time_tz_stamp . "', '" . $final_mysql_timestamp[$x] . "', '" . $new_tstamp[$x] . "', '" . $post_why . "', '" . $final_username[$x] . "')"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); } else { $query4 = "insert into " . $db_prefix . "audit (modified_by_user, modified_when, modified_from, modified_to, modified_why, user_modified) values ('" . $user . "', '" . $time_tz_stamp . "', '" . $final_mysql_timestamp[$x] . "', '" . $new_tstamp[$x] . "', '" . $post_why . "', '" . $final_username[$x] . "')"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); } echo "
@@ -702,14 +702,14 @@ $query = "select * from " . $db_prefix . "info where (fullname = '" . $post_username . "') and ((timestamp < '" . $calc . "') and (timestamp >= '" . $timestamp . "')) order by timestamp asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); $username = array(); $inout = array(); $notes = array(); $mysql_timestamp = array(); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $time_set = '1'; $username[] = "" . $row['fullname'] . ""; @@ -717,7 +717,7 @@ $notes[] = "" . $row['notes'] . ""; $mysql_timestamp[] = "" . $row['timestamp'] . ""; } - $num_rows = mysql_num_rows($result); + $num_rows = mysqli_num_rows($result); } $post_username = stripslashes($post_username); diff --git a/admin/topmain.php b/admin/topmain.php index dec9607..fac35ca 100644 --- a/admin/topmain.php +++ b/admin/topmain.php @@ -11,7 +11,7 @@ } else { - echo "
\n"; echo " \n"; @@ -110,9 +110,9 @@ $query = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees order by empfullname"; -$result = mysql_query($query); +$result = mysqli_query($GLOBALS["___mysqli_ston"], $query); -while ($row = mysql_fetch_array($result)) { +while ($row = mysqli_fetch_array($result)) { $empfullname = stripslashes("" . $row['empfullname'] . ""); $displayname = stripslashes("" . $row['displayname'] . ""); diff --git a/admin/usercreate.php b/admin/usercreate.php index b285017..1ce4c97 100644 --- a/admin/usercreate.php +++ b/admin/usercreate.php @@ -139,12 +139,12 @@ $display_name = addslashes($display_name); $query5 = "select empfullname from " . $db_prefix . "employees where empfullname = '" . $post_username . "' order by empfullname"; - $result5 = mysql_query($query5); + $result5 = mysqli_query($GLOBALS["___mysqli_ston"], $query5); - while ($row = mysql_fetch_array($result5)) { + while ($row = mysqli_fetch_array($result5)) { $tmp_username = "" . $row['empfullname'] . ""; } - mysql_free_result($result5); + ((mysqli_free_result($result5) || (is_object($result5) && (get_class($result5) == "mysqli_result"))) ? true : false); $post_username = stripslashes($post_username); $display_name = stripslashes($display_name); @@ -319,11 +319,11 @@ if (!empty($office_name)) { $query = "select * from " . $db_prefix . "offices where officename = '" . $office_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_officename = "" . $row['officename'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); if (!isset($tmp_officename)) { echo "Office is not defined.\n"; exit; @@ -332,11 +332,11 @@ if (!empty($group_name)) { $query = "select * from " . $db_prefix . "groups where groupname = '" . $group_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_groupname = "" . $row['groupname'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); if (!isset($tmp_officename)) { echo "Group is not defined.\n"; exit; @@ -447,7 +447,7 @@ $query3 = "insert into " . $db_prefix . "employees (empfullname, displayname, employee_passwd, email, groups, office, admin, reports, time_admin, disabled) values ('" . $post_username . "', '" . $display_name . "', '" . $password . "', '" . $email_addy . "', '" . $group_name . "', '" . $office_name . "', '" . $admin_perms . "', '" . $reports_perms . "', '" . $time_admin_perms . "', '" . $post_disabled . "')"; - $result3 = mysql_query($query3); + $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); echo "
\n"; echo " \n"; @@ -508,9 +508,9 @@ $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees where empfullname = '" . $post_username . "' order by empfullname"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); - while ($row = mysql_fetch_array($result4)) { + while ($row = mysqli_fetch_array($result4)) { $username = stripslashes("" . $row['empfullname'] . ""); $displayname = stripslashes("" . $row['displayname'] . ""); @@ -522,7 +522,7 @@ $time_admin = "" . $row['time_admin'] . ""; $disabled = "" . $row['disabled'] . ""; } - mysql_free_result($result4); + ((mysqli_free_result($result4) || (is_object($result4) && (get_class($result4) == "mysqli_result"))) ? true : false); echo " \n"; diff --git a/admin/userdelete.php b/admin/userdelete.php index 487c12a..bd54de4 100644 --- a/admin/userdelete.php +++ b/admin/userdelete.php @@ -96,9 +96,9 @@ $row_count = 0; $query = "select * from " . $db_prefix . "employees where empfullname = '" . $get_user . "' order by empfullname"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $username = stripslashes("" . $row['empfullname'] . ""); $displayname = stripslashes("" . $row['displayname'] . ""); @@ -109,14 +109,14 @@ $reports = "" . $row['reports'] . ""; $time_admin = "" . $row['time_admin'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); $get_user = stripslashes($get_user); // make sure you cannot delete the last admin user in the system!! // if (!empty($admin)) { - $admin_count = mysql_query("select empfullname from " . $db_prefix . "employees where admin = '1'"); - @$admin_count_rows = mysql_num_rows($admin_count); + $admin_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where admin = '1'"); + @$admin_count_rows = mysqli_num_rows($admin_count); if (@$admin_count_rows == "1") { $evil = "1"; } @@ -209,8 +209,8 @@ if (!empty($post_username)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_username = "" . $row['empfullname'] . ""; } if (!isset($tmp_username)) { @@ -221,8 +221,8 @@ if (!empty($display_name)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "' and displayname = '" . $display_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_display_name = "" . $row['displayname'] . ""; } if (!isset($tmp_display_name)) { @@ -233,8 +233,8 @@ if (!empty($email_addy)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "' and email = '" . $email_addy . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_email_addy = "" . $row['email'] . ""; } if (!isset($tmp_email_addy)) { @@ -245,8 +245,8 @@ if (!empty($office_name)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "' and office = '" . $office_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_office_name = "" . $row['office'] . ""; } if (!isset($tmp_office_name)) { @@ -257,8 +257,8 @@ if (!empty($group_name)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "' and groups = '" . $group_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_group_name = "" . $row['groups'] . ""; } if (!isset($tmp_group_name)) { @@ -287,11 +287,11 @@ // end post validation // $query2 = "delete from " . $db_prefix . "employees where empfullname = ('" . $post_username . "')"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); if ($delete_data == "1") { $query3 = "delete from " . $db_prefix . "info where fullname = ('" . $post_username . "')"; - $result3 = mysql_query($query3); + $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); } $post_username = stripslashes($post_username); diff --git a/admin/useredit.php b/admin/useredit.php index 95c817f..e43cec7 100644 --- a/admin/useredit.php +++ b/admin/useredit.php @@ -102,9 +102,9 @@ $row_count = 0; $query = "select * from " . $db_prefix . "employees where empfullname = '" . $get_user . "' order by empfullname"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $row_count++; $row_color = ($row_count % 2) ? $color2 : $color1; @@ -119,13 +119,13 @@ $time_admin = "" . $row['time_admin'] . ""; $disabled = "" . $row['disabled'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); // make sure you cannot edit the admin perms for the last admin user in the system!! // if (!empty($admin)) { - $admin_count = mysql_query("select empfullname from " . $db_prefix . "employees where admin = '1'"); - @$admin_count_rows = mysql_num_rows($admin_count); + $admin_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where admin = '1'"); + @$admin_count_rows = mysqli_num_rows($admin_count); if (@$admin_count_rows == "1") { $evil = "1"; } @@ -258,8 +258,8 @@ if (!empty($post_username)) { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_username = "" . $row['empfullname'] . ""; } if (!isset($tmp_username)) { @@ -401,11 +401,11 @@ if (!empty($office_name)) { $query = "select * from " . $db_prefix . "offices where officename = '" . $office_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_officename = "" . $row['officename'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); if (!isset($tmp_officename)) { echo "Office is not defined.\n"; exit; @@ -414,11 +414,11 @@ if (!empty($group_name)) { $query = "select * from " . $db_prefix . "groups where groupname = '" . $group_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_groupname = "" . $row['groupname'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); if (!isset($tmp_officename)) { echo "Group is not defined.\n"; exit; @@ -518,7 +518,7 @@ office = ('" . $office_name . "'), admin = ('" . $admin_perms . "'), reports = ('" . $reports_perms . "'), time_admin = ('" . $time_admin_perms . "'), disabled = ('" . $post_disabled . "') where empfullname = ('" . $post_username . "')"; - $result3 = mysql_query($query3); + $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); echo "
Username:$username
\n"; echo " \n"; @@ -586,9 +586,9 @@ $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees where empfullname = '" . $post_username . "' order by empfullname"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); - while ($row = mysql_fetch_array($result4)) { + while ($row = mysqli_fetch_array($result4)) { $username = stripslashes("" . $row['empfullname'] . ""); $displayname = stripslashes("" . $row['displayname'] . ""); @@ -600,7 +600,7 @@ $time_admin = "" . $row['time_admin'] . ""; $disabled = "" . $row['disabled'] . ""; } - mysql_free_result($result4); + ((mysqli_free_result($result4) || (is_object($result4) && (get_class($result4) == "mysqli_result"))) ? true : false); echo " \n"; diff --git a/admin/usersearch.php b/admin/usersearch.php index bf8c30e..27d0b00 100644 --- a/admin/usersearch.php +++ b/admin/usersearch.php @@ -225,11 +225,11 @@ if (!empty($office_name)) { $query = "select * from " . $db_prefix . "offices where officename = '" . $office_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_officename = "" . $row['officename'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); if (!isset($tmp_officename)) { echo "Office is not defined.\n"; exit; @@ -238,11 +238,11 @@ if (!empty($group_name)) { $query = "select * from " . $db_prefix . "groups where groupname = '" . $group_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $tmp_groupname = "" . $row['groupname'] . ""; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); if (!isset($tmp_officename)) { echo "Group is not defined.\n"; exit; @@ -310,17 +310,17 @@ $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees where empfullname LIKE '%" . $post_username . "%' and office = '" . $office_name . "' and groups = '" . $group_name . "' order by empfullname"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); } elseif (!empty($office_name)) { $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees where empfullname LIKE '%" . $post_username . "%' and office = '" . $office_name . "' order by empfullname"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); } elseif (empty($office_name)) { $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees where empfullname LIKE '%" . $post_username . "%' order by empfullname"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); } } elseif (!empty($display_name)) { $tmp_var = $display_name; @@ -330,17 +330,17 @@ $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees where displayname LIKE '%" . $display_name . "%' and office = '" . $office_name . "' and groups = '" . $group_name . "' order by empfullname"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); } elseif (!empty($office_name)) { $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees where displayname LIKE '%" . $display_name . "%' and office = '" . $office_name . "' order by empfullname"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); } elseif (empty($office_name)) { $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees where displayname LIKE '%" . $display_name . "%' order by empfullname"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); } } elseif (!empty($email_addy)) { $tmp_var = $email_addy; @@ -350,17 +350,17 @@ $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees where email LIKE '%" . $email_addy . "%' and office = '" . $office_name . "' and groups = '" . $group_name . "' order by empfullname"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); } elseif (!empty($office_name)) { $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees where email LIKE '%" . $email_addy . "%' and office = '" . $office_name . "' order by empfullname"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); } elseif (empty($office_name)) { $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees where email LIKE '%" . $email_addy . "%' order by empfullname"; - $result4 = mysql_query($query4); + $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); } } @@ -368,11 +368,11 @@ $tmp_var2 = stripslashes($tmp_var2); $row_count = "0"; -while ($row = mysql_fetch_array($result4)) { +while ($row = mysqli_fetch_array($result4)) { -@$user_count_rows = mysql_num_rows($user_count); -@$admin_count_rows = mysql_num_rows($admin_count); -@$reports_count_rows = mysql_num_rows($reports_count); +@$user_count_rows = mysqli_num_rows($user_count); +@$admin_count_rows = mysqli_num_rows($admin_count); +@$reports_count_rows = mysqli_num_rows($reports_count); $row_count++; @@ -460,7 +460,7 @@ \n"; echo " \n"; } -mysql_free_result($result4); +((mysqli_free_result($result4) || (is_object($result4) && (get_class($result4) == "mysqli_result"))) ? true : false); if ($row_count == "0") { diff --git a/reports/audit.php b/reports/audit.php index 7326cc6..30af2f9 100644 --- a/reports/audit.php +++ b/reports/audit.php @@ -410,9 +410,9 @@ $query = "select * from " . $db_prefix . "audit where modified_when >= '" . $from_timestamp . "' and modified_when <= '" . $to_timestamp . "' order by modified_when asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $modified_when[] = "" . $row["modified_when"] . ""; $modified_from[] = "" . $row["modified_from"] . ""; diff --git a/reports/get_csv.php b/reports/get_csv.php index 9e3ca67..2b87b3f 100644 --- a/reports/get_csv.php +++ b/reports/get_csv.php @@ -3,12 +3,12 @@ include '../config.inc.php'; include '../functions.php'; -@$db = mysql_pconnect($db_hostname, $db_username, $db_password); +@$db = ($GLOBALS["___mysqli_ston"] = mysqli_connect($db_hostname, $db_username, $db_password)); if (!$db) { echo "Error: Could not connect to the database. Please try again later."; exit; } -mysql_select_db($db_name); +mysqli_select_db($GLOBALS["___mysqli_ston"], $db_name); if (($_GET['rpt'] == 'timerpt') && (isset($_GET['display_ip'])) && (isset($_GET['csv'])) && (isset($_GET['office'])) && (isset($_GET['group'])) && (isset($_GET['fullname'])) && (isset($_GET['from'])) && (isset($_GET['to'])) && (isset($_GET['tzo'])) @@ -38,36 +38,36 @@ if (($office_name == "All") && ($group_name == "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif ((empty($office_name)) && (empty($group_name)) && ($fullname == 'All')) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif ((empty($office_name)) && (empty($group_name)) && ($fullname != 'All')) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL and empfullname = '" . $fullname . "' order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name == "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and tstamp IS NOT NULL order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name != "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and groups = '" . $group_name . "' and tstamp IS NOT NULL order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name != "All") && ($fullname != "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and groups = '" . $group_name . "' and empfullname = '" . $fullname . "' and tstamp IS NOT NULL order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } } else { @@ -75,41 +75,41 @@ if (($office_name == "All") && ($group_name == "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif ((empty($office_name)) && (empty($group_name)) && ($fullname == 'All')) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif ((empty($office_name)) && (empty($group_name)) && ($fullname != 'All')) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL and empfullname = '" . $fullname . "' order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name == "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and tstamp IS NOT NULL order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name != "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and groups = '" . $group_name . "' and tstamp IS NOT NULL order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name != "All") && ($fullname != "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and groups = '" . $group_name . "' and empfullname = '" . $fullname . "' and tstamp IS NOT NULL order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } } - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $employees_empfullname[] = stripslashes("" . $row['empfullname'] . ""); $employees_displayname[] = stripslashes("" . $row['displayname'] . ""); @@ -141,9 +141,9 @@ and " . $db_prefix . "info.`inout` = " . $db_prefix . "punchlist.punchitems and " . $db_prefix . "employees.empfullname = '" . $employees_empfullname[$x] . "' order by " . $db_prefix . "info.timestamp asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $display_stamp = "" . $row["timestamp"] . ""; $time = date($timefmt, $display_stamp); @@ -237,36 +237,36 @@ if (($office_name == "All") && ($group_name == "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif ((empty($office_name)) && (empty($group_name)) && ($fullname == 'All')) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif ((empty($office_name)) && (empty($group_name)) && ($fullname != 'All')) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL and empfullname = '" . $fullname . "' order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name == "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and tstamp IS NOT NULL order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name != "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and groups = '" . $group_name . "' and tstamp IS NOT NULL order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name != "All") && ($fullname != "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and groups = '" . $group_name . "' and empfullname = '" . $fullname . "' and tstamp IS NOT NULL order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } @@ -275,41 +275,41 @@ if (($office_name == "All") && ($group_name == "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif ((empty($office_name)) && (empty($group_name)) && ($fullname == 'All')) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif ((empty($office_name)) && (empty($group_name)) && ($fullname != 'All')) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL and empfullname = '" . $fullname . "' order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name == "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and tstamp IS NOT NULL order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name != "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and groups = '" . $group_name . "' and tstamp IS NOT NULL order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name != "All") && ($fullname != "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and groups = '" . $group_name . "' and empfullname = '" . $fullname . "' and tstamp IS NOT NULL order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } } - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $employees_empfullname[] = stripslashes("" . $row['empfullname'] . ""); $employees_displayname[] = stripslashes("" . $row['displayname'] . ""); @@ -342,9 +342,9 @@ and " . $db_prefix . "info.timestamp < '" . $to_timestamp . "' and " . $db_prefix . "info.`inout` = " . $db_prefix . "punchlist.punchitems and " . $db_prefix . "employees.empfullname = '" . $employees_empfullname[$x] . "' order by " . $db_prefix . "info.timestamp asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $info_fullname[] = stripslashes("" . $row['fullname'] . ""); $info_inout[] = "" . $row['inout'] . ""; @@ -915,9 +915,9 @@ $query = "select * from " . $db_prefix . "audit where modified_when >= '" . $from_timestamp . "' and modified_when <= '" . $to_timestamp . "' order by modified_when asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $modified_when[] = "" . $row["modified_when"] . ""; $modified_from[] = "" . $row["modified_from"] . ""; diff --git a/reports/header.reports.inc.php b/reports/header.reports.inc.php index 54edd75..f767709 100644 --- a/reports/header.reports.inc.php +++ b/reports/header.reports.inc.php @@ -27,24 +27,24 @@ // check for correct db version // -@ $db = mysql_pconnect($db_hostname, $db_username, $db_password); +@ $db = ($GLOBALS["___mysqli_ston"] = mysqli_connect($db_hostname, $db_username, $db_password)); if (!$db) { echo "Error: Could not connect to the database. Please try again later."; exit; } -mysql_select_db($db_name); +mysqli_select_db($GLOBALS["___mysqli_ston"], $db_name); $table = "dbversion"; -$result = mysql_query("SHOW TABLES LIKE '" . $db_prefix . $table . "'"); -@$rows = mysql_num_rows($result); +$result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW TABLES LIKE '" . $db_prefix . $table . "'"); +@$rows = mysqli_num_rows($result); if ($rows == "1") { $dbexists = "1"; } else { $dbexists = "0"; } -$db_version_result = mysql_query("select * from " . $db_prefix . "dbversion"); -while (@$row = mysql_fetch_array($db_version_result)) { +$db_version_result = mysqli_query($GLOBALS["___mysqli_ston"], "select * from " . $db_prefix . "dbversion"); +while (@$row = mysqli_fetch_array($db_version_result)) { @$my_dbversion = "" . $row["dbversion"] . ""; } diff --git a/reports/header_get_reports.php b/reports/header_get_reports.php index be02c7c..c7b7819 100644 --- a/reports/header_get_reports.php +++ b/reports/header_get_reports.php @@ -1,16 +1,16 @@ -\n"; -echo "\n"; -echo "\n"; -echo "\n"; -echo "\n"; -echo "\n"; -include '../scripts/dropdown_get_reports.php'; -echo "\n"; - -setTimeZone(); - -echo "\n"; -?> +\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +include '../scripts/dropdown_get_reports.php'; +echo "\n"; + +setTimeZone(); + +echo "\n"; +?> diff --git a/reports/header_post_reports.php b/reports/header_post_reports.php index 7e1fe31..6d713e5 100644 --- a/reports/header_post_reports.php +++ b/reports/header_post_reports.php @@ -1,16 +1,16 @@ -\n"; -echo "\n"; -echo "\n"; -echo "\n"; -echo "\n"; -echo "\n"; -include '../scripts/dropdown_post_reports.php'; -echo "\n"; - -setTimeZone(); - -echo "\n"; -?> +\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +include '../scripts/dropdown_post_reports.php'; +echo "\n"; + +setTimeZone(); + +echo "\n"; +?> diff --git a/reports/index.php b/reports/index.php index 3a0530b..5235493 100644 --- a/reports/index.php +++ b/reports/index.php @@ -1,49 +1,49 @@ -$title\n"; - include '../admin/header.php'; - include 'topmain.php'; - - echo "
Username:$username
\n"; - echo " \n"; - echo " \n"; - echo "
PHP Timeclock Reports
\n"; - echo " \n"; - echo " \n"; - echo " \n"; - echo "
You are not presently logged in, or do not have permission to view this page.
Click here to login.

\n"; - exit; - } -} - -include '../admin/header.php'; - -if ($use_reports_password == "yes") { - include 'topmain.php'; -} else { - include 'topmain.php'; -} -echo "$title - Reports\n"; - -echo "\n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -echo " \n"; -include '../footer.php'; -?> - +$title\n"; + include '../admin/header.php'; + include 'topmain.php'; + + echo "
Run Reports
• Daily Time Report •
• Hours Worked Report •
• Audit Log •
\n"; + echo " \n"; + echo " \n"; + echo "
PHP Timeclock Reports
\n"; + echo " \n"; + echo " \n"; + echo " \n"; + echo "
You are not presently logged in, or do not have permission to view this page.
Click here to login.

\n"; + exit; + } +} + +include '../admin/header.php'; + +if ($use_reports_password == "yes") { + include 'topmain.php'; +} else { + include 'topmain.php'; +} +echo "$title - Reports\n"; + +echo "\n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +echo " \n"; +include '../footer.php'; +?> + diff --git a/reports/timerpt.php b/reports/timerpt.php index e2e1f48..351f85d 100644 --- a/reports/timerpt.php +++ b/reports/timerpt.php @@ -57,20 +57,20 @@ if ($username_dropdown_only == "yes") { $query = "select * from " . $db_prefix . "employees order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); echo " \n"; - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); } else { echo " \n"; - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); } else { echo " \n"; + echo "\n"; } // if db is out of date, report it here // diff --git a/reports/total_hours.php b/reports/total_hours.php index 7d1d677..749b0db 100644 --- a/reports/total_hours.php +++ b/reports/total_hours.php @@ -8,6 +8,16 @@ include '../config.inc.php'; +if (!isset($tzo)) { + settype($tzo, "integer"); + if (isset($_COOKIE['tzoffset'])) { + $tzo = $_COOKIE['tzoffset']; + $tzo = $tzo * 60; + } else { + $tzo = 0; + } +} + if ($use_reports_password == "yes") { if (!isset($_SESSION['valid_reports_user'])) { @@ -58,20 +68,20 @@ if ($username_dropdown_only == "yes") { $query = "select empfullname from " . $db_prefix . "employees order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); echo " \n"; - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); } else { echo " \n"; - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); } else { echo " \n"; -echo " \n"; +echo " \n"; echo " - \n"; $row_count++; $row_color = ($row_count % 2) ? $color2 : $color1; From b71d819db9bb76a58350d038715edee737c15e3b Mon Sep 17 00:00:00 2001 From: Rick Boatright Date: Wed, 25 Jan 2017 18:56:21 -0600 Subject: [PATCH 09/17] updated readme --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 08f8e8f..1ce4610 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,20 @@ About This project is PHP Timeclock v1.04 with the Punchclock v0.8 add-on already installed. +I replaced the phpweather in the left hand sidebar with the saratoga-weather display, which works, and just looks nicer. See http://saratoga-weather.org/metars.php for examples, the original code can be downloaded from http://saratoga-weather.org/scripts-metar.php#metar. + +Added two variables in config.inc.php to support that. + +All calls to the various mysql_* functions have been replaced with calls to mysqli functions where they are compatible, or re-written where nessesary. + +The various problems with un-initialized variables have been fixed. + +All calls to ereg() have been replaced with calls to preg_match and the regular expressions edited as needed. + +Function calls in the lib.timeclock.php which were passing functions as parameters were not quoting the function names being passed, resulting in "Undefined constant" errors. All of those have been fixed. + +As of 25 January 2017, the system now works in PHP 5.6 and mysql 5.7. + Timeclock - What Is It? ======================= From 727fee4e485db921a713252098a379aa1a36e305 Mon Sep 17 00:00:00 2001 From: Rick Boatright Date: Wed, 25 Jan 2017 18:59:49 -0600 Subject: [PATCH 10/17] oops CORRECT version of readme --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 1ce4610..20c5a00 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,9 @@ About This project is PHP Timeclock v1.04 with the Punchclock v0.8 add-on already installed. +This Fork +========= + I replaced the phpweather in the left hand sidebar with the saratoga-weather display, which works, and just looks nicer. See http://saratoga-weather.org/metars.php for examples, the original code can be downloaded from http://saratoga-weather.org/scripts-metar.php#metar. Added two variables in config.inc.php to support that. @@ -53,17 +56,16 @@ Copyright (C) 2006 Ken Papizan REQUIREMENTS: - - at least PHP 4.1.x, with mysql support + - at least PHP 5.3.x, with mysqli support - MySQL - Webserver TESTED: - - PHP 4.34, 5.1.2 with mysql support - - MySQL 3.23.49, 4.0.17, 5.0.18 - - Apache 1.3.22, 1.3.29, 2.2.0 - - Firefox 1.0 - 1.5.0.4, Firefox 1.0 Preview Release, IE 6.0 SP1, IE 6.0 SP2 for XP, IE 7.0 beta 2 - + - PHP 5.6.19 with mysqli support + - MySQL 5.7.22 + - Apache 2.4.18 + Any version of mysql or webserver software that supports php, whether it's an earlier version than what's tested or later, will probably work fine. From e478105dec4325b907d9f654d41b2f0487250e5e Mon Sep 17 00:00:00 2001 From: Rick Boatright Date: Thu, 26 Jan 2017 11:33:39 -0600 Subject: [PATCH 11/17] update readme --- README.md | 85 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 20c5a00..690c810 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,47 @@ -About -===== +# About This project is PHP Timeclock v1.04 with the Punchclock v0.8 add-on already installed. -This Fork -========= +# This Fork -I replaced the phpweather in the left hand sidebar with the saratoga-weather display, which works, and just looks nicer. See http://saratoga-weather.org/metars.php for examples, the original code can be downloaded from http://saratoga-weather.org/scripts-metar.php#metar. +I replaced the phpweather in the left hand sidebar with the saratoga-weather display, which works, and just looks nicer. +See (http://saratoga-weather.org/metars.php) for examples, the original code can be downloaded from +(http://saratoga-weather.org/scripts-metar.php#metar). -Added two variables in config.inc.php to support that. +Added two variables in `config.inc.php` to support the improved weather display `$WxTimeZone` and `$WxList`. -All calls to the various mysql_* functions have been replaced with calls to mysqli functions where they are compatible, or re-written where nessesary. +All calls to the various *mysql_* functions have been replaced with calls to *mysqli* functions +where they are compatible, or re-written where nessesary. The various problems with un-initialized variables have been fixed. -All calls to ereg() have been replaced with calls to preg_match and the regular expressions edited as needed. +All calls to ereg() have been replaced with calls to preg_match and +the regular expressions edited as needed. -Function calls in the lib.timeclock.php which were passing functions as parameters were not quoting the function names being passed, resulting in "Undefined constant" errors. All of those have been fixed. +Function calls in the `lib.timeclock.php` which were passing functions as parameters were not quoting +the function names being passed, resulting in "Undefined constant" errors. All of those have been fixed. As of 25 January 2017, the system now works in PHP 5.6 and mysql 5.7. -Timeclock - What Is It? -======================= +# Timeclock - What Is It? (from http://timeclock.sf.net/ ...) -It is a simple yet effective web-based timeclock system. It allows you to track all employee time as well as upcoming vacations and more, and it can replace manual sign-in/sign-out sheets. +It is a simple yet effective web-based timeclock system. It allows you to track all employee time +as well as upcoming vacations and more, and it can replace manual sign-in/sign-out sheets. -An administration piece is included which allows an administrator to add or delete users, change a user's time or password (if using passwords is enabled), and hide the reports from your users where only an admin or a reports user has access to them. These reports can be run to show daily activitiy or for a range of dates, and can be run for all users, or individually for each user. +An administration piece is included which allows an administrator to add or delete users, change a +user's time or password (if using passwords is enabled), and hide the reports from your users where +only an admin or a reports user has access to them. These reports can be run to show daily activitiy +or for a range of dates, and can be run for all users, or individually for each user. -This product is distributed under the GPL. This program is free software; you can redistribute it and/or modify it under the terms of the GNU GeneralPublic License version 2, as published by the Free Software Foundation. +This product is distributed under the GPL. This program is free software; you can redistribute it and/or +modify it under the terms of the GNU GeneralPublic License version 2, as published by the +Free Software Foundation. -Punchclock - What Is It? -======================== +# Punchclock - What Is It? (from http://www.acmebase.org/punchclock/ ...) @@ -42,25 +49,25 @@ Punchclock is a drop-in enhancement to the Open Source PHP Timeclock software. Punchclock enhances PHP Timeclock with 5 extra features: - Computes overtime hours. - Keeps time cards for each employee. - Punchclock entry intended to replace your punchclock at the door. - Personal data entry screen for office personnel and mobile devices. - Flexible export to your spreadsheet or business software. + - Computes overtime hours. + - Keeps time cards for each employee. + - Punchclock entry intended to replace your punchclock at the door. + - Personal data entry screen for office personnel and mobile devices. + - Flexible export to your spreadsheet or business software. -PHP Timeclock -Version 1.04 -http://sourceforge.net/projects/timeclock -Copyright (C) 2006 Ken Papizan +## PHP Timeclock source credits +- Version 1.04 +- http://sourceforge.net/projects/timeclock +- Copyright (C) 2006 Ken Papizan -REQUIREMENTS: +### REQUIREMENTS: - at least PHP 5.3.x, with mysqli support - MySQL - Webserver -TESTED: +### TESTED: - PHP 5.6.19 with mysqli support - MySQL 5.7.22 @@ -69,12 +76,9 @@ TESTED: Any version of mysql or webserver software that supports php, whether it's an earlier version than what's tested or later, will probably work fine. - - ##Installation -New Install -___ +### New Install - Unpack the distribution into your webserver's document root directory. - Create a database named "timeclock" or whatever you wish to name it. @@ -98,20 +102,27 @@ ___ certain users can run them, then give these users reports level access. -Migration from another verison of 1.04 (ie: old official release) -___ +### Migration from another verison of 1.04 (ie: old official release) - Backup your current install directory and database. - Delete all files in your current install directory. - - Copy all files from a zip of this repo's master branch (https://github.com/andrew867/timeclock/archive/master.zip) into your install directory. - - Modify the new `config.inc.php` file to match your old settings, make sure you correctly set your timezone in php.ini (recommended) or `config.inc.php`. + - Copy all files from a zip of this repo's master branch + (https://github.com/boatright/timeclock/archive/master.zip) into your install directory. + - Modify the new `config.inc.php` file to match your old settings, make sure you correctly + set your timezone in php.ini (recommended) or `config.inc.php`. + - See the notes in config.inc.php about entering the new variables for weather display. +# FAQs ##Roles -Admin level access and reports level access are completely separate from each other. Just because a user has admin level access does not give that user reports level access. You must specifically give them reports level access when you are creating or editing the users, if you choose to secure these reports for these users. To make PHP Timeclock lock down the reports to only these users, set the use_reports_password setting in config.inc.php to "yes". + +Admin level access and reports level access are completely separate from each other. +Just because a user has admin level access does not give that user reports level access. +You must specifically give them reports level access when you are creating or editing the users, +if you choose to secure these reports for these users. To make PHP Timeclock lock down the +reports to only these users, set the use_reports_password setting in config.inc.php to "yes". ##License -________ This software and changes made are licensed under the GNU GENERAL PUBLIC LICENSE 2 as found in docs/LICENSE From 96b57174807b482828083d07eee24d3de7185802 Mon Sep 17 00:00:00 2001 From: Rick Boatright Date: Thu, 26 Jan 2017 15:10:02 -0600 Subject: [PATCH 12/17] collation in sql, document config --- config.inc.php | 11 ++ create_tables.sql | 327 ++++++++++++++++++++++++++-------------------- 2 files changed, 195 insertions(+), 143 deletions(-) diff --git a/config.inc.php b/config.inc.php index 2e8e6ec..6499534 100644 --- a/config.inc.php +++ b/config.inc.php @@ -141,6 +141,17 @@ /* Choose the way times are displayed. Default is "g:i a". + g 12-hour format of an hour without leading zeros 1 through 12 + G 24-hour format of an hour without leading zeros 0 through 23 + h 12-hour format of an hour with leading zeros 01 through 12 + H 24-hour format of an hour with leading zeros 00 through 23 + + i Minutes with leading zeros + + a Lowercase Ante meridiem and Post meridiem am or pm + A Uppercase Ante meridiem and Post meridiem + + Possibilities for this variable are: $timefmt --> 1) G:i diff --git a/create_tables.sql b/create_tables.sql index 073cf37..eb524be 100644 --- a/create_tables.sql +++ b/create_tables.sql @@ -1,150 +1,191 @@ # if you would like to utilize a table prefix when creating these tables, be sure to reflect that in config.inc.php so the program # will be aware of it. this option is $db_prefix. if you are unaware of what is meant by utilizing a 'table prefix', then please disregard. -# -# Table structure for table `audit` -# - -CREATE TABLE audit ( - modified_by_ip VARCHAR(39) NOT NULL DEFAULT '', - modified_by_user VARCHAR(50) NOT NULL DEFAULT '', - modified_when BIGINT(14) NOT NULL, - modified_from BIGINT(14) NOT NULL, - modified_to BIGINT(14) NOT NULL, - modified_why VARCHAR(250) NOT NULL DEFAULT '', - user_modified VARCHAR(50) NOT NULL DEFAULT '', - PRIMARY KEY (modified_when), - UNIQUE KEY modified_when (modified_when) -) - ENGINE =MyISAM; - -# -------------------------------------------------------- - -# -# Table structure for table `dbversion` -# - -CREATE TABLE dbversion ( - dbversion DECIMAL(5, 1) NOT NULL DEFAULT '0.0', - PRIMARY KEY (dbversion) -) - ENGINE =MyISAM; - -# -# Dumping data for table `dbversion` -# +-- -------------------------------------------------------- -INSERT INTO dbversion VALUES ('1.4'); +-- +-- Table structure for table `audit` +-- + +CREATE TABLE `audit` ( + `modified_by_ip` varchar(39) COLLATE utf8_bin NOT NULL DEFAULT '', + `modified_by_user` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', + `modified_when` bigint(14) NOT NULL, + `modified_from` bigint(14) NOT NULL, + `modified_to` bigint(14) NOT NULL, + `modified_why` varchar(250) COLLATE utf8_bin NOT NULL DEFAULT '', + `user_modified` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; -# -------------------------------------------------------- - -# -# Table structure for table `employees` -# - -CREATE TABLE employees ( - empfullname VARCHAR(50) NOT NULL DEFAULT '', - tstamp BIGINT(14) DEFAULT NULL, - employee_passwd VARCHAR(25) NOT NULL DEFAULT '', - displayname VARCHAR(50) NOT NULL DEFAULT '', - email VARCHAR(75) NOT NULL DEFAULT '', - groups VARCHAR(50) NOT NULL DEFAULT '', - office VARCHAR(50) NOT NULL DEFAULT '', - admin TINYINT(1) NOT NULL DEFAULT '0', - reports TINYINT(1) NOT NULL DEFAULT '0', - time_admin TINYINT(1) NOT NULL DEFAULT '0', - disabled TINYINT(1) NOT NULL DEFAULT '0', - PRIMARY KEY (empfullname) -) - ENGINE =MyISAM; - -# -# Dumping data for table `employees` -# - -INSERT INTO employees VALUES ('admin', NULL, 'xy.RY2HT1QTc2', 'administrator', '', '', '', 1, 1, 1, ''); - -# -------------------------------------------------------- - -# -# Table structure for table `groups` -# - -CREATE TABLE groups ( - groupname VARCHAR(50) NOT NULL DEFAULT '', - groupid INT(10) NOT NULL AUTO_INCREMENT, - officeid INT(10) NOT NULL DEFAULT '0', - PRIMARY KEY (groupid) -) - ENGINE =MyISAM; - -# -------------------------------------------------------- - -# -# Table structure for table `info` -# - -CREATE TABLE info ( - fullname VARCHAR(50) NOT NULL DEFAULT '', - `inout` VARCHAR(50) NOT NULL DEFAULT '', - timestamp BIGINT(14) DEFAULT NULL, - notes VARCHAR(250) DEFAULT NULL, - ipaddress VARCHAR(39) NOT NULL DEFAULT '', - KEY fullname (fullname) -) - ENGINE =MyISAM; - -# -------------------------------------------------------- - -# -# Table structure for table `metars` -# - -CREATE TABLE metars ( - metar VARCHAR(255) NOT NULL DEFAULT '', - timestamp TIMESTAMP NOT NULL, - station VARCHAR(4) NOT NULL DEFAULT '', - PRIMARY KEY (station), - UNIQUE KEY station (station) -) - ENGINE =MyISAM; - -# -------------------------------------------------------- - -# -# Table structure for table `offices` -# - -CREATE TABLE offices ( - officename VARCHAR(50) NOT NULL DEFAULT '', - officeid INT(10) NOT NULL AUTO_INCREMENT, - PRIMARY KEY (officeid) -) - ENGINE =MyISAM; - -# -------------------------------------------------------- - -# -# Table structure for table `punchlist` -# - -CREATE TABLE punchlist ( - punchitems VARCHAR(50) NOT NULL DEFAULT '', - color VARCHAR(7) NOT NULL DEFAULT '', - in_or_out TINYINT(1) DEFAULT NULL, - PRIMARY KEY (punchitems) -) - ENGINE =MyISAM; - -# -# Dumping data for table `punchlist` -# - -INSERT INTO punchlist VALUES ('in', '#009900', 1); -INSERT INTO punchlist VALUES ('out', '#FF0000', 0); -INSERT INTO punchlist VALUES ('break', '#FF9900', 0); -INSERT INTO punchlist VALUES ('lunch', '#0000FF', 0); - -# -------------------------------------------------------- +-- -------------------------------------------------------- +-- +-- Table structure for table `dbversion` +-- +CREATE TABLE `dbversion` ( + `dbversion` decimal(5,1) NOT NULL DEFAULT '0.0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + +INSERT INTO dbversion VALUES ('1.4'); +-- -------------------------------------------------------- + +-- +-- Table structure for table `employees` +-- + +CREATE TABLE `employees` ( + `empfullname` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', + `tstamp` bigint(14) DEFAULT NULL, + `employee_passwd` varchar(25) COLLATE utf8_bin NOT NULL DEFAULT '', + `displayname` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', + `email` varchar(75) COLLATE utf8_bin NOT NULL DEFAULT '', + `groups` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', + `office` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', + `admin` tinyint(1) NOT NULL DEFAULT '0', + `reports` tinyint(1) NOT NULL DEFAULT '0', + `time_admin` tinyint(1) NOT NULL DEFAULT '0', + `disabled` tinyint(1) NOT NULL DEFAULT '0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `groups` +-- + +CREATE TABLE `groups` ( + `groupname` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', + `groupid` int(10) NOT NULL, + `officeid` int(10) NOT NULL DEFAULT '0' +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `info` +-- + +CREATE TABLE `info` ( + `fullname` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', + `inout` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', + `timestamp` bigint(14) DEFAULT NULL, + `notes` varchar(250) COLLATE utf8_bin DEFAULT NULL, + `ipaddress` varchar(39) COLLATE utf8_bin NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `metars` +-- + +CREATE TABLE `metars` ( + `metar` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '', + `timestamp` timestamp NOT NULL, + `station` varchar(4) COLLATE utf8_bin NOT NULL DEFAULT '' +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `offices` +-- + +CREATE TABLE `offices` ( + `officename` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', + `officeid` int(10) NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `punchlist` +-- + +CREATE TABLE `punchlist` ( + `punchitems` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', + `color` varchar(7) COLLATE utf8_bin NOT NULL DEFAULT '', + `in_or_out` tinyint(1) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; + +-- +-- Indexes for dumped tables +-- + +-- +-- Indexes for table `audit` +-- +ALTER TABLE `audit` + ADD PRIMARY KEY (`modified_when`), + ADD UNIQUE KEY `modified_when` (`modified_when`); + +-- +-- Indexes for table `dbversion` +-- +ALTER TABLE `dbversion` + ADD PRIMARY KEY (`dbversion`); + +-- +-- Indexes for table `employees` +-- +ALTER TABLE `employees` + ADD PRIMARY KEY (`empfullname`); + +-- +-- Indexes for table `groups` +-- +ALTER TABLE `groups` + ADD PRIMARY KEY (`groupid`); + +-- +-- Indexes for table `info` +-- +ALTER TABLE `info` + ADD KEY `fullname` (`fullname`); + +-- +-- Indexes for table `metars` +-- +ALTER TABLE `metars` + ADD PRIMARY KEY (`station`), + ADD UNIQUE KEY `station` (`station`); + +-- +-- Indexes for table `offices` +-- +ALTER TABLE `offices` + ADD PRIMARY KEY (`officeid`); + +-- +-- Indexes for table `punchlist` +-- +ALTER TABLE `punchlist` + ADD PRIMARY KEY (`punchitems`); + +-- +-- AUTO_INCREMENT for dumped tables +-- + +-- +-- AUTO_INCREMENT for table `groups` +-- +ALTER TABLE `groups` + MODIFY `groupid` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3; +-- +-- AUTO_INCREMENT for table `offices` +-- +ALTER TABLE `offices` + MODIFY `officeid` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2; + + -- + -- Insert default data. Version, admin login, etc. + -- + + INSERT INTO employees VALUES ('admin', NULL, 'xy.RY2HT1QTc2', 'administrator', '', '', '', 1, 1, 1, ''); + INSERT INTO dbversion VALUES ('1.4'); + INSERT INTO punchlist VALUES ('in', '#009900', 1); + INSERT INTO punchlist VALUES ('out', '#FF0000', 0); + INSERT INTO punchlist VALUES ('break', '#FF9900', 0); + INSERT INTO punchlist VALUES ('lunch', '#0000FF', 0); + \ No newline at end of file From 83c008158988c2e50504953dc494bde10bc6bfee Mon Sep 17 00:00:00 2001 From: Rick Boatright Date: Thu, 26 Jan 2017 15:12:05 -0600 Subject: [PATCH 13/17] fix regex. // 12 Hour with or without leading zeros with upper or lower case AM or PM // First digit of hours in 12 hour format can not be > 1. // First digit of minutes can not be > 5 any time. // 24 Hour with or without leading zeros with upper or lower case AM or PM // First digit of hours in 24 hour format can not be > 2. // First digit of minutes can not be > 5 any time. // No am/pm in 24 hour format. No need for case indifferent /i. --- admin/timeedit.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/admin/timeedit.php b/admin/timeedit.php index e322e43..5a09af2 100644 --- a/admin/timeedit.php +++ b/admin/timeedit.php @@ -442,6 +442,12 @@ // end post validation // if ($timefmt_24hr == '0') { + + // 12 Hour with or without leading zeros with upper or lower case AM or PM // + // Regex was /^([0-9]?[0-9])+:+([0-9]+[0-9])+([a|p]+m)$/i // + // Now /^([0-1]?[0-9])+:+([0-5]+[0-9])+([a|p]+m)$/i // + // First digit of hours in 12 hour format can not be > 1. // + // First digit of minutes can not be > 5 any time. // if ((!preg_match('/' . "^([0-9]?[0-9])+:+([0-9]+[0-9])+([a|p]+m)$" . '/i', $edit_time_textbox[$x], $time_regs)) && (!preg_match('/' . "^([0-9]?[0-9])+:+([0-9]+[0-9])+( [a|p]+m)$" . '/i', $edit_time_textbox[$x], $time_regs))) { $evil_time = '1'; @@ -458,7 +464,15 @@ } } } elseif ($timefmt_24hr == '1') { - if (!preg_match('/' . "^([0-9]?[0-9])+:+([0-9]+[0-9])+([a|p]+m)$" . '/i', $edit_time_textbox[$x], $time_regs)) { + + // 24 Hour with or without leading zeros with upper or lower case AM or PM // + // Regex was /^([0-9]?[0-9])+:+([0-9]+[0-9])+([a|p]+m)$/i // + // Now /^([0-2]?[0-9])+:+([0-5]+[0-9])+$/ // + // First digit of hours in 24 hour format can not be > 2. // + // First digit of minutes can not be > 5 any time. // + // No am/pm in 24 hour format. No need for case indifferent /i. // + + if (!preg_match('/' . "^([0-2]?[0-9])+:+([0-5]+[0-9])+$" . '/', $edit_time_textbox[$x], $time_regs)) { $evil_time = '1'; } else { From 506976d6d2706bc366c32d2d17a9c4722f137754 Mon Sep 17 00:00:00 2001 From: Dean Serenevy Date: Fri, 24 Feb 2017 16:39:11 -0500 Subject: [PATCH 14/17] Start using placeholders in DB queries Create some helper functions to prepare/execute and return result objects so that code can move away from stripslashes/addslashes insanity without too much pain. Converted a handful of scripts so far. --- admin/statusadmin.php | 3 +- admin/statuscreate.php | 27 +------ admin/statusdelete.php | 14 ++-- admin/statusedit.php | 53 +++++------- admin/usercreate.php | 103 ++++++++---------------- admin/userdelete.php | 108 ++++++++----------------- admin/useredit.php | 132 ++++++++++++------------------ admin/usersearch.php | 134 ++++++++++--------------------- functions.php | 113 ++++++++++++++++++++++++++ leftmain.php | 177 ++++++++++++----------------------------- 10 files changed, 345 insertions(+), 519 deletions(-) diff --git a/admin/statusadmin.php b/admin/statusadmin.php index 70a850d..3790aa0 100644 --- a/admin/statusadmin.php +++ b/admin/statusadmin.php @@ -79,8 +79,7 @@ $row_count = 0; -$query = "select * from " . $db_prefix . "punchlist"; -$result = mysqli_query($GLOBALS["___mysqli_ston"], $query); +$result = tc_select("*", "punchlist"); while ($row = mysqli_fetch_array($result)) { diff --git a/admin/statuscreate.php b/admin/statuscreate.php index 8557c82..1c31f2e 100644 --- a/admin/statuscreate.php +++ b/admin/statuscreate.php @@ -153,16 +153,11 @@ exit; } - $post_statusname = stripslashes($post_statusname); - $post_statusname = addslashes($post_statusname); - - $string = strstr($post_statusname, "\'"); + $string = strstr($post_statusname, "'"); $string2 = strstr($post_statusname, "\""); if (empty($string)) { - $query = "select punchitems from " . $db_prefix . "punchlist where punchitems = '" . $post_statusname . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - + $result = tc_select("punchitems", "punchlist", "punchitems = ?", $post_statusname); while ($row = mysqli_fetch_array($result)) { $dupe = '1'; } @@ -213,13 +208,6 @@ echo "
Run Reports
• Daily Time Report •
• Hours Worked Report •
• Audit Log •
Username:  *
Choose Office: @@ -147,9 +147,9 @@ if ($fullname != "All") { $query = "select * from " . $db_prefix . "employees where empfullname = '" . $fullname . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $empfullname = stripslashes("" . $row['empfullname'] . ""); $displayname = stripslashes("" . $row['displayname'] . ""); } @@ -162,8 +162,8 @@ if (($office_name != "All") && (!empty($office_name))) { $query = "select officename from " . $db_prefix . "offices where officename = '" . $office_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $getoffice = "" . $row['officename'] . ""; } if (!isset($getoffice)) { @@ -173,8 +173,8 @@ } if (($group_name != "All") && (!empty($group_name))) { $query = "select groupname from " . $db_prefix . "groups where groupname = '" . $group_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $getgroup = "" . $row['groupname'] . ""; } if (!isset($getgroup)) { @@ -425,20 +425,20 @@ if ($username_dropdown_only == "yes") { $query = "select * from " . $db_prefix . "employees order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); echo "
Username:  *
Choose Office: 'admin' order by " . $db_prefix . "info.timestamp asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $display_stamp = "" . $row["timestamp"] . ""; $time = date($timefmt, $display_stamp); diff --git a/reports/topmain.php b/reports/topmain.php index bc5ec0c..e639418 100644 --- a/reports/topmain.php +++ b/reports/topmain.php @@ -11,7 +11,7 @@ } else { - echo "
Username:  *
Choose Office: @@ -239,9 +249,9 @@ if ($fullname != "All") { $query = "select empfullname, displayname from " . $db_prefix . "employees where empfullname = '" . $fullname . "'"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $empfullname = stripslashes("" . $row['empfullname'] . ""); $displayname = stripslashes("" . $row['displayname'] . ""); } @@ -254,8 +264,8 @@ if (($office_name != "All") && (!empty($office_name))) { $query = "select officename from " . $db_prefix . "offices where officename = '" . $office_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $getoffice = "" . $row['officename'] . ""; } if (!isset($getoffice)) { @@ -265,8 +275,8 @@ } if (($group_name != "All") && (!empty($group_name))) { $query = "select groupname from " . $db_prefix . "groups where groupname = '" . $group_name . "'"; - $result = mysql_query($query); - while ($row = mysql_fetch_array($result)) { + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + while ($row = mysqli_fetch_array($result)) { $getgroup = "" . $row['groupname'] . ""; } if (!isset($getgroup)) { @@ -574,20 +584,20 @@ if ($username_dropdown_only == "yes") { $query = "select empfullname from " . $db_prefix . "employees order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); echo "
Username:  *
Choose Office: 'admin' order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif ((empty($office_name)) && (empty($group_name)) && ($fullname == 'All')) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL and empfullname <> 'admin' order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif ((empty($office_name)) && (empty($group_name)) && ($fullname != 'All')) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL and empfullname = '" . $fullname . "' and empfullname <> 'admin' order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name == "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and tstamp IS NOT NULL and empfullname <> 'admin' order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name != "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and groups = '" . $group_name . "' and tstamp IS NOT NULL and empfullname <> 'admin' order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name != "All") && ($fullname != "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and groups = '" . $group_name . "' and empfullname = '" . $fullname . "' and empfullname <> 'admin' and tstamp IS NOT NULL order by displayname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } @@ -878,42 +888,42 @@ $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL and empfullname <> 'admin' order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif ((empty($office_name)) && (empty($group_name)) && ($fullname == 'All')) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL and empfullname <> 'admin' order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif ((empty($office_name)) && (empty($group_name)) && ($fullname != 'All')) { $query = "select empfullname, displayname from " . $db_prefix . "employees WHERE tstamp IS NOT NULL and empfullname = '" . $fullname . "' and empfullname <> 'admin' order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name == "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and tstamp IS NOT NULL and empfullname <> 'admin' order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name != "All") && ($fullname == "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and groups = '" . $group_name . "' and tstamp IS NOT NULL and empfullname <> 'admin' order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } elseif (($office_name != "All") && ($group_name != "All") && ($fullname != "All")) { $query = "select empfullname, displayname from " . $db_prefix . "employees where office = '" . $office_name . "' and groups = '" . $group_name . "' and empfullname = '" . $fullname . "' and empfullname <> 'admin' and tstamp IS NOT NULL order by empfullname asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); } } - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $employees_empfullname[] = stripslashes("" . $row['empfullname'] . ""); $employees_displayname[] = stripslashes("" . $row['displayname'] . ""); @@ -946,9 +956,9 @@ and " . $db_prefix . "info.timestamp < '" . $to_timestamp . "' and " . $db_prefix . "info.`inout` = " . $db_prefix . "punchlist.punchitems and " . $db_prefix . "employees.empfullname = '" . $employees_empfullname[$x] . "' and " . $db_prefix . "employees.empfullname <> 'admin' order by " . $db_prefix . "info.timestamp asc"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysql_fetch_array($result)) { + while ($row = mysqli_fetch_array($result)) { $info_fullname[] = stripslashes("" . $row['fullname'] . ""); $info_inout[] = "" . $row['inout'] . ""; diff --git a/scripts/dropdown_get.php b/scripts/dropdown_get.php index c5ec536..c60fff2 100644 --- a/scripts/dropdown_get.php +++ b/scripts/dropdown_get.php @@ -11,10 +11,10 @@ function office_names() { @$office_name = $_GET['officename']; $query = "select * from ".$db_prefix."offices"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); $cnt=1; - while ($row=mysql_fetch_array($result)) { + while ($row=mysqli_fetch_array($result)) { if (isset($abc)) { echo "select.options[$cnt] = new Option(\"".$row['officename']."\");\n"; echo "select.options[$cnt].value = \"".$row['officename']."\";\n"; @@ -26,7 +26,7 @@ function office_names() { } $cnt++; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); ?> } @@ -43,9 +43,9 @@ function group_names() { @@ -53,12 +53,12 @@ function group_names() { if (groups_select.options[groups_select.selectedIndex].value != '') { diff --git a/scripts/dropdown_get_reports.php b/scripts/dropdown_get_reports.php index 0169d87..6c0ed82 100644 --- a/scripts/dropdown_get_reports.php +++ b/scripts/dropdown_get_reports.php @@ -14,10 +14,10 @@ function office_names() { } @@ -44,9 +44,9 @@ function group_names() { if (offices_select.options[offices_select.selectedIndex].text == "") { @@ -54,12 +54,12 @@ function group_names() { $query2 = "select * from ".$db_prefix."offices, ".$db_prefix."groups where ".$db_prefix."groups.officeid = ".$db_prefix."offices.officeid and ".$db_prefix."offices.officename = '".$office_row."' order by ".$db_prefix."groups.groupname asc"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); echo "groups_select.options[0] = new Option(\"All\");\n"; echo "groups_select.options[0].value = 'All';\n"; $cnt = 1; - while ($row2=mysql_fetch_array($result2)) { + while ($row2=mysqli_fetch_array($result2)) { $groups = "".$row2['groupname'].""; echo "groups_select.options[$cnt] = new Option(\"$groups\");\n"; echo "groups_select.options[$cnt].value = \"$groups\";\n"; @@ -69,8 +69,8 @@ function group_names() { } if (users_select.options[users_select.selectedIndex].value != 'All') { users_select.length = 0; @@ -107,9 +107,9 @@ function user_names() { if (offices_select.options[offices_select.selectedIndex].text == "") { @@ -117,9 +117,9 @@ function user_names() { $query2 = "select * from ".$db_prefix."offices, ".$db_prefix."groups where ".$db_prefix."groups.officeid = ".$db_prefix."offices.officeid and ".$db_prefix."offices.officename = '".$office_row."' order by ".$db_prefix."groups.groupname asc"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); - while ($row2=mysql_fetch_array($result2)) { + while ($row2=mysqli_fetch_array($result2)) { $groups = "".$row2['groupname'].""; ?> @@ -127,13 +127,13 @@ function user_names() { 'admin' order by empfullname asc"; - $result3 = mysql_query($query3); + $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); echo "users_select.options[0] = new Option(\"All\");\n"; echo "users_select.options[0].value = 'All';\n"; $usercnt = 1; - while ($row3=mysql_fetch_array($result3)) { + while ($row3=mysqli_fetch_array($result3)) { $users = "".$row3['empfullname'].""; echo "users_select.options[$usercnt] = new Option(\"$users\");\n"; echo "users_select.options[$usercnt].value = \"$users\";\n"; @@ -147,9 +147,9 @@ function user_names() { } if (groups_select.options[groups_select.selectedIndex].value == 'All') { } @@ -45,9 +45,9 @@ function group_names() { @@ -57,12 +57,12 @@ function group_names() { $query2 = "select * from ".$db_prefix."offices, ".$db_prefix."groups where ".$db_prefix."groups.officeid = ".$db_prefix."offices.officeid and ".$db_prefix."offices.officename = '".$office_row."' order by ".$db_prefix."groups.groupname asc"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); echo "groups_select.options[0] = new Option(\"all\");\n"; echo "groups_select.options[0].value = 'all';\n"; $cnt = 1; - while ($row2=mysql_fetch_array($result2)) { + while ($row2=mysqli_fetch_array($result2)) { $groups = "".$row2['groupname'].""; echo "groups_select.options[$cnt] = new Option(\"$groups\");\n"; echo "groups_select.options[$cnt].value = \"$groups\";\n"; @@ -73,8 +73,8 @@ function group_names() { } if (groups_select.options[groups_select.selectedIndex].value != 'all') { @@ -88,10 +88,10 @@ function group_names() { echo "groups_select.options[0].value = 'all';\n"; $query3 = "select * from ".$db_prefix."groups order by groupname asc"; - $result3 = mysql_query($query3); + $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); $cnt=1; - while ($row3=mysql_fetch_array($result3)) { + while ($row3=mysqli_fetch_array($result3)) { if ("".$row3['groupname']."" == stripslashes($display_group)) { echo "groups_select.options[$cnt] = new Option(\"".$row3['groupname']."\",\"".$row3['groupname']."\", true, true);\n"; } else { @@ -100,7 +100,7 @@ function group_names() { } $cnt++; } - mysql_free_result($result3); + ((mysqli_free_result($result3) || (is_object($result3) && (get_class($result3) == "mysqli_result"))) ? true : false); ?> } } diff --git a/scripts/dropdown_post.php b/scripts/dropdown_post.php index 60082a9..c64ee79 100644 --- a/scripts/dropdown_post.php +++ b/scripts/dropdown_post.php @@ -11,10 +11,10 @@ function office_names() { @$office_name = $_POST['office_name']; $query = "select * from ".$db_prefix."offices"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); $cnt=1; - while ($row=mysql_fetch_array($result)) { + while ($row=mysqli_fetch_array($result)) { if ("".$row['officename']."" == stripslashes($office_name)) { echo "select.options[$cnt] = new Option(\"".$row['officename']."\",\"".$row['officename']."\", true, true);\n"; } else { @@ -23,7 +23,7 @@ function office_names() { } $cnt++; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); ?> } @@ -40,9 +40,9 @@ function group_names() { @@ -50,12 +50,12 @@ function group_names() { if (groups_select.options[groups_select.selectedIndex].value != '') { diff --git a/scripts/dropdown_post_reports.php b/scripts/dropdown_post_reports.php index cc8dcdb..05b6780 100644 --- a/scripts/dropdown_post_reports.php +++ b/scripts/dropdown_post_reports.php @@ -13,10 +13,10 @@ function office_names() { @$office_name = $_POST['office_name']; $query = "select * from ".$db_prefix."offices"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); $cnt=1; - while ($row=mysql_fetch_array($result)) { + while ($row=mysqli_fetch_array($result)) { if ("".$row['officename']."" == stripslashes($office_name)) { echo "select.options[$cnt] = new Option(\"".$row['officename']."\",\"".$row['officename']."\", true, true);\n"; } else { @@ -25,7 +25,7 @@ function office_names() { } $cnt++; } - mysql_free_result($result); + ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); ?> } @@ -47,9 +47,9 @@ function group_names() { @$group_name = $_POST['group_name']; $query = "select * from ".$db_prefix."offices"; - $result = mysql_query($query); + $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row=mysql_fetch_array($result)) { + while ($row=mysqli_fetch_array($result)) { $office_row = addslashes("".$row['officename'].""); ?> @@ -57,12 +57,12 @@ function group_names() { if (users_select.options[users_select.selectedIndex].value != 'All') { users_select.length = 0; @@ -110,9 +110,9 @@ function user_names() { if (offices_select.options[offices_select.selectedIndex].text == "") { @@ -120,8 +120,8 @@ function user_names() { $query2 = "select * from ".$db_prefix."offices, ".$db_prefix."groups where ".$db_prefix."groups.officeid = ".$db_prefix."offices.officeid and ".$db_prefix."offices.officename = '".$office_row."' order by ".$db_prefix."groups.groupname asc"; - $result2 = mysql_query($query2); - while ($row2=mysql_fetch_array($result2)) { + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); + while ($row2=mysqli_fetch_array($result2)) { $groups = "".$row2['groupname'].""; ?> @@ -129,13 +129,13 @@ function user_names() { 'admin' order by empfullname asc"; - $result3 = mysql_query($query3); + $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); echo "users_select.options[0] = new Option(\"All\");\n"; echo "users_select.options[0].value = 'All';\n"; $usercnt = 1; - while ($row3=mysql_fetch_array($result3)) { + while ($row3=mysqli_fetch_array($result3)) { $users = "".$row3['empfullname'].""; echo "users_select.options[$usercnt] = new Option(\"$users\");\n"; echo "users_select.options[$usercnt].value = \"$users\";\n"; @@ -149,9 +149,9 @@ function user_names() { } if (groups_select.options[groups_select.selectedIndex].value == 'All') { } @@ -41,9 +41,9 @@ function group_names() { @@ -52,12 +52,12 @@ function group_names() { $query2 = "select * from ".$db_prefix."offices, ".$db_prefix."groups where ".$db_prefix."groups.officeid = ".$db_prefix."offices.officeid and ".$db_prefix."offices.officename = '".$office_row."' order by ".$db_prefix."groups.groupname asc"; - $result2 = mysql_query($query2); + $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); echo "groups_select.options[0] = new Option(\"all\");\n"; echo "groups_select.options[0].value = 'all';\n"; $cnt = 1; - while ($row2=mysql_fetch_array($result2)) { + while ($row2=mysqli_fetch_array($result2)) { $groups = "".$row2['groupname'].""; echo "groups_select.options[$cnt] = new Option(\"$groups\");\n"; echo "groups_select.options[$cnt].value = \"$groups\";\n"; @@ -68,8 +68,8 @@ function group_names() { } if (groups_select.options[groups_select.selectedIndex].value != 'all') { @@ -83,10 +83,10 @@ function group_names() { echo "groups_select.options[0].value = 'all';\n"; $query3 = "select * from ".$db_prefix."groups order by groupname asc"; - $result3 = mysql_query($query3); + $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); $cnt=1; - while ($row3=mysql_fetch_array($result3)) { + while ($row3=mysqli_fetch_array($result3)) { if ("".$row3['groupname']."" == stripslashes($display_group)) { echo "groups_select.options[$cnt] = new Option(\"".$row3['groupname']."\",\"".$row3['groupname']."\", true, true);\n"; } else { @@ -95,7 +95,7 @@ function group_names() { } $cnt++; } - mysql_free_result($result3); + ((mysqli_free_result($result3) || (is_object($result3) && (get_class($result3) == "mysqli_result"))) ? true : false); ?> } } diff --git a/templates/admin_index_tpl.php b/templates/admin_index_tpl.php index 444e524..726a7ae 100644 --- a/templates/admin_index_tpl.php +++ b/templates/admin_index_tpl.php @@ -6,7 +6,7 @@ echo "
VARIABLE VALUE DESCRIPTION
MySql DB Settings
mysql DB Settings
db_hostname: $db_hostname This is the hostname for your @@ -289,13 +289,13 @@ $row_color = ($row_count % 2) ? $color2 : $color1; echo "
metar: $metarSets the ICAO (International - Civil Aviation Organization) for your local airport. This is the unique four letter international ID for the airport. METAR - reports are created at roughly 4500 airports from around the world, so you probably live near one of them. The airports make a - report once or twice an hour, and these reports are stored at the National Weather Service and are publically available via HTTP - or FTP. Visit - https://pilotweb.nas.faa.gov/qryhtml/icao/ to find a corresponding ICAO near you. If 'display_weather' is set - to \"no\", this option is ignored. If 'display_weather' is set to \"yes\", you MUST provide an ICAO here. + If 'display_weather' is set + to \"no\", this option is ignored. If 'display_weather' is set to \"yes\", you have to set an WxList in config.inc.php.
+ The ICAO (International Civil Aviation Organization) for your weather location is defined in config.inc.php, not here.
+ You can configure the weather display to use reports created at any of roughly 4500 airports from around the world, + so you probably live near one of them. The reports are stored at the National Weather Service and are publically available via HTTP + or FTP.

Visit + https://pilotweb.nas.faa.gov/qryhtml/icao/ to find a corresponding ICAO near you.
\n"; } - if (!empty($string)) { - $post_statusname = stripslashes($post_statusname); - } - if (!empty($string2)) { - $post_statusname = stripslashes($post_statusname); - } - echo "
\n"; echo " \n"; echo " \n"; @@ -244,13 +232,6 @@ Out\n"; } - if (!empty($string)) { - $post_statusname = stripslashes($post_statusname); - } - if (!empty($string2)) { - $post_statusname = stripslashes($post_statusname); - } - echo " \n"; echo "
* required 
\n"; echo " \n"; @@ -264,9 +245,7 @@ exit; } else { - - $query = "insert into " . $db_prefix . "punchlist (punchitems, color, in_or_out) values ('" . $post_statusname . "', '" . $post_color . "', '" . $create_status . "')"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + $result = tc_insert_strings("punchlist", array("punchitems" => $post_statusname, "color" => $post_color, "in_or_out" => $create_status)); echo " \n"; echo " \n"; diff --git a/admin/statusdelete.php b/admin/statusdelete.php index 8bb841a..70f1bdd 100644 --- a/admin/statusdelete.php +++ b/admin/statusdelete.php @@ -40,8 +40,7 @@ $get_status = $_GET['statusname']; - $query = "select * from " . $db_prefix . "punchlist where punchitems = '" . $get_status . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + $result = tc_select("*", "punchlist", "punchitems = ?", $get_status); while ($row = mysqli_fetch_array($result)) { @@ -124,7 +123,7 @@ echo "
\n"; echo " \n"; echo "
- Deleting this status does NOT delete it from the database history. It merely removes it from the list of status + Deleting this status does NOT delete it from the database history. It merely removes it from the list of status choices.
\n"; echo " \n"; echo " @@ -145,11 +144,9 @@ exit; } - $query = "select * from " . $db_prefix . "punchlist where punchitems = '" . $post_statusname . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + $result = tc_select("*", "punchlist", "punchitems = ?", $post_statusname); while ($row = mysqli_fetch_array($result)) { - $punchitem = "" . $row['punchitems'] . ""; $color = "" . $row['color'] . ""; $in_or_out = "" . $row['in_or_out'] . ""; @@ -159,8 +156,7 @@ exit; } - $query2 = "delete from " . $db_prefix . "punchlist where punchitems = ('" . $post_statusname . "')"; - $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); + $result2 = tc_delete("punchlist", "punchitems = ?", $post_statusname); if ($post_in_out == '1') { $post_in_out = 'In'; @@ -232,7 +228,7 @@ echo " \n"; echo " \n"; echo " \n"; echo " \n"; diff --git a/admin/statusedit.php b/admin/statusedit.php index 059f204..7bfc328 100644 --- a/admin/statusedit.php +++ b/admin/statusedit.php @@ -40,11 +40,9 @@ $get_status = $_GET['statusname']; - $query = "select * from " . $db_prefix . "punchlist where punchitems = '" . $get_status . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + $result = tc_select("*", "punchlist", "punchitems = ?", $get_status); while ($row = mysqli_fetch_array($result)) { - $punchitem = "" . $row['punchitems'] . ""; $color = "" . $row['color'] . ""; $in_or_out = "" . $row['in_or_out'] . ""; @@ -147,12 +145,7 @@ // begin post validation // if (!empty($get_status)) { - $query = "select * from " . $db_prefix . "punchlist where punchitems = '" . $get_status . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysqli_fetch_array($result)) { - $getstatus = "" . $row['punchitems'] . ""; - } - ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); + $getstatus = tc_select_value("punchitems", "punchlist", "punchitems = ?", $get_status); if (!isset($getstatus)) { echo "Status is not defined.\n"; exit; @@ -163,12 +156,7 @@ exit; } - if (get_magic_quotes_gpc()) { - $post_statusname = stripslashes($post_statusname); - } - $post_statusname = addslashes($post_statusname); - - $string = strstr($post_statusname, "\'"); + $string = strstr($post_statusname, "'"); $string2 = strstr($post_statusname, "\""); if ((empty($post_statusname)) || (empty($post_color)) || (!preg_match('/' . "^([[:alnum:]]| |-|_|.)+$" . '/i', $post_statusname)) || @@ -260,13 +248,6 @@ echo "
Status Name:$post_statusname
Color:$post_color
\n"; } - if (!empty($string)) { - $post_statusname = stripslashes($post_statusname); - } - if (!empty($string2)) { - $post_statusname = stripslashes($post_statusname); - } - echo "
\n"; echo " \n"; echo " \n"; @@ -295,13 +276,6 @@ exit; } - if (!empty($string)) { - $post_statusname = stripslashes($post_statusname); - } - if (!empty($string2)) { - $post_statusname = stripslashes($post_statusname); - } - echo " \n"; echo "
* required 
\n"; echo " \n"; @@ -317,12 +291,21 @@ } else { - $query = "update " . $db_prefix . "punchlist set punchitems = ('" . $post_statusname . "'), color = ('" . $post_color . "'), in_or_out = ('" . $create_status . "') - where punchitems = ('" . $get_status . "')"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - - $query2 = "update " . $db_prefix . "info set `inout` = ('" . $post_statusname . "') where `inout` = ('" . $get_status . "')"; - $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); + tc_update_strings( + "punchlist", + array( + "punchitems" => $post_statusname, + "color" => $post_color, + "in_or_out" => $create_status + ), + "punchitems = ?", $get_status + ); + + tc_update_strings( + "info", + array("inout" => $post_statusname), + "`inout` = ?", $get_status + ); echo "\n"; echo " \n"; diff --git a/admin/usercreate.php b/admin/usercreate.php index 1ce4c97..71ae2e4 100644 --- a/admin/usercreate.php +++ b/admin/usercreate.php @@ -123,8 +123,8 @@ include 'header_post.php'; include 'topmain.php'; - $post_username = stripslashes($_POST['post_username']); - $display_name = stripslashes($_POST['display_name']); + $post_username = $_POST['post_username']; + $display_name = $_POST['display_name']; $password = $_POST['password']; $confirm_password = $_POST['confirm_password']; $email_addy = $_POST['email_addy']; @@ -135,19 +135,7 @@ $time_admin_perms = $_POST['time_admin_perms']; $post_disabled = $_POST['disabled']; - $post_username = addslashes($post_username); - $display_name = addslashes($display_name); - - $query5 = "select empfullname from " . $db_prefix . "employees where empfullname = '" . $post_username . "' order by empfullname"; - $result5 = mysqli_query($GLOBALS["___mysqli_ston"], $query5); - - while ($row = mysqli_fetch_array($result5)) { - $tmp_username = "" . $row['empfullname'] . ""; - } - ((mysqli_free_result($result5) || (is_object($result5) && (get_class($result5) == "mysqli_result"))) ? true : false); - - $post_username = stripslashes($post_username); - $display_name = stripslashes($display_name); + $tmp_username = tc_select_value("empfullname", "employees", "empfullname = ? ORDER by empfullname", $post_username); $string = strstr($post_username, "\""); $string2 = strstr($display_name, "\""); @@ -160,11 +148,6 @@ (($reports_perms != '1') && (!empty($reports_perms))) || (($time_admin_perms != '1') && (!empty($time_admin_perms))) || (($post_disabled != '1') && (!empty($post_disabled))) || (!empty($string)) || (!empty($string2)) ) { - - if (@tmp_username == $post_username) { - $tmp_username = stripslashes($tmp_username); - } - echo "
\n"; echo " \n"; echo "
\n"; @@ -317,41 +300,21 @@ echo "
\n"; } - if (!empty($office_name)) { - $query = "select * from " . $db_prefix . "offices where officename = '" . $office_name . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysqli_fetch_array($result)) { - $tmp_officename = "" . $row['officename'] . ""; - } - ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); - if (!isset($tmp_officename)) { - echo "Office is not defined.\n"; - exit; - } + if (!empty($office_name) + and is_null(tc_select_value("officename", "offices", "officename = ?", $office_name)) + ) { + echo "Office is not defined.\n"; + exit; } - if (!empty($group_name)) { - $query = "select * from " . $db_prefix . "groups where groupname = '" . $group_name . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysqli_fetch_array($result)) { - $tmp_groupname = "" . $row['groupname'] . ""; - } - ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); - if (!isset($tmp_officename)) { - echo "Group is not defined.\n"; - exit; - } + if (!empty($group_name) + and is_null(tc_select_value("groupname", "groups", "groupname = ?", $group_name)) + ) { + echo "Group is not defined.\n"; + exit; } // end post validation // - - if (!empty($string)) { - $post_username = stripslashes($post_username); - } - if (!empty($string2)) { - $display_name = stripslashes($display_name); - } - $password = crypt($password, 'xy'); $confirm_password = crypt($confirm_password, 'xy'); @@ -369,13 +332,6 @@ style='color:red;font-family:Tahoma;font-size:11px;padding-left:20px;'>  *
Password:
Confirm Password: $post_username, + 'displayname' => $display_name, + 'employee_passwd' => $password, + 'email' => $email_addy, + 'groups' => $group_name, + 'office' => $office_name, + 'admin' => $admin_perms, + 'reports' => $reports_perms, + 'time_admin' => $time_admin_perms, + 'disabled' => $post_disabled + )); echo "\n"; echo " \n"; @@ -505,15 +466,13 @@ \n"; echo " \n"; - $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees - where empfullname = '" . $post_username . "' - order by empfullname"; - $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); - + $result4 = tc_select( + "empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled", + "employees", "empfullname = ? ORDER BY empfullname", $post_username + ); while ($row = mysqli_fetch_array($result4)) { - - $username = stripslashes("" . $row['empfullname'] . ""); - $displayname = stripslashes("" . $row['displayname'] . ""); + $username = "" . $row['empfullname'] . ""; + $displayname = "" . $row['displayname'] . ""; $user_email = "" . $row['email'] . ""; $office = "" . $row['office'] . ""; $groups = "" . $row['groups'] . ""; diff --git a/admin/userdelete.php b/admin/userdelete.php index bd54de4..5109a2c 100644 --- a/admin/userdelete.php +++ b/admin/userdelete.php @@ -38,7 +38,7 @@ exit; } - $get_user = stripslashes($_GET['username']); + $get_user = $_GET['username']; @$get_office = $_GET['officename']; echo "
\n"; @@ -91,17 +91,12 @@ echo " \n"; echo " \n"; include '../footer.php'; - $post_username = stripslashes($post_username); - $display_name = stripslashes($display_name); exit; } - $post_username = stripslashes($post_username); - $display_name = stripslashes($display_name); - $post_username = addslashes($post_username); - $display_name = addslashes($display_name); - - $query3 = "update " . $db_prefix . "employees set displayname = ('" . $display_name . "'), email = ('" . $email_addy . "'), groups = ('" . $group_name . "'), - office = ('" . $office_name . "'), admin = ('" . $admin_perms . "'), reports = ('" . $reports_perms . "'), time_admin = ('" . $time_admin_perms . "'), - disabled = ('" . $post_disabled . "') - where empfullname = ('" . $post_username . "')"; - $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); + tc_update_strings("employees", array( + 'displayname' => $display_name, + 'email' => $email_addy, + 'groups' => $group_name, + 'office' => $office_name, + 'admin' => $admin_perms, + 'reports' => $reports_perms, + 'time_admin' => $time_admin_perms, + 'disabled' => $post_disabled + ), "empfullname = ?", $post_username); echo "
\n"; - $get_user = addslashes($get_user); - - $row_count = 0; - - $query = "select * from " . $db_prefix . "employees where empfullname = '" . $get_user . "' order by empfullname"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + $result = tc_select("*", "employees", "empfullname = ? ORDER BY empfullname", $get_user); while ($row = mysqli_fetch_array($result)) { - $username = stripslashes("" . $row['empfullname'] . ""); - $displayname = stripslashes("" . $row['displayname'] . ""); + $username = "" . $row['empfullname'] . ""; + $displayname = "" . $row['displayname'] . ""; $user_email = "" . $row['email'] . ""; $office = "" . $row['office'] . ""; $groups = "" . $row['groups'] . ""; @@ -110,13 +105,11 @@ $time_admin = "" . $row['time_admin'] . ""; } ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); - $get_user = stripslashes($get_user); // make sure you cannot delete the last admin user in the system!! // if (!empty($admin)) { - $admin_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where admin = '1'"); - @$admin_count_rows = mysqli_num_rows($admin_count); + @$admin_count_rows = mysqli_num_rows(tc_select("empfullname", "employees", "admin = '1'")); if (@$admin_count_rows == "1") { $evil = "1"; } @@ -192,8 +185,8 @@ exit; } elseif ($request == 'POST') { - $post_username = stripslashes($_POST['post_username']); - $display_name = stripslashes($_POST['display_name']); + $post_username = $_POST['post_username']; + $display_name = $_POST['display_name']; $email_addy = $_POST['email_addy']; $office_name = $_POST['office_name']; $group_name = $_POST['group_name']; @@ -202,69 +195,41 @@ $time_admin_perms = $_POST['time_admin_perms']; @$delete_data = $_POST['delete_all_user_data']; - $post_username = addslashes($post_username); - $display_name = addslashes($display_name); - // begin post validation // - if (!empty($post_username)) { - $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysqli_fetch_array($result)) { - $tmp_username = "" . $row['empfullname'] . ""; - } - if (!isset($tmp_username)) { - echo "Something is fishy here.\n"; - exit; - } + if (!empty($post_username) + and is_null(tc_select_value("empfullname", "employees", "empfullname = ?", $post_username)) + ) { + echo "Something is fishy here.\n"; + exit; } - if (!empty($display_name)) { - $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "' and displayname = '" . $display_name . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysqli_fetch_array($result)) { - $tmp_display_name = "" . $row['displayname'] . ""; - } - if (!isset($tmp_display_name)) { - echo "Something is fishy here.\n"; - exit; - } + if (!empty($display_name) + and is_null(tc_select_value("displayname", "employees", "empfullname = ? AND displayname = ?", array($post_username, $display_name))) + ) { + echo "Something is fishy here.\n"; + exit; } - if (!empty($email_addy)) { - $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "' and email = '" . $email_addy . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysqli_fetch_array($result)) { - $tmp_email_addy = "" . $row['email'] . ""; - } - if (!isset($tmp_email_addy)) { - echo "Something is fishy here.\n"; - exit; - } + if (!empty($email_addy) + and is_null(tc_select_value("email", "employees", "empfullname = ? AND email = ?", array($post_username, $email_addy))) + ) { + echo "Something is fishy here.\n"; + exit; } - if (!empty($office_name)) { - $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "' and office = '" . $office_name . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysqli_fetch_array($result)) { - $tmp_office_name = "" . $row['office'] . ""; - } - if (!isset($tmp_office_name)) { - echo "Something is fishy here.\n"; - exit; - } + if (!empty($office_name) + and is_null(tc_select_value("office", "employees", "empfullname = ? AND office = ?", array($post_username, $office_name))) + ) { + echo "Something is fishy here.\n"; + exit; } - if (!empty($group_name)) { - $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "' and groups = '" . $group_name . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysqli_fetch_array($result)) { - $tmp_group_name = "" . $row['groups'] . ""; - } - if (!isset($tmp_group_name)) { - echo "Something is fishy here.\n"; - exit; - } + if (!empty($group_name) + and is_null(tc_select_value("groups", "employees", "empfullname = ? AND groups = ?", array($post_username, $group_name))) + ) { + echo "Something is fishy here.\n"; + exit; } if (($admin_perms != '0') && ($admin_perms != '1')) { @@ -286,17 +251,12 @@ // end post validation // - $query2 = "delete from " . $db_prefix . "employees where empfullname = ('" . $post_username . "')"; - $result2 = mysqli_query($GLOBALS["___mysqli_ston"], $query2); + tc_delete("employees", "empfullname = ?", $post_username); if ($delete_data == "1") { - $query3 = "delete from " . $db_prefix . "info where fullname = ('" . $post_username . "')"; - $result3 = mysqli_query($GLOBALS["___mysqli_ston"], $query3); + tc_delete("info", "fullname = ?", $post_username); } - $post_username = stripslashes($post_username); - $display_name = stripslashes($display_name); - echo "\n"; echo " \n"; echo " \n"; include '../footer.php'; exit; @@ -232,8 +222,8 @@ include 'header_post.php'; include 'topmain.php'; - $post_username = stripslashes($_POST['post_username']); - $display_name = stripslashes($_POST['display_name']); + $post_username = $_POST['post_username']; + $display_name = $_POST['display_name']; $email_addy = $_POST['email_addy']; $office_name = $_POST['office_name']; @$get_office = $_POST['get_office']; @@ -254,22 +244,18 @@ if (isset($evil)) { $admin_perms = "1"; } - $post_username = addslashes($post_username); if (!empty($post_username)) { - $query = "select * from " . $db_prefix . "employees where empfullname = '" . $post_username . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysqli_fetch_array($result)) { - $tmp_username = "" . $row['empfullname'] . ""; - } + $tmp_username = tc_select_value("empfullname", "employees", "empfullname = ?", $post_username); if (!isset($tmp_username)) { - echo "$tmp_username, $post_username. Something is fishy here.\n"; + echo htmlspecialchars("$tmp_username, $post_username. Something is fishy here.\n"); exit; } } + else { + $tmp_username = ""; + } - $post_username = stripslashes($post_username); - $tmp_post_username = stripslashes($post_username); $string = strstr($display_name, "\""); if ((!preg_match('/' . "^([[:alnum:]]| |-|'|,)+$" . '/i', $display_name)) || (empty($display_name)) || (empty($email_addy)) || (empty($office_name)) || (empty($group_name)) || (!preg_match('/' . "^([[:alnum:]]|_|\.|-)+@([[:alnum:]]|\.|-)+(\.)([a-z]{2,4})$" . '/i', $email_addy)) || (($admin_perms != '1') && (!empty($admin_perms))) || @@ -286,12 +272,12 @@ echo " \n"; echo " \n"; +   Edit User\n"; echo " +   Change Password\n"; echo " \n"; +   Delete User\n"; echo " \n"; echo "
\n"; diff --git a/admin/useredit.php b/admin/useredit.php index e43cec7..b2a3702 100644 --- a/admin/useredit.php +++ b/admin/useredit.php @@ -43,10 +43,6 @@ $get_user = $_GET['username']; @$get_office = $_GET['officename']; - if (get_magic_quotes_gpc()) { - $get_user = stripslashes($get_user); - } - echo "\n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; echo "
\n"; @@ -97,20 +93,15 @@ echo "
\n"; - $get_user = addslashes($get_user); - $row_count = 0; - - $query = "select * from " . $db_prefix . "employees where empfullname = '" . $get_user . "' order by empfullname"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); + $result = tc_select("*", "employees", "empfullname = ?", $get_user); while ($row = mysqli_fetch_array($result)) { - $row_count++; $row_color = ($row_count % 2) ? $color2 : $color1; - $username = stripslashes("" . $row['empfullname'] . ""); - $displayname = stripslashes("" . $row['displayname'] . ""); + $username = "" . $row['empfullname'] . ""; + $displayname = "" . $row['displayname'] . ""; $user_email = "" . $row['email'] . ""; $groups_tmp = "" . $row['groups'] . ""; $office = "" . $row['office'] . ""; @@ -124,8 +115,7 @@ // make sure you cannot edit the admin perms for the last admin user in the system!! // if (!empty($admin)) { - $admin_count = mysqli_query($GLOBALS["___mysqli_ston"], "select empfullname from " . $db_prefix . "employees where admin = '1'"); - @$admin_count_rows = mysqli_num_rows($admin_count); + @$admin_count_rows = mysqli_num_rows(tc_select("empfullname", "employees", "admin = '1'")); if (@$admin_count_rows == "1") { $evil = "1"; } @@ -223,7 +213,7 @@ echo "
 
User Summary   User Summary
Edit User -   Edit User
Change Password -   Change Password
Delete User -   Delete User
Create New User   Create New User
User Search   @@ -399,38 +385,22 @@ echo "
\n"; } - if (!empty($office_name)) { - $query = "select * from " . $db_prefix . "offices where officename = '" . $office_name . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysqli_fetch_array($result)) { - $tmp_officename = "" . $row['officename'] . ""; - } - ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); - if (!isset($tmp_officename)) { - echo "Office is not defined.\n"; - exit; - } + if (!empty($office_name) + and is_null(tc_select_value("officename", "offices", "officename = ?", $office_name)) + ) { + echo "Office is not defined.\n"; + exit; } - if (!empty($group_name)) { - $query = "select * from " . $db_prefix . "groups where groupname = '" . $group_name . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysqli_fetch_array($result)) { - $tmp_groupname = "" . $row['groupname'] . ""; - } - ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); - if (!isset($tmp_officename)) { - echo "Group is not defined.\n"; - exit; - } + if (!empty($group_name) + and is_null(tc_select_value("groupname", "groups", "groupname = ?", $group_name)) + ) { + echo "Group is not defined.\n"; + exit; } // end post validation // - if (!empty($string)) { - $display_name = stripslashes($display_name); - } - echo "
\n"; echo "
\n"; echo " \n"; @@ -439,8 +409,8 @@ echo " \n"; echo " \n"; echo " \n"; + colspan=2 width=80% style='padding-left:20px;'>$tmp_username\n"; echo " \n"; @@ -501,24 +471,22 @@ echo " \n"; echo " \n"; echo "
Username:$tmp_post_username
Display Name:  *
 
\n"; echo " \n"; @@ -529,12 +497,12 @@ echo " \n"; echo " \n"; +   Edit User\n"; echo " +   Change Password\n"; echo " \n"; +   Delete User\n"; echo " \n"; echo " \n"; echo " \n"; - $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees - where empfullname = '" . $post_username . "' - order by empfullname"; - $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); - + $result4 = tc_select( + "empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled", + "employees", + "empfullname = ? ORDER BY empfullname", + $post_username + ); while ($row = mysqli_fetch_array($result4)) { - - $username = stripslashes("" . $row['empfullname'] . ""); - $displayname = stripslashes("" . $row['displayname'] . ""); + $username = "" . $row['empfullname'] . ""; + $displayname = "" . $row['displayname'] . ""; $user_email = "" . $row['email'] . ""; $office = "" . $row['office'] . ""; $groups = "" . $row['groups'] . ""; @@ -639,7 +607,7 @@ $disabled = "No"; } echo " \n"; echo " \n"; echo "
User Summary   User Summary
Edit User -   Edit User
Change Password -   Change Password
Delete User -   Delete User
Create New User   Create New User
User Search   @@ -583,15 +551,15 @@ echo "
User Account Disabled?$disabled
\n"; diff --git a/admin/usersearch.php b/admin/usersearch.php index 27d0b00..6bb68b8 100644 --- a/admin/usersearch.php +++ b/admin/usersearch.php @@ -118,17 +118,12 @@ include 'header_post.php'; include 'topmain.php'; -@$post_username = stripslashes($_POST['post_username']); -@$display_name = stripslashes($_POST['display_name']); +@$post_username = $_POST['post_username']; +@$display_name = $_POST['display_name']; @$email_addy = $_POST['email_addy']; @$office_name = $_POST['office_name']; @$group_name = $_POST['group_name']; -//$post_username = addslashes($post_username); -//$display_name = addslashes($display_name); -//$office_name = addslashes($office_name); -//$group_name = addslashes($group_name); - // begin post validation // if ((!preg_match('/' . "^([[:alnum:]]| |-|'|,)+$" . '/i', $post_username)) || (!preg_match('/' . "^([[:alnum:]]| |-|'|,)+$" . '/i', $display_name)) || @@ -223,30 +218,18 @@ $evil_input = "1"; } -if (!empty($office_name)) { - $query = "select * from " . $db_prefix . "offices where officename = '" . $office_name . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysqli_fetch_array($result)) { - $tmp_officename = "" . $row['officename'] . ""; - } - ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); - if (!isset($tmp_officename)) { - echo "Office is not defined.\n"; - exit; - } +if (!empty($office_name) + and is_null(tc_select_value("officename", "offices", "officename = ?", $office_name)) +) { + echo "Office is not defined.\n"; + exit; } -if (!empty($group_name)) { - $query = "select * from " . $db_prefix . "groups where groupname = '" . $group_name . "'"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - while ($row = mysqli_fetch_array($result)) { - $tmp_groupname = "" . $row['groupname'] . ""; - } - ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); - if (!isset($tmp_officename)) { - echo "Group is not defined.\n"; - exit; - } +if (!empty($group_name) + and is_null(tc_select_value("groupname", "groups", "groupname = ?", $group_name)) +) { + echo "Group is not defined.\n"; + exit; } // end post validation // @@ -297,83 +280,48 @@ } else { -$post_username = addslashes($post_username); -$display_name = addslashes($display_name); -$office_name = addslashes($office_name); -$group_name = addslashes($group_name); +$query_where = array(); +$query_params = array(); if (!empty($post_username)) { $tmp_var = $post_username; $tmp_var2 = "Username"; - - if ((!empty($office_name)) && (!empty($group_name))) { - $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees - where empfullname LIKE '%" . $post_username . "%' and office = '" . $office_name . "' and groups = '" . $group_name . "' - order by empfullname"; - $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); - } elseif (!empty($office_name)) { - $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees - where empfullname LIKE '%" . $post_username . "%' and office = '" . $office_name . "' - order by empfullname"; - $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); - } elseif (empty($office_name)) { - $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees - where empfullname LIKE '%" . $post_username . "%' - order by empfullname"; - $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); - } -} elseif (!empty($display_name)) { + $query_where[] = "empfullname LIKE ?"; + $query_params[] = "%" . $post_username . "%"; +} +elseif (!empty($display_name)) { $tmp_var = $display_name; $tmp_var2 = "Display Name"; - - if ((!empty($office_name)) && (!empty($group_name))) { - $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees - where displayname LIKE '%" . $display_name . "%' and office = '" . $office_name . "' and groups = '" . $group_name . "' - order by empfullname"; - $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); - } elseif (!empty($office_name)) { - $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees - where displayname LIKE '%" . $display_name . "%' and office = '" . $office_name . "' - order by empfullname"; - $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); - } elseif (empty($office_name)) { - $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees - where displayname LIKE '%" . $display_name . "%' - order by empfullname"; - $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); - } -} elseif (!empty($email_addy)) { + $query_where[] = "displayname LIKE ?"; + $query_params[] = "%" . $display_name . "%"; +} +elseif (!empty($email_addy)) { $tmp_var = $email_addy; $tmp_var2 = "Email Address"; + $query_where[] = "email LIKE ?"; + $query_params[] = "%" . $email_addy . "%"; +} - if ((!empty($office_name)) && (!empty($group_name))) { - $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees - where email LIKE '%" . $email_addy . "%' and office = '" . $office_name . "' and groups = '" . $group_name . "' - order by empfullname"; - $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); - } elseif (!empty($office_name)) { - $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees - where email LIKE '%" . $email_addy . "%' and office = '" . $office_name . "' - order by empfullname"; - $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); - } elseif (empty($office_name)) { - $query4 = "select empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled from " . $db_prefix . "employees - where email LIKE '%" . $email_addy . "%' - order by empfullname"; - $result4 = mysqli_query($GLOBALS["___mysqli_ston"], $query4); +if (!empty($office_name)) { + $query_where[] = "office = ?"; + $query_params[] = $office_name; + + if (!empty($group_name)) { + $query_where[] = "groups = ?"; + $query_params[] = $group_name; } } -$tmp_var = stripslashes($tmp_var); -$tmp_var2 = stripslashes($tmp_var2); $row_count = "0"; +$result4 = tc_select( + "empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled", + "employees", + implode(" AND ", $query_where) . " ORDER BY empfullname", + $query_params +); while ($row = mysqli_fetch_array($result4)) { -@$user_count_rows = mysqli_num_rows($user_count); -@$admin_count_rows = mysqli_num_rows($admin_count); -@$reports_count_rows = mysqli_num_rows($reports_count); - $row_count++; if ($row_count == "1") { @@ -401,8 +349,8 @@ } $row_color = ($row_count % 2) ? $color2 : $color1; -$empfullname = stripslashes("" . $row['empfullname'] . ""); -$displayname = stripslashes("" . $row['displayname'] . ""); +$empfullname = "" . $row['empfullname'] . ""; +$displayname = "" . $row['displayname'] . ""; echo "
 $row_count \n"; echo " \n"; diff --git a/functions.php b/functions.php index d37b2fa..02ba441 100644 --- a/functions.php +++ b/functions.php @@ -1,5 +1,118 @@ $value) { + $refs[$key] = &$params[$key]; + } + array_unshift($refs, $types); + return call_user_func_array(array($stmt, 'bind_param'), @$refs); +} + +function tc_execute($query, $params = array(), $types = null) { + if (!($stmt = $GLOBALS["___mysqli_ston"]->prepare($query))) { + error_log("Failed to prepare $query: " . mysqli_error($GLOBALS["___mysqli_ston"])); + return false; + } + _tc_bind_param($stmt, $params, $types); + if (!$stmt->execute()) { + error_log("Failed to execute: " . $stmt->error); + return false; + } + return $stmt->close(); +} + +function tc_query($query, $params = array(), $types = null) { + if (!($stmt = $GLOBALS["___mysqli_ston"]->prepare($query))) { + error_log("Failed to prepare $query: " . mysqli_error($GLOBALS["___mysqli_ston"])); + return false; + } + _tc_bind_param($stmt, $params, $types); + if (!$stmt->execute()) { + error_log("Failed to execute: " . $stmt->error); + return false; + } + return $stmt->get_result(); +} + +function tc_select($what, $from, $where = '1=1', $params = array(), $types = null) { + global $db_prefix; + return tc_query("SELECT $what FROM ${db_prefix}$from WHERE $where", $params, $types); +} + +function tc_select_value($what, $from, $where = '1=1', $params = array(), $types = null) { + global $db_prefix; + $result = tc_query("SELECT $what FROM ${db_prefix}$from WHERE $where", $params, $types); + $value = null; + while ($row = mysqli_fetch_array($result)) { + $value = $row[0]; + } + return $value; +} + +function tc_delete($from, $where, $params = array(), $types = null) { + global $db_prefix; + return tc_query("DELETE FROM ${db_prefix}$from WHERE $where", $params, $types); +} + +function tc_insert_strings($db, $keyvals) { + global $db_prefix; + $keys = ''; + $places = ''; + $types = ''; + $values = array(); + foreach ($keyvals as $key => $value) { + if (!empty($keys)) { + $keys .= ","; + $places .= ","; + } + $keys .= "`$key`"; + $places .= "?"; + $types .= "s"; + $values[] = "$value"; + } + tc_execute("INSERT INTO ${db_prefix}$db ($keys) VALUES ($places)", $values, $types); + return mysqli_insert_id($GLOBALS["___mysqli_ston"]); +} + +function tc_update_strings($db, $keyvals, $where = '1=1', $bind = array(), $types = null) { + global $db_prefix; + $places = ''; + $set_types = ''; + $values = array(); + foreach ($keyvals as $key => $value) { + if (!empty($places)) { + $places .= ","; + } + $places .= "`$key` = ?"; + $set_types .= "s"; + $values[] = "$value"; + } + if (!is_array($bind)) { + $bind = array($bind); + } + if (!is_null($types)) { + $types = $set_types . $types; + } + tc_execute("UPDATE ${db_prefix}$db SET $places WHERE $where", array_merge($values, $bind), $types); +} + + + function secsToHours($secs, $round_time) { /* The logic for this function was written by Adam Woodbeck, who initially wrote it to round to the diff --git a/leftmain.php b/leftmain.php index 927abad..36d3efb 100644 --- a/leftmain.php +++ b/leftmain.php @@ -7,11 +7,17 @@ // set cookie if 'Remember Me?' checkbox is checked, or reset cookie if 'Reset Cookie?' is checked // +if ($show_display_name == "yes") { + $emp_name_field = "displayname"; +} else { + $emp_name_field = "empfullname"; +} + if ($request == 'POST') { @$remember_me = $_POST['remember_me']; @$reset_cookie = $_POST['reset_cookie']; - @$fullname = stripslashes($_POST['left_fullname']); - @$displayname = stripslashes($_POST['left_displayname']); + @$fullname = $_POST['left_fullname']; + @$displayname = $_POST['left_displayname']; if ((isset($remember_me)) && ($remember_me != '1')) { echo "Something is fishy here.\n"; exit; @@ -26,35 +32,23 @@ if ($show_display_name == "yes") { if (isset($displayname)) { - $displayname = addslashes($displayname); - $query = "select displayname from " . $db_prefix . "employees where displayname = '" . $displayname . "'"; - $emp_name_result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - - while ($row = mysqli_fetch_array($emp_name_result)) { - $tmp_displayname = "" . $row['displayname'] . ""; - } + $tmp_displayname = tc_select_value("displayname", "employees", "displayname = ?", $displayname); if ((!isset($tmp_displayname)) && (!empty($displayname))) { echo "Username is not in the database.\n"; exit; } - $displayname = stripslashes($displayname); + $emp_name = $tmp_displayname; } } elseif ($show_display_name == "no") { if (isset($fullname)) { - $fullname = addslashes($fullname); - $query = "select empfullname from " . $db_prefix . "employees where empfullname = '" . $fullname . "'"; - $emp_name_result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - - while ($row = mysqli_fetch_array($emp_name_result)) { - $tmp_empfullname = "" . $row['empfullname'] . ""; - } + $tmp_empfullname = tc_select_value("empfullname", "employees", "empfullname = ?", $fullname); if ((!isset($tmp_empfullname)) && (!empty($fullname))) { echo "Username is not in the database.\n"; exit; } - $fullname = stripslashes($fullname); + $emp_name = $tmp_empfullname; } } @@ -62,13 +56,7 @@ // end post validation // if (isset($remember_me)) { - - if ($show_display_name == "yes") { - setcookie("remember_me", stripslashes($displayname), time() + (60 * 60 * 24 * 365 * 2)); - } elseif ($show_display_name == "no") { - setcookie("remember_me", stripslashes($fullname), time() + (60 * 60 * 24 * 365 * 2)); - } - + setcookie("remember_me", $emp_name, time() + (60 * 60 * 24 * 365 * 2)); } elseif (isset($reset_cookie)) { setcookie("remember_me", "", time() - 3600); } @@ -115,50 +103,26 @@ // query to populate dropdown with employee names // if ($show_display_name == "yes") { - - $query = "select displayname from " . $db_prefix . "employees where disabled <> '1' and empfullname <> 'admin' order by displayname"; - $emp_name_result = mysqli_query($GLOBALS["___mysqli_ston"], $query); echo " \n"; - ((mysqli_free_result($emp_name_result) || (is_object($emp_name_result) && (get_class($emp_name_result) == "mysqli_result"))) ? true : false); - echo " \n"; - } else { - - $query = "select empfullname from " . $db_prefix . "employees where disabled <> '1' and empfullname <> 'admin' order by empfullname"; - $emp_name_result = mysqli_query($GLOBALS["___mysqli_ston"], $query); echo " \n"; - ((mysqli_free_result($emp_name_result) || (is_object($emp_name_result) && (get_class($emp_name_result) == "mysqli_result"))) ? true : false); - echo " \n"; } +echo " \n"; +((mysqli_free_result($emp_name_result) || (is_object($emp_name_result) && (get_class($emp_name_result) == "mysqli_result"))) ? true : false); +echo " \n"; + // determine whether to use encrypted passwords or not // @@ -174,8 +138,7 @@ // query to populate dropdown with punchlist items // -$query = "select punchitems from " . $db_prefix . "punchlist"; -$punchlist_result = mysqli_query($GLOBALS["___mysqli_ston"], $query); +$punchlist_result = tc_select("punchitems", "punchlist"); echo " \n"; } elseif (isset($_COOKIE['remember_me'])) { echo " \n"; } echo " \n"; -echo " \n"; @@ -232,8 +195,7 @@ class=misc_items style='padding-left:0px;padding-right:0px;' tabindex=5> $fullname, "inout" => $inout, "timestamp" => $tz_stamp, "notes" => $notes); if (strtolower($ip_logging) == "yes") { - $query = "insert into " . $db_prefix . "info (fullname, `inout`, timestamp, notes, ipaddress) values ('" . $fullname . "', '" . $inout . "', - '" . $tz_stamp . "', '" . $notes . "', '" . $connecting_ip . "')"; - } else { - $query = "insert into " . $db_prefix . "info (fullname, `inout`, timestamp, notes) values ('" . $fullname . "', '" . $inout . "', '" . $tz_stamp . "', - '" . $notes . "')"; + $clockin["ipaddress"] = $connecting_ip; } - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - - $update_query = "update " . $db_prefix . "employees set tstamp = '" . $tz_stamp . "' where empfullname = '" . $fullname . "'"; - $other_result = mysqli_query($GLOBALS["___mysqli_ston"], $update_query); + tc_insert_strings("info", $clockin); + tc_update_strings("employees", array("tstamp" => $tz_stamp), "empfullname = ?", $fullname); echo "\n"; echo "\n"; @@ -353,43 +300,26 @@ class=misc_items style='padding-left:0px;padding-right:0px;' tabindex=5> $fullname, "inout" => $inout, "timestamp" => $tz_stamp, "notes" => $notes); if (strtolower($ip_logging) == "yes") { - $query = "insert into " . $db_prefix . "info (fullname, `inout`, timestamp, notes, ipaddress) values ('" . $fullname . "', '" . $inout . "', - '" . $tz_stamp . "', '" . $notes . "', '" . $connecting_ip . "')"; - } else { - $query = "insert into " . $db_prefix . "info (fullname, `inout`, timestamp, notes) values ('" . $fullname . "', '" . $inout . "', '" . $tz_stamp . "', - '" . $notes . "')"; + $clockin["ipaddress"] = $connecting_ip; } - $result = mysqli_query($GLOBALS["___mysqli_ston"], $query); - - $update_query = "update " . $db_prefix . "employees set tstamp = '" . $tz_stamp . "' where empfullname = '" . $fullname . "'"; - $other_result = mysqli_query($GLOBALS["___mysqli_ston"], $update_query); + tc_insert_strings("info", $clockin); + tc_update_strings("employees", array("tstamp" => $tz_stamp), "empfullname = ?", $fullname); echo "\n"; echo "\n"; @@ -402,14 +332,7 @@ class=misc_items style='padding-left:0px;padding-right:0px;' tabindex=5>\n"; echo " \n"; +} + +function msg_added($msg) { + echo "\n"; +} + +function msg_converted($msg) { + echo "\n"; +} + +// Ensure that the corresponding table exists, creates it if missing. +// Note: need not create all columns since we will add any missing columns +// with ensure_field. +function ensure_table($table, $columns, $engine = "ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin") { + global $db_name; + global $db_prefix; + $rows = mysqli_num_rows(tc_query("SHOW TABLES LIKE '$db_prefix$table'")); + + if (empty($rows)) { + tc_query("CREATE TABLE $db_prefix$table ($columns) $engine"); + msg_added("$table table has been added to the $db_name database."); + return 1; + } + return 0; +} + +// Ensure field is present and has correct type. Does not check other +// attributes (NULL, default, ...) +function ensure_field($table, $field, $type, $extra) { + global $db_prefix; + $result = tc_query("SHOW FIELDS FROM $db_prefix$table LIKE '$field'"); + + while ($row = mysqli_fetch_array($result)) { + $current_type = "" . $row['Type'] . ""; + if (strtolower($type) !== strtolower($current_type)) { + tc_query("ALTER TABLE $db_prefix$table CHANGE `$field` `$field` $type $extra"); + msg_changed("$field field in $table table has been changed from type $current_type to type $type."); + return 1; + } + } + + if (empty($current_type)) { + tc_query("ALTER TABLE $db_prefix$table ADD `$field` $type $extra;"); + msg_added("$field field has been added to the $table table."); + return 1; + } + + return 0; +} + +// Ensure a simple non-primary/non-unique index is present on the named +// field. If a primary/unique index exists, we won't create another. +function ensure_index($table, $field) { + global $db_prefix; + $rows = mysqli_num_rows(tc_query("SHOW INDEX FROM $db_prefix$table WHERE column_name = ?", $field)); + + if (empty($rows)) { + tc_query("CREATE INDEX {$db_prefix}{$table}_{$field} ON {$db_prefix}{$table} (`{$field}`)"); + msg_added("INDEX has been added to the {$table}.{$field} column."); + return 1; + } + return 0; +} + + $self = $_SERVER['PHP_SELF']; $request = $_SERVER['REQUEST_METHOD']; @@ -22,11 +89,7 @@ exit; } -$count = "0"; -$tmp_count = "0"; -$emp_tstamp_count = "0"; -$info_timestamp_count = "0"; -$passed_or_not = "0"; +$changes_made = 0; $gmt_offset = date('Z'); echo "
-
Remember Me?Remember Me?
-
Reset Cookie?Reset Cookie?
\n"; echo "
\n"; - - if ($show_display_name == "yes") { - $strip_fullname = stripslashes($displayname); - } else { - $strip_fullname = stripslashes($fullname); - } - - echo "You have entered the wrong password for $strip_fullname. Please try again."; + echo "You have entered the wrong password for $emp_name. Please try again."; include 'footer.php'; exit; } From 476d6b9fcf403fa8bdf5e1f24e9564e727181d49 Mon Sep 17 00:00:00 2001 From: Dean Serenevy Date: Fri, 10 Mar 2017 13:00:17 -0500 Subject: [PATCH 15/17] DB Upgrade script: Add functions to simplify and expand checks; ensure matches create_tables.sql --- admin/dbupgrade.php | 510 ++++++++++++++++---------------------------- create_tables.sql | 135 ++++-------- 2 files changed, 222 insertions(+), 423 deletions(-) diff --git a/admin/dbupgrade.php b/admin/dbupgrade.php index 6f7158d..8ff4ca9 100644 --- a/admin/dbupgrade.php +++ b/admin/dbupgrade.php @@ -6,6 +6,73 @@ include 'topmain.php'; echo "$title - Upgrade Database\n"; +function msg_changed($msg) { + echo "
Changed: $msg
Added: $msg
Converted: $msg
\n"; @@ -77,29 +140,26 @@ // determine the privileges of the PHP Timeclock user // -$result = mysqli_query($GLOBALS["___mysqli_ston"], "show grants for current_user()"); +$count = "0"; +$result = tc_query("show grants for current_user()"); while ($row = mysqli_fetch_array($result)) { $abc = stripslashes("" . $row["0"] . ""); if (((preg_match("/\bgrant\b/i", $abc)) && (preg_match("/\bselect\b/i", $abc)) && (preg_match("/\binsert\b/i", $abc)) && (preg_match("/\bupdate\b/i", $abc)) && (preg_match("/\bdelete\b/i", $abc)) && (preg_match("/\bcreate\b/i", $abc)) && - (preg_match("/\balter\b/i", $abc)) && (preg_match("/\bon `$db_name`\.\* to '$db_username'@'$db_hostname|%\b/i", $abc))) || - (preg_match("/\bgrant all privileges on `$db_name`\.\* to '$db_username'@'$db_hostname|%' \b/i", $abc)) || - (preg_match("/\bgrant all privileges on \*\.\* to '$db_username'@'$db_hostname|%' \b/i", $abc)) + (preg_match("/\balter\b/i", $abc)) && (preg_match("/\bon `\Q$db_name`.*\E to '\Q$db_username\E'@/i", $abc))) || + (preg_match("/\bgrant all privileges on \Q`$db_name`.*\E to '\Q$db_username\E'@'/i", $abc)) || + (preg_match("/\bgrant all privileges on \*\.\* to '\Q$db_username\E'@/i", $abc)) ) { $count++; } } + if (!empty($count)) { if ($request == 'GET') { - $query_admin = "select empfullname from " . $db_prefix . "employees where empfullname = 'admin'"; - $result_admin = mysqli_query($GLOBALS["___mysqli_ston"], $query_admin); - - while ($row = mysqli_fetch_array($result_admin)) { - $user_admin = "" . $row["empfullname"] . ""; - } + $user_admin = tc_select_value("empfullname", "employees", "empfullname = 'admin'"); echo " \n"; echo "
\n"; @@ -153,360 +213,158 @@ echo " \n"; - // track the database changes that have been made since version 0.9 // - - // employees table additions // - - $field = "employee_passwd"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysqli_num_rows($result); - - if (empty($rows)) { - $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field VARCHAR(25) NOT NULL;"); - echo " \n"; - $passed_or_not = "1"; - } - - $field = "displayname"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysqli_num_rows($result); - - if (empty($rows)) { - $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field VARCHAR(50) NOT NULL;"); - echo " \n"; - $passed_or_not = "1"; - } - - $field = "email"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysqli_num_rows($result); - - if (empty($rows)) { - $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field VARCHAR(75) NOT NULL;"); - echo " \n"; - $passed_or_not = "1"; - } - - $field = "groups"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysqli_num_rows($result); - - if (empty($rows)) { - $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field VARCHAR(50) NOT NULL;"); - echo " \n"; - $passed_or_not = "1"; - } - - $field = "office"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysqli_num_rows($result); - - if (empty($rows)) { - $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field VARCHAR(50) NOT NULL;"); - echo " \n"; - $passed_or_not = "1"; - } - - $field = "admin"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysqli_num_rows($result); - - if (empty($rows)) { - $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field TINYINT(1) NOT NULL default '0';"); - echo " \n"; - $passed_or_not = "1"; - } - - $field = "reports"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysqli_num_rows($result); - - if (empty($rows)) { - $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field TINYINT(1) NOT NULL default '0';"); - echo " \n"; - $passed_or_not = "1"; - } - - $field = "time_admin"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysqli_num_rows($result); - - if (empty($rows)) { - $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field TINYINT(1) NOT NULL default '0';"); - echo " \n"; - $passed_or_not = "1"; - } + // TABLE: audit // + $changes_made += ensure_table("audit", "modified_when bigint(14)"); - $field = "disabled"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "employees LIKE '" . $field . "'"); - @$rows = mysqli_num_rows($result); + $changes_made += ensure_field("audit", "modified_when", "bigint(14)", ""); + $changes_made += ensure_field("audit", "modified_from", "bigint(14)", "NOT NULL"); + $changes_made += ensure_field("audit", "modified_to", "bigint(14)", "NOT NULL"); + $changes_made += ensure_field("audit", "modified_by_ip", "varchar(39)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); + $changes_made += ensure_field("audit", "modified_by_user", "varchar(50)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); + $changes_made += ensure_field("audit", "modified_why", "varchar(250)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); + $changes_made += ensure_field("audit", "user_modified", "varchar(50)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); - if (empty($rows)) { - $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees ADD $field TINYINT(1) NOT NULL default '0';"); - echo " \n"; - $passed_or_not = "1"; - } + $changes_made += ensure_index("audit", "modified_when"); - // employees table changes // + // TABLE: employees // + $changes_made += ensure_table("employees", "empfullname varchar(50) PRIMARY KEY COLLATE utf8_bin"); - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW FIELDS FROM " . $db_prefix . "employees"); + $result = tc_query("SHOW FIELDS FROM {$db_prefix}employees"); while ($row = mysqli_fetch_array($result)) { $name = "" . $row["Field"] . ""; - $type = "" . $row["Type"] . ""; - $tmp_type = strtoupper($type); - - if (($name == 'empfullname') && ($type != 'varchar(50)')) { - $alter_result = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees CHANGE empfullname empfullname VARCHAR(50) NOT NULL"); - echo " \n"; - $passed_or_not = "1"; - } + $type = strtolower("" . $row["Type"] . ""); + + // This one needs some data conversion: if (($name == 'tstamp') && ($type != 'bigint(14)')) { - $alter_result = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "employees CHANGE tstamp tstamp BIGINT(14) DEFAULT NULL"); - echo " \n"; - $emp_tstamp_count++; - $passed_or_not = "1"; + tc_query("ALTER TABLE {$db_prefix}employees CHANGE tstamp tstamp BIGINT(14) DEFAULT NULL"); + msg_changed("$name field in employees table has been changed from type $type to type BIGINT(14)."); + $changes_made += 1; + + tc_query("UPDATE {$db_prefix}employees SET tstamp = (unix_timestamp(tstamp) - '$gmt_offset')"); + $num_rows = mysqli_affected_rows($GLOBALS["___mysqli_ston"]); + if (!empty($num_rows)) { + msg_converted("$num_rows rows in the employees table were converted from a mysql timestamp to a unix timestamp."); + } } } - ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); - - // info table additions // - - $field = "ipaddress"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "info LIKE '" . $field . "'"); - @$rows = mysqli_num_rows($result); - - if (empty($rows)) { - $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "info ADD $field VARCHAR(39) NOT NULL;"); - echo " \n"; - $passed_or_not = "1"; - } - // info table changes // + $changes_made += ensure_field("employees", "empfullname", "varchar(50)", "PRIMARY KEY COLLATE utf8_bin"); + $changes_made += ensure_field("employees", "tstamp", "bigint(14)", "DEFAULT NULL"); + $changes_made += ensure_field("employees", "employee_passwd", "varchar(25)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); + $changes_made += ensure_field("employees", "displayname", "varchar(50)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); + $changes_made += ensure_field("employees", "email", "varchar(75)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); + $changes_made += ensure_field("employees", "groups", "varchar(50)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); + $changes_made += ensure_field("employees", "office", "varchar(50)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); + $changes_made += ensure_field("employees", "admin", "tinyint(1)", "NOT NULL DEFAULT '0'"); + $changes_made += ensure_field("employees", "reports", "tinyint(1)", "NOT NULL DEFAULT '0'"); + $changes_made += ensure_field("employees", "time_admin", "tinyint(1)", "NOT NULL DEFAULT '0'"); + $changes_made += ensure_field("employees", "disabled", "tinyint(1)", "NOT NULL DEFAULT '0'"); - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW FIELDS FROM " . $db_prefix . "info"); - while ($row = mysqli_fetch_array($result)) { - $name = "" . $row["Field"] . ""; - $type = "" . $row["Type"] . ""; - $tmp_type = strtoupper($type); - - if (($name == 'inout') && ($type != 'varchar(50)')) { - $alter_result = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "info CHANGE `inout` `inout` VARCHAR(50) NOT NULL"); - echo " \n"; - $passed_or_not = "1"; - } - if (($name == 'timestamp') && ($type != 'bigint(14)')) { - $alter_result = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "info CHANGE timestamp timestamp BIGINT(14) DEFAULT NULL"); - echo " \n"; - $info_timestamp_count++; - $passed_or_not = "1"; - } - } - ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); - // punchlist table additions // + // TABLE: groups // + $changes_made += ensure_table("groups", "groupid int(10) AUTO_INCREMENT PRIMARY KEY"); - $field = "in_or_out"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW fields from " . $db_prefix . "punchlist LIKE '" . $field . "'"); - $rows = mysqli_num_rows($result); + $changes_made += ensure_field("groups", "groupid", "int(10)", "AUTO_INCREMENT PRIMARY KEY"); + $changes_made += ensure_field("groups", "groupname", "varchar(50)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); + $changes_made += ensure_field("groups", "officeid", "int(10)", "NOT NULL DEFAULT '0'"); - if (empty($rows)) { - $passwd_query = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "punchlist ADD $field TINYINT(1) NOT NULL default '0';"); - echo " \n"; - $passed_or_not = "1"; - } - // punchlist table changes // + // TABLE: info // + $changes_made += ensure_table("info", "fullname varchar(50) COLLATE utf8_bin NOT NULL DEFAULT ''"); - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW FIELDS FROM " . $db_prefix . "punchlist"); + $result = tc_query("SHOW FIELDS FROM {$db_prefix}info"); while ($row = mysqli_fetch_array($result)) { $name = "" . $row["Field"] . ""; - $type = "" . $row["Type"] . ""; - $tmp_type = strtoupper($type); - - if (($name == 'punchitems') && ($type != 'varchar(50)')) { - $alter_result = mysqli_query($GLOBALS["___mysqli_ston"], "ALTER TABLE " . $db_prefix . "punchlist CHANGE punchitems punchitems VARCHAR(50) NOT NULL"); - echo " \n"; - $passed_or_not = "1"; - } - } - ((mysqli_free_result($result) || (is_object($result) && (get_class($result) == "mysqli_result"))) ? true : false); + $type = strtolower("" . $row["Type"] . ""); - // add metars table // - - $table = "metars"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW TABLES LIKE '" . $db_prefix . $table . "'"); - $rows = mysqli_num_rows($result); - - if (empty($rows)) { - $metars_query = mysqli_query($GLOBALS["___mysqli_ston"], "CREATE TABLE " . $db_prefix . "metars (metar varchar(255) NOT NULL default '', - timestamp timestamp(14) NOT NULL, station varchar(4) NOT NULL default '', - PRIMARY KEY (station), UNIQUE KEY station (station)) TYPE=MyISAM;"); - echo " \n"; - $passed_or_not = "1"; - } - - // add dbversion table // - - $table = "dbversion"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW TABLES LIKE '" . $db_prefix . $table . "'"); - $rows = mysqli_num_rows($result); - - if (empty($rows)) { - $dbversion_query = mysqli_query($GLOBALS["___mysqli_ston"], "CREATE TABLE " . $db_prefix . "dbversion (dbversion decimal(5,1) NOT NULL default '0.0', - PRIMARY KEY (dbversion)) TYPE=MyISAM;"); - echo " \n"; - $passed_or_not = "1"; - } - - // dbversion table changes // - - $table = "dbversion"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW TABLES LIKE '" . $db_prefix . $table . "'"); - $rows = mysqli_num_rows($result); - - if (!empty($rows)) { - $dbversion_result = mysqli_query($GLOBALS["___mysqli_ston"], "select * from " . $db_prefix . "dbversion"); - while ($row = mysqli_fetch_array($dbversion_result)) { - $tmp_dbversion = "" . $row["dbversion"] . ""; - } - if (!isset($tmp_dbversion)) { - $compare_result = mysqli_query($GLOBALS["___mysqli_ston"], "INSERT INTO " . $db_prefix . "dbversion (dbversion) VALUES ('" . $dbversion . "');"); - echo " \n"; - $passed_or_not = "1"; - } elseif (@$tmp_dbversion != $dbversion) { - $update_query = "update dbversion set " . $db_prefix . "dbversion = '" . $dbversion . "'"; - $update_result = mysqli_query($GLOBALS["___mysqli_ston"], $update_query); - echo " \n"; - $passed_or_not = "1"; + // This one needs some data conversion: + if (($name == 'timestamp') && ($type != 'bigint(14)')) { + tc_query("ALTER TABLE {$db_prefix}info CHANGE timestamp timestamp BIGINT(14) DEFAULT NULL"); + msg_changed("$name field in info table has been changed from type $type to type BIGINT(14)."); + $changes_made += 1; + + tc_query("UPDATE {$db_prefix}info SET timestamp = (unix_timestamp(tstamp) - '$gmt_offset')"); + $num_rows = mysqli_affected_rows($GLOBALS["___mysqli_ston"]); + if (!empty($num_rows)) { + msg_converted("$num_rows rows in the info table were converted from a mysql timestamp to a unix timestamp."); + } } } - // add offices table // + $changes_made += ensure_field("info", "fullname", "varchar(50)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); + $changes_made += ensure_field("info", "inout", "varchar(50)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); + $changes_made += ensure_field("info", "timestamp", "bigint(14)", "DEFAULT NULL"); + $changes_made += ensure_field("info", "notes", "varchar(250)", "COLLATE utf8_bin DEFAULT NULL"); + $changes_made += ensure_field("info", "ipaddress", "varchar(39)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); - $table = "offices"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW TABLES LIKE '" . $db_prefix . $table . "'"); - $rows = mysqli_num_rows($result); + $changes_made += ensure_index("info", "fullname"); + $changes_made += ensure_index("info", "timestamp"); - if (empty($rows)) { - $metars_query = mysqli_query($GLOBALS["___mysqli_ston"], "CREATE TABLE " . $db_prefix . "offices (officename varchar(50) NOT NULL default '', - officeid int(10) NOT NULL auto_increment, - PRIMARY KEY (officeid), UNIQUE KEY officeid (officeid)) TYPE=MyISAM;"); - echo " \n"; - $passed_or_not = "1"; - } - // add groups table // + // TABLE: metars // + $changes_made += ensure_table("metars", "station varchar(4) PRIMARY KEY COLLATE utf8_bin"); - $table = "groups"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW TABLES LIKE '" . $db_prefix . $table . "'"); - $rows = mysqli_num_rows($result); + $changes_made += ensure_field("metars", "station", "varchar(4)", "PRIMARY KEY COLLATE utf8_bin"); + $changes_made += ensure_field("metars", "metar", "varchar(255)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); + $changes_made += ensure_field("metars", "timestamp", "timestamp", "NOT NULL"); - if (empty($rows)) { - $metars_query = mysqli_query($GLOBALS["___mysqli_ston"], "CREATE TABLE " . $db_prefix . "groups (groupname varchar(50) NOT NULL default '', - groupid int(10) NOT NULL auto_increment, - officeid int(10) NOT NULL default '0', - PRIMARY KEY (groupid), UNIQUE KEY groupid (groupid)) TYPE=MyISAM;"); - echo " \n"; - $passed_or_not = "1"; - } - // add audit table // - - $table = "audit"; - $result = mysqli_query($GLOBALS["___mysqli_ston"], "SHOW TABLES LIKE '" . $db_prefix . $table . "'"); - $rows = mysqli_num_rows($result); - - if (empty($rows)) { - $audit_query = mysqli_query($GLOBALS["___mysqli_ston"], "CREATE TABLE " . $db_prefix . "audit (modified_by_ip varchar(39) NOT NULL default '', - modified_by_user varchar(50) NOT NULL default '', - modified_when bigint(14) NOT NULL, modified_from bigint(14) NOT NULL, - modified_to bigint(14) NOT NULL, modified_why varchar(250) NOT NULL default '', - user_modified varchar(50) NOT NULL, - PRIMARY KEY (modified_when), UNIQUE KEY modified_when (modified_when)) TYPE=MyISAM;"); - echo " \n"; - $passed_or_not = "1"; - } + // TABLE: offices // + $changes_made += ensure_table("offices", "officeid int(10) AUTO_INCREMENT PRIMARY KEY"); - if (isset($recreate_admin)) { + $changes_made += ensure_field("offices", "officeid", "int(10)", "AUTO_INCREMENT PRIMARY KEY"); + $changes_made += ensure_field("offices", "officename", "varchar(50)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); - if ($recreate_admin == '1') { - // add admin user // + // TABLE: punchlist // + $changes_made += ensure_table("punchlist", "punchitems varchar(50) PRIMARY KEY COLLATE utf8_bin"); - $admin = "admin"; + $changes_made += ensure_field("punchlist", "punchitems", "varchar(50)", "PRIMARY KEY COLLATE utf8_bin"); + $changes_made += ensure_field("punchlist", "color", "varchar(7)", "COLLATE utf8_bin NOT NULL DEFAULT ''"); + $changes_made += ensure_field("punchlist", "in_or_out", "tinyint(1)", "DEFAULT NULL"); - $query_admin = "select empfullname from " . $db_prefix . "employees where empfullname = '" . $admin . "'"; - $result_admin = mysqli_query($GLOBALS["___mysqli_ston"], $query_admin); - while ($row_admin = mysqli_fetch_array($result_admin)) { - $admin_user = stripslashes("" . $row_admin['empfullname'] . ""); - } + // TABLE: dbversion // + $changes_made += ensure_table("dbversion", "dbversion decimal(5,1) NOT NULL DEFAULT '0.0'"); - if (!isset($admin_user)) { - $add_admin_query = mysqli_query($GLOBALS["___mysqli_ston"], "INSERT INTO " . $db_prefix . "employees - VALUES ('admin', NULL, 'xy.RY2HT1QTc2', 'administrator', '', '', '', 1, 1, 1, '');"); + $changes_made += ensure_field("dbversion", "dbversion", "decimal(5,1)", "NOT NULL DEFAULT '0.0'"); - echo " \n"; - $passed_or_not = "1"; - } - } + $current_dbversion = tc_select_value("dbversion", "dbversion"); + if (empty($current_dbversion)) { + tc_insert_strings("dbversion", array("dbversion" => $dbversion)); + $changes_made += 1; + msg_changed("the database is now at version $dbversion."); } - - // convert mysql timestamps to unix timestamps // - - if (!empty($emp_tstamp_count)) { - $emp_tstamp_result = mysqli_query($GLOBALS["___mysqli_ston"], "update " . $db_prefix . "employees set tstamp = (unix_timestamp(tstamp) - '" . $gmt_offset . "')"); - $employee_rows = mysqli_affected_rows($GLOBALS["___mysqli_ston"]); - - if (!empty($employee_rows)) { - echo " \n"; - } + elseif ($current_dbversion != $dbversion) { + tc_update_strings("dbversion", array("dbversion" => $dbversion)); + msg_changed("the database has been upgraded from version $current_dbversion to version $dbversion."); + $changes_made += 1; } - unset($emp_tstamp_count); - if (!empty($info_timestamp_count)) { - $info_timestamp_result = mysqli_query($GLOBALS["___mysqli_ston"], "update " . $db_prefix . "info set timestamp = (unix_timestamp(timestamp) - '" . $gmt_offset . "')"); - $info_rows = mysqli_affected_rows($GLOBALS["___mysqli_ston"]); - - if (!empty($info_rows)) { - echo " \n"; + // Recreate admin // + if (isset($recreate_admin) and $recreate_admin == '1') { + $admin = "admin"; + $admin_user = tc_select_value("empfullname", "employees", "empfullname = ?", $admin); + + if (!isset($admin_user)) { + tc_insert_strings("employees", array( + "empfullname" => $admin, + "employee_passwd" => 'xy.RY2HT1QTc2', + "displayname" => 'administrator', + "admin" => 1, + "reports" => 1, + "time_admin" => 1, + )); + msg_added("$admin user has been added to the $db_name database."); + $changes_made += 1; } } - unset($info_timestamp_count); - if (empty($passed_or_not)) { - echo " \n"; + + if (empty($changes_made)) { + echo "\n"; } else { - echo " \n"; + echo "\n"; } echo "
Added$field field has been added to the employees table.
Added$field field has been added to the employees table.
Added$field field has been added to the employees table.
Added$field field has been added to the employees table.
Added$field field has been added to the employees table.
Added$field field has been added to the employees table.
Added$field field has been added to the employees table.
Added$field field has been added to the employees table.
Added$field field has been added to the employees table.
Changed$name field in employees table has been changed from type $tmp_type to type VARCHAR(50).
Changed$name field in employees table has been changed from type $tmp_type to type BIGINT(14).
Added$field field has been added to the employees table.
Changed$name field in info table has been changed from type $tmp_type to type VARCHAR(50).
Changed$name field in info table has been changed from type $tmp_type to type BIGINT(14).
Added$field field has been added to the punchlist table.
Changed$name field in punchlist table has been changed from type $tmp_type to type VARCHAR(50).
Added$table table has been added to the $db_name database.
Added$table table has been added to the $db_name database.
Changed: the version of the database is $dbversion.
Changed: the version of the database has been changed from $tmp_dbversion to $dbversion.
Added$table table has been added to the $db_name database.
Added$table table has been added to the $db_name database.
Added$table table has been added to the $db_name database.
Added$admin user has been added to the $db_name database.
Converted$employee_rows rows in the employees table were converted from a mysql timestamp to a unix - timestamp.
Converted:$info_rows rows in the info table were converted from a mysql timestamp to a unix timestamp.
No changes were made to the - database.
No changes were made to the database.
Your database is now up to date. -
Your database is now up to date.
\n"; echo "
\n"; echo " \n"; echo " \n"; -echo " \n"; +echo " \n"; +echo " \n"; echo " \n"; echo " \n"; echo " \n"; @@ -84,6 +85,7 @@ while ($row = mysqli_fetch_array($result)) { $punchitem = "" . $row['punchitems'] . ""; + $punchnext = "" . $row['punchnext'] . ""; $color = "" . $row['color'] . ""; $in_or_out = "" . $row['in_or_out'] . ""; @@ -99,7 +101,9 @@ echo " \n"; echo " \n"; - echo " \n"; + echo " \n"; + echo " \n"; echo " \n"; if ((strpos($user_agent, "MSIE 6")) || (strpos($user_agent, "MSIE 5")) || (strpos($user_agent, "MSIE 4")) || (strpos($user_agent, "MSIE 3"))) { diff --git a/admin/statuscreate.php b/admin/statuscreate.php index 1c31f2e..ec7e5f2 100644 --- a/admin/statuscreate.php +++ b/admin/statuscreate.php @@ -75,7 +75,7 @@    Create Status\n"; echo " \n"; echo " \n"; echo " \n"; echo " \n"; + echo " \n"; echo " \n"; echo "
 Status NameColorOn PunchColorIn/OutEditDelete
 $row_count $punchitem $color " . ($punchnext ? "→ " : "") . "$punchnext $color$in_or_out_tmp
Status Name: *
Color:Is Status considered 'In' or 'Out'?In Out
On Punch Become:
* required 
\n"; echo " \n"; @@ -101,6 +104,7 @@ $post_statusname = $_POST['post_statusname']; $post_color = $_POST['post_color']; $create_status = $_POST['create_status']; + $punchnext = $_POST['punchnext']; echo "\n"; echo " \n"; @@ -163,8 +167,14 @@ } } + $punchnext_ok = true; + if (has_value($punchnext)) { + $punchnext_ok = ($punchnext == tc_select_value("punchitems", "punchlist", "punchitems = ?", $punchnext)); + } + if ((empty($post_statusname)) || (empty($post_color)) || (!preg_match('/' . "^([[:alnum:]]| |-|_|\.)+$" . '/i', $post_statusname)) || (isset($dupe)) || ((!preg_match('/' . "^(#[a-fA-F0-9]{6})+$" . '/i', $post_color)) && (!preg_match('/' . "^([a-fA-F0-9]{6})+$" . '/i', $post_color))) || (!empty($string)) || (!empty($string2)) + || !$punchnext_ok ) { if (empty($post_statusname)) { @@ -206,6 +216,11 @@ echo " \n"; echo "
Status already exists. Create another status.
\n"; + } elseif (!$punchnext_ok) { + echo " \n"; + echo " \n"; + echo "
+ \"On Punch\" target is invalid!
\n"; } echo "
\n"; @@ -232,6 +247,10 @@ Out
On Punch Become:
* required 
\n"; echo " \n"; @@ -245,7 +264,15 @@ exit; } else { - $result = tc_insert_strings("punchlist", array("punchitems" => $post_statusname, "color" => $post_color, "in_or_out" => $create_status)); + $result = tc_insert_strings( + "punchlist", + array( + "punchitems" => $post_statusname, + "color" => $post_color, + "in_or_out" => $create_status, + "punchnext" => $punchnext + ) + ); echo " \n"; echo " \n"; @@ -271,6 +298,8 @@ echo " \n"; + echo " \n"; echo " \n"; echo "
Is Status considered 'In' or 'Out'? $create_status_tmp
On Punch:$punchnext
\n"; echo " \n"; diff --git a/admin/statusedit.php b/admin/statusedit.php index 7bfc328..6d68176 100644 --- a/admin/statusedit.php +++ b/admin/statusedit.php @@ -46,6 +46,7 @@ $punchitem = "" . $row['punchitems'] . ""; $color = "" . $row['color'] . ""; $in_or_out = "" . $row['in_or_out'] . ""; + $punchnext = "" . $row['punchnext'] . ""; } echo "
\n"; @@ -123,6 +124,10 @@ exit; } + echo " \n"; + echo " \n"; echo "
On Punch Become:
* required 
\n"; echo " \n"; @@ -141,6 +146,7 @@ $post_statusname = $_POST['post_statusname']; $post_color = $_POST['post_color']; $create_status = $_POST['create_status']; + $punchnext = $_POST['punchnext']; // begin post validation // @@ -152,6 +158,12 @@ } } + $punchnext_ok = true; + if (has_value($punchnext)) { + $punchnext_ok = ($punchnext == tc_select_value("punchitems", "punchlist", "punchitems = ?", $punchnext)); + } + + if (($create_status !== '0') && ($create_status !== '1')) { exit; } @@ -161,6 +173,7 @@ if ((empty($post_statusname)) || (empty($post_color)) || (!preg_match('/' . "^([[:alnum:]]| |-|_|.)+$" . '/i', $post_statusname)) || ((!preg_match('/' . "^(#[a-fA-F0-9]{6})+$" . '/i', $post_color)) && (!preg_match('/' . "^([a-fA-F0-9]{6})+$" . '/i', $post_color))) || (!empty($string)) || (!empty($string2)) + || !$punchnext_ok ) { echo "\n"; @@ -246,6 +259,11 @@ echo " \n"; echo "
Double Quotes are not allowed.
\n"; + } elseif (!$punchnext_ok) { + echo " \n"; + echo " \n"; + echo "
+ \"On Punch\" target is invalid!
\n"; } echo "
\n"; @@ -276,6 +294,10 @@ exit; } + echo "
On Punch Become:
* required 
\n"; echo " \n"; @@ -296,16 +318,19 @@ array( "punchitems" => $post_statusname, "color" => $post_color, - "in_or_out" => $create_status + "in_or_out" => $create_status, + "punchnext" => $punchnext ), "punchitems = ?", $get_status ); - tc_update_strings( - "info", - array("inout" => $post_statusname), - "`inout` = ?", $get_status - ); + if ($post_statusname != $get_status) { + tc_update_strings( + "info", + array("inout" => $post_statusname), + "`inout` = ?", $get_status + ); + } echo "\n"; echo " \n"; @@ -380,6 +405,8 @@ echo " \n"; + echo " \n"; echo " \n"; echo "
Is Status considered 'In' or 'Out'?$create_status_tmp
On Punch:$punchnext
\n"; echo " \n"; diff --git a/admin/usercreate.php b/admin/usercreate.php index 71ae2e4..742ffff 100644 --- a/admin/usercreate.php +++ b/admin/usercreate.php @@ -90,6 +90,9 @@ echo " \n"; + echo " \n"; echo " \n"; echo " \n"; + echo " \n"; echo " \n"; echo "
Email Address:  *
Barcode: +
Office:
User Account Disabled? Yes  No
Initial Punch: +
* required 
\n"; echo " \n"; @@ -128,12 +134,14 @@ $password = $_POST['password']; $confirm_password = $_POST['confirm_password']; $email_addy = $_POST['email_addy']; + $user_barcode = value_or_null($_POST['barcode']);// UNIQUE constraint so no empty strings $office_name = $_POST['office_name']; @$group_name = $_POST['group_name']; $admin_perms = $_POST['admin_perms']; $reports_perms = $_POST['reports_perms']; $time_admin_perms = $_POST['time_admin_perms']; $post_disabled = $_POST['disabled']; + $inout = $_POST['inout']; $tmp_username = tc_select_value("empfullname", "employees", "empfullname = ? ORDER by empfullname", $post_username); @@ -340,6 +348,9 @@ echo " \n"; + echo " \n"; echo " \n"; } + echo " \n"; echo " \n"; echo "
Email Address:  *
Barcode: +
Office:  Yes  No
Initial Punch: +
* required 
\n"; echo " \n"; @@ -402,6 +416,7 @@ 'displayname' => $display_name, 'employee_passwd' => $password, 'email' => $email_addy, + 'barcode' => $user_barcode, 'groups' => $group_name, 'office' => $office_name, 'admin' => $admin_perms, @@ -410,6 +425,19 @@ 'disabled' => $post_disabled )); + if (has_value($inout)) { + $inout = tc_select_value("punchitems", "punchlist", "punchitems = ?", $inout); + if (has_value($inout)) { + $tz_stamp = time(); + $clockin = array("fullname" => $post_username, "inout" => $inout, "timestamp" => $tz_stamp); + if (yes_no_bool($ip_logging)) { + $clockin["ipaddress"] = $connecting_ip; + } + tc_insert_strings("info", $clockin); + tc_update_strings("employees", array("tstamp" => $tz_stamp), "empfullname = ?", $post_username); + } + } + echo "
\n"; echo " \n"; echo " \n"; $result4 = tc_select( - "empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled", + "empfullname, displayname, email, barcode, groups, office, admin, reports, time_admin, disabled", "employees", "empfullname = ? ORDER BY empfullname", $post_username ); while ($row = mysqli_fetch_array($result4)) { $username = "" . $row['empfullname'] . ""; $displayname = "" . $row['displayname'] . ""; $user_email = "" . $row['email'] . ""; + $user_barcode = "" . $row['barcode'] . ""; $office = "" . $row['office'] . ""; $groups = "" . $row['groups'] . ""; $admin = "" . $row['admin'] . ""; @@ -491,6 +520,8 @@ colspan=2 width=80% style='padding-left:20px;'>***hidden***\n"; echo " \n"; + echo " \n"; echo " \n"; echo " \n"; + echo " \n"; echo " \n"; echo "
\n"; @@ -467,13 +495,14 @@ echo "
Email Address:$user_email
Barcode:$user_barcode
Office:$office
Group:User Account Disabled?$disabled
Initial Punch:$inout
\n"; echo " \n"; diff --git a/admin/userdelete.php b/admin/userdelete.php index 5109a2c..660e994 100644 --- a/admin/userdelete.php +++ b/admin/userdelete.php @@ -98,6 +98,7 @@ $username = "" . $row['empfullname'] . ""; $displayname = "" . $row['displayname'] . ""; $user_email = "" . $row['email'] . ""; + $user_barcode = "" . $row['barcode'] . ""; $office = "" . $row['office'] . ""; $groups = "" . $row['groups'] . ""; $admin = "" . $row['admin'] . ""; @@ -136,6 +137,8 @@ width=80% style='padding-left:20px;'>$displayname\n"; echo " \n"; + echo " \n"; echo " \n"; echo " \n"; + echo " \n"; echo " \n"; + echo " \n"; echo " \n"; $result4 = tc_select( - "empfullname, displayname, email, groups, office, admin, reports, time_admin, disabled", + "empfullname, displayname, email, barcode, groups, office, admin, reports, time_admin, disabled", "employees", "empfullname = ? ORDER BY empfullname", $post_username @@ -561,6 +570,7 @@ $username = "" . $row['empfullname'] . ""; $displayname = "" . $row['displayname'] . ""; $user_email = "" . $row['email'] . ""; + $user_barcode = "" . $row['barcode'] . ""; $office = "" . $row['office'] . ""; $groups = "" . $row['groups'] . ""; $admin = "" . $row['admin'] . ""; @@ -576,6 +586,8 @@ colspan=2 width=80% style='padding-left:20px;'>$displayname\n"; echo " \n"; + echo " \n"; echo " \n"; echo " \n"; echo " \n"; + size='25' maxlength='50' name='post_username'>\n"; echo " \n"; + size='25' maxlength='50' name='display_name'>\n"; echo " \n"; + size='25' maxlength='75' name='email_addy'>\n"; + echo " \n"; echo " \n"; echo " \n"; + name='post_username' value='$post_username'>\n"; echo " \n"; + name='display_name' value='$display_name'>\n"; echo " \n"; + name='email_addy' value='$email_addy'>\n"; + echo " \n"; echo "
Email Address:$user_email
Barcode:$user_barcode
Office:$office
Group:Email Address:  *
Barcode: +
Office:
Email Address:  *
Barcode: +
Office:
Email Address:$user_email
Barcode:$user_barcode
Office:$office
Group:
Username:
Display Name:
Email Address:
Barcode:
Office: \n"; echo " \n"; echo " \n"; +  A Username, Display Name, Email Address, or Barcode is required.\n"; echo "
-  A Username, Display Name, or Email Address is required.
\n"; $evil_input = "1"; } -if (!empty($office_name) +if (has_value($office_name) and is_null(tc_select_value("officename", "offices", "officename = ?", $office_name)) ) { echo "Office is not defined.\n"; exit; } -if (!empty($group_name) +if (has_value($group_name) and is_null(tc_select_value("groupname", "groups", "groupname = ?", $group_name)) ) { echo "Group is not defined.\n"; @@ -245,19 +243,16 @@ echo "
Username:
Display Name:
Email Address:
Barcode:
Office: \n"; echo " \n"; - echo " \n"; + echo " \n"; echo "
User Search Summary
Search Results for \"$tmp_var\" in $tmp_var2
Search Results for $tmp_var
\n"; echo " \n"; echo " \n"; @@ -452,9 +449,7 @@ style='color:red;' size='25' maxlength='50' name='post_username' - value=\"$post_username\" - onFocus=\"javascript:form.display_name.disabled=true;form.email_addy.disabled=true; - form.display_name.style.background='#eeeeee';form.email_addy.style.background='#eeeeee';\"> + value=\"$post_username\"> \n"; @@ -466,9 +461,7 @@ style='color:red;' size='25' maxlength='50' name='display_name' - value=\"$display_name\" - onFocus=\"javascript:form.post_username.disabled=true;form.email_addy.disabled=true; - form.post_username.style.background='#eeeeee';form.email_addy.style.background='#eeeeee';\"> + value=\"$display_name\"> \n"; @@ -479,9 +472,18 @@ style='color:red;font-family:Tahoma;font-size:10px;padding-left:20px;'> + name='email_addy' value=\"$email_addy\"> + + + \n"; + echo " + + + \n"; diff --git a/config.inc.php b/config.inc.php index 6499534..5112097 100644 --- a/config.inc.php +++ b/config.inc.php @@ -87,6 +87,24 @@ $use_reports_password = "no"; +/* Choose whether to allow barcode clock-in/out. Options are "yes" or "no". + If "yes" is chosen, the barcode entry will be visible and focused by + default on the main timeclock screen. Scanning the employee barcode will + immediately change their status. +*/ + +$barcode_clockin = "yes"; + + +/* Choose whether to allow selecting employee name from dropdown to + clock-in/out. Options are "yes" or "no". If "yes" is chosen, the a + dropdown (and password entry if enabled) will be displayed on the + timeclock screen and employees will be able to change their status. +*/ + +$manual_clockin = "yes"; + + /* Enable the option to log the ip addresses of the connecting computers when users punch-in/out, or when a time is manually added, edited, or deleted. Default is "yes". */ diff --git a/functions.php b/functions.php index 02ba441..46c99c7 100644 --- a/functions.php +++ b/functions.php @@ -111,7 +111,46 @@ function tc_update_strings($db, $keyvals, $where = '1=1', $bind = array(), $type tc_execute("UPDATE ${db_prefix}$db SET $places WHERE $where", array_merge($values, $bind), $types); } +function btag($tag, $attr = array()) { + $begin = array(htmlentities($tag)); + foreach ($attr as $key => $value) { + $begin[] = htmlentities($key) . "=\"" . htmlentities($value) . "\""; + } + return "<" . implode(" ", $begin) . ">"; +} + +function tag($tag, $content = "", $attr = array()) { + return btag($tag, $attr) . htmlentities($content) . ""; +} + +function html_options($result, $selected='') { + $rv = array(); + while ($row = mysqli_fetch_array($result)) { + $value = htmlentities($row[0]); + $display = htmlentities(is_null(@$row[1]) ? $row[0] : $row[1]); + $sel = ($row[0] == $selected) ? " selected" : ""; + $rv[] = "\n"; + } + return implode("", $rv); +} +function yes_no_bool($val, $default=false) { + if (strtolower(@$val) == 'yes') { + return true; + } + if (strtolower(@$val) == 'no') { + return false; + } + return $default; +} + +function value_or_null($val) { + return ((strlen(trim(@$val)) == 0) ? null : $val); +} + +function has_value($val) { + return (strlen(trim(@$val)) != 0); +} function secsToHours($secs, $round_time) { diff --git a/leftmain.php b/leftmain.php index 36d3efb..727e253 100644 --- a/leftmain.php +++ b/leftmain.php @@ -18,6 +18,7 @@ @$reset_cookie = $_POST['reset_cookie']; @$fullname = $_POST['left_fullname']; @$displayname = $_POST['left_displayname']; + @$barcode = (yes_no_bool($barcode_clockin) ? $_POST['left_barcode'] : ""); if ((isset($remember_me)) && ($remember_me != '1')) { echo "Something is fishy here.\n"; exit; @@ -28,37 +29,52 @@ } // begin post validation // + $errors = array(); + + if (has_value($barcode)) { + $tmp_name = tc_select_value($emp_name_field, "employees", "barcode = ?", $barcode); + if (!has_value($tmp_name)) { + $errors[] = "Invalid barcode '$barcode'"; + } elseif (isset($emp_name) and $emp_name != $tmp_name) { + $errors[] = "Username / Barcode mismatch"; + } else { + $emp_name = $tmp_name; + } + } - if ($show_display_name == "yes") { - - if (isset($displayname)) { - $tmp_displayname = tc_select_value("displayname", "employees", "displayname = ?", $displayname); - if ((!isset($tmp_displayname)) && (!empty($displayname))) { - echo "Username is not in the database.\n"; - exit; + $tmp_name = ''; + if (yes_no_bool($show_display_name)) { + if (has_value($displayname)) { + $tmp_name = tc_select_value($emp_name_field, "employees", "displayname = ?", $displayname); + if (!has_value($tmp_name)) { + $errors[] = "Invalid username '$displayname'"; } - $emp_name = $tmp_displayname; } - - } elseif ($show_display_name == "no") { - - if (isset($fullname)) { - $tmp_empfullname = tc_select_value("empfullname", "employees", "empfullname = ?", $fullname); - if ((!isset($tmp_empfullname)) && (!empty($fullname))) { - echo "Username is not in the database.\n"; - exit; + } else { + if (has_value($fullname)) { + $tmp_name = tc_select_value($emp_name_field, "employees", "empfullname = ?", $fullname); + if (!has_value($tmp_name)) { + $errors[] = "Invalid username '$fullname'"; } - $emp_name = $tmp_empfullname; } + } + if (has_value($tmp_name)) { + if (isset($emp_name) and $emp_name != $tmp_name) { + $errors[] = "Username / Barcode mismatch"; + } else { + $emp_name = $tmp_name; + } } // end post validation // - if (isset($remember_me)) { - setcookie("remember_me", $emp_name, time() + (60 * 60 * 24 * 365 * 2)); - } elseif (isset($reset_cookie)) { - setcookie("remember_me", "", time() - 3600); + if (empty($errors)) { + if (isset($remember_me)) { + setcookie("remember_me", $emp_name, time() + (60 * 60 * 24 * 365 * 2)); + } elseif (isset($reset_cookie)) { + setcookie("remember_me", "", time() - 3600); + } } ob_end_flush(); @@ -87,7 +103,7 @@ // display form to submit signin/signout information // -echo " \n"; +echo " \n"; if ($links == "none") { echo " \n"; @@ -95,84 +111,85 @@ echo " \n"; } -echo " \n"; -echo " \n"; -echo " \n"; -echo " + + +BARCODE_CLOCKIN; +} -if ($show_display_name == "yes") { - echo " \n"; +if (yes_no_bool($barcode_clockin) and yes_no_bool($manual_clockin)) { + echo ''; } -$emp_name_result = tc_select($emp_name_field, "employees", "disabled <> '1' AND empfullname <> 'admin' ORDER BY $emp_name_field"); -echo " \n"; -while ($row = mysqli_fetch_array($emp_name_result)) { - $abc = "" . $row[$emp_name_field] . ""; +if (yes_no_bool($manual_clockin)) { + echo " \n"; + echo " \n"; + echo " \n"; + echo " \n"; -((mysqli_free_result($emp_name_result) || (is_object($emp_name_result) && (get_class($emp_name_result) == "mysqli_result"))) ? true : false); -echo " \n"; - -// determine whether to use encrypted passwords or not // - -if ($use_passwd == "yes") { - echo " \n"; - echo " \n"; + echo " \n"; + echo html_options( + tc_select($emp_name_field, "employees", "disabled <> '1' AND empfullname <> 'admin' ORDER BY $emp_name_field"), + @$_COOKIE['remember_me'] + ); + echo " \n"; echo " \n"; -} -echo " \n"; -echo " \n"; + echo " \n"; + echo " \n"; + } -$punchlist_result = tc_select("punchitems", "punchlist"); + echo " \n"; + echo " \n"; -echo " \n"; -((mysqli_free_result($punchlist_result) || (is_object($punchlist_result) && (get_class($punchlist_result) == "mysqli_result"))) ? true : false); - -echo " \n"; -echo " \n"; -echo " \n"; - -if (!isset($_COOKIE['remember_me'])) { - echo " \n"; -} elseif (isset($_COOKIE['remember_me'])) { - echo " \n"; + echo " \n"; + echo " \n"; + echo " \n"; + + if (!isset($_COOKIE['remember_me'])) { + echo " \n"; + } elseif (isset($_COOKIE['remember_me'])) { + echo " \n"; + } + echo " \n"; } -echo " \n"; -echo " \n"; +echo " \n"; -if ($display_weather == 'yes') { +if (yes_no_bool($display_weather)) { echo ''; @@ -191,80 +208,51 @@ class=misc_items style='padding-left:0px;padding-right:0px;' tabindex=5>\n"; - echo "
Barcode:
Please sign in below:
Name:
\n"; - -// query to populate dropdown with employee names // +if (yes_no_bool($barcode_clockin)) { + echo <<Barcode:
+ + +

Please sign in below:
Name:
\n"; + + // query to populate dropdown with employee names // - if ((isset($_COOKIE['remember_me'])) && ($_COOKIE['remember_me'] == $abc)) { - echo " \n"; + if ($show_display_name == "yes") { + echo " \n"; } -} -echo "
Password:
"; - echo "
In/Out:
\n"; + // determine whether to use encrypted passwords or not // -// query to populate dropdown with punchlist items // + if ($use_passwd == "yes") { + echo "
Password:
"; + echo "
In/Out:
\n"; -echo " \n"; + echo " \n"; + echo html_options(tc_select("punchitems", "punchlist")); + echo "
Notes:
"; -echo "
- -
Remember Me?
- -
Reset Cookie?
Notes:
"; + echo "
+ +
Remember Me?
+ +
Reset Cookie?
'; include 'sidebar-metar-display.php'; echo '
\n"; - echo " \n"; - echo "
\n"; - echo "
\n"; - echo "You have not chosen a username or a status. Please try again.\n"; - include 'footer.php'; - exit; - } - - if (!$displayname) { - echo "
\n"; - echo " \n"; - echo " \n"; - echo " \n"; +echo " \n"; +echo "
\n"; - echo "
\n"; - echo "You have not chosen a username. Please try again.\n"; - include 'footer.php'; - exit; - } - - } elseif ($show_display_name == "no") { - - if (!$fullname && !$inout) { - echo "
\n"; - echo " \n"; - echo " \n"; - echo " \n"; +echo "
\n"; - echo "
\n"; - echo "You have not chosen a username or a status. Please try again.\n"; - include 'footer.php'; - exit; - } - - if (!$fullname) { - echo "
\n"; - echo " \n"; - echo " \n"; - echo " \n"; -echo " \n"; -echo "
\n"; - echo "
\n"; - echo "You have not chosen a username. Please try again.\n"; - include 'footer.php'; - exit; - } - + if (!has_value($emp_name) && !has_value($inout)) { + $errors[] = "You have not chosen a username or a status. Please try again."; + } + elseif (!has_value($emp_name)) { + $errors[] = "You have not chosen a username. Please try again."; + } + elseif (!has_value($inout)) { + $errors[] = "You have not chosen a status. Please try again."; } - if (!$inout) { + if (!empty($errors)) { echo "
\n"; echo " \n"; echo " \n"; echo " \n"; -echo "
\n"; echo "
\n"; - echo "You have not chosen a status. Please try again.\n"; + echo implode("
\n", $errors); include 'footer.php'; exit; } @@ -280,10 +268,10 @@ class=misc_items style='padding-left:0px;padding-right:0px;' tabindex=5> $fullname, "inout" => $inout, "timestamp" => $tz_stamp, "notes" => $notes); diff --git a/alter_tables.sql b/sql/alter_tables.sql similarity index 89% rename from alter_tables.sql rename to sql/alter_tables.sql index d2716f0..85338a1 100644 --- a/alter_tables.sql +++ b/sql/alter_tables.sql @@ -1,6 +1,19 @@ # if you would like to utilize a table prefix when upgrading these tables, be sure to use the one you have setup in config.inc.php. # this option is $db_prefix. if you are unaware of what is meant by utilizing a 'table prefix', then please disregard. +-- Database upgrades may be performed automatically in the app under +-- "Administration -> Upgrade Database" as long as the database connection +-- used by your web app has the required privileges. Otherwise you must +-- perform the upgrade manually. +-- +-- When upgrading from versions older than 1.04, perform the upgrades +-- described in this file in order to reach dbversion 1.4. +-- +-- To upgrade from dbversion 1.4 or newer, run the upgrade scripts in this +-- directory, one at a time, until your database is upgraded to the latest +-- version. + + ################################################################### # # diff --git a/create_tables.sql b/sql/create_tables.sql similarity index 96% rename from create_tables.sql rename to sql/create_tables.sql index ed2e70d..ed7e3ac 100644 --- a/create_tables.sql +++ b/sql/create_tables.sql @@ -46,6 +46,7 @@ CREATE TABLE `employees` ( `employee_passwd` varchar(25) COLLATE utf8_bin NOT NULL DEFAULT '', `displayname` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', `email` varchar(75) COLLATE utf8_bin NOT NULL DEFAULT '', + `barcode` varchar(75) COLLATE utf8_bin UNIQUE, `groups` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', `office` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', `admin` tinyint(1) NOT NULL DEFAULT '0', @@ -114,6 +115,7 @@ CREATE TABLE `offices` ( CREATE TABLE `punchlist` ( `punchitems` varchar(50) PRIMARY KEY COLLATE utf8_bin, + `punchnext` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT '', `color` varchar(7) COLLATE utf8_bin NOT NULL DEFAULT '', `in_or_out` tinyint(1) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; @@ -125,7 +127,7 @@ CREATE TABLE `punchlist` ( -- INSERT INTO employees VALUES ('admin', NULL, 'xy.RY2HT1QTc2', 'administrator', '', '', '', 1, 1, 1, ''); -INSERT INTO dbversion VALUES ('1.4'); +INSERT INTO dbversion VALUES ('1.5'); INSERT INTO punchlist VALUES ('in', '#009900', 1); INSERT INTO punchlist VALUES ('out', '#FF0000', 0); INSERT INTO punchlist VALUES ('break', '#FF9900', 0); diff --git a/sql/upgrade_v1.4-v2.0.sql b/sql/upgrade_v1.4-v2.0.sql new file mode 100644 index 0000000..f9df17f --- /dev/null +++ b/sql/upgrade_v1.4-v2.0.sql @@ -0,0 +1,5 @@ + +ALTER TABLE `employees` ADD `barcode` varchar(75) COLLATE utf8_bin UNIQUE; +ALTER TABLE `punchlist` ADD `punchnext` varchar(50) COLLATE utf8_bin NOT NULL DEFAULT ''; + +UPDATE `dbversion` SET `dbversion` = '1.5'; From a438a0f4ccc77b6ec5a00925aceaf88ec444b346 Mon Sep 17 00:00:00 2001 From: Dean Serenevy Date: Fri, 10 Mar 2017 14:01:26 -0500 Subject: [PATCH 17/17] Version bump to 2.0.0 - Update documentation versions and URLs --- README.md | 6 +-- config.inc.php | 2 +- docs/CHANGELOG | 11 +++-- docs/CREDITS | 2 - docs/INSTALL | 107 +++++++++++++++++++++++-------------------------- docs/README | 2 - docs/TODO | 2 - footer.php | 40 +++++++++--------- 8 files changed, 79 insertions(+), 93 deletions(-) diff --git a/README.md b/README.md index 690c810..867dba8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # About -This project is PHP Timeclock v1.04 with the Punchclock v0.8 add-on already installed. +This project is PHP Timeclock with the Punchclock add-on already installed. # This Fork @@ -56,8 +56,6 @@ Punchclock enhances PHP Timeclock with 5 extra features: - Flexible export to your spreadsheet or business software. ## PHP Timeclock source credits -- Version 1.04 -- http://sourceforge.net/projects/timeclock - Copyright (C) 2006 Ken Papizan @@ -102,7 +100,7 @@ version than what's tested or later, will probably work fine. certain users can run them, then give these users reports level access. -### Migration from another verison of 1.04 (ie: old official release) +### Migration from another verison (ie: old official release) - Backup your current install directory and database. - Delete all files in your current install directory. diff --git a/config.inc.php b/config.inc.php index 5112097..a3e080e 100644 --- a/config.inc.php +++ b/config.inc.php @@ -420,7 +420,7 @@ $app_name = "PHP Timeclock"; -$app_version = "1.04"; +$app_version = "2.0.0"; /* Sets the title in the header. This is what the page will be named by default when you make a "favorite" or "bookmark" in your browser. Change as you see fit. */ diff --git a/docs/CHANGELOG b/docs/CHANGELOG index e743288..5c846b4 100644 --- a/docs/CHANGELOG +++ b/docs/CHANGELOG @@ -1,10 +1,13 @@ -PHP Timeclock -Version 1.04 -http://sourceforge.net/projects/timeclock +PHP Timeclock Changelog Copyright (C) 2006 Ken Papizan -PHP Timeclock Changelog +PHP Timeclock 2.0.0 released 2017-03-09 + + * Barcode punch in/out + + + 1.04 11/15/07 ----------------------- diff --git a/docs/CREDITS b/docs/CREDITS index ecbcce0..bb7c687 100644 --- a/docs/CREDITS +++ b/docs/CREDITS @@ -1,6 +1,4 @@ PHP Timeclock -Version 1.04 -http://sourceforge.net/projects/timeclock Copyright (C) 2006 Ken Papizan diff --git a/docs/INSTALL b/docs/INSTALL index acae3f2..8bebf55 100644 --- a/docs/INSTALL +++ b/docs/INSTALL @@ -1,6 +1,4 @@ PHP Timeclock -Version 1.04 -http://sourceforge.net/projects/timeclock Copyright (C) 2006 Ken Papizan @@ -12,67 +10,66 @@ REQUIREMENTS: --- Javascript enabled web browser -TESTED: +TESTED CONFIGURATIONS: ---- PHP 4.34, 5.1.2 with mysql support ---- MySQL 3.23.49, 4.0.17, 5.0.18 ---- Apache 1.3.22, 1.3.29, 2.2.0 ---- Firefox 1.0 - 1.5.0.4, Firefox 1.0 Preview Release, IE 6.0 SP1, IE 6.0 SP2 for XP, IE 7.0 beta 2 - -Any version of mysql or webserver software that supports php, whether it's an earlier -version than what's tested or later, will probably work fine. Any web browser that supports -css2 should work fine (IE5+, Mozilla 1.0+, Firefox). - -*********************************************************************************************** -Beginning with version 0.9.4, an option has been provided to display punch-in/out times -according to the timezone of the connecting client system. The client must enable cookies and -javascript in their web browser in order to take advantage of this option. -*********************************************************************************************** +Debian 8.0 (Jessie): PHP 5.6.30, MariaDB 10.0, Apache 2.4.10 + packages: apache2 libapache2-mod-php5 php5-mysqlnd + A Dockerfile is available at: https://github.com/duelafn/dockerfiles/tree/master/timecard INSTALLATION: New Install ----------- ---- Unpack the distribution into your webserver's document root directory. +--- Unpack the distribution into your webserver's document root directory. --- Create a database named "timeclock" or whatever you wish to name it. --- Create a mysql user named "timeclock" (or whatever you wish to name it) with a password. - Give this user at least SELECT, UPDATE, INSERT, DELETE, ALTER, and CREATE privileges to ONLY + Give this user at least SELECT, UPDATE, INSERT, DELETE, ALTER, and CREATE privileges to ONLY this database. --- Import the tables using the create_tables.sql script included in this distribution. --- Edit config.inc.php. --- Open index.php with your web browser. ---- Click on the Administration link on the right side of the page. Input "admin" (without the quotes) - for the username and "admin" (without the quotes) for the password. Please change the password +--- Click on the Administration link on the right side of the page. Input "admin" (without the quotes) + for the username and "admin" (without the quotes) for the password. Please change the password for this admin user after the initial setup of PHP Timeclock is complete. ---- Create at least one office by clicking on the Create Office link on the left side of the page. +--- Create at least one office by clicking on the Create Office link on the left side of the page. You MUST create an office to achieve the desired results. Create more offices if needed. ---- Create at least one group by clicking on the Create Group link on the left side of the page. +--- Create at least one group by clicking on the Create Group link on the left side of the page. You MUST create a group to achieve the desired results. Create more groups if needed. --- Add your users by clicking on the Create New Users link, and assign them to the office(s) and - group(s) you created above. Give Sys Admin level access for users who will administrate - PHP Timeclock. Give Time Admin level access for users who will need to edit users' time, but - who will not need Sys Admin level access. If you require the reports to be secured so only - certain users can run them, then give these users reports level access. - - *** Admin level access and reports level access are completely separate from each other. Just - *** because a user has admin level access does not give that user reports level access. You must - *** specifically give them reports level access when you are creating or editing the users, - *** if you choose to secure these reports for these users. To make PHP Timeclock lock down the + group(s) you created above. Give Sys Admin level access for users who will administrate + PHP Timeclock. Give Time Admin level access for users who will need to edit users' time, but + who will not need Sys Admin level access. If you require the reports to be secured so only + certain users can run them, then give these users reports level access. + + *** Admin level access and reports level access are completely separate from each other. Just + *** because a user has admin level access does not give that user reports level access. You must + *** specifically give them reports level access when you are creating or editing the users, + *** if you choose to secure these reports for these users. To make PHP Timeclock lock down the *** reports to only these users, set the use_reports_password setting in config.inc.php to "yes". +Upgrading from 1.04 +------------------- +--- Backup and move your current installation. +--- Unpack the distribution into your webserver's document root directory. +--- Edit config.inc.php or simply replace the new config.inc.php with your previous config.inc.php. +--- Either login to PHP Timeclock and run the Upgrade Database script within the Admin section, or + upgrade the database by running the upgrade scripts in the "sql" directory, one at a time, until + your database is upgraded to the latest version. + + Upgrading from 1.02 or 1.03 --------------------------- --- Backup and move your current installation. ---- Unpack the distribution into your webserver's document root directory. +--- Unpack the distribution into your webserver's document root directory. --- Edit config.inc.php or simply replace the new config.inc.php with your previous config.inc.php. Upgrading from 1.01 or 1.0 -------------------------- --- Backup and move your current installation. ---- Unpack the distribution into your webserver's document root directory. +--- Unpack the distribution into your webserver's document root directory. --- Edit config.inc.php. --- Either login to PHP Timeclock and run the Upgrade Database script within the Admin section, or upgrade the database by running the queries that are contained in the alter_tables.sql script. @@ -81,44 +78,42 @@ Upgrading from 1.01 or 1.0 Upgrading from 0.9.4 or 0.9.4-1 ------------------------------- --- Backup and move your current installation. ---- Unpack the distribution into your webserver's document root directory. ---- Upgrade the database by running the queries that are contained in the +--- Unpack the distribution into your webserver's document root directory. +--- Upgrade the database by running the queries that are contained in the alter_tables.sql script included in this distribution against the PHP Timeclock - database. The Upgrade Database link in the Administration section of PHP Timeclock will - not work for this particular upgrade since the admin user needs to be added to the database - initially. Meaning, you cannot even get to the Upgrade Database page until the admin user + database. The Upgrade Database link in the Administration section of PHP Timeclock will + not work for this particular upgrade since the admin user needs to be added to the database + initially. Meaning, you cannot even get to the Upgrade Database page until the admin user is added to the database. --- Edit config.inc.php. --- Open index.php with your web browser. ---- Click on the Administration link on the right side of the page. Input "admin" (without the quotes) - for the username and "admin" (without the quotes) for the password. Please change the password +--- Click on the Administration link on the right side of the page. Input "admin" (without the quotes) + for the username and "admin" (without the quotes) for the password. Please change the password for this admin user after the initial setup of PHP Timeclock is complete. ---- Create at least one office by clicking on the Create Office link on the left side of the page. +--- Create at least one office by clicking on the Create Office link on the left side of the page. You MUST create an office to achieve the desired results. Create more offices if needed. ---- Create at least one group by clicking on the Create Group link on the left side of the page. +--- Create at least one group by clicking on the Create Group link on the left side of the page. You MUST create a group to achieve the desired results. Create more groups if needed. ---- Edit your users by clicking on the User Summary link, then click on their username, and then - assign them to the office(s) and group(s) you created above. Give Sys Admin level access for - users who will administrate PHP Timeclock. Give Time Admin level access for users who will +--- Edit your users by clicking on the User Summary link, then click on their username, and then + assign them to the office(s) and group(s) you created above. Give Sys Admin level access for + users who will administrate PHP Timeclock. Give Time Admin level access for users who will need to edit users' time, but who will not need Sys Admin level access. If you require the reports to be secured so only certain users can run them, then give these users reports - level access. + level access. - *** Admin level access and reports level access are completely separate from each other. Just - *** because a user has admin level access does not give that user reports level access. You must - *** specifically give them reports level access when you are creating or editing the users, - *** if you choose to secure these reports for these users. To make PHP Timeclock lock down the + *** Admin level access and reports level access are completely separate from each other. Just + *** because a user has admin level access does not give that user reports level access. You must + *** specifically give them reports level access when you are creating or editing the users, + *** if you choose to secure these reports for these users. To make PHP Timeclock lock down the *** reports to only these users, set the use_reports_password setting in config.inc.php to "yes". -Upgrading from releases prior to 0.9.4 +Upgrading from releases prior to 0.9.4 -------------------------------------- --- The best way to upgrade from versions prior to 0.9.4 is to download version 0.9.4 and upgrade to that version first. Then follow the upgrade instructions included - in that version of the distribution. + in that version of the distribution. The reason for doing it this way is that the timestamps are stored differently for versions - 0.9.4 and higher than in previous versions. Upgrading to 0.9.4 first will preserve the + 0.9.4 and higher than in previous versions. Upgrading to 0.9.4 first will preserve the punch-in/out history for each user. - - diff --git a/docs/README b/docs/README index a6ecfc3..27e49a6 100644 --- a/docs/README +++ b/docs/README @@ -1,6 +1,4 @@ PHP Timeclock -Version 1.04 -http://sourceforge.net/projects/timeclock Copyright (C) 2006 Ken Papizan diff --git a/docs/TODO b/docs/TODO index f4f8dd7..93e39f8 100644 --- a/docs/TODO +++ b/docs/TODO @@ -1,6 +1,4 @@ PHP Timeclock -Version 1.04 -http://sourceforge.net/projects/timeclock Copyright (C) 2006 Ken Papizan diff --git a/footer.php b/footer.php index 37bcbcb..e861c72 100644 --- a/footer.php +++ b/footer.php @@ -1,22 +1,18 @@ -
Powered by Apache ± MySql - ±"; - -if ($email == "none") { - echo " PHP"; -} else { - echo " PHP • $email"; -} - -echo " • $app_name $app_version
\n"; -echo "
\n"; -echo "\n"; -echo "\n"; -?> +
"; + +if ($email != "none") { + echo "$email • "; +} + +echo "$app_name $app_version
\n"; +echo "
\n"; +echo "\n"; +echo "\n"; +?>