1 : <?php
2 : /**
3 : * Config.php
4 : * 08-Nov-2011
5 : *
6 : * PHP Version 5
7 : *
8 : * @category Services
9 : * @package Services_Openstreetmap
10 : * @author Ken Guest <kguest@php.net>
11 : * @license BSD http://www.opensource.org/licenses/bsd-license.php
12 : * @version Release: @package_version@
13 : * @link Config.php
14 : */
15 :
16 : /**
17 : * Services_Openstreetmap_Config
18 : *
19 : * @category Services
20 : * @package Services_Openstreetmap
21 : * @author Ken Guest <kguest@php.net>
22 : * @license BSD http://www.opensource.org/licenses/bsd-license.php
23 : * @link Config.php
24 : */
25 : class Services_Openstreetmap_Config
26 : {
27 :
28 : /**
29 : * Minimum version of the OSM API that is supported.
30 : * @var float
31 : * @internal
32 : */
33 : protected $minVersion = null;
34 :
35 : /**
36 : * Maximum version of the OSM API that is supported.
37 : * @var float
38 : * @internal
39 : */
40 : protected $maxVersion = null;
41 :
42 : /**
43 : * timeout, in seconds.
44 : * @var integer
45 : * @internal
46 : */
47 : protected $timeout = null;
48 :
49 : /**
50 : * number of elements allowed per changeset
51 : * @var integer
52 : * @internal
53 : */
54 : protected $changesetMaximumElements = null;
55 :
56 : /**
57 : * Maximum number of nodes per way.
58 : * @var integer
59 : * @internal
60 : */
61 : protected $waynodesMaximum = null;
62 :
63 : /**
64 : * Number of tracepoints per way.
65 : * @var integer
66 : * @internal
67 : */
68 : protected $tracepointsPerPage = null;
69 :
70 : /**
71 : * Max size of area that can be downloaded in one request.
72 : * @var float
73 : * @internal
74 : */
75 : protected $areaMaximum = null;
76 :
77 :
78 : /**
79 : * Default config settings
80 : *
81 : * @var array
82 : * @see Services_Openstreetmap::getConfig
83 : * @see Services_Openstreetmap::setConfig
84 : */
85 : protected $config = array(
86 : 'adapter' => 'HTTP_Request2_Adapter_Socket',
87 : 'api_version' => '0.6',
88 : 'password' => null,
89 : 'passwordfile' => null,
90 : 'server' => 'http://api.openstreetmap.org/',
91 : 'User-Agent' => 'Services_Openstreetmap',
92 : 'user' => null,
93 : 'verbose' => false,
94 : );
95 :
96 : /**
97 : * Version of the [OSM] API which communications will be over.
98 : * @var string
99 : * @internal
100 : */
101 : protected $api_version = '0.6';
102 :
103 : /**
104 : * Server to connect to.
105 : * @var string
106 : * @internal
107 : */
108 : protected $server = 'http://api.openstreetmap.org/';
109 :
110 : /**
111 : * Get the value of a configuration setting - if none is set all are
112 : * returned.
113 : *
114 : * <code>
115 : * $config = $osm->getConfig();
116 : * </code>
117 : *
118 : * @param string $name name. optional.
119 : *
120 : * @return mixed value of $name parameter, array of all configuration
121 : * parameters if $name is not given
122 : * @throws Services_Openstreetmap_InvalidArgumentException If the parameter
123 : * is unknown
124 : */
125 : public function getValue($name = null)
126 : {
127 10 : if (is_null($name)) {
128 0 : return $this->config;
129 10 : } elseif (!array_key_exists($name, $this->config)) {
130 0 : throw new Services_Openstreetmap_InvalidArgumentException(
131 0 : "Unknown config parameter '$name'"
132 0 : );
133 : }
134 10 : return $this->config[$name];
135 : }
136 :
137 : /**
138 : * set at least one configuration variable.
139 : *
140 : * <pre>
141 : * $osm->setConfig('user', 'fred@example.com');
142 : * $osm->setConfig(array('user' => 'fred@example.com', 'password' => 'Simples'));
143 : * $osm->setConfig('user' => 'f@example.com')->setConfig('password' => 'Sis');
144 : * </pre>
145 : *
146 : * The following parameters are available:
147 : * <ul>
148 : * <li> 'adapter' - adapter to use (string)</li>
149 : * <li> 'api_version' - Version of API to communicate via (string)</li>
150 : * <li> 'password' - password (string, optional)</li>
151 : * <li> 'passwordfile' - passwordfile (string, optional)</li>
152 : * <li> 'server' - server to connect to (string)</li>
153 : * <li> 'User-Agent' - User-Agent (string)</li>
154 : * <li> 'user' - user (string, optional)</li>
155 : * <li> 'verbose' - verbose (boolean, optional)</li>
156 : * </ul>
157 : *
158 : * @param mixed $config array containing config settings
159 : * @param mixed $value config value if $config is not an array
160 : *
161 : * @throws Services_Openstreetmap_InvalidArgumentException If the parameter
162 : * is unknown
163 : *
164 : * @return Services_Openstreetmap_Config
165 : */
166 : public function setValue($config, $value = null)
167 : {
168 10 : if (is_array($config)) {
169 10 : if (isset($config['adapter'])) {
170 10 : $this->config['adapter'] = $config['adapter'];
171 10 : }
172 10 : foreach ($config as $key=>$value) {
173 10 : if (!array_key_exists($key, $this->config)) {
174 0 : throw new Services_Openstreetmap_InvalidArgumentException(
175 0 : "Unknown config parameter '$key'"
176 0 : );
177 : }
178 : switch($key) {
179 10 : case 'server':
180 10 : $this->setServer($value);
181 10 : break;
182 10 : case 'passwordfile':
183 0 : $this->setPasswordfile($value);
184 0 : break;
185 10 : case 'api_version':
186 0 : $this->config[$key] = $value;
187 0 : $api = "Services_Openstreetmap_API_V" . str_replace(
188 0 : '.',
189 0 : '',
190 : $value
191 0 : );
192 0 : $this->api = new $api;
193 0 : break;
194 10 : default:
195 10 : $this->config[$key] = $value;
196 10 : }
197 10 : }
198 10 : } else {
199 0 : if (!array_key_exists($config, $this->config)) {
200 0 : throw new Services_Openstreetmap_InvalidArgumentException(
201 0 : "Unknown config parameter '$config'"
202 0 : );
203 : }
204 0 : $this->config[$config] = $value;
205 0 : if ($config == 'server') {
206 0 : $this->setServer($this->server);
207 0 : } elseif ($config == 'passwordfile') {
208 0 : $this->setPasswordfile($value);
209 0 : }
210 : }
211 10 : return $this;
212 : }
213 :
214 : /**
215 : * Connect to specified server.
216 : *
217 : * @param string $server base server details, e.g. http://api.openstreetmap.org
218 : *
219 : * @return Services_Openstreetmap
220 : */
221 : public function setServer($server)
222 : {
223 : try {
224 10 : $c = $this->getTransport()->getResponse($server . '/api/capabilities');
225 10 : } catch (Exception $ex) {
226 0 : throw new Services_Openstreetmap_Exception(
227 0 : 'Could not get a valid response from server',
228 0 : $ex->getCode(),
229 : $ex
230 0 : );
231 : }
232 10 : $this->server = $server;
233 10 : $capabilities = $c->getBody();
234 10 : if (!$this->_checkCapabilities($capabilities)) {
235 0 : throw new Services_Openstreetmap_Exception(
236 : 'Problem checking server capabilities'
237 0 : );
238 : }
239 10 : $this->config['server'] = $server;
240 :
241 10 : return $this;
242 : }
243 :
244 : /**
245 : * Set and parse a password file, setting username and password as specified
246 : * in the file.
247 : *
248 : * A password file is a ASCII text file, with username and passwords pairs
249 : * on each line, seperated [delimited] by a semicolon.
250 : * Lines starting with a hash [#] are comments.
251 : * If only one non-commented line is present in the file, that username and
252 : * password will be used for authentication.
253 : * If more than one set of usernames and passwords are present, the
254 : * username must be specified, and the matching password from the file will
255 : * be used.
256 : *
257 : * <pre>
258 : * # Example password file.
259 : * fredfs@example.com:Wilma4evah
260 : * barney@example.net:B3ttyRawks
261 : * </pre>
262 : *
263 : * @param string $file file containing credentials
264 : *
265 : * @return Services_Openstreetmap
266 : */
267 : public function setPasswordfile($file)
268 : {
269 0 : if (is_null($file)) {
270 0 : return $this;
271 : }
272 0 : $lines = @file($file);
273 0 : if ($lines === false) {
274 0 : throw new Services_Openstreetmap_Exception(
275 : 'Could not read password file'
276 0 : );
277 : }
278 0 : $this->config['passwordfile'] = $file;
279 0 : array_walk($lines, create_function('&$val', '$val = trim($val);'));
280 0 : if (sizeof($lines) == 1) {
281 0 : if (strpos($lines[0], '#') !== 0) {
282 0 : list($this->config['user'], $this->config['password'])
283 0 : = explode(':', $lines[0]);
284 0 : }
285 0 : } elseif (sizeof($lines) == 2) {
286 0 : if (strpos($lines[0], '#') === 0) {
287 0 : if (strpos($lines[1], '#') !== 0) {
288 0 : list($this->config['user'], $this->config['password'])
289 0 : = explode(':', $lines[1]);
290 0 : }
291 0 : }
292 0 : } else {
293 0 : foreach ($lines as $line) {
294 0 : if (strpos($line, '#') === 0) {
295 0 : continue;
296 : }
297 0 : list($user, $pwd) = explode(':', $line);
298 0 : if ($user == $this->config['user']) {
299 0 : $this->config['password'] = $pwd;
300 0 : }
301 0 : }
302 : }
303 0 : return $this;
304 : }
305 :
306 : /**
307 : * Set the Transport instance.
308 : *
309 : * @param Services_Openstreetmap_Transport $transport Transport instance.
310 : *
311 : * @return Services_Openstreetmap_Config
312 : */
313 : public function setTransport(Services_Openstreetmap_Transport $transport)
314 : {
315 10 : $this->transport = $transport;
316 10 : return $this;
317 : }
318 :
319 : /**
320 : * Retrieve the current Transport instance.
321 : *
322 : * @return Services_Openstreetmap_Transport.
323 : */
324 : public function getTransport()
325 : {
326 10 : return $this->transport;
327 : }
328 :
329 : /**
330 : * Return all config settings in an array.
331 : *
332 : * @return array
333 : */
334 : public function asArray()
335 : {
336 9 : return $this->config;
337 : }
338 :
339 : /**
340 : * Set various properties to describe the capabilities that the connected
341 : * server supports.
342 : *
343 : * @param mixed $capabilities XML describing the capabilities of the server
344 : *
345 : * @see maxVersion
346 : * @see minVersion
347 : * @see timeout
348 : *
349 : * @return boolean
350 : *
351 : * @internal
352 : * @throws Services_Openstreetmap_Exception If the API Version is not
353 : * supported.
354 : */
355 : private function _checkCapabilities($capabilities)
356 : {
357 10 : $xml = simplexml_load_string($capabilities);
358 10 : if ($xml === false) {
359 0 : return false;
360 : }
361 :
362 10 : $this->minVersion = (float) $this->getXmlValue($xml, 'version', 'minimum');
363 10 : $this->maxVersion = (float) $this->getXmlValue($xml, 'version', 'maximum');
364 10 : if (($this->minVersion > $this->api_version
365 10 : || $this->api_version > $this->maxVersion)
366 10 : ) {
367 0 : throw new Services_Openstreetmap_Exception(
368 0 : 'Specified API Version ' . $this->api_version .' not supported.'
369 0 : );
370 : }
371 10 : $this->timeout = (int) $this->getXmlValue($xml, 'timeout', 'seconds');
372 : //changesets
373 10 : $this->changesetMaximumElements = (int) $this->getXmlValue(
374 10 : $xml,
375 10 : 'changesets',
376 : 'maximum_elements'
377 10 : );
378 :
379 : // Maximum number of nodes per way.
380 10 : $this->waynodesMaximum = (int) $this->getXmlValue(
381 10 : $xml,
382 10 : 'waynodes',
383 : 'maximum'
384 10 : );
385 :
386 : // Number of tracepoints per way.
387 10 : $this->tracepointsPerPage = (int) $this->getXmlValue(
388 10 : $xml,
389 10 : 'tracepoints',
390 : 'per_page'
391 10 : );
392 :
393 : // Max size of area that can be downloaded in one request.
394 10 : $this->areaMaximum = (float) $this->getXmlValue(
395 10 : $xml,
396 10 : 'area',
397 : 'maximum'
398 10 : );
399 10 : return true;
400 : }
401 :
402 : /**
403 : * Max size of area that can be downloaded in one request.
404 : *
405 : * <code>
406 : * $osm = new Services_Openstreetmap();
407 : * $area_allowed = $osm->getMaxArea();
408 : * </code>
409 : *
410 : * @return float
411 : */
412 : public function getMaxArea()
413 : {
414 0 : return $this->areaMaximum;
415 : }
416 :
417 : /**
418 : * minVersion - min API version supported by connected server.
419 : *
420 : * <code>
421 : * $config = array('user' => 'fred@example.net', 'password' => 'wilma4eva');
422 : * $osm = new Services_Openstreetmap($config);
423 : * $min = $osm->getMinVersion();
424 : * </code>
425 : *
426 : * @return float
427 : */
428 : public function getMinVersion()
429 : {
430 0 : return $this->minVersion;
431 : }
432 :
433 : /**
434 : * maxVersion - max API version supported by connected server.
435 : *
436 : * <code>
437 : * $config = array('user' => 'fred@example.net', 'password' => 'wilma4eva');
438 : * $osm = new Services_Openstreetmap($config);
439 : * $max = $osm->getMaxVersion();
440 : * </code>
441 : *
442 : * @return float
443 : */
444 : public function getMaxVersion()
445 : {
446 0 : return $this->maxVersion;
447 : }
448 :
449 : /**
450 : * Return the number of seconds that must elapse before a connection is
451 : * considered to have timed-out.
452 : *
453 : * @return int
454 : */
455 : public function getTimeout()
456 : {
457 0 : return $this->timeout;
458 : }
459 :
460 : /**
461 : * Maximum number of tracepoints per page.
462 : *
463 : * <code>
464 : * $osm = new Services_Openstreetmap();
465 : * $tracepoints = $osm->getTracepointsPerPage();
466 : * </code>
467 : *
468 : * @return float
469 : */
470 : public function getTracepointsPerPage()
471 : {
472 0 : return $this->tracepointsPerPage;
473 : }
474 :
475 : /**
476 : * Maximum number of nodes per way.
477 : *
478 : * Anymore than that and the way must be split.
479 : *
480 : * <code>
481 : * $osm = new Services_Openstreetmap();
482 : * $max = $osm->getMaxNodes();
483 : * </code>
484 : *
485 : * @return float
486 : */
487 : public function getMaxNodes()
488 : {
489 0 : return $this->waynodesMaximum;
490 : }
491 :
492 : /**
493 : * Number of elements allowed per changeset
494 : *
495 : * <code>
496 : * $osm = new Services_Openstreetmap();
497 : * $max = $osm->getMaxElements();
498 : * </code>
499 : *
500 : * @return float
501 : */
502 : public function getMaxElements()
503 : {
504 0 : return $this->changesetMaximumElements;
505 : }
506 :
507 : /**
508 : * getXmlValue
509 : *
510 : * @param SimpleXMLElement $xml Object
511 : * @param string $tag name of tag
512 : * @param string $attribute name of attribute
513 : * @param mixed $default default value
514 : *
515 : * @return string
516 : */
517 : public function getXmlValue(
518 : SimpleXMLElement $xml,
519 : $tag,
520 : $attribute,
521 : $default = null
522 : ) {
523 10 : $obj = $xml->xpath('//' . $tag);
524 10 : if (empty($obj)) {
525 0 : return $default;
526 : }
527 10 : return $obj[0]->attributes()->$attribute;
528 : }
529 :
530 : }
531 :
532 : ?>
|