json(['message' => ctrans('texts.self_update_not_available')], 403); } nlog('Test filesystem is writable'); $this->testWritable(); nlog('Clear cache directory'); $this->clearCacheDir(); nlog('copying release file'); if (copy($this->getDownloadUrl(), storage_path("app/{$this->filename}"))) { nlog('Copied file from URL'); } else { return response()->json(['message' => 'Download not yet available. Please try again shortly.'], 410); } nlog('Finished copying'); $file = Storage::disk('local')->path($this->filename); nlog('Extracting tar'); $phar = new \PharData($file); $phar->extractTo(base_path(), null, true); nlog('Finished extracting files'); unlink($file); nlog('Deleted release zip file'); foreach ($this->purge_file_list as $purge_file_path) { $purge_file = base_path($purge_file_path); if (file_exists($purge_file)) { unlink($purge_file); } } nlog('Removing cache files'); Artisan::call('clear-compiled'); Artisan::call('route:clear'); Artisan::call('view:clear'); Artisan::call('migrate', ['--force' => true]); Artisan::call('config:clear'); $this->buildCache(true); nlog('Called Artisan commands'); return response()->json(['message' => 'Update completed'], 200); } private function clearCacheDir() { $directoryIterator = new \RecursiveDirectoryIterator(base_path('bootstrap/cache'), \RecursiveDirectoryIterator::SKIP_DOTS); foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) { unlink(base_path('bootstrap/cache/').$file->getFileName()); $file = null; } $directoryIterator = null; } private function testWritable() { $directoryIterator = new \RecursiveDirectoryIterator(base_path(), \RecursiveDirectoryIterator::SKIP_DOTS); foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) { if (strpos($file->getPathname(), '.git') !== false) { continue; } if ($file->isFile() && ! $file->isWritable()) { nlog("Cannot update system because {$file->getFileName()} is not writable"); throw new FilePermissionsFailure("Cannot update system because {$file->getFileName()} is not writable"); } $file = null; } $directoryIterator = null; return true; } public function checkVersion() { return trim(file_get_contents(config('ninja.version_url'))); } private function getDownloadUrl() { $version = $this->checkVersion(); return "https://github.com/invoiceninja/invoiceninja/releases/download/v{$version}/invoiceninja.tar"; } }