From 6480fd73a7c24b939d4b25ffacfdab0c8bb9c930 Mon Sep 17 00:00:00 2001 From: Friendika Date: Wed, 2 Mar 2011 03:25:12 -0800 Subject: [PATCH] units conversion app - needs some styling and code cleanup --- addon/convert/UnitConvertor.php | 283 ++++++++++++++++++++++++++++++++ addon/convert/convert.php | 223 +++++++++++++++++++++++++ include/dba.php | 7 +- include/nav.php | 2 +- 4 files changed, 511 insertions(+), 4 deletions(-) create mode 100644 addon/convert/UnitConvertor.php create mode 100644 addon/convert/convert.php diff --git a/addon/convert/UnitConvertor.php b/addon/convert/UnitConvertor.php new file mode 100644 index 0000000000..d7933a8fb4 --- /dev/null +++ b/addon/convert/UnitConvertor.php @@ -0,0 +1,283 @@ + | +// | Co-authored by : CVH, Chris Hansel | +// +----------------------------------------------------------------------+ +// +// $Id: UnitConvertor.php,v 1.00 2002/02/20 11:40:00 stasokhvat Exp $ + +/** +* UnitConvertor is able to convert between different units and currencies. +* +* @author Stanislav Okhvat +* @version $Id: UnitConvertor.php,v 1.00 2002/03/01 17:00:00 stasokhvat Exp $ +* @package UnitConvertor +* @access public +* @history 01.03.2002 Implemented the code for regular and offset-based +* conversions +* +* 13.12.2004 +* By Chris Hansel (CVH): changed getConvSpecs in order to have it look up +* intermediary conversions (also see comments in check_key). +* +* Intermediary conversions are useful when no conversion ratio is specified +* between two units when we calculate between the two. For example, we want +* to convert between Fahrenheit and Kelvin, and we have only +* specified how to convert Centigrade<->Fahrenheit and +* Centigrade<->Kelvin. While a direct (Fahrenheit->Kelvin) or +* reverse (Kelvin->Fahrenheit) lookups fail, looking for an intermediary +* unit linking the two (Centigrade) helps us do the conversion. +* +* 13.12.2004 +* Chris Hansel (CVH): $to_array argument of addConversion method can now +* contain units as 'unit1/unit2/unit3', when all units stand for the same +* thing. See examples in unitconv.php +*/ +class UnitConvertor +{ + /** + * Stores conversion ratios. + * + * @var array + * @access private + */ + var $conversion_table = array(); + + /** + * Decimal point character (default is "." - American - set in constructor). + * + * @var string + * @access private + */ + var $decimal_point; + + /** + * Thousands separator (default is "," - American - set in constructor). + * + * @var string + * @access private + */ + var $thousand_separator; + + /** + * For future use + * + * @var array + * @access private + */ + var $bases = array(); + + /** + * Constructor. Initializes the UnitConvertor object with the most important + * properties. + * + * @param string decimal point character + * @param string thousand separator character + * @return void + * @access public + */ + function UnitConvertor($dec_point = '.', $thousand_sep = ',') + { + $this->decimal_point = $dec_point; + $this->thousand_separator = $thousand_sep; + + } // end func UnitConvertor + + /** + * Adds a conversion ratio to the conversion table. + * + * @param string the name of unit from which to convert + * @param array array( + * "pound"=>array("ratio"=>'', "offset"=>'') + * ) + * "pound" - name of unit to set conversion ration to + * "ratio" - 'double' conversion ratio which, when + * multiplied by the number of $from_unit units produces + * the result + * "offset" - an offset from 0 which will be added to + * the result when converting (needed for temperature + * conversions and defaults to 0). + * @return boolean true if successful, false otherwise + * @access public + */ + function addConversion($from_unit, $to_array) + { + if (!isset($this->conversion_table[$from_unit])) { + while(list($key, $val) = each($to_array)) + { + if (strstr($key, '/')) + { + $to_units = explode('/', $key); + foreach ($to_units as $to_unit) + { + $this->bases[$from_unit][] = $to_unit; + + if (!is_array($val)) + { + $this->conversion_table[$from_unit."_".$to_unit] = array("ratio"=>$val, "offset"=>0); + } + else + { + $this->conversion_table[$from_unit."_".$to_unit] = + array( + "ratio"=>$val['ratio'], + "offset"=>(isset($val['offset']) ? $val['offset'] : 0) + ); + } + } + } + else + { + $this->bases[$from_unit][] = $key; + + if (!is_array($val)) + { + $this->conversion_table[$from_unit."_".$key] = array("ratio"=>$val, "offset"=>0); + } + else + { + $this->conversion_table[$from_unit."_".$key] = + array( + "ratio"=>$val['ratio'], + "offset"=>(isset($val['offset']) ? $val['offset'] : 0) + ); + } + } + } + return true; + } + return false; + + } // end func addConversion + + /** + * Converts from one unit to another using specified precision. + * + * @param double value to convert + * @param string name of the source unit from which to convert + * @param string name of the target unit to which we are converting + * @param integer double precision of the end result + * @return void + * @access public + */ + function convert($value, $from_unit, $to_unit, $precision) + { + if ($this->getConvSpecs($from_unit, $to_unit, $value, $converted )) + { + return number_format($converted , (int)$precision, $this->decimal_point, $this->thousand_separator); + } else { + return false; + } + } // end func + + /** + * CVH : changed this Function getConvSpecs in order to have it look up + * intermediary Conversions from the + * "base" unit being that one that has the highest hierarchical order in one + * "logical" Conversion_Array + * when taking $conv->addConversion('km', + * array('meter'=>1000, 'dmeter'=>10000, 'centimeter'=>100000, + * 'millimeter'=>1000000, 'mile'=>0.62137, 'naut.mile'=>0.53996, + * 'inch(es)/zoll'=>39370, 'ft/foot/feet'=>3280.8, 'yd/yard'=>1093.6)); + * "km" would be the logical base unit for all units of dinstance, thus, + * if the function fails to find a direct or reverse conversion in the table + * it is only logical to suspect that if there is a chance + * converting the value it only is via the "base" unit, and so + * there is not even a need for a recursive search keeping the perfomance + * acceptable and the ressource small... + * + * CVH check_key checks for a key in the Conversiontable and returns a value + */ + function check_key( $key) { + if ( array_key_exists ($key,$this->conversion_table)) { + if (! empty($this->conversion_table[$key])) { + return $this->conversion_table[$key]; + } + } + return false; + } + + /** + * Key function. Finds the conversion ratio and offset from one unit to another. + * + * @param string name of the source unit from which to convert + * @param string name of the target unit to which we are converting + * @param double conversion ratio found. Returned by reference. + * @param double offset which needs to be added (or subtracted, if negative) + * to the result to convert correctly. + * For temperature or some scientific conversions, + * i.e. Fahrenheit -> Celcius + * @return boolean true if ratio and offset are found for the supplied + * units, false otherwise + * @access private + */ + function getConvSpecs($from_unit, $to_unit, $value, &$converted) + { + $key = $from_unit."_".$to_unit; + $revkey = $to_unit."_".$from_unit; + $found = false; + if ($ct_arr = $this->check_key($key)) { + // Conversion Specs found directly + $ratio = (double)$ct_arr['ratio']; + $offset = $ct_arr['offset']; + $converted = (double)(($value * $ratio)+ $offset); + + return true; + } // not found in direct order, try reverse order + elseif ($ct_arr = $this->check_key($revkey)) { + $ratio = (double)(1/$ct_arr['ratio']); + $offset = -$ct_arr['offset']; + $converted = (double)(($value + $offset) * $ratio); + + return true; + } // not found test for intermediary conversion + else { + // return ratio = 1 if keyparts match + if ($key == $revkey) { + $ratio = 1; + $offset = 0; + $converted = $value; + return true; + } + // otherwise search intermediary + reset($this->conversion_table); + while (list($convk, $i1_value) = each($this->conversion_table)) { + // split the key into parts + $keyparts = preg_split("/_/",$convk); + // return ratio = 1 if keyparts match + + // Now test if either part matches the from or to unit + if ($keyparts[1] == $to_unit && ($i2_value = $this->check_key($keyparts[0]."_".$from_unit))) { + // an intermediary $keyparts[0] was found + // now let us put things together intermediary 1 and 2 + $converted = (double)(((($value - $i2_value['offset']) / $i2_value['ratio']) * $i1_value['ratio'])+ $i1_value['offset']); + + $found = true; + + } elseif ($keyparts[1] == $from_unit && ($i2_value = $this->check_key($keyparts[0]."_".$to_unit))) { + // an intermediary $keyparts[0] was found + // now let us put things together intermediary 2 and 1 + $converted = (double)(((($value - $i1_value['offset']) / $i1_value['ratio']) + $i2_value['offset']) * $i2_value['ratio']); + + $found = true; + } + } + return $found; + } + + } // end func getConvSpecs + +} // end class UnitConvertor +?> \ No newline at end of file diff --git a/addon/convert/convert.php b/addon/convert/convert.php new file mode 100644 index 0000000000..a3448ce01e --- /dev/null +++ b/addon/convert/convert.php @@ -0,0 +1,223 @@ +Units Conversion'; +} + + +function convert_module() {} + + + + + + + +function convert_content($app) { + +include("UnitConvertor.php"); + + class TP_Converter extends UnitConvertor { + function TP_Converter($lang = "en") + { + if ($lang != 'en' ) { + $dec_point = '.'; $thousand_sep = "'"; + } else { + $dec_point = '.'; $thousand_sep = ","; + } + + $this->UnitConvertor($dec_point , $thousand_sep ); + + } // end func UnitConvertor + + function find_base_unit($from,$to) { + while (list($skey,$sval) = each($this->bases)) { + if ($skey == $from || $to == $skey || in_array($to,$sval) || in_array($from,$sval)) { + return $skey; + } + } + return false; + } + + function getTable($value, $from_unit, $to_unit, $precision) { + + if ($base_unit = $this->find_base_unit($from_unit,$to_unit)) { + + // A baseunit was found now lets convert from -> $base_unit + + $cell ['value'] = $this->convert($value, $from_unit, $base_unit, $precision)." ".$base_unit; + $cell ['class'] = ($base_unit == $from_unit || $base_unit == $to_unit) ? "framedred": ""; + $cells[] = $cell; + // We now have the base unit and value now lets produce the table; + while (list($key,$val) = each($this->bases[$base_unit])) { + $cell ['value'] = $this->convert($value, $from_unit, $val, $precision)." ".$val; + $cell ['class'] = ($val == $from_unit || $val == $to_unit) ? "framedred": ""; + $cells[] = $cell; + } + + $cc = count($cells); + $string = ""; + $string .= ""; + $i=0; + foreach ($cells as $cell) { + if ($i==0) { + $string .= ""; + $i++; + } else { + $string .= ""; + } + } + $string .= "
$value $from_unit".$cell['value']."
".$cell['value']."
"; + return $string; + } + + } +} + + +$conv = new TP_Converter('en'); + + +$conversions = array( + 'Temperature'=>array('base' =>'Celsius', + 'conv'=>array( + 'Fahrenheit'=>array('ratio'=>1.8, 'offset'=>32), + 'Kelvin'=>array('ratio'=>1, 'offset'=>273), + 'Reaumur'=>0.8 + ) + ), + 'Weight' => array('base' =>'kg', + 'conv'=>array( + 'g'=>1000, + 'mg'=>1000000, + 't'=>0.001, + 'grain'=>15432, + 'oz'=>35.274, + 'lb'=>2.2046, + 'cwt(UK)' => 0.019684, + 'cwt(US)' => 0.022046, + 'ton (US)' => 0.0011023, + 'ton (UK)' => 0.0009842 + ) + ), + 'Distance' => array('base' =>'km', + 'conv'=>array( + 'm'=>1000, + 'dm'=>10000, + 'cm'=>100000, + 'mm'=>1000000, + 'mile'=>0.62137, + 'naut.mile'=>0.53996, + 'inch(es)'=>39370, + 'ft'=>3280.8, + 'yd'=>1093.6, + 'furlong'=>4.970969537898672, + 'fathom'=>546.8066491688539 + ) + ), + 'Area' => array('base' =>'km 2', + 'conv'=>array( + 'ha'=>100, + 'acre'=>247.105, + 'm 2'=>pow(1000,2), + 'dm 2'=>pow(10000,2), + 'cm 2'=>pow(100000,2), + 'mm 2'=>pow(1000000,2), + 'mile 2'=>pow(0.62137,2), + 'naut.miles 2'=>pow(0.53996,2), + 'in 2'=>pow(39370,2), + 'ft 2'=>pow(3280.8,2), + 'yd 2'=>pow(1093.6,2), + ) + ), + 'Volume' => array('base' =>'m 3', + 'conv'=>array( + 'in 3'=>61023.6, + 'ft 3'=>35.315, + 'cm 3'=>pow(10,6), + 'dm 3'=>1000, + 'litre'=>1000, + 'hl'=>10, + 'yd 3'=>1.30795, + 'gal(US)'=>264.172, + 'gal(UK)'=>219.969, + 'pint' => 2113.376, + 'quart' => 1056.688, + 'cup' => 4266.753, + 'fl oz' => 33814.02, + 'tablespoon' => 67628.04, + 'teaspoon' => 202884.1, + 'pt (UK)'=>1000/0.56826, + 'barrel petroleum'=>1000/158.99, + 'Register Tons'=>2.832, + 'Ocean Tons'=>1.1327 + ) + ), + 'Speed' =>array('base' =>'kmph', + 'conv'=>array( + 'mps'=>0.0001726031, + 'milesph'=>0.62137, + 'knots'=>0.53996, + 'mach STP'=>0.0008380431, + 'c (warp)'=>9.265669e-10 + ) + ) +); + + +while (list($key,$val) = each($conversions)) { + $conv->addConversion($val['base'], $val['conv']); + $list[$key][] = $val['base']; + while (list($ukey,$uval) = each($val['conv'])) { + $list[$key][] = $ukey; + } +} + + $o .= '

