]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/Units.php
Use __construct
[SourceForge/phpwiki.git] / lib / Units.php
1 <?php
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 {
26     function __construct()
27     {
28         if (DISABLE_UNITS)
29             $this->errcode = 1;
30         elseif (defined("UNITS_EXE")) // ignore dynamic check
31             $this->errcode = 0;
32         else
33             exec("units m2", $o, $this->errcode);
34     }
35
36     /**
37      * $this->_attribute_base = $units->Definition($this->_attribute);
38      */
39     function Definition($query)
40     {
41         static $Definitions = array();
42         if (isset($Definitions[$query])) return $Definitions[$query];
43         if ($this->errcode)
44             return $query;
45         $query = preg_replace("/,/", "", $query);
46         if ($query == '' or $query == '*')
47             return ($Definitions[$query] = '');
48         // detect date values, currently only ISO: YYYY-MM-DD or YY-MM-DD
49         if (preg_match("/^(\d{2,4})-(\d{1,2})-(\d{1,2})$/", $query, $m)) {
50             $date = mktime(0, 0, 0, $m[2], $m[3], $m[1]);
51             return ($Definitions[$query] = "$date date");
52         }
53         if (preg_match("/^(\d{2,4})-(\d{1,2})-(\d{1,2}) (\d{1,2}):(\d{2}):?(\d{2})?$/", $query, $m)) {
54             $date = mktime($m[4], $m[5], @$m[6], $m[2], $m[3], $m[1]);
55             return ($Definitions[$query] = "$date date");
56         }
57         $def = $this->_cmd("\"$query\"");
58         if (preg_match("/Definition: (.+)$/", $def, $m))
59             return ($Definitions[$query] = $m[1]);
60         else {
61             trigger_error("units: " . $def, E_USER_WARNING);
62             return '';
63         }
64     }
65
66     /**
67      * We must ensure that the same baseunits are matched against.
68      * We cannot compare m^2 to m or ''
69      * $val_base = $this->_units->basevalue($value); // SemanticAttributeSearchQuery
70      */
71     function basevalue($query, $def = false)
72     {
73         if (!$def) $def = $this->Definition($query);
74         if ($def) {
75             if (is_numeric($def)) // e.g. "1 million"
76                 return $def;
77             if (preg_match("/^([-0-9].*) \w.*$/", $def, $m))
78                 return $m[1];
79         }
80         return '';
81     }
82
83     /**
84      * $this->_unit = $units->baseunit($this->_attribute);  // SemanticAttributeSearchQuery
85      * and Cached_SemanticLink::_expandurl()
86      */
87     function baseunit($query, $def = false)
88     {
89         if (!$def) $def = $this->Definition($query);
90         if ($def) {
91             if (preg_match("/ (.+)$/", $def, $m))
92                 return $m[1];
93         }
94         return '';
95     }
96
97     function _cmd($args)
98     {
99         if ($this->errcode) return $args;
100         if (defined("UNITS_EXE")) {
101             $s = UNITS_EXE . " $args";
102             $result = `$s`;
103         } else
104             $result = `units $args`;
105         return trim($result);
106     }
107 }