http://www.phing.info/

Source Code Coverage

Designed for use with PHPUnit, Xdebug and Phing.

Methods: 25 LOC: 506 Statements: 156
Legend: executednot executeddead code
Source file Statements Methods Total coverage
Object.php 100.0% 84.0% 97.8%
   
1
<?php
2
/**
3
 * Object.php
4
 * 26-Apr-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     Object.php
14
 */
15
16
/**
17
 * Services_OpenStreetMap_Object
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     Object.php
24
 */
25
class Services_OpenStreetMap_Object
26
{
27
    protected $xml = null;
28
29
    /**
30
     * Array of tags in key/value format
31
     *
32
     * @var array
33
     */
34
    protected $tags = array();
35
36
    protected $id = null;
37
38
    protected $transport = null;
39
40
    protected $config = null;
41
42
    /**
43
     * type of object
44
     *
45
     * @var string
46
     */
47
    protected $type = null;
48
49
    protected $obj = null;
50
51
    protected $dirty = false;
52
53
    protected $action = null;
54
55
    protected $changesetId = null;
56
57
    /**
58
     * getXml
59
     *
60
     * @return string
61
     */
62
    public function getXml()
63
    {
64 7
        return $this->xml;
65
    }
66
67
    /**
68
     * If modified, return the osmChangeXML for the object, otherwise the defining
69
     * XML.
70
     *
71
     * @return string
72
     * @link   http://wiki.openstreetmap.org/wiki/OsmChange
73
     */
74
    public function __toString()
75
    {
76 2
        $changeXML = $this->getOsmChangeXml();
77 2
        if (is_null($changeXML)) {
78 1
            return '' . $this->getXml();
79 1
        } else {
80 1
            return $changeXML;
81
        }
82
    }
83
84
    /**
85
     * setXml
86
     *
87
     * @param SimpleXMLElement $xml OSM XML
88
     *
89
     * @return void
90
     */
91
    public function setXml(SimpleXMLElement $xml)
92
    {
93 32
        $this->xml = $xml->saveXml();
94 32
        $obj = $xml->xpath('//' . $this->getType());
95 32
        foreach ($obj[0]->children() as $child) {
96 25
            $key = (string) $child->attributes()->k;
97 25
            if ($key != '') {
98 24
                $this->tags[$key] = (string) $child->attributes()->v;
99 24
            }
100 32
        }
101 32
        $this->obj = $obj;
102 32
        return $this;
103
    }
104
105
    /**
106
     * Store a specified value.
107
     *
108
     * @param string $value Most likely an id value, returned from the server.
109
     *
110
     * @return void
111
     */
112
    public function setVal($value)
113
    {
114
        $this->xml = $value;
115
        return $this;
116
    }
117
118
    /**
119
     * Set the Changeset Id for this object.
120
     *
121
     * @param integer $id Changeset Id (numeric)
122
     *
123
     * @return Services_OpenStreetMap_Object
124
     */
125
    public function setChangesetId($id)
126
    {
127 6
        $this->changesetId = $id;
128 6
        return $this;
129
    }
130
131
    /**
132
     * Generate and return the OsmChange XML required to record the changes
133
     * made to the object in question.
134
     *
135
     * @return string
136
     * @link   http://wiki.openstreetmap.org/wiki/OsmChange
137
     */
138
    public function getOsmChangeXml()
139
    {
140 7
        $type = $this->getType();
141 7
        if ($this->dirty) {
142 2
            $version = $this->getVersion();
143 2
            $version++;
144 2
            $domd = new DomDocument();
145 2
            $domd->loadXml($this->getXml());
146 2
            $xpath = new DomXPath($domd);
147 2
            $nodelist = $xpath->query("//{$type}");
148 2
            $nodelist->item(0)->setAttribute('action', $this->action);
149 2
            $nodelist->item(0)->setAttribute('id', $this->getId());
150
151 2
            if (!is_null($this->changesetId)) {
152 1
                $nodelist->item(0)->setAttribute('changeset', $this->changesetId);
153 1
            }
154 2
            $tags = $xpath->query("//{$type}/tag");
155
156 2
            $set = array();
157 2
            for ($i = 0; $i < $tags->length; $i++) {
158 1
                $key = $tags->item($i)->getAttribute('k');
159 1
                $val = $tags->item($i)->getAttribute('v');
160 1
                $set[$key] = $val;
161 1
            }
162
163 2
            $diff = array_diff($this->getTags(), $set);
164
165
            // Remove existing tags
166 2
            for ($i = 0; $i < $tags->length; $i++) {
167 1
                $rkey = $tags->item($i)->getAttribute('k');
168 1
                if (isset($diff[$rkey])) {
169 1
                    $nodelist->item(0)->removeChild($tags->item($i));
170 1
                }
171 1
            }
172
173 2
            foreach ($diff as $key=>$value) {
174 2
                $new = $domd->createElement('tag');
175 2
                $new->setAttribute('k', $key);
176 2
                $new->setAttribute('v', $value);
177 2
                $nodelist->item(0)->appendChild($new);
178 2
            }
179
180 2
            $xml = $domd->saveXml($nodelist->item(0));
181 2
            $xml = "<{$this->action}>{$xml}</{$this->action}>";
182 2
            return $this->osmChangeXml($xml);
183
184 5
        } elseif ($this->action == 'delete') {
185 4
            $xml = null;
186 4
            $domd = new DomDocument();
187 4
            $domd->loadXml($this->getXml());
188 4
            $xpath = new DomXPath($domd);
189 4
            $n = $xpath->query("//{$type}");
190 4
            $version = $this->getVersion();
191 4
            $version++;
192 4
            if (!is_null($this->changesetId)) {
193 4
                $n->item(0)->setAttribute('changeset', $this->changesetId);
194 4
            }
195 4
            $n->item(0)->setAttribute('action', 'delete');
196 4
            $xml = $domd->saveXml($n->item(0));
197 4
            return $this->osmChangeXml("<delete>{$xml}</delete>");
198 4
        }
199
    }
200
201
    /**
202
     * Amend changeXML with specific updates as appropriate.
203
     *
204
     * @param string $xml OsmChange XML as generated by getOsmChangeXml
205
     *
206
     * @return string
207
     * @see    getOsmChangeXml
208
     * @link   http://wiki.openstreetmap.org/wiki/OsmChange
209
     */
210
    public function osmChangeXml($xml)
211
    {
212 5
        return $xml;
213
    }
214
215
    /**
216
     * Retrieve the id of the object in question.
217
     *
218
     * @return integer id of the object
219
     */
220
    public function getId()
221
    {
222 23
        if (!is_null($this->id)) {
223 9
            return $this->id;
224 9
        }
225
226 20
        $attribs = $this->getAttributes();
227 20
        if (!is_null($attribs)) {
228 18
            return (integer) $attribs->id;
229 18
        }
230
    }
231
232
    /**
233
     * Set the id value of the object in question.
234
     *
235
     * <pre>
236
     * $obj->setId($id)->...
237
     * </pre>
238
     *
239
     * @param integer $value new id of the object
240
     *
241
     * @return Services_OpenStreetMap_Object
242
     */
243
    public function setId($value)
244
    {
245 7
        $this->id = $value;
246 7
        return $this;
247
    }
248
249
    /**
250
     * Retrieve the uid of the object in question.
251
     *
252
     * @return integer uid of the object
253
     */
254
    public function getUid()
255
    {
256 3
        $attribs = $this->getAttributes();
257 3
        if (!is_null($attribs)) {
258 2
            return (integer) $attribs->uid;
259 2
        }
260
    }
261
262
    /**
263
     * Retrieve the user (creator/editor) of the object in question.
264
     *
265
     * @return string user of the object
266
     */
267
    public function getUser()
268
    {
269 3
        $attribs = $this->getAttributes();
270 3
        if (!is_null($attribs)) {
271 2
            return (string) $attribs->user;
272 2
        }
273
    }
274
275
    /**
276
     * Retrieve the version of the object in question
277
     *
278
     * @return string version of the object
279
     */
280
    public function getVersion()
281
    {
282 10
        $attribs = $this->getAttributes();
283 10
        if (!is_null($attribs)) {
284 9
            return (integer) $attribs->version;
285 9
        }
286
    }
287
288
    /**
289
     * Return the attributes set for this object in question.
290
     *
291
     * @return string getAttributes()
292
     */
293
    public function getAttributes()
294
    {
295
296 30
        if (is_null($this->obj[0])) {
297 10
            return null;
298 10
        }
299 25
        return $this->obj[0]->attributes();
300
    }
301
302
    /**
303
     * Return the tags set for this object in question.
304
     *
305
     * @return array tags
306
     */
307
    public function getTags()
308
    {
309 20
        return $this->tags;
310
    }
311
312
313
    /**
314
     * Return value of specified tag as set against this object.
315
     * If tag isn't set, return null.
316
     *
317
     * @param string $key Key value, For example, 'amenity', 'highway' etc
318
     *
319
     * @return string
320
     */
321
    public function getTag($key)
322
    {
323 1
        if (isset($this->tags[$key])) {
324 1
            return $this->tags[$key];
325 1
        } else {
326
            return null;
327
        }
328
    }
329
330
    /**
331
     * Return which type of object this is.
332
     *
333
     * @return string type
334
     */
335
    public function getType()
336
    {
337 33
        return $this->type;
338
    }
339
340
    /**
341
     * Get each distinct version of an object.
342
     *
343
     * @return Services_OpenStreetMap_Objects
344
     */
345
    public function history()
346
    {
347 2
        $transport = null;
348 2
        $type = $this->getType();
349 2
        $id = $this->getId();
350 2
        $config = $this->getConfig();
351 2
        $url = $config->getValue('server')
352
            . 'api/'
353 2
            . $config->getValue('api_version')
354 2
            . "/$type/$id/history";
355 2
        $class = 'Services_OpenStreetMap_' . ucfirst($type) . 's';
356 2
        $transport = $this->getTransport();
357 2
        $response = $transport->getResponse($url);
358 2
        $obj = new $class();
359 2
        $sxe = @simplexml_load_string($response->getBody());
360 2
        if ($sxe === false) {
361
            $obj->setVal(trim($response->getBody()));
362
        } else {
363 2
            $obj->setXml($sxe);
364
        }
365 2
        return $obj;
366
    }
367
368
    /**
369
     * Get all relations referring to the object in question.
370
     *
371
     * @return Services_OpenStreetMap_Relations
372
     */
373
    public function getRelations()
374
    {
375 2
        $type = $this->getType();
376 2
        $id = $this->getId();
377 2
        $config = $this->getConfig();
378 2
        $url = $config->getValue('server')
379
            . 'api/'
380 2
            . $config->getValue('api_version')
381 2
            . "/$type/$id/relations";
382 2
        $response = $this->getTransport()->getResponse($url);
383 2
        $obj = new Services_OpenStreetMap_Relations();
384 2
        $sxe = @simplexml_load_string($response->getBody());
385 2
        if ($sxe === false) {
386
            $obj->setVal(trim($response->getBody()));
387
        } else {
388 2
            $obj->setXml($sxe);
389
        }
390 2
        return $obj;
391
    }
392
393
    /**
394
     * setTag
395
     *
396
     * <pre>
397
     * $obj->setTag('key', 'value')->setTag(...);
398
     * </pre>
399
     *
400
     * @param mixed $key   key
401
     * @param mixed $value value
402
     *
403
     * @return Services_OpenStreetMap_Object
404
     */
405
    public function setTag($key, $value)
406
    {
407 7
        if (is_null($this->action)) {
408 6
            if ($this->getId() < 0) {
409 4
                $this->action = 'create';
410 4
            } else {
411 2
                $this->action = 'modify';
412
            }
413 6
        }
414 7
        $this->dirty = true;
415 7
        $this->tags[$key] = $value;
416 7
        return $this;
417
    }
418
419
    /**
420
     * Set a number of tags at once, using an associative array.
421
     *
422
     * <pre>
423
     * $obj->setTag(
424
     *  array(
425
     *   'key' => 'value',
426
     *   'key2', 'value2',
427
     *  )
428
     * );
429
     * </pre>
430
     *
431
     * @param array $tags array of tags.
432
     *
433
     * @return Services_OpenStreetMap_Object
434
     */
435
    public function setTags($tags = array())
436
    {
437 1
        foreach ($tags as $key => $value) {
438 1
            $this->setTag($key, $value);
439 1
        }
440 1
        return $this;
441
    }
442
443
    /**
444
     * Mark the object as deleted.
445
     *
446
     * <pre>
447
     * $obj->delete();
448
     * </pre>
449
     *
450
     * @return void
451
     */
452
    public function delete()
453
    {
454 4
        $this->action = 'delete';
455 4
        return $this;
456
    }
457
458
    /**
459
     * Set Config object
460
     *
461
     * @param Services_OpenStreetMap_Config $config Config object
462
     *
463
     * @return Services_OpenStreetMap_Changeset
464
     */
465
    public function setConfig(Services_OpenStreetMap_Config $config)
466
    {
467 32
        $this->config = $config;
468 32
        return $this;
469
    }
470
471
    /**
472
     * Get current Config object
473
     *
474
     * @return Services_OpenStreetMap_Config
475
     */
476
    public function getConfig()
477
    {
478 14
        return $this->config;
479
    }
480
481
    /**
482
     * Set the Transport instance.
483
     *
484
     * @param Services_OpenStreetMap_Transport $transport Transport instance.
485
     *
486
     * @return Services_OpenStreetMap_Config
487
     */
488
    public function setTransport($transport)
489
    {
490 33
        $this->transport = $transport;
491 33
        return $this;
492
    }
493
494
    /**
495
     * Retrieve the current Transport instance.
496
     *
497
     * @return Services_OpenStreetMap_Transport.
498
     */
499
    public function getTransport()
500
    {
501 12
        return $this->transport;
502
    }
503
}
504
505
// vim:set et ts=4 sw=4:
506
?>


Report generated at 2012-10-02T18:40:35+01:00