Unit Conversions

'; + + + if (isset($_POST['from_unit']) && isset($_POST['value'])) { + $_POST['value'] = $_POST['value'] + 0; + + + $o .= ($conv->getTable($_POST['value'], $_POST['from_unit'], $_POST['to_unit'], 5))."

"; + } else { + $o .= "

Select:

"; + } + + if(isset($_POST['value'])) + $value = $_POST['value']; + else + $value = ''; + + $o .= '
'; + $o .= ''; + $o .= ''; + + $o .= '
'; + + return $o; +} diff --git a/include/dba.php b/include/dba.php index d3da8eae05..b05a1cabf4 100644 --- a/include/dba.php +++ b/include/dba.php @@ -113,13 +113,14 @@ function printable($s) { if(! function_exists('dbg')) { function dbg($state) { global $db; + if($db) $db->dbg($state); }} if(! function_exists('dbesc')) { function dbesc($str) { global $db; - if($db->connected) + if($db && $db->connected) return($db->escape($str)); else return(str_replace("'","\\'",$str)); @@ -138,7 +139,7 @@ function q($sql) { $args = func_get_args(); unset($args[0]); - if($db->connected) { + if($db && $db->connected) { $ret = $db->q(vsprintf($sql,$args)); return $ret; } @@ -165,7 +166,7 @@ if(! function_exists('dbq')) { function dbq($sql) { global $db; - if($db->connected) + if($db && $db->connected) $ret = $db->q($sql); else $ret = false; diff --git a/include/nav.php b/include/nav.php index 043cf0f7fa..5e29cc3c4b 100644 --- a/include/nav.php +++ b/include/nav.php @@ -82,7 +82,7 @@ function nav(&$a) { * */ - if(x($_SESSION,'uid')) { + if(local_user()) { $a->page['nav'] .= '' . t('Network') . '' . "\r\n";