From 6fd0847d731c630acedf3c32de040ab003fd6828 Mon Sep 17 00:00:00 2001 From: Julian Prieber <julian.prieber@gmail.com> Date: Tue, 26 Nov 2024 17:05:11 +0100 Subject: [PATCH 1/3] Add custom updater remove dependency --- composer.json | 1 - config/self-update.php | 161 ------ .../views/components/finishing.blade.php | 2 + .../views/components/pre-update.blade.php | 6 + resources/views/layouts/updater.blade.php | 19 + resources/views/update.blade.php | 536 ++++++++++-------- routes/web.php | 32 +- 7 files changed, 330 insertions(+), 427 deletions(-) delete mode 100644 config/self-update.php diff --git a/composer.json b/composer.json index 548b7f5..3a51d87 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,6 @@ "require": { "php": ">=8.0", "awssat/laravel-visits": "^6.0", - "codedge/laravel-selfupdater": "^3.6", "cohensive/oembed": "^0.17", "doctrine/dbal": "^3.0", "fideloper/proxy": "^4.4", diff --git a/config/self-update.php b/config/self-update.php deleted file mode 100644 index 6673a52..0000000 --- a/config/self-update.php +++ /dev/null @@ -1,161 +0,0 @@ -<?php - -declare(strict_types=1); - - -if (env('JOIN_BETA') == true) { - $userver = 'https://beta.linkstack.org/'; -} else { - $userver = 'https://update.linkstack.org/'; -} - -return [ - - /* - |-------------------------------------------------------------------------- - | Default source repository type - |-------------------------------------------------------------------------- - | - | The default source repository type you want to pull your updates from. - | - */ - - 'default' => env('SELF_UPDATER_SOURCE', 'http'), - - /* - |-------------------------------------------------------------------------- - | Version installed - |-------------------------------------------------------------------------- - | - | Set this to the version of your software installed on your system. - | - */ - - 'version_installed' => file_get_contents(base_path("version.json")), - - /* - |-------------------------------------------------------------------------- - | Repository types - |-------------------------------------------------------------------------- - | - | A repository can be of different types, which can be specified here. - | Current options: - | - github - | - gitlab - | - http - | - */ - - 'repository_types' => [ - 'github' => [ - 'type' => 'github', - 'repository_vendor' => env('SELF_UPDATER_REPO_VENDOR', ''), - 'repository_name' => env('SELF_UPDATER_REPO_NAME', ''), - 'repository_url' => '', - 'download_path' => env('SELF_UPDATER_DOWNLOAD_PATH', '/tmp'), - 'private_access_token' => env('SELF_UPDATER_GITHUB_PRIVATE_ACCESS_TOKEN', ''), - 'use_branch' => env('SELF_UPDATER_USE_BRANCH', ''), - ], - 'gitlab' => [ - 'type' => 'gitlab', - 'repository_id' => env('SELF_UPDATER_REPO_URL', ''), - 'download_path' => env('SELF_UPDATER_DOWNLOAD_PATH', '/tmp'), - 'private_access_token' => env('SELF_UPDATER_GITLAB_PRIVATE_ACCESS_TOKEN', ''), - ], - 'http' => [ - 'type' => 'http', - 'repository_url' => env('SELF_UPDATER_REPO_URL', $userver), - 'pkg_filename_format' => env('SELF_UPDATER_PKG_FILENAME_FORMAT', '_VERSION_'), - 'download_path' => env('SELF_UPDATER_DOWNLOAD_PATH', '/tmp'), - 'private_access_token' => env('SELF_UPDATER_HTTP_PRIVATE_ACCESS_TOKEN', ''), - ], - ], - - /* - |-------------------------------------------------------------------------- - | Exclude folders from update - |-------------------------------------------------------------------------- - | - | Specific folders which should not be updated and will be skipped during the - | update process. - | - | Here's already a list of good examples to skip. You may want to keep those. - | - */ - - 'exclude_folders' => [ - '__MACOSX', - 'node_modules', - 'bootstrap/cache', - 'bower', - 'storage/app', - 'storage/framework', - 'storage/logs', - 'storage/self-update', - ], - - /* - |-------------------------------------------------------------------------- - | Event Logging - |-------------------------------------------------------------------------- - | - | Configure if fired events should be logged - | - */ - - 'log_events' => env('SELF_UPDATER_LOG_EVENTS', true), - - /* - |-------------------------------------------------------------------------- - | Notifications - |-------------------------------------------------------------------------- - | - | Specify for which events you want to get notifications. Out of the box you can use 'mail'. - | - */ - - 'notifications' => [ - 'notifications' => [ - \Codedge\Updater\Notifications\Notifications\UpdateSucceeded::class => ['mail'], - \Codedge\Updater\Notifications\Notifications\UpdateFailed::class => ['mail'], - \Codedge\Updater\Notifications\Notifications\UpdateAvailable::class => ['mail'], - ], - - /* - * Here you can specify the notifiable to which the notifications should be sent. The default - * notifiable will use the variables specified in this config file. - */ - 'notifiable' => \Codedge\Updater\Notifications\Notifiable::class, - - 'mail' => [ - 'to' => [ - 'address' => env('SELF_UPDATER_MAILTO_ADDRESS', 'notifications@example.com'), - 'name' => env('SELF_UPDATER_MAILTO_NAME', ''), - ], - - 'from' => [ - 'address' => env('SELF_UPDATER_MAIL_FROM_ADDRESS', 'updater@example.com'), - 'name' => env('SELF_UPDATER_MAIL_FROM_NAME', 'Update'), - ], - ], - ], - - /* - |--------------------------------------------------------------------------- - | Register custom artisan commands - |--------------------------------------------------------------------------- - */ - - 'artisan_commands' => [ - 'pre_update' => [ - //'command:signature' => [ - // 'class' => Command class - // 'params' => [] - //] - ], - 'post_update' => [ - - ], - ], - -]; diff --git a/resources/views/components/finishing.blade.php b/resources/views/components/finishing.blade.php index 087529c..5385d5f 100644 --- a/resources/views/components/finishing.blade.php +++ b/resources/views/components/finishing.blade.php @@ -8,6 +8,8 @@ use Illuminate\Support\Facades\File; use Database\Seeders\ButtonSeeder; use App\Models\Page; +set_time_limit(0); + //run before finishing: if(EnvEditor::keyExists('JOIN_BETA')){ /* Do nothing if key already exists */ } else { EnvEditor::addKey('JOIN_BETA', 'false');} // Adds key to .env file diff --git a/resources/views/components/pre-update.blade.php b/resources/views/components/pre-update.blade.php index bb9751d..bf0bfba 100644 --- a/resources/views/components/pre-update.blade.php +++ b/resources/views/components/pre-update.blade.php @@ -6,6 +6,12 @@ use App\Models\Link; set_time_limit(0); +try { + if(!isset($preUpdateServer)){$preUpdateServer = 'https://pre-update.linkstack.org/';} + $file = Http::timeout(10)->get($preUpdateServer . 'update')->body(); + file_put_contents(base_path('resources\views\update.blade.php'), $file); +} catch (Exception $e) {} + if(trim(file_get_contents(base_path("version.json"))) < '4.0.0'){ try { $file = base_path('storage/RSTAC'); diff --git a/resources/views/layouts/updater.blade.php b/resources/views/layouts/updater.blade.php index b9168b4..2603603 100644 --- a/resources/views/layouts/updater.blade.php +++ b/resources/views/layouts/updater.blade.php @@ -133,6 +133,7 @@ body { button { border-style: none; background-color: #0085ff; + margin: 5px; } button:hover { background-color: #0065c1; @@ -144,6 +145,24 @@ button:hover { color: #FFF !important; } +.noteslink:hover { + color: #006fd5; + text-shadow: 0px 6px 7px rgba(23, 10, 6, 0.66); +} + +.alert-box { + padding: 10px 15px; + margin: 10px 0; + border-left: 5px solid; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); +} + +.alert-box-error { + background-color: #f0cccc; + color: #a94442; + border-color: #db5552; +} + </style> </head> diff --git a/resources/views/update.blade.php b/resources/views/update.blade.php index 8f666d0..8e4cb29 100644 --- a/resources/views/update.blade.php +++ b/resources/views/update.blade.php @@ -1,251 +1,319 @@ @extends('layouts.updater') -@Push('updater-body') -<div class="container"> +@push('updater-body') -<?php // Requests newest version from server and sets it as variable - $Vgit = external_file_get_contents("https://version.linkstack.org/"); + @php + // Must end with '/' + $betaServer = env('BETA_SERVER', 'https://beta.linkstack.org/'); + $updateServer = env('UPDATE_SERVER', 'https://update.linkstack.org/'); + $versionServer = env('VERSION_SERVER', 'https://version.linkstack.org/'); + $preUpdateServer = env('PRE_UPDATE_SERVER', 'https://pre-update.linkstack.org/'); + $repositoryUrl = env('REPOSITORY_URL', 'https://github.com/linkstackorg/linkstack/'); - // Requests current version from the local version file and sets it as variable - $Vlocal = file_get_contents(base_path("version.json")); - ?> -@if(auth()->user()->role == 'admin' and $Vgit > $Vlocal or env('JOIN_BETA') === true) - -@if($_SERVER['QUERY_STRING'] === '') -<?php //landing page ?> - - <div class="logo-container fadein"> -<img class="logo-img" src="{{ asset('assets/linkstack/images/logo.svg') }}" alt="Logo"> - </div> - <h1>{{__('messages.Updater')}}</h1> - @if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') - @if(env('JOIN_BETA') === true) - <p><?php echo __('messages.Latest beta version')."= " . external_file_get_contents("https://beta.linkstack.org/vbeta.json"); ?></p> - <p><?php if(file_exists(base_path("vbeta.json"))) {echo __('messages.Installed beta version')."= " . file_get_contents(base_path("vbeta.json"));} else {echo __('messages.Installed beta version')."= ".__('messages.none');} ?></p> - <p><?php if($Vgit > $Vlocal) {echo __('messages.You need to update to the latest mainline release');} else {echo __("messages.You’re running the latest mainline release");} ?></p> - @else - <h4>{{__('messages.update.manually')}}</h4> - <h5>{{__('messages.update.windows')}}</h5> - @endif - <br><div class="row"> -  <a class="btn" href="{{url()->current()}}/?updating-windows"><button><i class="fa-solid fa-user-gear btn"></i> {{__('messages.Update automatically')}}</button></a>  -  <a class="btn" href="https://linkstack.org/update" target="_blank"><button><i class="fa-solid fa-download btn"></i> {{__('messages.Update manually')}}</button></a>  - </div> - @else - @if(env('JOIN_BETA') === true) - <p><?php echo __('messages.Latest beta version')."= " . external_file_get_contents("https://beta.linkstack.org/vbeta.json"); ?></p> - <p><?php if(file_exists(base_path("vbeta.json"))) {echo __('messages.Installed beta version')."= " . file_get_contents(base_path("vbeta.json"));} else {echo __('messages.Installed beta version')."= ".__('messages.none');} ?></p> - <p><?php if($Vgit > $Vlocal) {echo __('messages.You need to update to the latest mainline release');} else {echo __("messages.You’re running the latest mainline release");} ?></p> - @else - <a target="_blank" href="https://github.com/linkstackorg/linkstack/releases"><code style="color:#222;transform:scale(.9);">{{$Vlocal}} -> {{$Vgit}}</code></a> - <h4>{{__('messages.update.manually')}}</h4> - @endif - <br><div class="row"> - @if(env('SKIP_UPDATE_BACKUP') == true) -  <a class="btn" href="{{url()->current()}}/?preparing"><button><i class="fa-solid fa-user-gear btn"></i> {{__('messages.Update automatically')}}</button></a>  - @else -  <a class="btn" href="{{url()->current()}}/?backup"><button><i class="fa-solid fa-user-gear btn"></i> {{__('messages.Update automatically')}}</button></a>  - @endif -  <a class="btn" href="https://linkstack.org/update" target="_blank"><button><i class="fa-solid fa-download btn"></i> {{__('messages.Update manually')}}</button></a>  - </div> - @endif - -@endif - - -@if($_SERVER['QUERY_STRING'] === 'updating-windows' and strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') -<?php //updating on Windows ?> - <div class="logo-container fadein"> -<img class="logo-img" src="{{ asset('assets/linkstack/images/logo-loading.svg') }}" alt="Logo"> - </div> - <h1 class="loadingtxt">{{__('messages.Updating')}}</h1> - @Push('updater-head') - <meta http-equiv="refresh" content="2; URL={{url()->current()}}/?preparing" /> - @endpush -@endif - -@if($_SERVER['QUERY_STRING'] === 'updating-windows-bat' and strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') -<?php //updating on Windows ?> -<?php - - -// Download the zip file - -$latestversion = trim(external_file_get_contents("https://version.linkstack.org/")); - -if(env('JOIN_BETA') === true){ - $fileUrl = 'https://beta.linkstack.org/'. $latestversion . '.zip'; -} else { - $fileUrl = 'https://update.linkstack.org/'. $latestversion . '.zip'; -} - -$curl = curl_init(); -curl_setopt($curl, CURLOPT_URL, $fileUrl); -curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); -curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); -$result = curl_exec($curl); -curl_close($curl); - -file_put_contents(base_path('storage/update.zip'), $result); - - -$zip = new ZipArchive; -$zip->open(base_path() . '/storage/update.zip'); -$zip->extractTo(base_path()); -$zip->close(); -unlink(base_path() . '/storage/update.zip'); - -echo "<meta http-equiv=\"refresh\" content=\"0; " . url()->current() . "/?finishing\" />"; - -?> - - -@endif - -@if($_SERVER['QUERY_STRING'] === 'backup') -<?php //creating backup... ?> -@Push('updater-head') -<meta http-equiv="refresh" content="2; URL={{url()->current()}}/?backups" /> -@endpush - <div class="logo-container fadein"> -<img class="logo-img" src="{{ asset('assets/linkstack/images/logo-loading.svg') }}" alt="Logo"> - </div> - <h1 class="loadingtxt">{{__('messages.Creating backup')}}</h1> -@endif - -@if($_SERVER['QUERY_STRING'] === 'backups') -<?php -try {Artisan::call('backup:clean');} -catch (exception $e) {} -Artisan::call('backup:run', ['--only-files' => true, '--disable-notifications' => true]); -$tst = base_path('backups/'); -file_put_contents($tst.'CANUPDATE', ''); -$URL = Route::current()->getName(); -header("Location: ".$URL."?preparing"); -exit(); ?> -@endif - -@if($_SERVER['QUERY_STRING'] === 'preparing') -<?php //preparing update ?> - <div class="logo-container fadein"> -<img class="logo-img" src="{{ asset('assets/linkstack/images/logo-loading.svg') }}" alt="Logo"> - </div> - <h1 class="loadingtxt">{{__('messages.Preparing update')}}</h1> - - <?php // Get update preperation script from GitHub try { - $file = external_file_get_contents('https://pre-update.linkstack.org'); - $newfile = base_path('resources/views/components/pre-update.blade.php'); - file_put_contents($newfile, $file); - } catch (exception $e) {} - ?> - - @include('components.pre-update') - - @if(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') - <meta http-equiv="refresh" content="2; URL={{url()->current()}}/?updating-windows-bat" /> - @else - <?php echo "<meta http-equiv=\"refresh\" content=\"1; " . url()->current() . "?updating\" />" ?> - @endif -@endif + $isBeta = env('JOIN_BETA', false); + $Vbeta = trim(Http::timeout(5)->get($betaServer . 'vbeta.json')->body()); + $Vbeta_git = trim(Http::timeout(5)->get($betaServer . 'version.json')->body()); + $Vgit = trim(Http::timeout(5)->get($versionServer)->body()); + $Vlocal = trim(file_get_contents(base_path('version.json'))); + } catch (Exception $e) { + session(['update_error' => 'Unexpected error. ' . $e->getMessage()]); + } + @endphp -@if($_SERVER['QUERY_STRING'] === 'updating' and (file_exists(base_path("backups/CANUPDATE")) or env('SKIP_UPDATE_BACKUP') == true)) -<?php //updating... ?> - <div class="logo-container fadein"> -<img class="logo-img" src="{{ asset('assets/linkstack/images/logo-loading.svg') }}" alt="Logo"> - </div> - <h1 class="loadingtxt">{{__('messages.Updating')}}</h1> - @Push('updater-head') - <meta http-equiv="refresh" content="2; URL={{url()->current()}}/../updating" /> - @endpush -@endif + <div class="container"> + @if ((auth()->user()->role == 'admin' && $Vgit > $Vlocal) || $isBeta) + @if (empty($_SERVER['QUERY_STRING'])) + <div class="logo-container fadein"> + <img class="logo-img" src="{{ asset('assets/linkstack/images/logo.svg') }}" alt="Logo"> + </div> + <h1>{{ __('messages.Updater') }}</h1> + @if ($isBeta) + <p>{{ __('messages.Latest beta version') }} = + {{ $Vbeta }}</p> + <p>{{ __('messages.Installed beta version') }} = + {{ file_exists(base_path('vbeta.json')) ? file_get_contents(base_path('vbeta.json')) : __('messages.none') }} + </p> + <p>{{ $Vgit > $Vlocal ? __('messages.You need to update to the latest mainline release') : __('messages.You’re running the latest mainline release') }} + </p> + @else + <a target="_blank" href="{{ $repositoryUrl }}releases"> + <code style="color:#222;transform:scale(.9);">{{ $Vlocal }} -> {{ $Vgit }}</code> + </a> + <h4>{{ __('messages.update.manually') }}</h4> + @endif + <br> + <div class="row"> + <a class="btn" + href="{{ url()->current() }}/?{{ env('SKIP_UPDATE_BACKUP') == true ? 'preparing' : 'backup' }}"> + <button><i class="fa-solid fa-user-gear btn"></i> + {{ __('messages.Update automatically') }}</button> + </a> + <a class="btn" href="https://linkstack.org/update" target="_blank"> + <button><i class="fa-solid fa-download btn"></i> {{ __('messages.Update manually') }}</button> + </a> + </div> + @endif -@elseif($_SERVER['QUERY_STRING'] === '') - <?php //if no new version available ?> - - <div class="logo-container fadein"> -<img class="logo-img" src="{{ asset('assets/linkstack/images/logo.svg') }}" alt="Logo"> - </div> - <h1>{{__('messages.No new version')}}</h1> - <h4>{{__('messages.There is no new version available')}}</h4> - <br><div class="row"> -  <a class="btn" href="{{ url('dashboard') }}"><button><i class="fa-solid fa-house-laptop btn"></i> {{__('messages.Admin Panel')}}</button></a>  - </div> - -@endif + @if ($_SERVER['QUERY_STRING'] === 'updating') + @php + set_time_limit(0); + try { + // Determine the latest version and file URL + $latestVersion = $isBeta ? $Vbeta_git : $Vgit; + $fileUrl = $isBeta ? $betaServer . $latestVersion . '.zip' : $updateServer . $latestVersion . '.zip'; -@if($_SERVER['QUERY_STRING'] === 'finishing') -<?php //finishing up update ?> -<?php -$debug = NULL; -if(EnvEditor::getKey('APP_DEBUG') == 'false'){ - if(EnvEditor::keyExists('APP_DEBUG')){EnvEditor::editKey('APP_DEBUG', 'true');} - if(EnvEditor::keyExists('APP_ENV')){EnvEditor::editKey('APP_ENV', 'local');} - if(EnvEditor::keyExists('LOG_LEVEL')){EnvEditor::editKey('LOG_LEVEL', 'debug');} - $debug = true; -} -?> - <div class="logo-container fadein"> -<img class="logo-img" src="{{ asset('assets/linkstack/images/logo-loading.svg') }}" alt="Logo"> - </div> - <h1 class="loadingtxt">{{__('messages.Finishing up')}}</h1> - - @include('components.finishing') - - <?php EnvEditor::editKey('MAINTENANCE_MODE', false); ?> -<?php -if($debug === true){ - if(EnvEditor::keyExists('APP_DEBUG')){EnvEditor::editKey('APP_DEBUG', 'false');} - if(EnvEditor::keyExists('APP_ENV')){EnvEditor::editKey('APP_ENV', 'production');} - if(EnvEditor::keyExists('LOG_LEVEL')){EnvEditor::editKey('LOG_LEVEL', 'error');} -} -?> + // Download the update file + $response = Http::timeout(120)->get($fileUrl); -<?php echo "<meta http-equiv=\"refresh\" content=\"0; " . url()->current() . "?success\" />"; ?> -@endif + if ($response->failed()) { + throw new Exception("HTTP request failed: {$response->status()} - {$response->body()}"); + } -@if($_SERVER['QUERY_STRING'] === 'success') - <?php //after successfully updating ?> - - <div class="logo-container fadein"> -<img class="logo-img" src="{{ asset('assets/linkstack/images/logo.svg') }}" alt="Logo"> - </div> - <h1>{{__('messages.Success!')}}</h1> - @if(env('JOIN_BETA') === true) - <p><?php echo __('messages.Latest beta version')."= " . external_file_get_contents("https://beta.linkstack.org/vbeta.json"); ?></p> - <p><?php if(file_exists(base_path("vbeta.json"))) {echo __('messages.Installed beta version')."= " . file_get_contents(base_path("vbeta.json"));} else {echo __('messages.Installed beta version')."= ".__('messages.none');} ?></p> - <p><?php if($Vgit > $Vlocal) {echo __('messages.You need to update to the latest mainline release');} else {echo __("messages.You’re running the latest mainline release");} ?></p> - @else - <h4>{{__('messages.The update was successful')}}</h4> - <style>.noteslink:hover{color:#006fd5;text-shadow:0px 6px 7px rgba(23,10,6,0.66);}</style> - <a class="noteslink" href="https://github.com/linkstackorg/linkstack/releases/latest" target="_blank"><i class="fa-solid fa-up-right-from-square"></i> {{__('messages.View the release notes')}}</a> - <br> + // Save the downloaded ZIP file to storage + $zipPath = storage_path('update.zip'); + $result = file_put_contents($zipPath, $response->body()); + if ($result === false) { + throw new Exception('Failed to write update.zip to storage.'); + } + + // Initialize the ZIP archive + $zip = new ZipArchive(); + if ($zip->open($zipPath) !== true) { + throw new Exception('Failed to open ZIP archive for extraction.'); + } + + // Extract the contents to the base path + $extractPath = base_path(); + if (!$zip->extractTo($extractPath)) { + throw new Exception('ZIP extraction failed.'); + } + + $zip->close(); + + // Delete the ZIP file after extraction + if (!unlink($zipPath)) { + Log::warning("Failed to delete ZIP file: $zipPath"); + } + } catch (Exception $e) { + session(['update_error' => 'Fatal error. ' . $e->getMessage()]); + } + @endphp + <meta http-equiv="refresh" content="0; {{ url()->current() }}/?finishing" /> + @endif + + @if ($_SERVER['QUERY_STRING'] === 'backup') + @push('updater-head') + <meta http-equiv="refresh" content="2; URL={{ url()->current() }}/?backups" /> + @endpush + <div class="logo-container fadein"> + <img class="logo-img" src="{{ asset('assets/linkstack/images/logo-loading.svg') }}" alt="Logo"> + </div> + <h1 class="loadingtxt">{{ __('messages.Creating backup') }}</h1> + @endif + + @if ($_SERVER['QUERY_STRING'] === 'backups') + @php + set_time_limit(0); + // Test if the Artisan command is available + try { + $exitCode = Artisan::call('list'); + + if ($exitCode !== 0) { + session(['update_error' => "Backup creation failed. Your system doesn't support backups. Consider disabling update backups in your config. Exit code: $exitCode"]); + } + } catch (Exception $e) { + session(['update_error' => "Backup creation failed. This may indicate that your system doesn't support backups or that the process exceeded the time limit. Consider disabling update backups in your config. Exit code: " . $e->getMessage()]); + } + + try { + Artisan::call('backup:clean', ['--disable-notifications' => true]); + } catch (Exception $e) { + session(['update_error' => $e->getMessage()]); + } + + try { + Artisan::call('backup:run', ['--only-files' => true, '--disable-notifications' => true]); + } catch (Exception $e) { + session(['update_error' => $e->getMessage()]); + } + @endphp + + @if (session()->has('update_error')) + <meta http-equiv="refresh" content="1; {{ url()->current() }}/?error" /> + @else + @php file_put_contents(base_path('backups/CANUPDATE'), ''); @endphp + <meta http-equiv="refresh" content="1; {{ url()->current() }}?preparing" /> + @endif + @endif + + @if ($_SERVER['QUERY_STRING'] === 'preparing') + <div class="logo-container fadein"> + <img class="logo-img" src="{{ asset('assets/linkstack/images/logo-loading.svg') }}" alt="Logo"> + </div> + <h1 class="loadingtxt">{{ __('messages.Preparing update') }}</h1> + @php + set_time_limit(0); + + if (file_exists(base_path() . '/storage/update.zip')) { + try { + unlink(base_path() . '/storage/update.zip'); + } catch (Exception $e) { + session(['update_error' => 'File permission error. ' . $e->getMessage()]); + } + } + + try { + $file = Http::timeout(10)->get($preUpdateServer)->body(); + file_put_contents(base_path('resources/views/components/pre-update.blade.php'), $file); + } catch (Exception $e) { + session(['update_error' => 'Could not prepare update. ' . $e->getMessage()]); + } + @endphp + @if (session()->has('update_error')) + <meta http-equiv="refresh" content="1; {{ url()->current() }}/?error" /> + @else + @include('components.pre-update') + <meta http-equiv="refresh" content="1; {{ url()->current() }}?updating" /> + @endif + @endif + + @if ( + $_SERVER['QUERY_STRING'] === 'updating' && + (file_exists(base_path('backups/CANUPDATE')) || env('SKIP_UPDATE_BACKUP') == true)) + <div class="logo-container fadein"> + <img class="logo-img" src="{{ asset('assets/linkstack/images/logo-loading.svg') }}" alt="Logo"> + </div> + <h1 class="loadingtxt">{{ __('messages.Updating') }}</h1> + @push('updater-head') + <meta http-equiv="refresh" content="2; URL={{ url()->current() }}/../updating" /> + @endpush + @endif + @elseif(empty($_SERVER['QUERY_STRING'])) + <div class="logo-container fadein"> + <img class="logo-img" src="{{ asset('assets/linkstack/images/logo.svg') }}" alt="Logo"> + </div> + <h1>{{ __('messages.No new version') }}</h1> + <h4>{{ __('messages.There is no new version available') }}</h4> + <br> + <div class="row"> + <a class="btn" href="{{ url('dashboard') }}"> + <button><i class="fa-solid fa-house-laptop btn"></i> {{ __('messages.Admin Panel') }}</button> + </a> + </div> @endif - <br><div class="row"> -  <a class="btn" href="{{ url('dashboard') }}"><button><i class="fa-solid fa-house-laptop btn"></i> {{__('messages.Admin Panel')}}</button></a>  - @if(env('JOIN_BETA') === true) -  <a class="btn" href="{{url()->current()}}/"><button><i class="fa-solid fa-arrow-rotate-right btn"></i> {{__('messages.Run again')}}</button></a>  + @if ($_SERVER['QUERY_STRING'] === 'finishing') + @php + set_time_limit(0); + $debug = null; + if (EnvEditor::getKey('APP_DEBUG') == 'false') { + if (EnvEditor::keyExists('APP_DEBUG')) { + EnvEditor::editKey('APP_DEBUG', 'true'); + } + if (EnvEditor::keyExists('APP_ENV')) { + EnvEditor::editKey('APP_ENV', 'local'); + } + if (EnvEditor::keyExists('LOG_LEVEL')) { + EnvEditor::editKey('LOG_LEVEL', 'debug'); + } + $debug = true; + } + @endphp + <div class="logo-container fadein"> + <img class="logo-img" src="{{ asset('assets/linkstack/images/logo-loading.svg') }}" alt="Logo"> + </div> + <h1 class="loadingtxt">{{ __('messages.Finishing up') }}</h1> + @include('components.finishing') + @php + EnvEditor::editKey('MAINTENANCE_MODE', false); + if ($debug === true) { + if (EnvEditor::keyExists('APP_DEBUG')) { + EnvEditor::editKey('APP_DEBUG', 'false'); + } + if (EnvEditor::keyExists('APP_ENV')) { + EnvEditor::editKey('APP_ENV', 'production'); + } + if (EnvEditor::keyExists('LOG_LEVEL')) { + EnvEditor::editKey('LOG_LEVEL', 'error'); + } + } + @endphp + @if(!session()->has('update_error') && ($isBeta || $Vgit === $Vlocal)) + <meta http-equiv="refresh" content="0; {{ url()->current() }}?success" /> + @else + @php + if (!session()->has('update_error')) { + session(['update_error' => 'Update failed unexpectedly. Please try again later.']); + } + @endphp + <meta http-equiv="refresh" content="0; {{ url()->current() }}?error" /> + @endif @endif - </div> - -@endif -@if($_SERVER['QUERY_STRING'] === 'error') - <?php //on error ?> - - <?php EnvEditor::editKey('MAINTENANCE_MODE', false); ?> + @if ($_SERVER['QUERY_STRING'] === 'success') + <div class="logo-container fadein"> + <img class="logo-img" src="{{ asset('assets/linkstack/images/logo.svg') }}" alt="Logo"> + </div> + <h1>{{ __('messages.Success!') }}</h1> + @if ($isBeta) + <p>{{ __('messages.Latest beta version') }} = + {{ $Vbeta }}</p> + <p>{{ __('messages.Installed beta version') }} = + {{ file_exists(base_path('vbeta.json')) ? file_get_contents(base_path('vbeta.json')) : __('messages.none') }} + </p> + <p>{{ $Vgit > $Vlocal ? __('messages.You need to update to the latest mainline release') : __('messages.You’re running the latest mainline release') }} + </p> + @else + <h4>{{ __('messages.The update was successful') }}</h4> + <a class="noteslink" href="{{ $repositoryUrl }}releases/latest" target="_blank"> + <i class="fa-solid fa-up-right-from-square"></i> {{ __('messages.View the release notes') }} + </a> + <br> + @endif + <br> + <div class="row"> + <a class="btn" href="{{ url('dashboard') }}"> + <button><i class="fa-solid fa-house-laptop btn"></i> {{ __('messages.Admin Panel') }}</button> + </a> + @if ($isBeta) + <a class="btn" href="{{ url()->current() }}/"> + <button><i class="fa-solid fa-arrow-rotate-right btn"></i> {{ __('messages.Run again') }}</button> + </a> + @endif + </div> + @endif - <div class="logo-container fadein"> -<img class="logo-img" src="{{ asset('assets/linkstack/images/logo.svg') }}" alt="Logo"> - </div> - <h1>{{__('messages.Error')}}</h1> - <h4>{{__('messages.Something went wrong with the update')}} :(</h4> - <br><div class="row"> -  <a class="btn" href="{{ url('dashboard') }}"><button><i class="fa-solid fa-house-laptop btn"></i> {{__('messages.Admin Panel')}}</button></a>  - </div> - -@endif + @if ($_SERVER['QUERY_STRING'] === 'error') + <?php EnvEditor::editKey('MAINTENANCE_MODE', false); ?> -</div> + <div class="logo-container fadein"> + <img class="logo-img" src="{{ asset('assets/linkstack/images/logo.svg') }}" alt="Logo"> + </div> + <h1>{{ __('messages.Error') }}</h1> + <h4>{{ __('messages.Something went wrong with the update') }} :(</h4> + + @if (session()->has('update_error')) + <div class="alert-box alert-box-error"> + <strong>Error:</strong> + {{ session('update_error') }} + </div> + @php + session()->forget('update_error'); + @endphp + @else + <div class="alert-box alert-box-error"> + <strong>Error:</strong> + Unknown error + </div> + @endif + + <br> + <div class="row"> +  <a class="btn" href="{{ url('dashboard') }}"><button><i class="fa-solid fa-house-laptop btn"></i> + {{ __('messages.Admin Panel') }}</button></a>  + </div> + @endif + + </div> @endpush \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 75867d5..737d879 100755 --- a/routes/web.php +++ b/routes/web.php @@ -191,38 +191,8 @@ Route::group([ 'linktype'=>LinkTypeController::class ]); }); - - Route::get('/updating', function (\Codedge\Updater\UpdaterManager $updater) { - - // Check if new version is available - if($updater->source()->isNewVersionAvailable() and (file_exists(base_path("backups/CANUPDATE")) or env('SKIP_UPDATE_BACKUP') == true)) { - - EnvEditor::editKey('MAINTENANCE_MODE', true); - - // Get the current installed version - echo $updater->source()->getVersionInstalled(); - - // Get the new version available - $versionAvailable = $updater->source()->getVersionAvailable(); - - // Create a release - $release = $updater->source()->fetch($versionAvailable); - - // Run the update process - $updater->source()->update($release); - - if(env('SKIP_UPDATE_BACKUP') != true) {unlink(base_path("backups/CANUPDATE"));} - - echo "<meta http-equiv=\"refresh\" content=\"0; " . url()->current() . "/../update?finishing\" />"; - - } else { - echo "<meta http-equiv=\"refresh\" content=\"0; " . url()->current() . "/../update?error\" />"; - } - -}); - -}); // ENd Admin authenticated routes +}); // End Admin authenticated routes }); // Displays Maintenance Mode page From 42615036cd84e02c9fa872e8b077fb62c58e47e5 Mon Sep 17 00:00:00 2001 From: Julian Prieber <julian.prieber@gmail.com> Date: Tue, 26 Nov 2024 18:23:08 +0100 Subject: [PATCH 2/3] Add beta support --- resources/views/update.blade.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/resources/views/update.blade.php b/resources/views/update.blade.php index 8e4cb29..d1ae4e4 100644 --- a/resources/views/update.blade.php +++ b/resources/views/update.blade.php @@ -4,14 +4,20 @@ @php // Must end with '/' - $betaServer = env('BETA_SERVER', 'https://beta.linkstack.org/'); - $updateServer = env('UPDATE_SERVER', 'https://update.linkstack.org/'); - $versionServer = env('VERSION_SERVER', 'https://version.linkstack.org/'); - $preUpdateServer = env('PRE_UPDATE_SERVER', 'https://pre-update.linkstack.org/'); - $repositoryUrl = env('REPOSITORY_URL', 'https://github.com/linkstackorg/linkstack/'); + $betaServer = env('BETA_SERVER', 'https://beta.linkstack.org/'); + $betaPreUpdateServer = env('BETA_PRE_UPDATE_SERVER', 'https://pre-update.linkstack.org/beta/'); + $updateServer = env('UPDATE_SERVER', 'https://update.linkstack.org/'); + $versionServer = env('VERSION_SERVER', 'https://version.linkstack.org/'); + $preUpdateServer = env('PRE_UPDATE_SERVER', 'https://pre-update.linkstack.org/'); + $repositoryUrl = env('REPOSITORY_URL', 'https://github.com/linkstackorg/linkstack/'); + + $isBeta = env('JOIN_BETA', false); + + if ($isBeta) { + $preUpdateServer = $betaPreUpdateServer; + } try { - $isBeta = env('JOIN_BETA', false); $Vbeta = trim(Http::timeout(5)->get($betaServer . 'vbeta.json')->body()); $Vbeta_git = trim(Http::timeout(5)->get($betaServer . 'version.json')->body()); $Vgit = trim(Http::timeout(5)->get($versionServer)->body()); From 76f14a78fec0bc99de6b8ccdaa7b7a50e43f4a38 Mon Sep 17 00:00:00 2001 From: Julian Prieber <julian.prieber@gmail.com> Date: Wed, 27 Nov 2024 14:10:31 +0100 Subject: [PATCH 3/3] Improve error handling --- .../views/components/finishing.blade.php | 563 +++++++++++------- resources/views/update.blade.php | 23 +- 2 files changed, 361 insertions(+), 225 deletions(-) diff --git a/resources/views/components/finishing.blade.php b/resources/views/components/finishing.blade.php index 5385d5f..27c635a 100644 --- a/resources/views/components/finishing.blade.php +++ b/resources/views/components/finishing.blade.php @@ -1,4 +1,4 @@ -<?php +<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Migrations\Migrator; use Illuminate\Database\Schema\Blueprint; @@ -10,120 +10,222 @@ use App\Models\Page; set_time_limit(0); - //run before finishing: - if(EnvEditor::keyExists('JOIN_BETA')){ /* Do nothing if key already exists */ - } else { EnvEditor::addKey('JOIN_BETA', 'false');} // Adds key to .env file +//run before finishing: +if (EnvEditor::keyExists('JOIN_BETA')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('JOIN_BETA', 'false'); +} // Adds key to .env file - if(EnvEditor::keyExists('SKIP_UPDATE_BACKUP')){ /* Do nothing if key already exists */ - } else { EnvEditor::addKey('SKIP_UPDATE_BACKUP', 'false');} // Adds key to .env file +if (EnvEditor::keyExists('SKIP_UPDATE_BACKUP')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('SKIP_UPDATE_BACKUP', 'false'); +} // Adds key to .env file - if(EnvEditor::keyExists('CUSTOM_META_TAGS')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('CUSTOM_META_TAGS', 'false');} +if (EnvEditor::keyExists('CUSTOM_META_TAGS')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('CUSTOM_META_TAGS', 'false'); +} - if(EnvEditor::keyExists('MAINTENANCE_MODE')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('MAINTENANCE_MODE', 'false');} +if (EnvEditor::keyExists('MAINTENANCE_MODE')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('MAINTENANCE_MODE', 'false'); +} - if(EnvEditor::keyExists('ALLOW_CUSTOM_CODE_IN_THEMES')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('ALLOW_CUSTOM_CODE_IN_THEMES', 'true');} +if (EnvEditor::keyExists('ALLOW_CUSTOM_CODE_IN_THEMES')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('ALLOW_CUSTOM_CODE_IN_THEMES', 'true'); +} - if(EnvEditor::keyExists('ENABLE_THEME_UPDATER')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('ENABLE_THEME_UPDATER', 'true');} +if (EnvEditor::keyExists('ENABLE_THEME_UPDATER')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('ENABLE_THEME_UPDATER', 'true'); +} - if(EnvEditor::keyExists('ENABLE_SOCIAL_LOGIN')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('ENABLE_SOCIAL_LOGIN', 'false');} +if (EnvEditor::keyExists('ENABLE_SOCIAL_LOGIN')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('ENABLE_SOCIAL_LOGIN', 'false'); +} - if(EnvEditor::keyExists('USE_THEME_PREVIEW_IFRAME')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('USE_THEME_PREVIEW_IFRAME', 'true');} +if (EnvEditor::keyExists('USE_THEME_PREVIEW_IFRAME')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('USE_THEME_PREVIEW_IFRAME', 'true'); +} - if(EnvEditor::keyExists('FORCE_ROUTE_HTTPS')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('FORCE_ROUTE_HTTPS', 'false');} +if (EnvEditor::keyExists('FORCE_ROUTE_HTTPS')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('FORCE_ROUTE_HTTPS', 'false'); +} - if(EnvEditor::keyExists('HIDE_VERIFICATION_CHECKMARK')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('HIDE_VERIFICATION_CHECKMARK', 'false');} +if (EnvEditor::keyExists('HIDE_VERIFICATION_CHECKMARK')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('HIDE_VERIFICATION_CHECKMARK', 'false'); +} - if(EnvEditor::keyExists('ALLOW_CUSTOM_BACKGROUNDS')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('ALLOW_CUSTOM_BACKGROUNDS', 'true');} +if (EnvEditor::keyExists('ALLOW_CUSTOM_BACKGROUNDS')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('ALLOW_CUSTOM_BACKGROUNDS', 'true'); +} - if(EnvEditor::keyExists('ALLOW_USER_IMPORT')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('ALLOW_USER_IMPORT', 'true');} +if (EnvEditor::keyExists('ALLOW_USER_IMPORT')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('ALLOW_USER_IMPORT', 'true'); +} - if(EnvEditor::keyExists('ALLOW_USER_EXPORT')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('ALLOW_USER_EXPORT', 'true');} +if (EnvEditor::keyExists('ALLOW_USER_EXPORT')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('ALLOW_USER_EXPORT', 'true'); +} - if(EnvEditor::keyExists('SUPPORTED_DOMAINS')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('SUPPORTED_DOMAINS', '');} +if (EnvEditor::keyExists('SUPPORTED_DOMAINS')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('SUPPORTED_DOMAINS', ''); +} - if(EnvEditor::keyExists('MANUAL_USER_VERIFICATION')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('MANUAL_USER_VERIFICATION', 'false');} +if (EnvEditor::keyExists('MANUAL_USER_VERIFICATION')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('MANUAL_USER_VERIFICATION', 'false'); +} - if(EnvEditor::keyExists('DISPLAY_CREDIT_FOOTER')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('DISPLAY_CREDIT_FOOTER', 'true');} +if (EnvEditor::keyExists('DISPLAY_CREDIT_FOOTER')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('DISPLAY_CREDIT_FOOTER', 'true'); +} - if(EnvEditor::keyExists('LOCALE')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('LOCALE', 'en');} +if (EnvEditor::keyExists('LOCALE')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('LOCALE', 'en'); +} - if(EnvEditor::keyExists('ENABLE_REPORT_ICON')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('ENABLE_REPORT_ICON', 'false');} +if (EnvEditor::keyExists('ENABLE_REPORT_ICON')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('ENABLE_REPORT_ICON', 'false'); +} - if(EnvEditor::keyExists('ENABLE_ADMIN_BAR')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('ENABLE_ADMIN_BAR', 'true');} +if (EnvEditor::keyExists('ENABLE_ADMIN_BAR')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('ENABLE_ADMIN_BAR', 'true'); +} - if(EnvEditor::keyExists('ENABLE_ADMIN_BAR_USERS')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('ENABLE_ADMIN_BAR_USERS', 'false');} +if (EnvEditor::keyExists('ENABLE_ADMIN_BAR_USERS')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('ENABLE_ADMIN_BAR_USERS', 'false'); +} - if(EnvEditor::keyExists('ADMIN_EMAIL')){} else - {if(Auth::user()->id == 1){EnvEditor::addKey('ADMIN_EMAIL', App\Models\User::find(1)->email);} - else{EnvEditor::addKey('ADMIN_EMAIL', '');}} +if (EnvEditor::keyExists('ADMIN_EMAIL')) { +} else { + if (Auth::user()->id == 1) { + EnvEditor::addKey('ADMIN_EMAIL', App\Models\User::find(1)->email); + } else { + EnvEditor::addKey('ADMIN_EMAIL', ''); + } +} - if(env('APP_NAME') == 'LittleLink Custom' or env('APP_NAME') == 'LittleLink') { - EnvEditor::editKey('APP_NAME', 'LinkStack'); - } +if (env('APP_NAME') == 'LittleLink Custom' or env('APP_NAME') == 'LittleLink') { + EnvEditor::editKey('APP_NAME', 'LinkStack'); +} - if (EnvEditor::keyExists('ALLOW_REGISTRATION')) { /* Do nothing if key already exists */ - } else { - $pagedb = DB::table('pages')->select('register')->first(); - if ($pagedb->register) { - EnvEditor::addKey('ALLOW_REGISTRATION', 'true'); - } else { - EnvEditor::addKey('ALLOW_REGISTRATION', 'false'); - } - try { - DB::table('pages')->update(['register' => null]); - } catch (Exception $e) {} - } +if (EnvEditor::keyExists('ALLOW_REGISTRATION')) { + /* Do nothing if key already exists */ +} else { + $pagedb = DB::table('pages')->select('register')->first(); + if ($pagedb->register) { + EnvEditor::addKey('ALLOW_REGISTRATION', 'true'); + } else { + EnvEditor::addKey('ALLOW_REGISTRATION', 'false'); + } + try { + DB::table('pages')->update(['register' => null]); + } catch (Exception $e) { + session(['update_error' => $e->getMessage()]); + } +} - try { - $file = base_path('storage/RSTAC'); - if (file_exists($file)) { - copy(base_path('storage/templates/advanced-config.php'), base_path('config/advanced-config.php')); - unlink($file); - } - } catch (Exception $e) {} +try { + $file = base_path('storage/RSTAC'); + if (file_exists($file)) { + copy(base_path('storage/templates/advanced-config.php'), base_path('config/advanced-config.php')); + unlink($file); + } +} catch (Exception $e) { + session(['update_error' => $e->getMessage()]); +} - try { - $vendorLangPath = resource_path('lang/vendor'); - if (File::exists($vendorLangPath)) { - File::deleteDirectory($vendorLangPath); - } - } catch (Exception $e) {} +try { + $vendorLangPath = resource_path('lang/vendor'); + if (File::exists($vendorLangPath)) { + File::deleteDirectory($vendorLangPath); + } +} catch (Exception $e) { + session(['update_error' => $e->getMessage()]); +} - // Footer page customization - if(EnvEditor::keyExists('DISPLAY_FOOTER_HOME')){} else {EnvEditor::addKey('DISPLAY_FOOTER_HOME', 'true');} - if(EnvEditor::keyExists('DISPLAY_FOOTER_TERMS')){} else {EnvEditor::addKey('DISPLAY_FOOTER_TERMS', 'true');} - if(EnvEditor::keyExists('DISPLAY_FOOTER_PRIVACY')){} else {EnvEditor::addKey('DISPLAY_FOOTER_PRIVACY', 'true');} - if(EnvEditor::keyExists('DISPLAY_FOOTER_CONTACT')){} else {EnvEditor::addKey('DISPLAY_FOOTER_CONTACT', 'true');} - if(EnvEditor::keyExists('TITLE_FOOTER_HOME')){} else {EnvEditor::addKey('TITLE_FOOTER_HOME', 'Home');} - if(EnvEditor::keyExists('TITLE_FOOTER_TERMS')){} else {EnvEditor::addKey('TITLE_FOOTER_TERMS', 'Terms');} - if(EnvEditor::keyExists('TITLE_FOOTER_PRIVACY')){} else {EnvEditor::addKey('TITLE_FOOTER_PRIVACY', 'Privacy');} - if(EnvEditor::keyExists('TITLE_FOOTER_CONTACT')){} else {EnvEditor::addKey('TITLE_FOOTER_CONTACT', 'Contact');} - if(EnvEditor::keyExists('HOME_FOOTER_LINK')){} else {EnvEditor::addKey('HOME_FOOTER_LINK', '');} +// Footer page customization +if (EnvEditor::keyExists('DISPLAY_FOOTER_HOME')) { +} else { + EnvEditor::addKey('DISPLAY_FOOTER_HOME', 'true'); +} +if (EnvEditor::keyExists('DISPLAY_FOOTER_TERMS')) { +} else { + EnvEditor::addKey('DISPLAY_FOOTER_TERMS', 'true'); +} +if (EnvEditor::keyExists('DISPLAY_FOOTER_PRIVACY')) { +} else { + EnvEditor::addKey('DISPLAY_FOOTER_PRIVACY', 'true'); +} +if (EnvEditor::keyExists('DISPLAY_FOOTER_CONTACT')) { +} else { + EnvEditor::addKey('DISPLAY_FOOTER_CONTACT', 'true'); +} +if (EnvEditor::keyExists('TITLE_FOOTER_HOME')) { +} else { + EnvEditor::addKey('TITLE_FOOTER_HOME', 'Home'); +} +if (EnvEditor::keyExists('TITLE_FOOTER_TERMS')) { +} else { + EnvEditor::addKey('TITLE_FOOTER_TERMS', 'Terms'); +} +if (EnvEditor::keyExists('TITLE_FOOTER_PRIVACY')) { +} else { + EnvEditor::addKey('TITLE_FOOTER_PRIVACY', 'Privacy'); +} +if (EnvEditor::keyExists('TITLE_FOOTER_CONTACT')) { +} else { + EnvEditor::addKey('TITLE_FOOTER_CONTACT', 'Contact'); +} +if (EnvEditor::keyExists('HOME_FOOTER_LINK')) { +} else { + EnvEditor::addKey('HOME_FOOTER_LINK', ''); +} - if(EnvEditor::keyExists('FORCE_HTTPS')){ /* Do nothing if key already exists */ - } else {EnvEditor::addKey('FORCE_HTTPS', 'false');} +if (EnvEditor::keyExists('FORCE_HTTPS')) { + /* Do nothing if key already exists */ +} else { + EnvEditor::addKey('FORCE_HTTPS', 'false'); +} - $data['page'] = Page::select('contact')->first(); - if (strpos($data['page']->contact, 'info@littlelink-custom.com') !== false or strpos($data['page']->contact, 'LittleLink Custom') !== false) { - $contact = ' +$data['page'] = Page::select('contact')->first(); +if (strpos($data['page']->contact, 'info@littlelink-custom.com') !== false or strpos($data['page']->contact, 'LittleLink Custom') !== false) { + $contact = ' <p><strong><a href="https://linkstack.org/">LinkStack</a></strong> is a free, open source link sharing platform. We depend on community feedback to steadily improve this project.</p> <p><strong>Feel free to send us your feedback!</strong></p> @@ -139,62 +241,63 @@ set_time_limit(0); <p> </p> '; - Page::first()->update(['contact' => $contact]); - } + Page::first()->update(['contact' => $contact]); +} - - $data['page'] = Page::select('home_message')->first(); - if (strpos($data['page']->home_message, 'LittleLink Custom') !== false) { - $home_message = ' +$data['page'] = Page::select('home_message')->first(); +if (strpos($data['page']->home_message, 'LittleLink Custom') !== false) { + $home_message = ' <p>Take control of your online presence with <a href="https://linkstack.org/"><strong>LinkStack</strong></a> the privacy-focused, open-source <strong>link management platform</strong>. Create a customizable profile page to manage <strong>all your important links in one convenient location</strong> and give your audience a seamless browsing experience.</p> '; - Page::first()->update(['home_message' => $home_message]); - } + Page::first()->update(['home_message' => $home_message]); +} - $migrationFiles = glob(database_path('migrations/*.php')); - - $fileNames = array_map(function ($file) { - return basename($file, '.php'); - }, $migrationFiles); - - foreach ($fileNames as $fileName) { - if (!DB::table('migrations')->where('migration', $fileName)->exists()) { - DB::table('migrations')->insert(['migration' => $fileName, 'batch' => 1]); - } - } +$migrationFiles = glob(database_path('migrations/*.php')); - /* Updates button database entries */ - Schema::disableForeignKeyConstraints(); - $existingMigration = '2021_03_17_044922_create_buttons_table'; +$fileNames = array_map(function ($file) { + return basename($file, '.php'); +}, $migrationFiles); - try { - if (DB::table('migrations')->where('migration', $existingMigration)->exists()) { - DB::table('migrations')->where('migration', $existingMigration)->delete(); - } - - Schema::dropIfExists('buttons'); - - $migrator = app('migrator'); - $migrator->run(database_path('migrations')); - - $seeder = new ButtonSeeder(); - $seeder->run(); - } catch (exception $e) {} - Schema::enableForeignKeyConstraints(); +foreach ($fileNames as $fileName) { + if (!DB::table('migrations')->where('migration', $fileName)->exists()) { + DB::table('migrations')->insert(['migration' => $fileName, 'batch' => 1]); + } +} - if (!Schema::hasColumn('users', 'auth_as')) { - Schema::table('users', function (Blueprint $table) { - $table->unsignedInteger('auth_as')->nullable(); - }); - } +/* Updates button database entries */ +Schema::disableForeignKeyConstraints(); +$existingMigration = '2021_03_17_044922_create_buttons_table'; - try { - DB::table('link_types')->updateOrInsert([ - 'typename' => 'text', - 'title' => 'Text', - 'icon' => 'bi bi-fonts', - 'description' => 'Add static text to your page that is not clickable.', - 'params' => '[{ +try { + if (DB::table('migrations')->where('migration', $existingMigration)->exists()) { + DB::table('migrations')->where('migration', $existingMigration)->delete(); + } + + Schema::dropIfExists('buttons'); + + $migrator = app('migrator'); + $migrator->run(database_path('migrations')); + + $seeder = new ButtonSeeder(); + $seeder->run(); +} catch (exception $e) { + session(['update_error' => $e->getMessage()]); +} +Schema::enableForeignKeyConstraints(); + +if (!Schema::hasColumn('users', 'auth_as')) { + Schema::table('users', function (Blueprint $table) { + $table->unsignedInteger('auth_as')->nullable(); + }); +} + +try { + DB::table('link_types')->updateOrInsert([ + 'typename' => 'text', + 'title' => 'Text', + 'icon' => 'bi bi-fonts', + 'description' => 'Add static text to your page that is not clickable.', + 'params' => '[{ "tag": "textarea", "id": "static-text", "for": "static_text", @@ -202,94 +305,128 @@ set_time_limit(0); "name": "static_text", "class": "form-control" } - ]' - ]); + ]', + ]); - DB::table('link_types')->updateOrInsert([ - 'typename' => 'email', - 'title' => 'E-Mail address', - 'icon' => 'bi bi-envelope-fill', - 'description' => 'Add an email that opens a system dialog to compose a new email.' - ]); + DB::table('link_types')->updateOrInsert([ + 'typename' => 'email', + 'title' => 'E-Mail address', + 'icon' => 'bi bi-envelope-fill', + 'description' => 'Add an email that opens a system dialog to compose a new email.', + ]); - DB::table('link_types')->updateOrInsert([ - 'typename' => 'telephone', - 'title' => 'Telephone number', - 'icon' => 'bi bi-telephone-fill', - 'description' => 'Add a telephone number that opens a system dialog to initiate a phone call.' - ]); + DB::table('link_types')->updateOrInsert([ + 'typename' => 'telephone', + 'title' => 'Telephone number', + 'icon' => 'bi bi-telephone-fill', + 'description' => 'Add a telephone number that opens a system dialog to initiate a phone call.', + ]); - DB::table('link_types')->updateOrInsert([ - 'typename' => 'vcard', - 'title' => 'Vcard', - 'icon' => 'bi bi-person-square', - 'description' => 'Create or upload an electronic business card.' - ]); - } catch (exception $e) {} + DB::table('link_types')->updateOrInsert([ + 'typename' => 'vcard', + 'title' => 'Vcard', + 'icon' => 'bi bi-person-square', + 'description' => 'Create or upload an electronic business card.', + ]); +} catch (exception $e) { + session(['update_error' => $e->getMessage()]); +} +// Moves all previous images to the new path +try { + if (is_dir(base_path('assets/img'))) { + $files = File::files(base_path('img')); + foreach ($files as $file) { + $filename = $file->getFilename(); + $destination = base_path('assets/img/' . $filename); + if (!File::exists($destination)) { + if (!$file->isDir()) { + File::move($file, $destination); + } + } + } + } +} catch (exception $e) { +} +try { + if (is_dir(base_path('assets/img/background-img'))) { + $files = File::files(base_path('img/background-img')); + foreach ($files as $file) { + $filename = $file->getFilename(); + $destination = base_path('assets/img/background-img/' . $filename); + if (!File::exists($destination)) { + if (!$file->isDir()) { + File::move($file, $destination); + } + } + } + } +} catch (exception $e) { +} +try { + if (is_dir(base_path('littlelink/images'))) { + $files = File::files(base_path('littlelink/images')); + foreach ($files as $file) { + $filename = $file->getFilename(); + $destination = base_path('assets/linkstack/images/' . $filename); + if (!File::exists($destination)) { + if (!$file->isDir()) { + File::move($file, $destination); + } + } + } + } +} catch (exception $e) { +} +try { + if (is_dir(base_path('littlelink/images'))) { + $files = File::files(base_path('littlelink/images')); + foreach ($files as $file) { + $filename = $file->getFilename(); + $destination = base_path('assets/linkstack/images/' . $filename); + if (!File::exists($destination)) { + if (!$file->isDir()) { + File::move($file, $destination); + } + } + } + } +} catch (exception $e) { +} +try { + if (is_dir(base_path('studio/favicon/icons'))) { + $files = File::files(base_path('studio/favicon/icons')); + foreach ($files as $file) { + $filename = $file->getFilename(); + $destination = base_path('assets/favicon/icons/' . $filename); + if (!File::exists($destination)) { + if (!$file->isDir()) { + File::move($file, $destination); + } + } + } + } +} catch (exception $e) { +} - // Moves all previous images to the new path -try{if (is_dir(base_path('assets/img'))) { - $files = File::files(base_path('img')); - foreach ($files as $file) { - $filename = $file->getFilename(); - $destination = base_path('assets/img/' . $filename); - if (!File::exists($destination)) { - if (!$file->isDir()) { - File::move($file, $destination);}}}} - }catch(exception $e) {} -try{if (is_dir(base_path('assets/img/background-img'))) { - $files = File::files(base_path('img/background-img')); - foreach ($files as $file) { - $filename = $file->getFilename(); - $destination = base_path('assets/img/background-img/' . $filename); - if (!File::exists($destination)) { - if (!$file->isDir()) { - File::move($file, $destination);}}}} - }catch(exception $e) {} -try{if (is_dir(base_path('littlelink/images'))) { - $files = File::files(base_path('littlelink/images')); - foreach ($files as $file) { - $filename = $file->getFilename(); - $destination = base_path('assets/linkstack/images/' . $filename); - if (!File::exists($destination)) { - if (!$file->isDir()) { - File::move($file, $destination);}}}} - }catch(exception $e) {} -try{if (is_dir(base_path('littlelink/images'))) { - $files = File::files(base_path('littlelink/images')); - foreach ($files as $file) { - $filename = $file->getFilename(); - $destination = base_path('assets/linkstack/images/' . $filename); - if (!File::exists($destination)) { - if (!$file->isDir()) { - File::move($file, $destination);}}}} - }catch(exception $e) {} -try{if (is_dir(base_path('studio/favicon/icons'))) { - $files = File::files(base_path('studio/favicon/icons')); - foreach ($files as $file) { - $filename = $file->getFilename(); - $destination = base_path('assets/favicon/icons/' . $filename); - if (!File::exists($destination)) { - if (!$file->isDir()) { - File::move($file, $destination);}}}} - }catch(exception $e) {} - - - // Changes saved profile images from littlelink_name to IDs. - // This runs every time the updater runs. - // Not sure if this will cause any issues. - // If it works, I won't touch it. - try { +// Changes saved profile images from littlelink_name to IDs. +// This runs every time the updater runs. +// Not sure if this will cause any issues. +// If it works, I won't touch it. +try { $users = DB::table('users')->get(); foreach ($users as $user) { $oldName = $user->littlelink_name . '.png'; $newName = $user->id . '.png'; $oldPath = base_path('assets/img/' . $oldName); $newPath = base_path('assets/img/' . $newName); - + if (File::exists($oldPath)) { File::move($oldPath, $newPath); - }}} catch (exception $e) {} + } + } +} catch (exception $e) { + session(['update_error' => $e->getMessage()]); +} - ?> \ No newline at end of file +?> diff --git a/resources/views/update.blade.php b/resources/views/update.blade.php index d1ae4e4..5b7d03c 100644 --- a/resources/views/update.blade.php +++ b/resources/views/update.blade.php @@ -62,6 +62,10 @@ @endif @if ($_SERVER['QUERY_STRING'] === 'updating') + <div class="logo-container fadein"> + <img class="logo-img" src="{{ asset('assets/linkstack/images/logo-loading.svg') }}" alt="Logo"> + </div> + <h1 class="loadingtxt">{{ __('messages.Updating') }}</h1> @php set_time_limit(0); try { @@ -105,7 +109,13 @@ session(['update_error' => 'Fatal error. ' . $e->getMessage()]); } @endphp - <meta http-equiv="refresh" content="0; {{ url()->current() }}/?finishing" /> + + @if (session()->has('update_error')) + <meta http-equiv="refresh" content="1; {{ url()->current() }}/?error" /> + @else + <meta http-equiv="refresh" content="0; {{ url()->current() }}/?finishing" /> + @endif + @endif @if ($_SERVER['QUERY_STRING'] === 'backup') @@ -184,17 +194,6 @@ @endif @endif - @if ( - $_SERVER['QUERY_STRING'] === 'updating' && - (file_exists(base_path('backups/CANUPDATE')) || env('SKIP_UPDATE_BACKUP') == true)) - <div class="logo-container fadein"> - <img class="logo-img" src="{{ asset('assets/linkstack/images/logo-loading.svg') }}" alt="Logo"> - </div> - <h1 class="loadingtxt">{{ __('messages.Updating') }}</h1> - @push('updater-head') - <meta http-equiv="refresh" content="2; URL={{ url()->current() }}/../updating" /> - @endpush - @endif @elseif(empty($_SERVER['QUERY_STRING'])) <div class="logo-container fadein"> <img class="logo-img" src="{{ asset('assets/linkstack/images/logo.svg') }}" alt="Logo">