Subversion Repositories oidplus

Rev

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