json(['message' => ctrans('texts.self_update_not_available')], 403); } if(request()->has('tar')) { $this->use_tar = true; $this->filename = 'invoiceninja.tar'; } nlog('Test filesystem is writable'); $this->testWritable(); nlog('Clear cache directory'); $this->clearCacheDir(); nlog('copying release file'); // if (copy($this->getDownloadUrl(), storage_path('app/invoiceninja.zip'))) { 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'); if($this->use_tar) { $file = Storage::disk('local')->path($this->filename); nlog('Extracting tar'); $phar = new \PharData($file); $phar->extractTo(base_path()); nlog('Finished extracting files'); unlink($file); } else { $this->extractUsingZip(); } 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 extractUsingZip() { $file = Storage::disk('local')->path($this->filename); nlog('Extracting zip'); $zipFile = new \PhpZip\ZipFile(); $zipFile->openFile($file); $zipFile->deleteFromName(".htaccess"); $zipFile->rewrite(); $zipFile->extractTo(base_path()); $zipFile->close(); $zipFile = null; unlink($file); } // private function deleteDirectory($dir) // { // if (! file_exists($dir)) { // return true; // } // if (! is_dir($dir) || is_link($dir)) { // return unlink($dir); // } // foreach (scandir($dir) as $item) { // if ($item == '.' || $item == '..') { // continue; // } // if (! $this->deleteDirectory($dir.'/'.$item)) { // if (! $this->deleteDirectory($dir.'/'.$item)) { // return false; // } // } // } // return rmdir($dir); // } // private function postHookUpdate() // { // if (config('ninja.app_version') == '5.3.82') { // Client::withTrashed()->cursor()->each(function ($client) { // $entity_settings = $this->checkSettingType($client->settings); // $entity_settings->md5 = md5(time()); // $client->settings = $entity_settings; // $client->save(); // }); // } // } 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()); } $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"); } } $directoryIterator = null; return true; } public function checkVersion() { return trim(file_get_contents(config('ninja.version_url'))); } private function getDownloadUrl() { $version = $this->checkVersion(); if(request()->has('tar')) return "https://github.com/invoiceninja/invoiceninja/releases/download/v{$version}/invoiceninja.tar"; return "https://github.com/invoiceninja/invoiceninja/releases/download/v{$version}/invoiceninja.zip"; } }