bootstrapDir = dirname(__DIR__); $this->rootDir = dirname(dirname($this->bootstrapDir)); $this->configDir = sprintf('%s/config', dirname(dirname($this->bootstrapDir))); $this->tempDir = sprintf('%s/temp', $this->bootstrapDir); $this->vendorDir = sprintf('%s/vendor', $this->rootDir); $this->viewsDir = sprintf('%s/views', $this->bootstrapDir); chdir($this->rootDir); putenv('HOME=' . $this->rootDir); } public function handleRequest() { if (!isset($_GET['act'])) { $this->view('index', ['appName' => 'Blue Twilight Bootstrapper']); } else { switch (trim($_GET['act'])) { case 'download': $this->download(); return; case 'extract': $this->extract(); return; case 'finalise': $this->finalise(); return; default: throw new \Exception(sprintf('Action \'%s\' was not recognised.', $_GET['act'])); } } } protected function download() { $appConfig = require_once sprintf('%s/app.php', $this->configDir); $servicesConfig = require_once sprintf('%s/services.php', $this->configDir); $versionNumber = sprintf('v%s', $appConfig['version']); $gitea = new GiteaService($servicesConfig['gitea'], $versionNumber); $releaseInfo = $gitea->getSpecificRelease($versionNumber); if (is_null($releaseInfo)) { throw new \Exception(sprintf('No release info found in Gitea for Blue Twilight version \'%s\'', $versionNumber)); } else if (!isset($releaseInfo->assets)) { throw new \Exception(sprintf('No assets found in Gitea for Blue Twilight version \'%s\'', $versionNumber)); } $vendorsPrefix = 'vendors'; $vendorsSuffix = '.tar.gz'; $selectedAsset = null; foreach ($releaseInfo->assets as $asset) { /* Ignore anything that is not "vendors.tar.gz" were the is also optional - e.g. vendors_2.1.2.tar.gz vendors.tar.gz but NOT 2.1.2_vendors.zip */ if (!starts_with($asset->name, $vendorsPrefix) || !ends_with($asset->name, $vendorsSuffix)) { continue; } $selectedAsset = $asset; break; } if (is_null($selectedAsset)) { throw new \Exception(sprintf('No vendors.tar.gz found in Gitea for Blue Twilight version \'%s\'', $versionNumber)); } $targetFileName = $this->getVendorsTempFileName(); $this->downloadFile($selectedAsset->browser_download_url, $targetFileName); $this->json([ 'result' => true, 'fileName' => $targetFileName ]); } protected function extract() { $targetFileName = $this->getVendorsTempFileName(); if (!file_exists($targetFileName) || !is_readable($targetFileName)) { throw new \Exception(sprintf('The file \'%s\' does not exist or is not readable', $targetFileName)); } $phar = new \PharData($targetFileName); $phar->extractTo($this->rootDir, null, true); // We should always have a vendor/autoload.php $vendorsTestFile = $this->getVendorsAutoloadFileName(); if (file_exists($vendorsTestFile)) { $this->json([ 'result' => true, 'testFile' => $vendorsTestFile ]); } else { throw new \Exception('The extraction failed'); } } protected function finalise() { $result = [ 'envFileCreated' => false ]; $result['envFileCreated'] = $this->createEnvFileIfNotExist(); require sprintf('%s/bootstrap/autoload.php', $this->rootDir); $app = require_once sprintf('%s/bootstrap/app.php', $this->rootDir); $kernel = $app->make(\Illuminate\Contracts\Console\Kernel::class); $kernel->bootstrap(); if ($result['envFileCreated']) { Artisan::call('key:generate'); } $kernel->terminate(null, null); $this->json($result); } private function downloadFile($sourceURL, $targetFilename) { $urlHandle = @fopen($sourceURL, 'r'); $tempFilename = @fopen($targetFilename, 'w'); if ($urlHandle === false) { throw new \Exception(sprintf('Failed downloading the file from %s', $sourceURL)); } else if ($tempFilename === false) { throw new \Exception(sprintf('Failed opening the file \'%s\' for writing', $targetFilename)); } while (!feof($urlHandle)) { $buffer = fread($urlHandle, 8192); fwrite($tempFilename, $buffer); } @fclose($urlHandle); @fclose($tempFilename); } private function createEnvFileIfNotExist() { $envFile = $this->getEnvFileName(); if (!file_exists($envFile)) { copy($this->getEnvExampleFileName(), $envFile); return true; } return false; } private function getEnvExampleFileName() { return sprintf('%s/.env.example', $this->rootDir); } private function getEnvFileName() { return sprintf('%s/.env', $this->rootDir); } private function getVendorsAutoloadFileName() { return sprintf('%s/autoload.php', $this->vendorDir); } private function getVendorsTempFileName() { return sprintf('%s/vendors.tar.gz', $this->tempDir); } private function json($data) { echo json_encode($data); } private function view($name, array $viewData = []) { $viewFile = sprintf('%s/%s.php', $this->viewsDir, $name); if (!file_exists($viewFile) || !is_readable($viewFile)) { throw new \Exception(sprintf('ERROR: View file \'%s\' does not exist.', $viewFile)); } // Provide keys as variables - e.g. $viewData['something'] becomes accessible via $something extract($viewData); require_once $viewFile; } }