]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/Units.php
No tabs
[SourceForge/phpwiki.git] / lib / Units.php
1 <?php // $Id$
2 /**
3  *
4  * Interface to man units(1), /usr/share/units.dat
5  *
6  * $ units "372.0 mi2"
7  *         Definition: 9.6347558e+08 m^2
8  * $ units "372.0 mi2" m^2
9  *         Definition: 9.6347558e+08 m^2
10  *
11  * Called by:
12  *    CachedMarkup.php: Cached_SemanticLink::_expandurl()
13  *    SemanticWeb.php: class SemanticAttributeSearchQuery
14  *
15  * Windows requires the cygwin /usr/bin/units.
16  * All successfully parsed unit definitions are stored in the wikidb,
17  * so that subsequent expansions will not require /usr/bin/units be called again.
18  * So far even on windows (cygwin) the process is fast enough.
19  *
20  * TODO: understand dates and maybe times
21  *   YYYY-MM-DD, "CW"ww/yy (CalendarWeek)
22  */
23
24 class Units {
25     function Units ($UNITSFILE = false) {
26         if (DISABLE_UNITS)
27             $this->errcode = 1;
28         elseif (defined("UNITS_EXE")) // ignore dynamic check
29         $this->errcode = 0;
30     else
31             exec("units m2", $o, $this->errcode);
32     }
33
34     /**
35      * $this->_attribute_base = $units->Definition($this->_attribute);
36      */
37     function Definition ($query) {
38     static $Definitions = array();
39     if (isset($Definitions[$query])) return $Definitions[$query];
40     if ($this->errcode)
41             return $query;
42     $query = preg_replace("/,/","", $query);
43     if ($query == '' or $query == '*')
44         return ($Definitions[$query] = '');
45     // detect date values, currently only ISO: YYYY-MM-DD or YY-MM-DD
46     if (preg_match("/^(\d{2,4})-(\d{1,2})-(\d{1,2})$/",$query, $m)) {
47         $date = mktime(0,0,0,$m[2],$m[3],$m[1]);
48         return ($Definitions[$query] = "$date date");
49     }
50     if (preg_match("/^(\d{2,4})-(\d{1,2})-(\d{1,2}) (\d{1,2}):(\d{2}):?(\d{2})?$/",$query, $m)) {
51         $date = mktime($m[4],$m[5],@$m[6],$m[2],$m[3],$m[1]);
52         return ($Definitions[$query] = "$date date");
53     }
54     $def = $this->_cmd("\"$query\"");
55     if (preg_match("/Definition: (.+)$/",$def,$m))
56         return ($Definitions[$query] = $m[1]);
57     else {
58         trigger_error("units: ". $def, E_USER_WARNING);
59         return '';
60     }
61     }
62
63     /**
64      * We must ensure that the same baseunits are matched against.
65      * We cannot compare m^2 to m or ''
66      * $val_base = $this->_units->basevalue($value); // SemanticAttributeSearchQuery
67      */
68     function basevalue($query, $def = false) {
69     if (!$def) $def = $this->Definition($query);
70     if ($def) {
71         if (is_numeric($def)) // e.g. "1 million"
72             return $def;
73         if (preg_match("/^([-0-9].*) \w.*$/",$def,$m))
74         return $m[1];
75     }
76     return '';
77     }
78
79     /**
80      * $this->_unit = $units->baseunit($this->_attribute);  // SemanticAttributeSearchQuery
81      * and Cached_SemanticLink::_expandurl()
82      */
83     function baseunit($query, $def  = false) {
84     if (!$def) $def = $this->Definition($query);
85     if ($def) {
86         if (preg_match("/ (.+)$/",$def,$m))
87         return $m[1];
88     }
89     return '';
90     }
91
92     function _cmd($args) {
93     if ($this->errcode) return $args;
94     if (defined("UNITS_EXE")) {
95         $s = UNITS_EXE ." $args";
96         $result = `$s`;
97     }
98     else
99         $result = `units $args`;
100     return trim($result);
101     }
102 }