Subversion Repositories oidplus

Rev

Rev 1321 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /*
  4.  * OIDplus 2.0
  5.  * Copyright 2019 - 2023 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.  
  20. use ViaThinkSoft\OIDplus\OIDplus;
  21. use ViaThinkSoft\OIDplus\OIDplusGui;
  22. use ViaThinkSoft\OIDplus\OIDplusException;
  23. use ViaThinkSoft\OIDplus\OIDplusHtmlException;
  24.  
  25. header('Content-Type:text/html; charset=UTF-8');
  26.  
  27. require_once __DIR__ . '/../../../../includes/oidplus.inc.php';
  28.  
  29. set_exception_handler(array(OIDplusGui::class, 'html_exception_handler'));
  30.  
  31. @set_time_limit(0);
  32.  
  33. OIDplus::init(true);
  34.  
  35. if (OIDplus::baseConfig()->getValue('DISABLE_PLUGIN_ViaThinkSoft\OIDplus\OIDplusPageAdminNostalgia', false)) {
  36.         throw new OIDplusException(_L('This plugin was disabled by the system administrator!'));
  37. }
  38.  
  39. if (!OIDplus::authUtils()->isAdminLoggedIn()) {
  40.         throw new OIDplusHtmlException(_L('You need to <a %1>log in</a> as administrator.',OIDplus::gui()->link('oidplus:login$admin')), null, 401);
  41. }
  42.  
  43. if (!class_exists('ZipArchive')) {
  44.         throw new OIDplusException(_L('The PHP extension "ZipArchive" needs to be installed to create a ZIP archive with an included database. Otherwise, you can just download the plain program without data.'));
  45. }
  46.  
  47. $dos_ids = array();
  48. $parent_oids = array();
  49. $i = 0;
  50.  
  51. // Root node
  52. $dos_ids[''] = str_pad(strval($i++), 8, '0', STR_PAD_LEFT);
  53. $parent_oids[''] = '';
  54. $iri[''] = array();
  55. $asn1[''] = array();
  56. $title[''] = 'OID Root';
  57. $description[''] = 'Exported by OIDplus 2.0';
  58.  
  59. // Now check all OIDs
  60. $res = OIDplus::db()->query("select * from ###objects where id like 'oid:%'");
  61. $res->naturalSortByField('id');
  62. while ($row = $res->fetch_object()) {
  63.         $oid = substr($row->id, strlen('oid:'));
  64.         $parent_oid = substr($row->parent, strlen('oid:'));
  65.  
  66.         $dos_ids[$oid] = str_pad(strval($i++), 8, '0', STR_PAD_LEFT);
  67.         fill_asn1($oid, $asn1);
  68.         fill_iri($oid, $iri);
  69.         $title[$oid] = vts_utf8_decode($row->title);
  70.         $description[$oid] = vts_utf8_decode($row->description);
  71.  
  72.         if ((oid_len($oid) > 1) && ($parent_oid == '')) {
  73.                 do {
  74.                         $real_parent = oid_len($oid) > 1 ? oid_up($oid) : '';
  75.                         $parent_oids[$oid] = $real_parent;
  76.  
  77.                         if (isset($dos_ids[$real_parent])) break; // did we already handle this parent node?
  78.  
  79.                         $dos_ids[$real_parent] = str_pad(strval($i++), 8, '0', STR_PAD_LEFT);
  80.                         fill_asn1($real_parent, $asn1); // well-known OIDs?
  81.                         fill_iri($real_parent, $iri); // well-known OIDs?
  82.                         $title[$real_parent] = '';
  83.                         $description[$real_parent] = '';
  84.                         $res2 = OIDplus::db()->query("select * from ###objects where id = ?", ["oid:$real_parent"]);
  85.                         while ($row2 = $res2->fetch_object()) {
  86.                                 $title[$real_parent] = vts_utf8_decode($row2->title);
  87.                                 $description[$real_parent] = vts_utf8_decode($row2->description);
  88.                         }
  89.  
  90.                         // next
  91.                         if ($real_parent == '') break;
  92.                         $oid = $real_parent;
  93.                 } while (true);
  94.         } else {
  95.                 $parent_oids[$oid] = $parent_oid;
  96.         }
  97. }
  98.  
  99. $tmp_file = OIDplus::localpath().'userdata/dos_export.zip';
  100.  
  101. $zip = new ZipArchive();
  102. if ($zip->open($tmp_file, ZipArchive::CREATE)!== true) {
  103.         throw new OIDplusException(_L("Cannot open file %1", $tmp_file));
  104. }
  105.  
  106. /**
  107.  * @param string $command
  108.  * @param string $data
  109.  * @return string
  110.  */
  111. function make_line(string $command, string $data): string {
  112.         return $command.$data."\r\n";
  113. }
  114.  
  115. // https://github.com/danielmarschall/oidplus_dos/blob/master/OIDFILE.PAS
  116. const CMD_VERSION         = 'VERS';
  117. const CMD_OWN_ID          = 'SELF';
  118. const CMD_PARENT          = 'SUPR';
  119. const CMD_CHILD           = 'CHLD';
  120. const CMD_ASN1_IDENTIFIER = 'ASN1';
  121. const CMD_UNICODE_LABEL   = 'UNIL';
  122. const CMD_DESCRIPTION     = 'DESC';
  123.  
  124. foreach ($dos_ids as $oid => $dos_id) {
  125.         $cont = make_line(CMD_VERSION, '2022');
  126.  
  127.         $cont .= make_line(CMD_OWN_ID, $dos_id.$oid);
  128.  
  129.         $parent_oid = $parent_oids[$oid];
  130.         $parent_id = $dos_ids[$parent_oid];
  131.         $cont .= make_line(CMD_PARENT, $parent_id.$parent_oid);
  132.  
  133.         foreach ($parent_oids as $child_oid => $parent_oid) {
  134.                 if ($child_oid == '') continue;
  135.                 if ($parent_oid == $oid) {
  136.                         $child_id = $dos_ids[$child_oid];
  137.                         $cont .= make_line(CMD_CHILD, $child_id.$child_oid);
  138.                 }
  139.         }
  140.  
  141.         foreach ($asn1[$oid] as $name) {
  142.                 $cont .= make_line(CMD_ASN1_IDENTIFIER, $name);
  143.         }
  144.  
  145.         foreach ($iri[$oid] as $name) {
  146.                 $cont .= make_line(CMD_UNICODE_LABEL, $name);
  147.         }
  148.  
  149.         $desc_ary1 = handleDesc_dos($title[$oid]);
  150.         $desc_ary2 = handleDesc_dos($description[$oid]);
  151.         $desc_ary = array_merge($desc_ary1, $desc_ary2);
  152.         $prev_line = '';
  153.         foreach ($desc_ary as $line_idx => $line) {
  154.                 if ($line == $prev_line) continue;
  155.                 if ($line_idx >= 10/*DESCEDIT_LINES*/) break;
  156.                 $cont .= make_line(CMD_DESCRIPTION, $line);
  157.                 $prev_line = $line;
  158.         }
  159.  
  160.         //echo "****$dos_id.OID\r\n";
  161.         //echo "$cont\r\n";
  162.  
  163.         $zip->addFromString("$dos_id.OID", $cont);
  164. }
  165.  
  166. $exe_url = 'https://github.com/danielmarschall/oidplus_dos/raw/master/OIDPLUS.EXE';
  167. $exe = url_get_contents($exe_url);
  168. if ($exe === false) {
  169.         throw new OIDplusException(_L("Cannot download the binary file from GitHub (%1)", $exe_url));
  170. }
  171. $zip->addFromString('OIDPLUS.EXE', $exe);
  172.  
  173. $zip->close();
  174.  
  175. if (!headers_sent()) {
  176.         header('Content-Type: application/zip');
  177.         header('Content-Disposition: attachment; filename=oidplus_dos.zip');
  178.         readfile($tmp_file);
  179. }
  180.  
  181. unlink($tmp_file);
  182.  
  183. OIDplus::invoke_shutdown();
  184.  
  185. # ---
  186.  
  187. /**
  188.  * @param string $oid
  189.  * @param array $asn1
  190.  * @return void
  191.  * @throws OIDplusException
  192.  */
  193. function fill_asn1(string $oid, array &$asn1) {
  194.         if (!isset($asn1[$oid])) $asn1[$oid] = array();
  195.         $res = OIDplus::db()->query("select * from ###asn1id where oid = ?", ["oid:$oid"]);
  196.         while ($row = $res->fetch_object()) {
  197.                 $asn1[$oid][] = $row->name;
  198.         }
  199. }
  200.  
  201. /**
  202.  * @param string $oid
  203.  * @param array $iri
  204.  * @return void
  205.  * @throws OIDplusException
  206.  */
  207. function fill_iri(string $oid, array &$iri) {
  208.         if (!isset($iri[$oid])) $iri[$oid] = array();
  209.         $res = OIDplus::db()->query("select * from ###iri where oid = ?", ["oid:$oid"]);
  210.         while ($row = $res->fetch_object()) {
  211.                 $iri[$oid][] = $row->name;
  212.         }
  213. }
  214.  
  215. /**
  216.  * @param string $desc
  217.  * @return array
  218.  */
  219. function handleDesc_dos(string $desc): array {
  220.         $desc = preg_replace('/\<br(\s*)?\/?\>/i', "\n", $desc); // br2nl
  221.         $desc = strip_tags($desc);
  222.         $desc = str_replace('&nbsp;', ' ', $desc);
  223.         $desc = html_entity_decode($desc);
  224.         $desc = str_replace("\r", "", $desc);
  225.         $desc = str_replace("\n", "  ", $desc);
  226.         $desc = str_replace("\t", "  ", $desc);
  227.         $desc = trim($desc);
  228.         $desc_ary = explode("\r\n", wordwrap($desc, 75, "\r\n", true));
  229.         if (implode('',$desc_ary) == '') $desc_ary = array();
  230.         return $desc_ary;
  231. }
  232.