http://www.phing.info/

Source Code Coverage

Designed for use with PHPUnit, Xdebug and Phing.

Methods: 14 LOC: 348 Statements: 145
Legend: executednot executeddead code
Source file Statements Methods Total coverage
Changeset.php 100.0% 92.9% 99.4%
   
1
<?php
2
/**
3
 * Changeset.php
4
 * 25-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     Changeset.php
14
 */
15
16
/**
17
 * Services_Openstreetmap_Changeset
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     Changeset.php
24
 */
25
class Services_Openstreetmap_Changeset extends Services_Openstreetmap_Object
26 1
{
27
    protected $type = 'changeset';
28
    protected $members = array();
29
    protected $membersIds = array();
30
    protected $open = false;
31
    protected $id = null;
32
33
    /**
34
     * __construct
35
     *
36
     * @return Services_Openstreetmap_Changeset
37
     */
38
    public function __construct()
39
    {
40
    }
41
42
    /**
43
     * begin
44
     *
45
     * @param string $message The changeset log message.
46
     *
47
     * @return void
48
     */
49
    public function begin($message)
50
    {
51 9
        $this->members = array();
52 9
        $this->open = true;
53 9
        $config = $this->getConfig();
54 9
        $userAgent = $config->getValue('User-Agent');
55
        $doc = "<?xml version='1.0' encoding=\"UTF-8\"?>\n" .
56 9
        '<osm version="0.6" generator="' . $userAgent . '">'
57 9
            . "<changeset id='0' open='false'>"
58 9
            . '<tag k="comment" v="' . $message . '"/>'
59 9
            . '<tag k="created_by" v="' . $userAgent . '/0.1"/>'
60 9
            . '</changeset></osm>';
61 9
        $url = $config->getValue('server')
62
            . 'api/'
63 9
            . $config->getValue('api_version')
64 9
            . '/changeset/create';
65 9
        $user = $config->getValue('user');
66 9
        $password = $config->getValue('password');
67 9
        if (is_null($user)) {
68 1
            throw new Services_Openstreetmap_Exception('User must be set');
69 1
        }
70 8
        if (is_null($password)) {
71 1
            throw new Services_Openstreetmap_Exception('Password must be set');
72 1
        }
73 7
        $response = $this->getTransport()->getResponse(
74 7
            $url,
75 7
            HTTP_Request2::METHOD_PUT,
76 7
            $user,
77 7
            $password,
78 7
            $doc,
79 7
            null,
80 7
            array(array('Content-type', 'text/xml', true))
81 7
        );
82 7
        $code = $response->getStatus();
83 7
        if (Services_Openstreetmap_Transport::OK == $code) {
84 7
            $trimmed = trim($response->getBody());
85 7
            if (is_numeric($trimmed)) {
86 6
                $this->id = $trimmed;
87 6
            }
88 7
        }
89
    }
90
91
    /**
92
     * add object to the changeset so changes can be transmitted to the server
93
     *
94
     * @param Services_Openstreetmap_Object $object OSM object
95
     *
96
     * @return void
97
     */
98
    public function add(Services_Openstreetmap_Object $object)
99
    {
100 7
        if ($this->open === false) {
101 1
            throw new Services_Openstreetmap_Exception(
102
                'Object added to closed changeset'
103 1
            );
104 1
        }
105 6
        $object->setChangesetId($this->getId());
106 6
        $objectId = $object->getType() . $object->getId();
107 6
        if (!in_array($objectId, $this->membersIds)) {
108 6
            $this->members[] = $object;
109 6
            $this->membersIds[] = $objectId;
110 6
        } else {
111 1
            throw new Services_Openstreetmap_Exception(
112
                'Object added to changeset already'
113 1
            );
114
        }
115
    }
116
117
    /**
118
     * commit
119
     *
120
     * Generate osmChange document and post it to the server, when successful
121
     * close the changeset.
122
     *
123
     * @return void
124
     * @link   http://wiki.openstreetmap.org/wiki/OsmChange
125
     */
126
    public function commit()
127
    {
128 6
        if (!$this->open) {
129 1
            throw new Services_Openstreetmap_Exception(
130
                'Attempt to commit a closed changeset'
131 1
            );
132 1
        }
133
134
        // Generate URL that the osmChange document will be posted to
135 6
        $cId = $this->getId();
136 6
        $config = $this->getConfig()->asArray();
137 6
        $url = $config['server']
138
            . 'api/'
139 6
            . $config['api_version'] .
140 6
            "/changeset/{$cId}/upload";
141
142
        // Generate the osmChange document
143 6
        $blocks = null;
144 6
        foreach ($this->members as $member) {
145 5
            $blocks .= $member->getOsmChangeXML() . "\n";
146 6
        }
147
148
        $doc = "<osmChange version='0.6' generator='Services_Openstreetmap'>\n"
149 6
             . $blocks . '</osmChange>';
150
151
        // Post the osmChange document to the server
152
        try {
153 6
            $response = $this->getTransport()->getResponse(
154 6
                $url,
155 6
                HTTP_Request2::METHOD_POST,
156 6
                $config['user'],
157 6
                $config['password'],
158 6
                $doc,
159 6
                null,
160 6
                array(array('Content-type', 'text/xml', true))
161 6
            );
162 5
            $this->updateObjectIds($response->getBody());
163 6
        } catch (Exception $ex) {
164 1
            $code = $ex->getCode();
165
        }
166
167 6
        if (isset($response) && is_object($response)) {
168 5
            $code = $response->getStatus();
169 5
        }
170 6
        if (Services_Openstreetmap_Transport::OK != $code) {
171 1
            throw new Services_Openstreetmap_Exception(
172 1
                'Error posting changeset',
173
                $code
174 1
            );
175
176 1
        }
177
        // Explicitly close the changeset
178 5
        $url = $config['server']
179
            . 'api/'
180 5
            . $config['api_version']
181 5
            . "/changeset/{$cId}/close";
182
183 5
        $code = null;
184 5
        $response = null;
185
        try {
186 5
            $response = $this->getTransport()->getResponse(
187 5
                $url,
188 5
                HTTP_Request2::METHOD_PUT,
189 5
                $config['user'],
190 5
                $config['password'],
191 5
                null,
192 5
                null,
193 5
                array(array('Content-type', 'text/xml', true))
194 5
            );
195 5
        } catch (Exception $ex) {
196 2
            $code = $ex->getCode();
197
        }
198 5
        if (isset($response) && is_object($response)) {
199 3
            $code = $response->getStatus();
200 3
        }
201 5
        if (Services_Openstreetmap_Transport::OK != $code) {
202 2
            throw new Services_Openstreetmap_Exception(
203 2
                'Error closing changeset',
204
                $code
205 2
            );
206 2
        }
207 3
        $this->open = false;
208
    }
209
210
    /**
211
     * getCreatedAt
212
     *
213
     * @return string
214
     */
215
    public function getCreatedAt()
216
    {
217 1
        return (string) $this->getAttributes()->created_at;
218
    }
219
220
    /**
221
     * getClosedAt
222
     *
223
     * @return string
224
     */
225
    public function getClosedAt()
226
    {
227 1
        return (string) $this->getAttributes()->closed_at;
228
    }
229
230
    /**
231
     * isOpen
232
     *
233
     * @return boolean
234
     */
235
    public function isOpen()
236
    {
237 10
        $attribs = $this->getAttributes();
238 10
        if (!is_null($attribs)) {
239 1
            return $attribs->open == 'true';
240 1
        } else {
241 9
            return $this->open;
242
        }
243
    }
244
245
    /**
246
     * getMinLon
247
     *
248
     * @return float
249
     */
250
    public function getMinLon()
251
    {
252 1
        return (float) $this->getAttributes()->min_lon;
253
    }
254
255
    /**
256
     * getMinLat
257
     *
258
     * @return float
259
     */
260
    public function getMinLat()
261
    {
262 1
        return (float) $this->getAttributes()->min_lat;
263
    }
264
265
266
    /**
267
     * getMaxLon
268
     *
269
     * @return float
270
     */
271
    public function getMaxLon()
272
    {
273 1
        return (float) $this->getAttributes()->max_lon;
274
    }
275
276
    /**
277
     * getMaxLat
278
     *
279
     * @return float
280
     */
281
    public function getMaxLat()
282
    {
283 1
        return (float) $this->getAttributes()->max_lat;
284
    }
285
286
287
    /**
288
     * getId
289
     *
290
     * @return numeric value or null if none set
291
     */
292
    public function getId()
293
    {
294 9
        $p_id = parent::getId();
295 9
        if (is_null($p_id)) {
296 1
            return $this->id;
297 1
        } else {
298 8
            return $p_id;
299
        }
300
    }
301
302
    /**
303
     * Given diffResult xml, update Ids of objects that are members of the
304
     * current changeset.
305
     *
306
     * @param string $body diffResult xml
307
     *
308
     * @return void
309
     */
310
    public function updateObjectIds($body)
311
    {
312 5
        $body = trim($body);
313 5
        $cxml = simplexml_load_string($body);
314 5
        $obj = $cxml->xpath('//diffResult');
315 5
        foreach ($obj[0]->children() as $child) {
316 5
            $old_id = null;
317 5
            $new_id = null;
318 5
            $old_id = (string) $child->attributes()->old_id;
319 5
            $new_id = (string) $child->attributes()->new_id;
320 5
            $this->updateObjectId($child->getName(), $old_id, $new_id);
321 5
        }
322
    }
323
324
    /**
325
     * Update id of some type of object
326
     *
327
     * @param string  $type   Object type
328
     * @param integer $old_id Old id
329
     * @param integer $new_id New id
330
     *
331
     * @return void
332
     */
333
    public function updateObjectId($type, $old_id, $new_id)
334
    {
335 5
        if ($old_id == $new_id) {
336 1
            return;
337 1
        }
338 4
        foreach ($this->members as $member) {
339 4
            if ($member->getType() == $type) {
340 4
                if ($member->getId() == $old_id) {
341 4
                    $member->setId($new_id);
342 4
                }
343 4
            }
344 4
        }
345
    }
346
}
347
// vim:set et ts=4 sw=4:
348
?>


Report generated at 2012-01-31T21:54:36Z