<?php declare(strict_types=1); namespace uib\ub\loadspeakr; use ARC2; use Exception; define("LS", "http://lodspeakr.org/lda/"); define("SKOS", "http://www.w3.org/2004/02/skos/core#"); define("RDF", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); define("DC", "http://purl.org/dc/terms/"); define("CNT", "http://www.w3.org/2011/content#"); define("RDFS", "http://www.w3.org/2000/01/rdf-schema#"); define("FILE", "settings.inc.php"); final class Importer { private $basedir; private $external_basedir; private Configuration $configuration; public function __construct(Configuration $configuration) { $this->configuration = $configuration; } public function run(): void { set_time_limit(0); error_reporting(E_ERROR); if (is_file(FILE)) { echo "There is an existing " . FILE . " file on this installation. Please remove it before importing a new one"; exit(0); } if (!isset($_GET['import']) && !isset($_POST['importtext'])) { $this->showInterface(); exit(0); } if (!is_writable('.')) { echo 'The webserver needs write permissions in "lodspeakr/" "lodspeakr/models/" and "lodspeakr/views/" dirs to import settings.'; exit(0); } echo $this->external_basedir; $parser = ARC2::getTurtleParser(); if (isset($_GET['import'])) { $parser->parse($_GET['import']); $this->external_basedir = str_replace('export', '', $_GET['import']); } elseif (isset($_POST['importtext'])) { $parser->parse(RDF, $_POST['importtext']); } else { HTTPStatus::send500(''); } $triples = $parser->getTriples(); $appArr = $this->search($triples, null, RDF . 'type', LS . 'Application'); if (!(sizeof($appArr) > 0)) { echo "I can't find an application from the URL given"; exit(0); } $app = $appArr[0]['s']; $this->external_basedir = $app; $compArr = $this->search($triples, null, SKOS . 'broader', $app); $content = "<?\n\$conf['debug'] = false;\n\$conf['mirror_external_uris'] = true;\n\n"; $this->basedir = preg_replace( '/import$/', '', (!empty($_SERVER['HTTPS'])) ? "https://" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] : "http://" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] ); $content .= "\$conf['basedir'] = \"$this->basedir\";\n"; $content .= "\$conf['parentApp'] = \"$app\";\n"; $pwd = getcwd(); $content .= "\$conf['home'] = \"$pwd/\";\n"; $q = $this->search($triples, $app, LS . 'usedParameter', null); $appParams = array(); foreach ($q as $p) { $param = $p['o']; $labelArr = $this->search($triples, $param, RDFS . 'label', null); $label = $labelArr[0]['o']; $format = $this->search($triples, $param, DC . 'hasFormat', null); $cntArr = $this->search($triples, $format[0]['o'], CNT . 'chars', null); $cnt = $cntArr[0]['o']; $appParams[$label] = $cnt; } foreach ($appParams as $k => $v) { $content .= "\$conf['$k'] = \"$v\";\n"; } $content .= "/*ATTENTION: By default this application is available to * be exported and copied (its configuration) * by others. If you do not want that, * turn the next option as false */ \$conf['export'] = true;\n\n"; //Components foreach ($compArr as $v) { $component = $v['s']; $componentTypeArr = $this->search($triples, $component, RDF . 'type', null); $compType = $componentTypeArr[0]['o']; $params = array(); $q = $this->search($triples, $component, LS . 'usedParameter', null); foreach ($q as $p) { $param = $p['o']; $labelArr = $this->search($triples, $param, RDFS . 'label', null); $label = $labelArr[0]['o']; $format = $this->search($triples, $param, DC . 'hasFormat', null); $cntArr = $this->search($triples, $format[0]['o'], CNT . 'chars', null); $cnt = $cntArr[0]['o']; $params[$label] = $cnt; } $inputs = array(); $q = $this->search($triples, $component, LS . 'usedInput', null); foreach ($q as $p) { $param = $p['o']; $labelArr = $this->search($triples, $param, RDFS . 'label', null); if (sizeof($labelArr) > 0) { $label = $labelArr[0]['o']; $format = $this->search($triples, $param, DC . 'hasFormat', null); $cntArr = $this->search($triples, $format[0]['o'], CNT . 'chars', null); $cnt = $cntArr[0]['o']; $inputs[$label] = $cnt; } } if ($compType == LS . "LodspeakrEndpointManagerComponent") { $content .= $this->createEndpoints($params); } elseif ($compType == LS . "LodspeakrNamespaceManagerComponent") { $content .= $this->createNamespaces($params); } elseif ($compType == LS . "LodspeakrSparqlEndpointRetriever") { $this->createModels($inputs); } elseif ($compType == LS . "LodspeakrStaticElementsComponent") { $this->createStatics($inputs); } elseif ($compType == LS . "LodspeakrVisualComponent") { $this->createViews($inputs); } elseif ($this->configuration->debugMode()) { Logging::log("Component '$component' (of type $compType) not supported", E_USER_WARNING); } } $content .= "?>\n"; try { $fh = fopen(FILE, 'ab'); fwrite($fh, $content); fclose($fh); } catch (Exception $e) { echo 'Caught exception while writing settings: ', $e->getMessage(), "\n"; exit(1); } $this->showFinishing(); } private function createEndpoints($ep) { $endpoints = ""; $conf = $this->configuration->getConfigValue('conf', ''); try { foreach ($ep as $k => $v) { if ($conf['endpoint'][$k] != $v) { $endpoints .= "\$conf[\"endpoint\"][\"$k\"] = \"$v\";\n"; } } $endpoints .= "\n\n"; } catch (Exception $e) { echo 'Caught exception while importing endpoints: ', $e->getMessage(), "\n"; exit(1); } return $endpoints; } private function createNamespaces($ns) { $conf = $this->configuration->getConfigValue('conf', ''); $namespaces = ""; try { foreach ($ns as $k => $v) { if ($conf["ns"][$k] != $v) { if (preg_match("|^" . $this->external_basedir . "|", $v)) { $newns = preg_replace("|^" . $this->external_basedir . "|", $this->basedir, $v); $namespaces .= "\$conf[\"ns\"][\"" . $k . "_ext\"] = \"$newns\";\n"; } $namespaces .= "\$conf[\"ns\"][\"$k\"] = \"$v\";\n"; } } $namespaces .= "\$conf[\"ns\"][\"basedir\"] = \"$this->basedir\";\n"; $namespaces .= "\n\n"; } catch (Exception $e) { echo 'Caught exception while importing namespaces: ', $e->getMessage(), "\n"; exit(1); } return $namespaces; } private function createModels($models): void { try { foreach ($models as $k => $v) { $path = explode("/", $k); for ($i = 0; $i < sizeof($path) - 1; $i++) { if (file_exists($path[$i])) { if (!is_dir($path[$i])) { unlink($path[$i]); if (!mkdir($concurrentDirectory = $path[$i]) && !is_dir($concurrentDirectory)) { throw new \RuntimeException( sprintf('Directory "%s" was not created', $concurrentDirectory) ); } } } elseif (!mkdir($concurrentDirectory = $path[$i]) && !is_dir($concurrentDirectory)) { throw new \RuntimeException( sprintf('Directory "%s" was not created', $concurrentDirectory) ); } chdir($path[$i]); } $fh = fopen(end($path), 'wb'); fwrite($fh, $v); fclose($fh); for ($i = 0; $i < sizeof($path) - 1; $i++) { chdir('..'); } } } catch (Exception $e) { echo 'Caught exception while importing models: ', $e->getMessage(), "\n"; exit(1); } } private function createViews($views): void { try { foreach ($views as $k => $v) { $path = explode("/", $k); for ($i = 0; $i < sizeof($path) - 1; $i++) { if (file_exists($path[$i])) { if (!is_dir($path[$i])) { unlink($path[$i]); if (!mkdir($concurrentDirectory = $path[$i]) && !is_dir($concurrentDirectory)) { throw new \RuntimeException( sprintf('Directory "%s" was not created', $concurrentDirectory) ); } } } elseif (!mkdir($concurrentDirectory = $path[$i]) && !is_dir($concurrentDirectory)) { throw new \RuntimeException( sprintf('Directory "%s" was not created', $concurrentDirectory) ); } chdir($path[$i]); } $fh = fopen(end($path), 'wb'); fwrite($fh, $v); fclose($fh); for ($i = 0; $i < sizeof($path) - 1; $i++) { chdir('..'); } } } catch (Exception $e) { echo 'Caught exception while importing views: ', $e->getMessage(), "\n"; exit(1); } } private function createStatics($statics): void { try { foreach ($statics as $k => $v) { $path = explode("/", $k); for ($i = 0; $i < sizeof($path) - 1; $i++) { if (file_exists($path[$i])) { if (!is_dir($path[$i])) { unlink($path[$i]); if (!mkdir($concurrentDirectory = $path[$i]) && !is_dir($concurrentDirectory)) { throw new \RuntimeException( sprintf('Directory "%s" was not created', $concurrentDirectory) ); } } } elseif (!mkdir($concurrentDirectory = $path[$i]) && !is_dir($concurrentDirectory)) { throw new \RuntimeException( sprintf('Directory "%s" was not created', $concurrentDirectory) ); } chdir($path[$i]); } $fh = fopen(end($path), 'wb'); fwrite($fh, $v); fclose($fh); for ($i = 0; $i < sizeof($path) - 1; $i++) { chdir('..'); } } } catch (Exception $e) { echo 'Caught exception while importing statics: ', $e->getMessage(), "\n"; exit(1); } } private function search($graph, $s = null, $p = null, $o = null): array { $results = array(); foreach ($graph as $v) { $threeOks = 0; /** * Check subject */ if ($s != null) { if ($v['s'] == $s) { $threeOks++; } } else { $threeOks++; } /** * Check predicate. */ if ($p != null) { if ($v['p'] == $p) { $threeOks++; } } else { $threeOks++; } /** * Check object. */ if ($o != null) { if ($v['o'] == $o) { $threeOks++; } } else { $threeOks++; } if ($threeOks == 3) { $results[] = $v; } } return $results; } private function showInterface(): void { $import_url = $this->configuration->getConfigValue('conf' , 'basedir') . 'import'; echo <<<HTML <html lang="eng"> <head> <title>Importing options</title> </head> <body> <h2>Paste application described in LDA</h2> You can paste the data obtained from another LODSPeaKr instance here in the box. You can also automatize this import by adding a parameter '?import=URL' to this page. Usually, the URL will be of the for <pre>https://example.com/export</pre> <form action="$import_url" method="post"> <textarea cols="100" rows="25" name="importtext"></textarea> <input type="submit" value="Import"/> </form> </body> </html> HTML; } private function showFinishing(): void { $base_dir = $this->configuration->getConfigValue('conf' , 'basedir'); echo <<<HTML <html lang="eng"> <head> <title>Finishing import</title> </head> <body> <h2>Import finished</h2> Your new application is ready. Please go to the <a href="$base_dir">home page</a>. </body> </html> HTML; } }