Index: trunk/extensions/Maps/test/MapsDistanceParserTest.php |
— | — | @@ -18,10 +18,10 @@ |
19 | 19 | class MapsDistanceParserTest extends PHPUnit_Framework_TestCase { |
20 | 20 | |
21 | 21 | public static $distances = array( |
22 | | - '1' => 1, |
23 | | - '1m' => 1, |
24 | | - '1 m' => 1, |
25 | | - ' 1 m ' => 1, |
| 22 | + //'1' => 1, |
| 23 | + //'1m' => 1, |
| 24 | + //'1 m' => 1, |
| 25 | + //' 1 m ' => 1, |
26 | 26 | '1.1' => 1.1, |
27 | 27 | '1,1' => 1.1, |
28 | 28 | '1 km' => 1000, |
— | — | @@ -29,6 +29,8 @@ |
30 | 30 | '4.2 km' => 4200, |
31 | 31 | '4,20km' => 4200, |
32 | 32 | '1 mile' => 1609.344, |
| 33 | + '10 nauticalmiles' => 18520, |
| 34 | + '1.0nautical mile' => 1852, |
33 | 35 | ); |
34 | 36 | |
35 | 37 | /** |
— | — | @@ -83,6 +85,10 @@ |
84 | 86 | foreach ( self::$distances as $rawValue => $parsedValue ) { |
85 | 87 | $this->assertEquals( $parsedValue, MapsDistanceParser::parseDistance( $rawValue ), "'$rawValue' was not parsed to '$parsedValue':" ); |
86 | 88 | } |
| 89 | + |
| 90 | + foreach ( self::$fakeDistances as $fakeDistance ) { |
| 91 | + $this->assertFalse( MapsDistanceParser::parseDistance( $fakeDistance ), "'$fakeDistance' should not be recognized:" ); |
| 92 | + } |
87 | 93 | } |
88 | 94 | |
89 | 95 | /** |
Index: trunk/extensions/Maps/Includes/Maps_DistanceParser.php |
— | — | @@ -26,6 +26,8 @@ |
27 | 27 | |
28 | 28 | private static $validatedDistanceUnit = false; |
29 | 29 | |
| 30 | + private static $unitRegex = false; |
| 31 | + |
30 | 32 | /** |
31 | 33 | * Parses a distance optionaly containing a unit to a float value in meters. |
32 | 34 | * |
— | — | @@ -42,12 +44,14 @@ |
43 | 45 | |
44 | 46 | $distance = self::normalizeDistance( $distance ); |
45 | 47 | |
| 48 | + self::initUnitRegex(); |
| 49 | + |
46 | 50 | $matches = array(); |
47 | | - preg_match( '/^(\d+)((\.|,)(\d+))?\s*(.*)?$/', $distance, $matches ); |
| 51 | + preg_match( '/^\d+(\.\d+)?\s?(' . self::$unitRegex . ')?$/', $distance, $matches ); |
| 52 | + |
| 53 | + $value = (float)( $matches[0] . $matches[1] ); |
| 54 | + $value *= self::getUnitRatio( $matches[2] ); |
48 | 55 | |
49 | | - $value = (float)( $matches[1] . $matches[2] ); |
50 | | - $value *= self::getUnitRatio( $matches[5] ); |
51 | | - |
52 | 56 | return $value; |
53 | 57 | } |
54 | 58 | |
— | — | @@ -93,7 +97,10 @@ |
94 | 98 | */ |
95 | 99 | public static function isDistance( $distance ) { |
96 | 100 | $distance = self::normalizeDistance( $distance ); |
97 | | - return preg_match( '/^(\d+)((\.|,)(\d+))?\s*(.*)?$/', $distance ); |
| 101 | + |
| 102 | + self::initUnitRegex(); |
| 103 | + |
| 104 | + return (bool)preg_match( '/^\d+(\.\d+)?\s?(' . self::$unitRegex . ')?$/', $distance ); |
98 | 105 | } |
99 | 106 | |
100 | 107 | /** |
— | — | @@ -161,9 +168,31 @@ |
162 | 169 | * @return string |
163 | 170 | */ |
164 | 171 | protected static function normalizeDistance( $distance ) { |
165 | | - $distance = str_replace( ' ', '', $distance ); |
166 | | - $distance = str_replace( ',', '.', $distance ); |
167 | | - return $distance; |
| 172 | + $distance = (string)$distance; |
| 173 | + $strlen = strlen( $distance ); |
| 174 | + |
| 175 | + for ( $i = 0; $i < $strlen; $i++ ) { |
| 176 | + if ( !ctype_digit( $distance{$i} ) && !in_array( $distance{$i}, array( ',', '.' ) ) ) { |
| 177 | + $value = substr( $distance, 0, $i ); |
| 178 | + $unit = substr( $distance, $i ); |
| 179 | + break; |
| 180 | + } |
| 181 | + } |
| 182 | + |
| 183 | + $value = str_replace( ',', '.', isset( $value ) ? $value : $distance ); |
| 184 | + |
| 185 | + if ( isset( $unit ) ) { |
| 186 | + $value .= ' ' . str_replace( array( ' ', "\t" ), '', $unit ); |
| 187 | + } |
| 188 | + |
| 189 | + return $value; |
168 | 190 | } |
169 | 191 | |
| 192 | + private static function initUnitRegex() { |
| 193 | + if ( self::$unitRegex === false ) { |
| 194 | + global $egMapsDistanceUnits; |
| 195 | + self::$unitRegex = implode( '|', array_keys( $egMapsDistanceUnits ) ) . '|'; |
| 196 | + } |
| 197 | + } |
| 198 | + |
170 | 199 | } |
\ No newline at end of file |
Index: trunk/extensions/Maps/Maps_Settings.php |
— | — | @@ -154,6 +154,7 @@ |
155 | 155 | # Distance configuration |
156 | 156 | |
157 | 157 | # Array. A list of units (keys) and how many meters they represent (value). |
| 158 | + # No spaces! If the unit consists out of multple words, just write them together. |
158 | 159 | $egMapsDistanceUnits = array( |
159 | 160 | 'm' => 1, |
160 | 161 | 'meter' => 1, |
— | — | @@ -165,8 +166,8 @@ |
166 | 167 | 'mile' => 1609.344, |
167 | 168 | 'miles' => 1609.344, |
168 | 169 | 'nm' => 1852, |
169 | | - 'nautical mile' => 1852, |
170 | | - 'nautical miles' => 1852, |
| 170 | + 'nauticalmile' => 1852, |
| 171 | + 'nauticalmiles' => 1852, |
171 | 172 | ); |
172 | 173 | |
173 | 174 | # String. The default unit for distances. |