Subversion Repositories oidplus

Rev

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