These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /*************************************************************************** |
||
3 | * For license information see doc/license.txt |
||
4 | * Import new data from geokrety.org. |
||
5 | * See util2/geokrety for check and repair functions. |
||
6 | * See discussion in http://redmine.opencaching.de/issues/18. |
||
7 | ***************************************************************************/ |
||
8 | |||
9 | checkJob(new Geokrety()); |
||
10 | |||
11 | class Geokrety |
||
12 | { |
||
13 | public $name = 'geokrety'; |
||
14 | public $interval = 900; |
||
15 | |||
16 | public function run() |
||
17 | { |
||
18 | global $opt; |
||
19 | |||
20 | if ($opt['cron']['geokrety']['run']) { |
||
21 | $xmlfile = $this->loadXML(); |
||
22 | if ($xmlfile === false) { |
||
23 | return; |
||
24 | } |
||
25 | |||
26 | $this->importXML($xmlfile); |
||
27 | if (!$opt['cron']['geokrety']['xml_archive']) { |
||
28 | $this->removeXML($xmlfile); |
||
29 | } |
||
30 | } |
||
31 | } |
||
32 | |||
33 | /* get file from XML interface |
||
34 | * and return path of saved xml |
||
35 | * or false on error |
||
36 | */ |
||
37 | public function loadXML() |
||
38 | { |
||
39 | global $opt; |
||
40 | |||
41 | if (!@mkdir(__DIR__ . '/../../../var/cache2/geokrety')) { |
||
42 | // die('can\'t create geogrety cache dir'); |
||
43 | } |
||
44 | $path = __DIR__ . '/../../../var/cache2/geokrety/import-' . date('Ymd-His') . '.xml'; |
||
45 | |||
46 | // Changed default-value for getSysConfig() from '2005-01-01 00:00:00' to 'NOW - 9d 12h' |
||
47 | // to safely stay in api-limit, even when client and server are in different time zones. |
||
48 | $modifiedSince = strtotime( |
||
49 | getSysConfig('geokrety_lastupdate', date($opt['db']['dateformat'], time() - 60 * 60 * 24 * 9.5)) |
||
50 | ); |
||
51 | if (!@copy('https://geokrety.org/export.php?modifiedsince=' . date('YmdHis', $modifiedSince - 1), $path)) { |
||
52 | return false; |
||
53 | } |
||
54 | |||
55 | return $path; |
||
56 | } |
||
57 | |||
58 | /** |
||
59 | * @param string $file |
||
60 | */ |
||
61 | public function removeXML($file) |
||
62 | { |
||
63 | @unlink($file); |
||
64 | } |
||
65 | |||
66 | /** |
||
67 | * @param string $file |
||
68 | */ |
||
69 | public function importXML($file) |
||
70 | { |
||
71 | global $opt; |
||
72 | |||
73 | $xr = new XMLReader(); |
||
74 | if (!$xr->open($file)) { |
||
75 | $xr->close(); |
||
76 | |||
77 | return; |
||
78 | } |
||
79 | |||
80 | $xr->read(); |
||
81 | if ($xr->nodeType != XMLReader::ELEMENT) { |
||
82 | echo 'error: First element expected, aborted' . "\n"; |
||
83 | |||
84 | return; |
||
85 | } |
||
86 | if ($xr->name != 'gkxml') { |
||
87 | echo 'error: First element not valid, aborted' . "\n"; |
||
88 | |||
89 | return; |
||
90 | } |
||
91 | |||
92 | $startUpdate = $xr->getAttribute('date'); |
||
93 | if ($startUpdate === '') { |
||
94 | echo 'error: Date attribute not valid, aborted' . "\n"; |
||
95 | |||
96 | return; |
||
97 | } |
||
98 | // is probably noot needed |
||
0 ignored issues
–
show
|
|||
99 | // while ($xr->read() && !($xr->name == 'geokret' || $xr->name == 'moves')) {} |
||
100 | |||
101 | $nRecordsCount = 0; |
||
102 | do { |
||
103 | if ($xr->nodeType == XMLReader::ELEMENT) { |
||
104 | $element = $xr->expand(); |
||
105 | switch ($xr->name) { |
||
106 | case 'geokret': |
||
107 | $this->importGeoKret($element); |
||
108 | break; |
||
109 | case 'moves': |
||
110 | $this->importMove($element); |
||
111 | break; |
||
112 | } |
||
113 | |||
114 | $nRecordsCount++; |
||
115 | } |
||
116 | } while ($xr->next()); |
||
117 | |||
118 | $xr->close(); |
||
119 | |||
120 | setSysConfig('geokrety_lastupdate', date($opt['db']['dateformat'], strtotime($startUpdate))); |
||
121 | } |
||
122 | |||
123 | /** |
||
124 | * @param DOMNode $element |
||
125 | */ |
||
126 | public function importGeoKret($element) |
||
127 | { |
||
128 | global $opt; |
||
129 | |||
130 | $id = $element->getAttribute('id'); |
||
131 | |||
132 | $name = html_entity_decode($this->getNodeValue($element, 'name')); |
||
133 | if ($name === '') { |
||
134 | return; |
||
135 | } |
||
136 | |||
137 | $userId = $this->getNodeAttribute($element, 'owner', 'id') + 0; |
||
138 | $username = $this->getNodeValue($element, 'owner'); |
||
139 | $this->checkUser($userId, $username); |
||
140 | |||
141 | $typeId = $this->getNodeAttribute($element, 'type', 'id') + 0; |
||
142 | $typename = $this->getNodeValue($element, 'type'); |
||
143 | $this->checkGeoKretType($typeId, $typename); |
||
144 | |||
145 | $description = html_entity_decode($this->getNodeValue($element, 'description')); |
||
146 | $dateCreated = strtotime($this->getNodeValue($element, 'datecreated')); |
||
147 | |||
148 | $distanceTravelled = $this->getNodeValue($element, 'distancetravelled') + 0; |
||
149 | $state = $this->getNodeValue($element, 'state') + 0; |
||
150 | |||
151 | $longitude = $this->getNodeAttribute($element, 'position', 'longitude') + 0; |
||
152 | $latitude = $this->getNodeAttribute($element, 'position', 'latitude') + 0; |
||
153 | |||
154 | sql( |
||
155 | "INSERT INTO `gk_item` |
||
156 | (`id`, `name`, `description`, `userid`, `datecreated`, |
||
157 | `distancetravelled`, `latitude`, `longitude`, `typeid`, `stateid`) |
||
158 | VALUES ('&1', '&2', '&3', '&4', '&5', '&6', '&7', '&8', '&9', '&10') |
||
159 | ON DUPLICATE KEY UPDATE |
||
160 | `name`='&2', `description`='&3', `userid`='&4', `datecreated`='&5', `distancetravelled`='&6', |
||
161 | `latitude`='&7', `longitude`='&8', `typeid`='&9', `stateid`='&10'", |
||
162 | $id, |
||
163 | $name, |
||
164 | $description, |
||
165 | $userId, |
||
166 | date($opt['db']['dateformat'], $dateCreated), |
||
167 | $distanceTravelled, |
||
168 | $latitude, |
||
169 | $longitude, |
||
170 | $typeId, |
||
171 | $state |
||
172 | ); |
||
173 | |||
174 | // Deleting and inserting item-waypoints if they have not changed will |
||
175 | // update caches.meta_last_modified -> caches.okapi_syncbase and thus trigger |
||
176 | // OKAPI changelog actions. This probably can be ignored as OKAPI will verify |
||
177 | // if data has really changed. |
||
178 | |||
179 | // update associated waypoints |
||
180 | /** |
||
181 | * This does not work properly, because geokret.waypoints does NOT contain the |
||
182 | * current location of the Kret but something like the last cache where it was logged. |
||
183 | * Evaluating the 'state' fielt might help, but for now, we import waypoint data |
||
184 | * from the moves instead. |
||
185 | * sql("DELETE FROM `gk_item_waypoint` WHERE id='&1'", $id); |
||
186 | * $waypoints = $element->getElementsByTagName('waypoints'); |
||
187 | * if ($waypoints->length > 0) |
||
188 | * { |
||
189 | * $wpItems = $waypoints->item(0)->getElementsByTagName('waypoint'); |
||
190 | * for ($i = 0; $i < $wpItems->length; $i++) |
||
191 | * { |
||
192 | * $wp = $wpItems->item($i)->nodeValue; |
||
193 | * if ($wp != '') |
||
194 | * sql("INSERT INTO `gk_item_waypoint` |
||
195 | * (`id`, `wp`) |
||
196 | * VALUES |
||
197 | * ('&1', '&2')", |
||
198 | * $id, $wp); |
||
199 | * } |
||
200 | * } |
||
201 | */ |
||
202 | } |
||
203 | |||
204 | /** |
||
205 | * @param DOMNode $element |
||
206 | */ |
||
207 | public function importMove($element) |
||
208 | { |
||
209 | global $opt; |
||
210 | |||
211 | $id = $element->getAttribute('id') + 0; |
||
212 | |||
213 | $gkId = $this->getNodeAttribute($element, 'geokret', 'id') + 0; |
||
214 | if (sql_value("SELECT COUNT(*) FROM `gk_item` WHERE `id`='&1'", 0, $gkId) == 0) { |
||
215 | return; |
||
216 | } |
||
217 | |||
218 | $latitude = $this->getNodeAttribute($element, 'position', 'latitude') + 0; |
||
219 | $longitude = $this->getNodeAttribute($element, 'position', 'longitude') + 0; |
||
220 | |||
221 | $dateLogged = strtotime($this->getNodeAttribute($element, 'date', 'logged')); |
||
222 | $dateMoved = strtotime($this->getNodeAttribute($element, 'date', 'moved')); |
||
223 | $userId = $this->getNodeAttribute($element, 'user', 'id') + 0; |
||
224 | $username = $this->getNodeValue($element, 'user'); |
||
225 | $this->checkUser($userId, $username); |
||
226 | |||
227 | $comment = html_entity_decode($this->getNodeValue($element, 'comment')); |
||
228 | $logTypeId = $this->getNodeAttribute($element, 'logtype', 'id') + 0; |
||
229 | $logTypeName = $this->getNodeValue($element, 'logtype'); |
||
230 | $this->checkMoveType($logTypeId, $logTypeName); |
||
231 | |||
232 | sql( |
||
233 | "INSERT INTO `gk_move` |
||
234 | (`id`, `itemid`, `latitude`, `longitude`, `datemoved`, `datelogged`, `userid`, `comment`, `logtypeid`) |
||
235 | VALUES ('&1', '&2', '&3', '&4', '&5', '&6', '&7', '&8', '&9') |
||
236 | ON DUPLICATE KEY UPDATE |
||
237 | `itemid`='&2', `latitude`='&3', `longitude`='&4', `datemoved`='&5', |
||
238 | `datelogged`='&6', `userid`='&7', `comment`='&8', `logtypeid`='&9'", |
||
239 | $id, |
||
240 | $gkId, |
||
241 | $latitude, |
||
242 | $longitude, |
||
243 | date($opt['db']['dateformat'], $dateMoved), |
||
244 | date($opt['db']['dateformat'], $dateLogged), |
||
245 | $userId, |
||
246 | $comment, |
||
247 | $logTypeId |
||
248 | ); |
||
249 | |||
250 | sql("DELETE FROM `gk_move_waypoint` WHERE id='&1'", $id); |
||
251 | |||
252 | // update associated waypoints |
||
253 | $waypoints = $element->getElementsByTagName('waypoints'); |
||
254 | if ($waypoints->length > 0) { |
||
255 | $wpItems = $waypoints->item(0)->getElementsByTagName('waypoint'); |
||
256 | for ($i = 0; $i < $wpItems->length; $i++) { |
||
257 | $wp = mb_trim($wpItems->item($i)->nodeValue); |
||
258 | if ($wp != '') { |
||
259 | sql("INSERT INTO `gk_move_waypoint` (`id`, `wp`) VALUES ('&1', '&2')", $id, $wp); |
||
260 | } |
||
261 | } |
||
262 | } |
||
263 | |||
264 | // update the current gk-waypoints based on the last move |
||
265 | sql("DELETE FROM `gk_item_waypoint` WHERE `id`='&1'", $gkId); |
||
266 | $rs = sql( |
||
267 | " |
||
268 | SELECT `id`,`logtypeid` FROM `gk_move` |
||
269 | WHERE `itemid`='&1' AND `logtypeid`!=2 |
||
270 | ORDER BY `datemoved` DESC LIMIT 1", |
||
271 | $gkId |
||
272 | ); |
||
273 | $r = sql_fetch_assoc($rs); |
||
274 | sql_free_result($rs); |
||
275 | if ($r === false) { |
||
276 | return; |
||
277 | } |
||
278 | |||
279 | if ($r['logtypeid'] == 0 /* dropped */ || $r['logtypeid'] == 3 /* seen in */) { |
||
280 | sql( |
||
281 | " |
||
282 | INSERT INTO `gk_item_waypoint` (`id`, `wp`) |
||
283 | SELECT '&1' AS `id`, `wp` |
||
284 | FROM `gk_move_waypoint` |
||
285 | WHERE `id`='&2' AND `wp`!=''", |
||
286 | $gkId, |
||
287 | $r['id'] |
||
288 | ); // "late log" bugfix: replaced $id parameter by $r['id'] |
||
289 | } |
||
290 | } |
||
291 | |||
292 | |||
293 | /** |
||
294 | * @param integer $id |
||
295 | * @param $name |
||
296 | */ |
||
297 | public function checkGeoKretType($id, $name) |
||
298 | { |
||
299 | sql( |
||
300 | "INSERT INTO `gk_item_type` (`id`, `name`) VALUES ('&1', '&2') ON DUPLICATE KEY UPDATE `name`='&2'", |
||
301 | $id, |
||
302 | $name |
||
303 | ); |
||
304 | } |
||
305 | |||
306 | |||
307 | /** |
||
308 | * @param integer $id |
||
309 | * @param $name |
||
310 | */ |
||
311 | public function checkUser($id, $name) |
||
312 | { |
||
313 | if ($id === 0) { |
||
314 | return; |
||
315 | } |
||
316 | |||
317 | sql("INSERT INTO `gk_user` (`id`, `name`) VALUES ('&1', '&2') ON DUPLICATE KEY UPDATE `name`='&2'", $id, $name); |
||
318 | } |
||
319 | |||
320 | |||
321 | /** |
||
322 | * @param integer $id |
||
323 | * @param $name |
||
324 | */ |
||
325 | public function checkMoveType($id, $name) |
||
326 | { |
||
327 | sql( |
||
328 | "INSERT INTO `gk_move_type` (`id`, `name`) VALUES ('&1', '&2') ON DUPLICATE KEY UPDATE `name`='&2'", |
||
329 | $id, |
||
330 | $name |
||
331 | ); |
||
332 | } |
||
333 | |||
334 | |||
335 | /** |
||
336 | * @param $domNode |
||
337 | * @param string $element |
||
338 | * @return string |
||
339 | */ |
||
340 | public function getNodeValue(&$domNode, $element) |
||
341 | { |
||
342 | $subNode = $domNode->getElementsByTagName($element); |
||
343 | if ($subNode->length < 1) { |
||
344 | return ''; |
||
345 | } else { |
||
346 | return $subNode->item(0)->nodeValue; |
||
347 | } |
||
348 | } |
||
349 | |||
350 | |||
351 | /** |
||
352 | * @param string $element |
||
353 | * @param string $attr |
||
354 | * @return string |
||
355 | */ |
||
356 | public function getNodeAttribute(&$domNode, $element, $attr) |
||
357 | { |
||
358 | $subNode = $domNode->getElementsByTagName($element); |
||
359 | if ($subNode->length < 1) { |
||
360 | return ''; |
||
361 | } else { |
||
362 | return $subNode->item(0)->getAttribute($attr); |
||
363 | } |
||
364 | } |
||
365 | } |
||
366 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.