4 changed files with 511 additions and 4 deletions
@ -0,0 +1,283 @@
|
||||
<?php |
||||
// +----------------------------------------------------------------------+ |
||||
// | PHP version 4.0 | |
||||
// +----------------------------------------------------------------------+ |
||||
// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | |
||||
// +----------------------------------------------------------------------+ |
||||
// | This source file is subject to version 2.0 of the PHP license, | |
||||
// | that is bundled with this package in the file LICENSE, and is | |
||||
// | available at through the world-wide-web at | |
||||
// | http://www.php.net/license/2_02.txt. | |
||||
// | If you did not receive a copy of the PHP license and are unable to | |
||||
// | obtain it through the world-wide-web, please send a note to | |
||||
// | license@php.net so we can mail you a copy immediately. | |
||||
// +----------------------------------------------------------------------+ |
||||
// | Authors: Stanislav Okhvat <stanis@ngs.ru> | |
||||
// | Co-authored by : CVH, Chris Hansel <chris@cpi-service.com> | |
||||
// +----------------------------------------------------------------------+ |
||||
// |
||||
// $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 <stanis@sibfair.nsk.su, stanis@ngs.ru> |
||||
* @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 |
||||
?> |
@ -0,0 +1,223 @@
|
||||
<?php |
||||
|
||||
|
||||
function convert_install() { |
||||
register_hook('app_menu', 'addon/convert/convert.php', 'convert_app_menu'); |
||||
} |
||||
|
||||
function convert_uninstall() { |
||||
unregister_hook('app_menu', 'addon/convert/convert.php', 'convert_app_menu'); |
||||
} |
||||
|
||||
function convert_app_menu($a,&$b) { |
||||
$b['app_menu'] .= '<div class="app-title"><a href="convert">Units Conversion</a></div>'; |
||||
} |
||||
|
||||
|
||||
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 = "<table class=\"framed grayish\" border=\"1\" cellpadding=\"5\" width=\"80%\" align=\"center\"><tr>"; |
||||
$string .= "<td rowspan=\"$cc\" align=\"center\">$value $from_unit</td>"; |
||||
$i=0; |
||||
foreach ($cells as $cell) { |
||||
if ($i==0) { |
||||
$string .= "<td class=\"".$cell['class']."\">".$cell['value']."</td>"; |
||||
$i++; |
||||
} else { |
||||
$string .= "</tr><tr><td class=\"".$cell['class']."\">".$cell['value']."</td>"; |
||||
} |
||||
} |
||||
$string .= "</tr></table>"; |
||||
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 .= '<h3>Unit Conversions</h3>'; |
||||
|
||||
|
||||
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))."</p>"; |
||||
} else { |
||||
$o .= "<p>Select:</p>"; |
||||
} |
||||
|
||||
if(isset($_POST['value'])) |
||||
$value = $_POST['value']; |
||||
else |
||||
$value = ''; |
||||
|
||||
$o .= '<form action="convert" method="post" name="conversion">'; |
||||
$o .= '<input name="value" type="text" id="value" value="' . $value . '" size="10" maxlength="10" />'; |
||||
$o .= '<select name="from_unit" size="12">'; |
||||
|
||||
|
||||
|
||||
reset($list); |
||||
while(list($key,$val) = each($list)) { |
||||
$o .= "\n\t<optgroup label=\"$key\">"; |
||||
while(list($ukey,$uval) = each($val)) { |
||||
$selected = (($uval == $_POST['from_unit']) ? ' selected="selected" ' : ''); |
||||
$o .= "\n\t\t<option value=\"$uval\" $selected >$uval</option>"; |
||||
} |
||||
$o .= "\n\t</optgroup>"; |
||||
} |
||||
|
||||
$o .= '</select>'; |
||||
|
||||
$o .= '<input type="submit" name="Submit" value="Submit" /></form>'; |
||||
|
||||
return $o; |
||||
} |
Loading…
Reference in new issue