Subversion Repositories oidplus

Rev

Rev 462 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
61 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
5
 * Copyright 2019 Daniel Marschall, ViaThinkSoft
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
256 daniel-mar 20
class OIDplusPageAdminOIDInfoExport extends OIDplusPagePluginAdmin {
21
 
327 daniel-mar 22
        /*private*/ const QUERY_LIST_OIDINFO_OIDS_V1 = '1.3.6.1.4.1.37476.2.5.2.1.5.1';
23
        /*private*/ const QUERY_GET_OIDINFO_DATA_V1  = '1.3.6.1.4.1.37476.2.5.2.1.6.1';
24
 
25
        public function action($actionID, $params) {
26
 
27
                if ($actionID == 'import_xml_file') {
28
                        if (!OIDplus::authUtils()::isAdminLoggedIn()) {
360 daniel-mar 29
                                throw new OIDplusException(_L('You need to log in as administrator.'));
327 daniel-mar 30
                        }
31
 
32
                        if (!isset($_FILES['userfile'])) {
360 daniel-mar 33
                                throw new OIDplusException(_L('Please choose a file.'));
327 daniel-mar 34
                        }
35
 
36
                        $xml_contents = file_get_contents($_FILES['userfile']['tmp_name']);
37
 
38
                        $errors = array();
39
                        list($count_imported_oids, $count_already_existing, $count_errors, $count_warnings) = $this->oidinfoImportXML($xml_contents, $errors, $replaceExistingOIDs=false, $orphan_mode=self::ORPHAN_AUTO_DEORPHAN);
40
                        if (count($errors) > 0) {
41
                                // Note: These "errors" can also be warnings (partial success)
420 daniel-mar 42
                                // TODO: since the output can be very long, should we really show it in a JavaScript alert() ?!
328 daniel-mar 43
                                return array(
381 daniel-mar 44
                                        "status" => -1,
327 daniel-mar 45
                                        "count_imported_oids" => $count_imported_oids,
46
                                        "count_already_existing" => $count_already_existing,
47
                                        "count_errors" => $count_errors,
48
                                        "count_warnings" => $count_warnings,
49
                                        "error" => implode("\n",$errors)
328 daniel-mar 50
                                );
327 daniel-mar 51
                        } else {
328 daniel-mar 52
                                return array(
327 daniel-mar 53
                                        "status" => 0,
54
                                        "count_imported_oids" => $count_imported_oids,
55
                                        "count_already_existing" => $count_already_existing,
56
                                        "count_errors" => $count_errors,
57
                                        "count_warnings" => $count_warnings
328 daniel-mar 58
                                );
327 daniel-mar 59
                        }
60
                } else if ($actionID == 'import_oidinfo_oid') {
61
                        if (!OIDplus::authUtils()::isAdminLoggedIn()) {
360 daniel-mar 62
                                throw new OIDplusException(_L('You need to log in as administrator.'));
327 daniel-mar 63
                        }
64
 
65
                        $oid = $params['oid'];
66
 
67
                        $query = self::QUERY_GET_OIDINFO_DATA_V1;
68
 
69
                        $payload = array(
70
                                "query" => $query, // we must repeat the query because we want to sign it
71
                                "system_id" => OIDplus::getSystemId(false),
72
                                "oid" => $oid
73
                        );
74
 
75
                        $signature = '';
76
                        if (!@openssl_sign(json_encode($payload), $signature, OIDplus::config()->getValue('oidplus_private_key'))) {
350 daniel-mar 77
                                if (!OIDplus::getPkiStatus()) {
360 daniel-mar 78
                                        throw new OIDplusException(_L('Error: Your system could not generate a private/public key pair. (OpenSSL is probably missing on your system). Therefore, you cannot register/unregister your OIDplus instance.'));
350 daniel-mar 79
                                } else {
360 daniel-mar 80
                                        throw new OIDplusException(_L('Signature failed'));
350 daniel-mar 81
                                }
327 daniel-mar 82
                        }
83
 
84
                        $data = array(
85
                                "payload" => $payload,
86
                                "signature" => base64_encode($signature)
87
                        );
88
 
463 daniel-mar 89
                        if (!function_exists('curl_exec')) {
90
                                throw new Exception(_L('The "CURL" PHP extension is not installed at your system. Please enable the PHP extension <code>php_curl</code>.'));
91
                        }
92
 
327 daniel-mar 93
                        $ch = curl_init();
94
                        curl_setopt($ch, CURLOPT_URL, 'https://oidplus.viathinksoft.com/reg2/query.php');
95
                        curl_setopt($ch, CURLOPT_POST, 1);
413 daniel-mar 96
                        curl_setopt($ch, CURLOPT_POSTFIELDS, "query=".urlencode($query)."&compressed=1&data=".urlencode(base64_encode(gzdeflate(json_encode($data)))));
327 daniel-mar 97
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
98
                        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
99
                        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
100
                        if (!($res = @curl_exec($ch))) {
360 daniel-mar 101
                                throw new OIDplusException(_L('Communication with ViaThinkSoft server failed: %1',curl_error($ch)));
327 daniel-mar 102
                        }
103
                        curl_close($ch);
104
 
370 daniel-mar 105
                        $json = @json_decode($res, true);
327 daniel-mar 106
 
107
                        if (!$json) {
370 daniel-mar 108
                                return array(
381 daniel-mar 109
                                        "status" => -1,
370 daniel-mar 110
                                        "error" => _L('JSON reply from ViaThinkSoft decoding error: %1',$res)
111
                                );
327 daniel-mar 112
                        }
113
 
381 daniel-mar 114
                        if (isset($json['error']) || ($json['status'] < 0)) {
370 daniel-mar 115
                                return array(
381 daniel-mar 116
                                        "status" => -1,
370 daniel-mar 117
                                        "error" => isset($json['error']) ? $json['error'] : _L('Received error status code: %1',$json['status'])
118
                                );
119
                        }
120
 
121
                        $errors = array();
122
                        list($count_imported_oids, $count_already_existing, $count_errors, $count_warnings) = $this->oidinfoImportXML('<oid-database>'.$json['xml'].'</oid-database>', $errors, $replaceExistingOIDs=false, $orphan_mode=self::ORPHAN_DISALLOW_ORPHANS);
123
                        if (count($errors) > 0) {
381 daniel-mar 124
                                return array("status" => -1, "error" => implode("\n",$errors));
370 daniel-mar 125
                        } else if ($count_imported_oids <> 1) {
381 daniel-mar 126
                                return array("status" => -1, "error" => _L('Imported %1, but expected to import 1',$count_imported_oids));
327 daniel-mar 127
                        } else {
370 daniel-mar 128
                                return array("status" => 0);
327 daniel-mar 129
                        }
130
                } else {
360 daniel-mar 131
                        throw new OIDplusException(_L('Unknown action ID'));
327 daniel-mar 132
                }
133
        }
134
 
75 daniel-mar 135
        public function init($html=true) {
303 daniel-mar 136
                // Nothing
61 daniel-mar 137
        }
138
 
139
        public function gui($id, &$out, &$handled) {
382 daniel-mar 140
                $ary = explode('$', $id);
141
                if (isset($ary[1])) {
142
                        $id = $ary[0];
143
                        $tab = $ary[1];
144
                } else {
145
                        $tab = 'export';
146
                }
327 daniel-mar 147
                if ($id === 'oidplus:oidinfo_compare_export') {
61 daniel-mar 148
                        $handled = true;
360 daniel-mar 149
                        $out['title'] = _L('List OIDs in your system which are missing at oid-info.com');
241 daniel-mar 150
                        $out['icon'] = file_exists(__DIR__.'/icon_big.png') ? OIDplus::webpath(__DIR__).'icon_big.png' : '';
61 daniel-mar 151
 
152
                        if (!OIDplus::authUtils()::isAdminLoggedIn()) {
153
                                $out['icon'] = 'img/error_big.png';
360 daniel-mar 154
                                $out['text'] = '<p>'._L('You need to <a %1>log in</a> as administrator.',OIDplus::gui()->link('oidplus:login')).'</p>';
281 daniel-mar 155
                                return;
61 daniel-mar 156
                        }
281 daniel-mar 157
 
327 daniel-mar 158
                        $query = self::QUERY_LIST_OIDINFO_OIDS_V1;
159
 
160
                        $payload = array(
161
                                "query" => $query, // we must repeat the query because we want to sign it
347 daniel-mar 162
                                "system_id" => OIDplus::getSystemId(false),
163
                                "show_all" => 1 // this is required so that the VTS OIDRA gets no false notifications for adding the systems in the directory 1.3.6.1.4.1.37476.30.9
327 daniel-mar 164
                        );
165
 
166
                        $signature = '';
167
                        if (!@openssl_sign(json_encode($payload), $signature, OIDplus::config()->getValue('oidplus_private_key'))) {
350 daniel-mar 168
                                if (!OIDplus::getPkiStatus()) {
360 daniel-mar 169
                                        throw new OIDplusException(_L('Error: Your system could not generate a private/public key pair. (OpenSSL is probably missing on your system). Therefore, you cannot register/unregister your OIDplus instance.'));
350 daniel-mar 170
                                } else {
360 daniel-mar 171
                                        throw new OIDplusException(_L('Signature failed'));
350 daniel-mar 172
                                }
327 daniel-mar 173
                        }
174
 
175
                        $data = array(
176
                                "payload" => $payload,
177
                                "signature" => base64_encode($signature)
178
                        );
179
 
463 daniel-mar 180
                        if (!function_exists('curl_exec')) {
181
                                throw new Exception(_L('The "CURL" PHP extension is not installed at your system. Please enable the PHP extension <code>php_curl</code>.'));
182
                        }
183
 
327 daniel-mar 184
                        $ch = curl_init();
185
                        curl_setopt($ch, CURLOPT_URL, 'https://oidplus.viathinksoft.com/reg2/query.php');
186
                        curl_setopt($ch, CURLOPT_POST, 1);
413 daniel-mar 187
                        curl_setopt($ch, CURLOPT_POSTFIELDS, "query=".urlencode($query)."&compressed=1&data=".urlencode(base64_encode(gzdeflate(json_encode($data)))));
327 daniel-mar 188
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
189
                        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
190
                        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
191
                        if (!($res = @curl_exec($ch))) {
360 daniel-mar 192
                                throw new OIDplusException(_L('Communication with ViaThinkSoft server failed: %1',curl_error($ch)));
327 daniel-mar 193
                        }
194
                        curl_close($ch);
195
 
382 daniel-mar 196
                        $out['text'] = '<p><a '.OIDplus::gui()->link('oidplus:datatransfer$export').'><img src="img/arrow_back.png" width="16" alt="'._L('Go back').'"> '._L('Go back to data transfer main page').'</a></p>';
197
 
370 daniel-mar 198
                        $json = @json_decode($res, true);
327 daniel-mar 199
 
200
                        if (!$json) {
201
                                $out['icon'] = 'img/error_big.png';
382 daniel-mar 202
                                $out['text'] .= _L('JSON reply from ViaThinkSoft decoding error: %1',$res);
347 daniel-mar 203
                                return;
327 daniel-mar 204
                        }
205
 
381 daniel-mar 206
                        if (isset($json['error']) || ($json['status'] < 0)) {
370 daniel-mar 207
                                $out['icon'] = 'img/error_big.png';
208
                                if (isset($json['error'])) {
382 daniel-mar 209
                                        $out['text'] .= _L('Received error: %1',$json['error']);
370 daniel-mar 210
                                } else {
382 daniel-mar 211
                                        $out['text'] .= _L('Received error status code: %1',$json['status']);
370 daniel-mar 212
                                }
213
                                return;
214
                        }
215
 
381 daniel-mar 216
                        if (isset($json['error']) || ($json['status'] < 0)) {
360 daniel-mar 217
                                $out['text'] .= '<p>'._L('Error: %1',htmlentities($json['error'])).'</p>';
327 daniel-mar 218
                        } else {
219
                                // TODO: If roots were created or deleted recently, we must do a re-query of the registration, so that the "roots" information at the directory service gets refreshed
360 daniel-mar 220
                                if (count($json['roots']) == 0) $out['text'] .= '<p>'._L('In order to use this feature, you need to have at least one (root) OID added in your system, and the system needs to report the newly added root to the directory service (the reporting interval is 1 hour).').'</p>';
327 daniel-mar 221
                                foreach ($json['roots'] as $root) {
222
                                        $oid = $root['oid'];
360 daniel-mar 223
                                        $out['text'] .= '<h2>'._L('Root OID %1',$oid).'</h2>';
327 daniel-mar 224
                                        if ($root['verified']) {
225
                                                $count = 0;
226
                                                $out['text'] .= '<div class="container box"><div id="suboid_table" class="table-responsive">';
227
                                                $out['text'] .= '<table class="table table-bordered table-striped">';
360 daniel-mar 228
                                                $out['text'] .= '<tr><th colspan="3">'._L('Actions').'</th><th>'._L('OID').'</th></tr>';
327 daniel-mar 229
 
230
                                                $lookup_nonoid = array();
231
                                                $row_lookup = array();
232
 
233
                                                $all_local_oids_of_root = array();
347 daniel-mar 234
                                                $res = OIDplus::db()->query("select * from ###objects where confidential <> 1");
327 daniel-mar 235
                                                while ($row = $res->fetch_object()) {
347 daniel-mar 236
                                                        $obj = OIDplusObject::parse($row->id);
237
                                                        if (!$obj) continue; // can happen when object type is not enabled
238
                                                        if ($obj->isConfidential()) continue; // This will also exclude OIDs which are descendants of confidential OIDs
327 daniel-mar 239
                                                        if (strpos($row->id, 'oid:') === 0) {
240
                                                                $oid = substr($row->id,strlen('oid:'));
241
                                                                if (strpos($oid.'.', $root['oid']) === 0) {
242
                                                                        $row_lookup[$oid] = $row;
243
                                                                        $all_local_oids_of_root[] = $oid;
244
                                                                }
245
                                                        } else {
246
                                                                $aids = $obj->getAltIds();
247
                                                                foreach ($aids as $aid) {
248
                                                                        if ($aid->getNamespace() == 'oid') {
249
                                                                                $oid = $aid->getId();
250
                                                                                if (strpos($oid.'.', $root['oid']) === 0) {
251
                                                                                        $row_lookup[$oid] = $row;
252
                                                                                        $all_local_oids_of_root[] = $oid;
253
                                                                                        $lookup_nonoid[$oid] = $row->id;
254
                                                                                }
255
                                                                        }
256
                                                                }
257
                                                        }
258
                                                }
259
 
348 daniel-mar 260
                                                natsort($all_local_oids_of_root);
327 daniel-mar 261
                                                foreach ($all_local_oids_of_root as $local_oid) {
262
                                                        if (!in_array($local_oid, $root['children'])) {
263
                                                                $count++;
264
 
265
                                                                // Start: Build oid-info.com create URL
266
 
267
                                                                $row = $row_lookup[$local_oid];
268
 
269
                                                                $url = "http://www.oid-info.com/cgi-bin/manage?f=".oid_up($local_oid)."&a=create";
270
 
271
                                                                $tmp = explode('.',$local_oid);
272
                                                                $url .= "&nb=".urlencode(array_pop($tmp));
273
 
274
                                                                $asn1_ids = array();
275
                                                                $res2 = OIDplus::db()->query("select * from ###asn1id where oid = ?", array($row->id));
276
                                                                while ($row2 = $res2->fetch_object()) {
277
                                                                        $asn1_ids[] = $row2->name; // 'unicode-label' is currently not in the standard format (oid.xsd)
278
                                                                }
279
                                                                $url .= "&id=".array_shift($asn1_ids); // urlencode wurde schon oben gemacht
280
                                                                $url .= "&syn_id=".implode('%0A', $asn1_ids); // urlencode wurde schon oben gemacht
281
 
282
                                                                $iri_ids = array();
283
                                                                $res2 = OIDplus::db()->query("select * from ###iri where oid = ?", array($row->id));
284
                                                                while ($row2 = $res2->fetch_object()) {
285
                                                                        $iri_ids[] = $row2->name;
286
                                                                }
287
                                                                $url .= "&unicode_label_list=".implode('%0A', $iri_ids); // urlencode wurde schon oben gemacht
288
 
289
                                                                if (!empty($row->title)) {
290
                                                                        $tmp_description = $row->title;
291
                                                                        $tmp_information = $row->description;
292
                                                                        if (trim($row->title) == trim(strip_tags($row->description))) {
293
                                                                                $tmp_information = '';
294
                                                                        }
295
                                                                } else if (isset($asn1_ids[0])) {
296
                                                                        $tmp_description = '"'.$asn1_ids[0].'"';
297
                                                                        $tmp_information = $row->description;
298
                                                                } else if (isset($iri_ids[0])) {
299
                                                                        $tmp_description = '"'.$iri_ids[0].'"';
300
                                                                        $tmp_information = $row->description;
301
                                                                } else if (!empty($row->description)) {
302
                                                                        $tmp_description = $row->description;
303
                                                                        $tmp_information = '';
304
                                                                } else if (!empty($row->comment)) {
305
                                                                        $tmp_description = $row->comment;
306
                                                                        $tmp_information = '';
307
                                                                } else {
360 daniel-mar 308
                                                                        $tmp_description = '<i>No description available</i>'; // do not translate
327 daniel-mar 309
                                                                        $tmp_information = '';
310
                                                                }
311
 
312
                                                                if ($tmp_information != '') {
313
                                                                        $tmp_information .= '<br/><br/>';
314
                                                                }
315
 
360 daniel-mar 316
                                                                $tmp_information .= 'See <a href="'.OIDplus::getSystemUrl(false).'?goto='.urlencode($id).'">more information</a>.'; // do not translate
327 daniel-mar 317
 
318
                                                                if (explode(':',$id,2)[0] != 'oid') {
360 daniel-mar 319
                                                                        $tmp_information = "Object: $id\n\n" . $tmp_information; // do not translate
327 daniel-mar 320
                                                                }
321
 
322
                                                                $url .= "&description=".urlencode(self::repair_relative_links($tmp_description));
323
                                                                $url .= "&info=".urlencode(self::repair_relative_links($tmp_information));
324
 
325
                                                                $url .= "&current_registrant_email=".urlencode($row->ra_email);
326
 
327
                                                                $res2 = OIDplus::db()->query("select * from ###ra where email = ?", array($row->ra_email));
328
                                                                if ($res2->num_rows() > 0) {
329
                                                                        $row2 = $res2->fetch_object();
330
 
331
                                                                        $tmp = array();
332
                                                                        if (!empty($row2->personal_name)) {
333
                                                                                $name_ary = split_firstname_lastname($row2->personal_name);
334
                                                                                $tmp_first_name = $name_ary[0];
335
                                                                                $tmp_last_name  = $name_ary[1];
336
                                                                                if (!empty($row2->ra_name)       ) $tmp[] = $row2->ra_name;
337
                                                                                if (!empty($row2->office)        ) $tmp[] = $row2->office;
338
                                                                                if (!empty($row2->organization)  ) $tmp[] = $row2->organization;
339
                                                                        } else {
340
                                                                                $tmp_first_name = $row2->ra_name;
341
                                                                                $tmp_last_name  = '';
342
                                                                                if (!empty($row2->personal_name) ) $tmp[] = $row2->personal_name;
343
                                                                                if (!empty($row2->office)        ) $tmp[] = $row2->office;
344
                                                                                if (!empty($row2->organization)  ) $tmp[] = $row2->organization;
345
                                                                        }
346
 
347
                                                                        if (empty($tmp_first_name) || empty($tmp_last_name)) {
348
                                                                                $name = self::split_name($tmp_first_name.' '.$tmp_last_name);
349
                                                                                $tmp_first_name = $name[0];
350
                                                                                $tmp_last_name = $name[1];
351
                                                                        }
352
                                                                        $url .= "&current_registrant_first_name=".urlencode($tmp_first_name);
353
                                                                        $url .= "&current_registrant_last_name=".urlencode($tmp_last_name);
354
 
355
                                                                        if ((count($tmp) > 0) && ($tmp[0] == $row2->ra_name)) array_shift($tmp);
356
                                                                        array_unique($tmp);
357
 
358
                                                                        if (!$row2->privacy) {
359
                                                                                if (!empty($row2->street))   $tmp[] = $row2->street;
360
                                                                                if (!empty($row2->zip_town)) $tmp[] = $row2->zip_town;
361
                                                                                if (!empty($row2->country))  $tmp[] = $row2->country;
362
                                                                                $url .= "&current_registrant_tel=".urlencode(!empty($row2->phone) ? $row2->phone : $row2->mobile);
363
                                                                                $url .= "&current_registrant_fax=".urlencode($row2->fax);
364
                                                                        }
365
                                                                        if (empty($row2->zip_town) && empty($row2->country)) {
366
                                                                                // The address is useless if we do neither know city nor country
367
                                                                                // Ignore it
368
                                                                        } else {
369
                                                                                $tmp = self::split_address_country(implode("<br/>", $tmp));
370
                                                                                $url .= "&current_registrant_address=".urlencode($tmp[0]);
371
                                                                                $url .= "&current_registrant_country=".urlencode($tmp[1]);
372
                                                                        }
373
                                                                }
374
                                                                if (!empty($row->updated)) {
375
                                                                        $tmp = explode('-', self::_formatdate($row->updated));
376
                                                                        $url .= "&modification_year=".urlencode($tmp[0]);
377
                                                                        $url .= "&modification_month=".urlencode($tmp[1]);
378
                                                                        $url .= "&modification_day=".urlencode($tmp[2]);
379
                                                                }
380
 
381
                                                                //$url .= "&submitter_last_name=".urlencode($xml->{'submitter'}->{'last-name'});
382
                                                                //$url .= "&submitter_first_name=".urlencode($xml->{'submitter'}->{'first-name'});
383
                                                                //$url .= "&submitter_email=".urlencode($xml->{'submitter'}->{'email'});
384
 
385
                                                                // End: Build oid-info.com create URL
386
 
387
                                                                // Note: "Actions" is at the left, because it has a fixed width, so the user can continue clicking without the links moving if the OID length changes between lines
388
                                                                $out['text'] .= '<tr id="missing_oid_'.str_replace('.','_',$local_oid).'">'.
360 daniel-mar 389
                                                                '<td><a '.OIDplus::gui()->link(isset($lookup_nonoid[$local_oid]) ? $lookup_nonoid[$local_oid] : 'oid:'.$local_oid, true).'>'._L('View local OID').'</a></td>'.
390
                                                                '<td><a href="javascript:removeMissingOid(\''.$local_oid.'\');">'._L('Ignore for now').'</a></td>'.
391
                                                                '<td><a target="_blank" href="'.$url.'">'._L('Add to oid-info.com manually').'</a></td>'.
327 daniel-mar 392
                                                                '<td>'.$local_oid.'</td>'.
393
                                                                '</tr>';
394
                                                        }
395
                                                }
396
                                                if ($count == 0) {
360 daniel-mar 397
                                                        $out['text'] .= '<tr><td colspan="4">'._L('No missing OIDs found').'</td></tr>';
327 daniel-mar 398
                                                }
399
                                                $out['text'] .= '</table></div></div>';
400
                                        } else {
360 daniel-mar 401
                                                $out['text'] .= '<p>'._L('This root is not validated. Please send an email to %1 in order to request ownership verification of this root OID.',$json['vts_verification_email']).'</p>';
327 daniel-mar 402
                                        }
403
                                }
404
                        }
61 daniel-mar 405
                }
327 daniel-mar 406
 
407
                if ($id === 'oidplus:oidinfo_compare_import') {
408
                        $handled = true;
360 daniel-mar 409
                        $out['title'] = _L('List OIDs at oid-info.com which are missing in your system');
327 daniel-mar 410
                        $out['icon'] = file_exists(__DIR__.'/icon_big.png') ? OIDplus::webpath(__DIR__).'icon_big.png' : '';
411
 
412
                        if (!OIDplus::authUtils()::isAdminLoggedIn()) {
413
                                $out['icon'] = 'img/error_big.png';
360 daniel-mar 414
                                $out['text'] = '<p>'._L('You need to <a %1>log in</a> as administrator.',OIDplus::gui()->link('oidplus:login')).'</p>';
327 daniel-mar 415
                                return;
416
                        }
417
 
418
                        $query = self::QUERY_LIST_OIDINFO_OIDS_V1;
419
 
420
                        $payload = array(
421
                                "query" => $query, // we must repeat the query because we want to sign it
347 daniel-mar 422
                                "system_id" => OIDplus::getSystemId(false),
348 daniel-mar 423
                                "show_all" => 0
327 daniel-mar 424
                        );
425
 
426
                        $signature = '';
427
                        if (!@openssl_sign(json_encode($payload), $signature, OIDplus::config()->getValue('oidplus_private_key'))) {
350 daniel-mar 428
                                if (!OIDplus::getPkiStatus()) {
360 daniel-mar 429
                                        throw new OIDplusException(_L('Error: Your system could not generate a private/public key pair. (OpenSSL is probably missing on your system). Therefore, you cannot register/unregister your OIDplus instance.'));
350 daniel-mar 430
                                } else {
360 daniel-mar 431
                                        throw new OIDplusException(_L('Signature failed'));
350 daniel-mar 432
                                }
327 daniel-mar 433
                        }
434
 
435
                        $data = array(
436
                                "payload" => $payload,
437
                                "signature" => base64_encode($signature)
438
                        );
439
 
463 daniel-mar 440
                        if (!function_exists('curl_exec')) {
441
                                throw new Exception(_L('The "CURL" PHP extension is not installed at your system. Please enable the PHP extension <code>php_curl</code>.'));
442
                        }
443
 
327 daniel-mar 444
                        $ch = curl_init();
445
                        curl_setopt($ch, CURLOPT_URL, 'https://oidplus.viathinksoft.com/reg2/query.php');
446
                        curl_setopt($ch, CURLOPT_POST, 1);
413 daniel-mar 447
                        curl_setopt($ch, CURLOPT_POSTFIELDS, "query=".urlencode($query)."&compressed=1&data=".urlencode(base64_encode(gzdeflate(json_encode($data)))));
327 daniel-mar 448
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
449
                        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
450
                        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
451
                        if (!($res = @curl_exec($ch))) {
360 daniel-mar 452
                                throw new OIDplusException(_L('Communication with ViaThinkSoft server failed: %1',curl_error($ch)));
327 daniel-mar 453
                        }
454
                        curl_close($ch);
455
 
382 daniel-mar 456
                        $out['text'] = '<p><a '.OIDplus::gui()->link('oidplus:datatransfer$import').'><img src="img/arrow_back.png" width="16" alt="'._L('Go back').'"> '._L('Go back to data transfer main page').'</a></p>';
457
 
370 daniel-mar 458
                        $json = @json_decode($res, true);
327 daniel-mar 459
 
460
                        if (!$json) {
461
                                $out['icon'] = 'img/error_big.png';
382 daniel-mar 462
                                $out['text'] .= _L('JSON reply from ViaThinkSoft decoding error: %1',$res);
347 daniel-mar 463
                                return;
327 daniel-mar 464
                        }
465
 
381 daniel-mar 466
                        if (isset($json['error']) || ($json['status'] < 0)) {
370 daniel-mar 467
                                $out['icon'] = 'img/error_big.png';
468
                                if (isset($json['error'])) {
382 daniel-mar 469
                                        $out['text'] .= _L('Received error: %1',$json['error']);
370 daniel-mar 470
                                } else {
382 daniel-mar 471
                                        $out['text'] .= _L('Received error status code: %1',$json['status']);
370 daniel-mar 472
                                }
473
                                return;
474
                        }
475
 
327 daniel-mar 476
                        $all_local_oids = array();
477
                        $res = OIDplus::db()->query("select id from ###objects");
478
                        while ($row = $res->fetch_array()) {
479
                                if (strpos($row['id'], 'oid:') === 0) {
480
                                        $all_local_oids[] = substr($row['id'],strlen('oid:'));
481
                                } else {
482
                                        $obj = OIDplusObject::parse($row['id']);
483
                                        if (!$obj) continue; // can happen when object type is not enabled
484
                                        $aids = $obj->getAltIds();
485
                                        foreach ($aids as $aid) {
486
                                                if ($aid->getNamespace() == 'oid') {
487
                                                        $all_local_oids[] = $aid->getId();
488
                                                }
489
                                        }
490
                                }
491
                        }
492
 
381 daniel-mar 493
                        if (isset($json['error']) || ($json['status'] < 0)) {
360 daniel-mar 494
                                $out['text'] .= '<p>'._L('Error: %1',htmlentities($json['error'])).'</p>';
327 daniel-mar 495
                        } else {
496
                                // TODO: If roots were created or deleted recently, we must do a re-query of the registration, so that the "roots" information at the directory service gets refreshed
360 daniel-mar 497
                                if (count($json['roots']) == 0) $out['text'] .= '<p>'._L('In order to use this feature, you need to have at least one (root) OID added in your system, and the system needs to report the newly added root to the directory service (the reporting interval is 1 hour).').'</p>';
327 daniel-mar 498
                                foreach ($json['roots'] as $root) {
499
                                        $oid = $root['oid'];
360 daniel-mar 500
                                        $out['text'] .= '<h2>'._L('Root OID %1',$oid).'</h2>';
327 daniel-mar 501
                                        // TODO: "Import all" button
502
                                        if ($root['verified']) {
503
                                                $count = 0;
504
                                                $out['text'] .= '<div class="container box"><div id="suboid_table" class="table-responsive">';
505
                                                $out['text'] .= '<table class="table table-bordered table-striped">';
360 daniel-mar 506
                                                $out['text'] .= '<tr><th colspan="4">'._L('Actions').'</th><th>'._L('OID').'</th></tr>';
348 daniel-mar 507
                                                natsort($root['children']);
327 daniel-mar 508
                                                foreach ($root['children'] as $child_oid) {
509
                                                        if (!in_array($child_oid, $all_local_oids)) {
510
                                                                $count++;
511
                                                                // Note: "Actions" is at the left, because it has a fixed width, so the user can continue clicking without the links moving if the OID length changes between lines
512
                                                                $out['text'] .= '<tr id="missing_oid_'.str_replace('.','_',$child_oid).'">'.
360 daniel-mar 513
                                                                '<td><a target="_blank" href="http://www.oid-info.com/get/'.$child_oid.'">'._L('View OID at oid-info.com').'</a></td>'.
514
                                                                '<td><a href="javascript:removeMissingOid(\''.$child_oid.'\');">'._L('Ignore for now').'</a></td>'.
515
                                                                '<td><a href="mailto:admin@oid-info.com">'._L('Report illegal OID').'</a></td>'.
516
                                                                (strpos($child_oid,'1.3.6.1.4.1.37476.30.9.') === 0 ? '<td>&nbsp;</td>' : '<td><a href="javascript:importMissingOid(\''.$child_oid.'\');">'._L('Import OID').'</a></td>').
327 daniel-mar 517
                                                                '<td>'.$child_oid.'</td>'.
518
                                                                '</tr>';
519
                                                        }
520
                                                }
521
                                                if ($count == 0) {
360 daniel-mar 522
                                                        $out['text'] .= '<tr><td colspan="5">'._L('No extra OIDs found').'</td></tr>';
327 daniel-mar 523
                                                }
524
                                                $out['text'] .= '</table></div></div>';
525
                                        } else {
360 daniel-mar 526
                                                $out['text'] .= '<p>'._L('This root is not validated. Please send an email to %1 in order to request ownership verification of this root OID.',$json['vts_verification_email']).'</p>';
327 daniel-mar 527
                                        }
528
                                }
529
                        }
530
                }
531
 
532
                if ($id === 'oidplus:datatransfer') {
533
                        $handled = true;
360 daniel-mar 534
                        $out['title'] = _L('Data Transfer');
327 daniel-mar 535
                        $out['icon'] = file_exists(__DIR__.'/icon_big.png') ? OIDplus::webpath(__DIR__).'icon_big.png' : '';
536
 
537
                        if (!OIDplus::authUtils()::isAdminLoggedIn()) {
538
                                $out['icon'] = 'img/error_big.png';
360 daniel-mar 539
                                $out['text'] = '<p>'._L('You need to <a %1>log in</a> as administrator.',OIDplus::gui()->link('oidplus:login')).'</p>';
327 daniel-mar 540
                                return;
541
                        }
542
 
420 daniel-mar 543
                        $out['text'] = '<br><div id="dataTransferArea" style="visibility: hidden"><div id="dataTransferTab" class="container" style="width:100%;">';
327 daniel-mar 544
 
420 daniel-mar 545
                        // ---------------- Tab control
546
                        $out['text'] .= OIDplus::gui()->tabBarStart();
547
                        $out['text'] .= OIDplus::gui()->tabBarElement('export', _L('Export'), $tab === 'export');
548
                        $out['text'] .= OIDplus::gui()->tabBarElement('import', _L('Import'), $tab === 'import');
549
                        $out['text'] .= OIDplus::gui()->tabBarEnd();
550
                        $out['text'] .= OIDplus::gui()->tabContentStart();
551
                        // ---------------- "Export" tab
552
                        $tabcont  = '<h2>'._L('Generate XML file containing all OIDs').'</h2>';
553
                        $tabcont .= '<p>'._L('These XML files are following the <a %1>XML schema</a> of <b>oid-info.com</b>. They can be used for various purposes though.','href="http://www.oid-info.com/oid.xsd" target="_blank"').'</p>';
554
                        $tabcont .= '<p><input type="button" onclick="window.open(\''.OIDplus::webpath(__DIR__).'oidinfo_export.php\',\'_blank\')" value="'._L('Generate XML (all OIDs)').'"></p>';
555
                        $tabcont .= '<p><input type="button" onclick="window.open(\''.OIDplus::webpath(__DIR__).'oidinfo_export.php?online=1\',\'_blank\')" value="'._L('Generate XML (only OIDs which do not exist at oid-info.com)').'"></p>';
556
                        $tabcont .= '<p><a href="http://www.oid-info.com/submit.htm" target="_blank">'._L('Upload XML files manually to oid-info.com').'</a></p>';
557
                        $tabcont .= '<br><p>'._L('Attention: Do not use this XML Export/Import to exchange, backup or restore data between OIDplus systems!<br>It will cause various loss of information, e.g. because Non-OIDs like GUIDs are converted in OIDs and can\'t be converted back.').'</p>';
558
                        $tabcont .= '<h2>'._L('Automatic export to oid-info.com').'</h2>';
327 daniel-mar 559
                        $privacy_level = OIDplus::config()->getValue('reg_privacy');
560
                        if ($privacy_level == 0) {
420 daniel-mar 561
                                $tabcont .= '<p>'._L('All your OIDs will automatically submitted to oid-info.com through the remote directory service in regular intervals.').' (<a '.OIDplus::gui()->link('oidplus:srv_registration').'>'._L('Change preference').'</a>)</p>';
327 daniel-mar 562
                        } else {
420 daniel-mar 563
                                $tabcont .= '<p>'._L('If you set the privacy option to "0" (your system is registered), then all your OIDs will be automatically exported to oid-info.com.').' (<a '.OIDplus::gui()->link('oidplus:srv_registration').'>'._L('Change preference').'</a>)</p>';
327 daniel-mar 564
                        }
420 daniel-mar 565
                        $tabcont .= '<h2>'._L('Comparison with oid-info.com').'</h2>';
566
                        $tabcont .= '<p><a '.OIDplus::gui()->link('oidplus:oidinfo_compare_export').'>'._L('List OIDs in your system which are missing at oid-info.com').'</a></p>';
567
                        $out['text'] .= OIDplus::gui()->tabContentPage('export', $tabcont, $tab === 'export');
568
                        // ---------------- "Import" tab
569
                        $tabcont  = '<h2>'._L('Import XML file').'</h2>';
570
                        $tabcont .= '<p>'._L('These XML files are following the <a %1>XML schema</a> of <b>oid-info.com</b>.','href="http://www.oid-info.com/oid.xsd" target="_blank"').'</p>';
571
                        // TODO: we need a waiting animation!
428 daniel-mar 572
                        $tabcont .= '<form action="javascript:void(0);" onsubmit="return uploadXmlFileOnSubmit(this);" enctype="multipart/form-data" id="uploadXmlFileForm">';
420 daniel-mar 573
                        $tabcont .= '<div>'._L('Choose XML file here').':<input type="file" name="userfile" value="" id="userfile">';
574
                        $tabcont .= '<br><input type="submit" value="'._L('Import XML').'"></div>';
575
                        $tabcont .= '</form>';
576
                        $tabcont .= '<br><p>'._L('Attention: Do not use this XML Export/Import to exchange, backup or restore data between OIDplus systems!<br>It will cause various loss of information, e.g. because Non-OIDs like GUIDs are converted in OIDs and can\'t be converted back.').'</p>';
577
                        $tabcont .= '<h2>'._L('Comparison with oid-info.com').'</h2>';
578
                        $tabcont .= '<p><a '.OIDplus::gui()->link('oidplus:oidinfo_compare_import').'>'._L('List OIDs at oid-info.com which are missing in your system').'</a></p>';
579
                        $out['text'] .= OIDplus::gui()->tabContentPage('import', $tabcont, $tab === 'import');
580
                        $out['text'] .= OIDplus::gui()->tabContentEnd();
581
                        // ---------------- Tab control END
327 daniel-mar 582
 
420 daniel-mar 583
                        $out['text'] .= '</div></div><script>document.getElementById("dataTransferArea").style.visibility = "visible";</script>';
327 daniel-mar 584
                }
61 daniel-mar 585
        }
586
 
106 daniel-mar 587
        public function tree(&$json, $ra_email=null, $nonjs=false, $req_goto='') {
281 daniel-mar 588
                if (!OIDplus::authUtils()::isAdminLoggedIn()) return false;
327 daniel-mar 589
 
61 daniel-mar 590
                if (file_exists(__DIR__.'/treeicon.png')) {
241 daniel-mar 591
                        $tree_icon = OIDplus::webpath(__DIR__).'treeicon.png';
61 daniel-mar 592
                } else {
593
                        $tree_icon = null; // default icon (folder)
594
                }
595
 
596
                $json[] = array(
327 daniel-mar 597
                        'id' => 'oidplus:datatransfer',
61 daniel-mar 598
                        'icon' => $tree_icon,
360 daniel-mar 599
                        'text' => _L('Data Transfer')
61 daniel-mar 600
                );
104 daniel-mar 601
 
602
                return true;
61 daniel-mar 603
        }
108 daniel-mar 604
 
605
        public function tree_search($request) {
606
                return false;
607
        }
139 daniel-mar 608
 
609
        public static function outputXML($only_non_existing) {
303 daniel-mar 610
                // This file contains class OIDInfoAPI.
611
                // We cannot include this in init(), because the init
612
                // of the registration plugin (OIDplusPageAdminRegistration) uses
613
                // OIDplusPageAdminOIDInfoExport::outputXML() before
614
                // OIDplusPageAdminOIDInfoExport::init() ,
615
                // because OIDplusPageAdminRegistration::init() comes first sometimes.
616
                require_once __DIR__ . '/oidinfo_api.inc.php';
327 daniel-mar 617
 
139 daniel-mar 618
                $oa = new OIDInfoAPI();
619
                $oa->addSimplePingProvider('viathinksoft.de:49500');
620
 
621
                $email = OIDplus::config()->getValue('admin_email');
622
                if (empty($email)) $email = 'unknown@example.com';
623
 
360 daniel-mar 624
                echo $oa->xmlAddHeader(OIDplus::config()->getValue('system_title'), isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'Export interface', $email); // do not translate
139 daniel-mar 625
 
626
                $params['allow_html'] = true;
627
                $params['allow_illegal_email'] = true; // It should be enabled, because the creator could have used some kind of human-readable anti-spam technique
628
                $params['soft_correct_behavior'] = OIDInfoAPI::SOFT_CORRECT_BEHAVIOR_NONE;
629
                $params['do_online_check'] = false; // Flag to disable this online check, because it generates a lot of traffic and runtime.
630
                $params['do_illegality_check'] = true;
631
                $params['do_simpleping_check'] = $only_non_existing;
632
                $params['auto_extract_name'] = '';
633
                $params['auto_extract_url'] = '';
634
                $params['always_output_comment'] = false;
635
                $params['creation_allowed_check'] = $only_non_existing;
636
                $params['tolerant_htmlentities'] = true;
637
                $params['ignore_xhtml_light'] = false;
638
 
639
                $nonConfidential = OIDplusObject::getAllNonConfidential();
181 daniel-mar 640
                natsort($nonConfidential);
139 daniel-mar 641
 
642
                foreach ($nonConfidential as $id) {
261 daniel-mar 643
                        $res = OIDplus::db()->query("select * from ###objects where id = ?", array($id));
236 daniel-mar 644
                        if ($row = $res->fetch_object()) {
139 daniel-mar 645
                                $elements['identifier'] = array();
261 daniel-mar 646
                                $res2 = OIDplus::db()->query("select * from ###asn1id where oid = ?", array($row->id));
236 daniel-mar 647
                                while ($row2 = $res2->fetch_object()) {
139 daniel-mar 648
                                        $elements['identifier'][] = $row2->name; // 'unicode-label' is currently not in the standard format (oid.xsd)
649
                                }
650
 
651
                                $elements['unicode-label'] = array();
261 daniel-mar 652
                                $res2 = OIDplus::db()->query("select * from ###iri where oid = ?", array($row->id));
236 daniel-mar 653
                                while ($row2 = $res2->fetch_object()) {
139 daniel-mar 654
                                        $elements['unicode-label'][] = $row2->name;
655
                                }
656
 
657
                                if (!empty($row->title)) {
658
                                        $elements['description'] = $row->title;
659
                                        $elements['information'] = $row->description;
660
                                        if (trim($row->title) == trim(strip_tags($row->description))) {
661
                                                $elements['information'] = '';
662
                                        }
663
                                } else if (isset($elements['identifier'][0])) {
664
                                        $elements['description'] = '"'.$elements['identifier'][0].'"';
665
                                        $elements['information'] = $row->description;
666
                                } else if (isset($elements['unicode-label'][0])) {
667
                                        $elements['description'] = '"'.$elements['unicode-label'][0].'"';
668
                                        $elements['information'] = $row->description;
669
                                } else if (!empty($row->description)) {
670
                                        $elements['description'] = $row->description;
671
                                        $elements['information'] = '';
204 daniel-mar 672
                                } else if (!empty($row->comment)) {
673
                                        $elements['description'] = $row->comment;
674
                                        $elements['information'] = '';
139 daniel-mar 675
                                } else {
360 daniel-mar 676
                                        $elements['description'] = '<i>No description available</i>'; // do not translate
139 daniel-mar 677
                                        $elements['information'] = '';
678
                                }
679
 
680
                                if ($elements['information'] != '') {
681
                                        $elements['information'] .= '<br/><br/>';
682
                                }
683
 
360 daniel-mar 684
                                $elements['information'] .= 'See <a href="'.OIDplus::getSystemUrl(false).'?goto='.urlencode($id).'">more information</a>.'; // do not translate
139 daniel-mar 685
 
686
                                if (explode(':',$id,2)[0] != 'oid') {
360 daniel-mar 687
                                        $elements['information'] = "Object: $id\n\n" . $elements['information']; // do not translate
139 daniel-mar 688
                                }
689
 
690
                                $elements['description'] = self::repair_relative_links($elements['description']);
691
                                $elements['information'] = self::repair_relative_links($elements['information']);
692
 
693
                                $elements['first-registrant']['first-name'] = '';
694
                                $elements['first-registrant']['last-name'] = '';
695
                                $elements['first-registrant']['address'] = '';
696
                                $elements['first-registrant']['email'] = '';
697
                                $elements['first-registrant']['phone'] = '';
698
                                $elements['first-registrant']['fax'] = '';
699
                                $elements['first-registrant']['creation-date'] = self::_formatdate($row->created);
700
 
182 daniel-mar 701
                                $elements['current-registrant']['first-name'] = '';
139 daniel-mar 702
                                $elements['current-registrant']['last-name'] = '';
703
                                $elements['current-registrant']['email'] = $row->ra_email;
704
                                $elements['current-registrant']['phone'] = '';
705
                                $elements['current-registrant']['fax'] = '';
706
                                $elements['current-registrant']['address'] = '';
251 daniel-mar 707
 
261 daniel-mar 708
                                $res2 = OIDplus::db()->query("select * from ###ra where email = ?", array($row->ra_email));
251 daniel-mar 709
                                if ($res2->num_rows() > 0) {
710
                                        $row2 = $res2->fetch_object();
267 daniel-mar 711
 
139 daniel-mar 712
                                        $tmp = array();
182 daniel-mar 713
                                        if (!empty($row2->personal_name)) {
714
                                                $name_ary = split_firstname_lastname($row2->personal_name);
715
                                                $elements['current-registrant']['first-name'] = $name_ary[0];
716
                                                $elements['current-registrant']['last-name']  = $name_ary[1];
717
                                                if (!empty($row2->ra_name)       ) $tmp[] = $row2->ra_name;
718
                                                if (!empty($row2->office)        ) $tmp[] = $row2->office;
719
                                                if (!empty($row2->organization)  ) $tmp[] = $row2->organization;
720
                                        } else {
721
                                                $elements['current-registrant']['first-name'] = $row2->ra_name;
722
                                                $elements['current-registrant']['last-name']  = '';
723
                                                if (!empty($row2->personal_name) ) $tmp[] = $row2->personal_name;
724
                                                if (!empty($row2->office)        ) $tmp[] = $row2->office;
725
                                                if (!empty($row2->organization)  ) $tmp[] = $row2->organization;
726
                                        }
727
 
728
                                        if ((count($tmp) > 0) && ($tmp[0] == $row2->ra_name)) array_shift($tmp);
729
                                        array_unique($tmp);
730
 
139 daniel-mar 731
                                        if (!$row2->privacy) {
732
                                                if (!empty($row2->street))   $tmp[] = $row2->street;
733
                                                if (!empty($row2->zip_town)) $tmp[] = $row2->zip_town;
734
                                                if (!empty($row2->country))  $tmp[] = $row2->country;
735
                                                $elements['current-registrant']['phone'] = !empty($row2->phone) ? $row2->phone : $row2->mobile;
736
                                                $elements['current-registrant']['fax'] = $row2->fax;
737
                                        }
267 daniel-mar 738
                                        if (empty($row2->zip_town) && empty($row2->country)) {
739
                                                // The address is useless if we do neither know city nor country
740
                                                // Ignore it
741
                                                $elements['current-registrant']['address'] = '';
742
                                        } else {
743
                                                $elements['current-registrant']['address'] = implode("<br/>", $tmp);
744
                                        }
139 daniel-mar 745
                                }
746
                                $elements['current-registrant']['modification-date'] = self::_formatdate($row->updated);
747
 
748
                                // Request from O.D. 20 May 2019: First registrant should not be empty (especially for cases where Creation and Modify Dates are the same)
749
                                // Actually, this is a problem because we don't know the first registrant.
750
                                // However, since oidinfo gets their XML very fast (if using registration), it is likely that the reported RA is still the same...
751
                                // ... and changes at the RA are not reported to oid-info.com anyways - the XML is only for creation
752
 
753
                                $elements['first-registrant']['first-name'] = $elements['current-registrant']['first-name'];
754
                                $elements['first-registrant']['last-name']  = $elements['current-registrant']['last-name'];
755
                                $elements['first-registrant']['address']    = $elements['current-registrant']['address'];
756
                                $elements['first-registrant']['email']      = $elements['current-registrant']['email'];
757
                                $elements['first-registrant']['phone']      = $elements['current-registrant']['phone'];
758
                                $elements['first-registrant']['fax']        = $elements['current-registrant']['fax'];
759
 
760
                                $elements['current-registrant']['first-name'] = '';
761
                                $elements['current-registrant']['last-name'] = '';
762
                                $elements['current-registrant']['address'] = '';
763
                                $elements['current-registrant']['email'] = '';
764
                                $elements['current-registrant']['phone'] = '';
765
                                $elements['current-registrant']['fax'] = '';
766
                                $elements['current-registrant']['modification-date'] = '';
767
 
768
                                // End request O.D. 20 May 2019
769
 
770
                                $obj = OIDplusObject::parse($row->id);
195 daniel-mar 771
 
772
                                list($ns,$id) = explode(':',$obj->nodeId());
773
                                if ($ns == 'oid') {
774
                                        echo $oa->createXMLEntry($id, $elements, $params, $comment=$obj->nodeId());
406 daniel-mar 775
                                } else {
776
                                        $alt_ids = $obj->getAltIds(); // TODO: slow!
777
                                        foreach ($alt_ids as $alt_id) {
778
                                                $ns = $alt_id->getNamespace();
779
                                                $id = $alt_id->getId();
780
                                                $desc = $alt_id->getDescription();
781
                                                if ($ns == 'oid') {
782
                                                        if (strpos($id, '2.25.') === 0) continue; // don't spam the uuid arc with GUID objects
783
                                                        echo $oa->createXMLEntry($id, $elements, $params, $comment=$obj->nodeId());
784
                                                }
193 daniel-mar 785
                                        }
786
                                }
139 daniel-mar 787
                        }
788
                }
789
 
790
                echo $oa->xmlAddFooter();
791
        }
792
 
793
        private static function _formatdate($str) {
794
                $str = explode(' ',$str)[0];
795
                if ($str == '0000-00-00') $str = '';
796
                return $str;
797
        }
798
 
799
        private static function repair_relative_links($str) {
800
                $str = preg_replace_callback('@(href\s*=\s*([\'"]))(.+)(\\2)@ismU', function($treffer) {
801
                        $url = $treffer[3];
182 daniel-mar 802
                        if ((stripos($url,'http:') !== 0) && (stripos($url,'https:') !== 0) && (stripos($url,'ftp:') !== 0)) {
803
                                if (stripos($url,'www.') === 0) {
139 daniel-mar 804
                                        $url .= 'http://' . $url;
805
                                } else {
227 daniel-mar 806
                                        $url = OIDplus::getSystemUrl() . $url;
139 daniel-mar 807
                                }
808
                        }
809
                        return $treffer[1].$url.$treffer[4];
810
                }, $str);
811
                return $str;
812
        }
327 daniel-mar 813
 
814
        private static function split_address_country($address) {
815
                global $oidinfo_countries;
816
                $ary = explode("\n", $address);
817
                $last_line = array_pop($ary);
818
                $rest = implode("\n", $ary);
819
                if (isset($oidinfo_countries[$last_line])) {
820
                        return array($rest, $oidinfo_countries[$last_line]);
821
                } else {
822
                        return array($rest."\n".$last_line, '');
823
                }
824
        }
825
 
826
        private static function split_name($name) {
827
                // uses regex that accepts any word character or hyphen in last name
828
                // https://stackoverflow.com/questions/13637145/split-text-string-into-first-and-last-name-in-php
829
                $name = trim($name);
830
                $last_name = (strpos($name, ' ') === false) ? '' : preg_replace('#.*\s([\w-]*)$#', '$1', $name);
462 daniel-mar 831
                $first_name = trim( preg_replace('#'.preg_quote($last_name,'#').'#', '', $name ) );
327 daniel-mar 832
                return array($first_name, $last_name);
833
        }
834
 
835
        /*protected*/ const ORPHAN_IGNORE = 0;
836
        /*protected*/ const ORPHAN_AUTO_DEORPHAN = 1;
837
        /*protected*/ const ORPHAN_DISALLOW_ORPHANS = 2;
838
 
839
        protected function oidinfoImportXML($xml_contents, &$errors, $replaceExistingOIDs=false, $orphan_mode=self::ORPHAN_AUTO_DEORPHAN) {
420 daniel-mar 840
                // TODO: Implement RA import (let the user decide)
841
                // TODO: Let the user decide about $replaceExistingOIDs
842
                // TODO: Let the user decide if "created=now" should be set (this is good when the XML files is created by the user itself to do bulk-inserts)
327 daniel-mar 843
 
844
                $xml_contents = str_replace('<description>', '<description><![CDATA[', $xml_contents);
845
                $xml_contents = str_replace('</description>', ']]></description>', $xml_contents);
846
 
847
                $xml_contents = str_replace('<information>', '<information><![CDATA[', $xml_contents);
848
                $xml_contents = str_replace('</information>', ']]></information>', $xml_contents);
849
 
850
                $xml = @simplexml_load_string($xml_contents);
851
 
852
                $count_already_existing = 0;
853
                $count_errors = 0;
854
                $count_warnings = 0;
855
 
856
                if (!$xml) {
360 daniel-mar 857
                        $errors[] = _L('Cannot read XML data. The XML file is probably invalid.');
327 daniel-mar 858
                        $count_errors++;
859
                        return array(0, 0, 1, 0);
860
                }
861
 
862
                $ok_oids = array();
863
 
864
                foreach ($xml->oid as $xoid) {
865
 
866
                        if (isset($xoid->{'dot-notation'})) {
867
                                $dot_notation = $xoid->{'dot-notation'}->__toString();
868
                        } else if (isset($xoid->{'asn1-notation'})) {
869
                                $dot_notation = asn1_to_dot($xoid->{'asn1-notation'}->__toString());
870
                        } else {
360 daniel-mar 871
                                $errors[] = _L('Cannot find dot notation because fields asn1-notation and dot-notation are both not existing');
327 daniel-mar 872
                                $count_errors++;
873
                                continue;
874
                        }
875
 
876
                        $id = "oid:$dot_notation";
877
                        $title = isset($xoid->{'description'}) ? $xoid->{'description'}->__toString() : '';
878
                        $info = isset($xoid->{'description'}) ? $xoid->{'information'}->__toString() : '';
879
 
880
                        if (isset($xoid->{'current-registrant'}->email)) {
881
                                $ra = $xoid->{'current-registrant'}->email->__toString();
882
                        } else if (isset($xoid->{'first-registrant'}->email)) {
883
                                $ra = $xoid->{'first-registrant'}->email->__toString();
884
                        } else {
885
                                $ra = '';
886
                        }
887
 
888
                        if (!oid_valid_dotnotation($dot_notation, false, false)) {
360 daniel-mar 889
                                $errors[] = _L('Ignored OID %1 because its dot notation is illegal or was not found',$dot_notation);
327 daniel-mar 890
                                $count_errors++;
891
                                continue;
892
                        }
893
 
894
                        $parent = 'oid:'.oid_up($dot_notation);
895
 
896
                        if ($orphan_mode === self::ORPHAN_DISALLOW_ORPHANS) {
897
                                $res = OIDplus::db()->query("select * from ###objects where id = ?", array($parent));
898
                                if ($res->num_rows() === 0) {
360 daniel-mar 899
                                        $errors[] = _L('Cannot import %1, because its parent is not in the database.',$dot_notation);
327 daniel-mar 900
                                        $count_errors++;
901
                                        continue;
902
                                }
903
                        }
904
 
905
                        $res = OIDplus::db()->query("select * from ###objects where id = ?", array($id));
906
                        if ($res->num_rows() > 0) {
907
                                if ($replaceExistingOIDs) {
908
                                        // TODO: better do this (and the following insert) as transaction
909
                                        OIDplus::db()->query("delete from ###asn1id where oid = ?", array($id));
910
                                        OIDplus::db()->query("delete from ###iri where oid = ?", array($id));
911
                                        OIDplus::db()->query("delete from ###objects where id = ?", array($id));
912
                                } else {
913
                                        //$errors[] = "Ignore OID '$dot_notation' because it already exists";
914
                                        //$count_errors++;
915
                                        $count_already_existing++;
916
                                        continue;
917
                                }
918
                        }
919
 
920
                        OIDplus::db()->query("insert into ###objects (id, parent, title, description, confidential, ra_email) values (?, ?, ?, ?, ?, ?)", array($id, $parent, $title, $info, 0, $ra));
921
 
922
                        $this_oid_has_warnings = false;
923
 
924
                        // ---------------------------------------------------------------------
925
 
926
                        $asn1ids = array();
927
                        if (isset($xoid->{'identifier'})) {
928
                                $asn1ids[] = $xoid->{'identifier'}->__toString();
929
                        }
930
                        if (isset($xoid->{'asn1-notation'})) {
931
                                $last_id = asn1_last_identifier($xoid->{'asn1-notation'}->__toString());
932
                                if ($last_id) {
933
                                        $asn1ids[] = $last_id;
934
                                }
935
                        }
936
                        if (isset($xoid->{'synonymous-identifier'})) {
937
                                foreach ($xoid->{'synonymous-identifier'} as $synid) {
938
                                        $asn1ids[] = $synid->__toString();
939
                                }
940
                        }
941
                        $asn1ids = array_unique($asn1ids);
942
                        foreach ($asn1ids as $asn1id) {
943
                                if (!oid_id_is_valid($asn1id)) {
360 daniel-mar 944
                                        $errors[] = _L('Warning').' ['._L('OID %1',$dot_notation).']: '._L('Ignored alphanumeric identifier %1, because it is invalid',$asn1id);
327 daniel-mar 945
                                        $this_oid_has_warnings = true;
946
                                } else {
947
                                        OIDplus::db()->query("delete from ###asn1id where oid = ? and name = ?", array($id, $asn1id));
948
                                        OIDplus::db()->query("insert into ###asn1id (oid, name) values (?, ?)", array($id, $asn1id));
949
                                }
950
                        }
951
 
952
                        // ---------------------------------------------------------------------
953
 
954
                        if (isset($xoid->{'unicode-label'})) {
955
                                $iris = array();
956
                                foreach ($xoid->{'unicode-label'} as $iri) {
957
                                        $iris[] = $iri->__toString();
958
                                }
959
                                $iris = array_unique($iris);
960
                                foreach ($iris as $iri) {
961
                                        if (!iri_arc_valid($iri, false)) {
360 daniel-mar 962
                                                $errors[] = _L('Warning').' ['._L('OID %1',$dot_notation).']: '._L('Ignored Unicode label %1, because it is invalid',$iri);
327 daniel-mar 963
                                                $this_oid_has_warnings = true;
964
                                        } else {
965
                                                OIDplus::db()->query("delete from ###iri where oid = ? and name = ?", array($id, $iri));
966
                                                OIDplus::db()->query("insert into ###iri (oid, name) values (?, ?)", array($id, $iri));
967
                                        }
968
                                }
969
                        }
970
 
971
                        if ($this_oid_has_warnings) $count_warnings++;
972
                        $ok_oids[] = $id;
973
                }
974
 
975
                // De-orphanize
976
                //if ($orphan_mode === self::ORPHAN_AUTO_DEORPHAN) OIDplus::db()->query("update ###objects set parent = 'oid:' where parent like 'oid:%' and parent not in (select id from ###objects)");
977
                foreach ($ok_oids as $id) {
978
                        // De-orphanize if neccessary
979
                        if ($orphan_mode === self::ORPHAN_AUTO_DEORPHAN) {
980
                                $res = OIDplus::db()->query("select * from ###objects where id = ? and parent not in (select id from ###objects)", array($id));
981
                                if ($res->num_rows() > 0) {
360 daniel-mar 982
                                        $errors[] = _L("%1 was de-orphaned (placed as root OID) because its parent is not existing.",$id);
327 daniel-mar 983
                                        $count_warnings++;
984
                                        OIDplus::db()->query("update ###objects set parent = 'oid:' where id = ? and parent not in (select id from ###objects)", array($id));
985
                                }
986
                        }
987
 
988
                        // We do the logging at the end, otherwise SUPOIDRA() might not work correctly if the OIDs were not imported in order or if there were orphans
989
                        OIDplus::logger()->log("[INFO]OID($id)+[INFO]SUPOID($id)+[INFO]SUPOIDRA($id)!/[INFO]A!", "Object '$id' was automatically created by the XML import tool");
990
                }
991
 
992
                $count_imported_oids = count($ok_oids);
993
 
994
                return array($count_imported_oids, $count_already_existing, $count_errors, $count_warnings);
995
 
996
        }
997
 
366 daniel-mar 998
}