From 5759d4819e5fe266503b761b412bfe77c0f82382 Mon Sep 17 00:00:00 2001 From: snipe Date: Tue, 10 Nov 2020 12:39:10 -0800 Subject: [PATCH] Improved upgrade.php script to check for PHP extensions (#8712) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Troubleshooting gd detection :( * Welp, that didn’t work. * Improvements to the update script that will make it easier to maintain * Improved spacing * Nicer intro * Sorry for all the commits - I have to push in order to test :( * More display improvements * Phrasing! * More formatting * Removed extra line break * Few more formatting changes * Remove the config caching - it’s too confusing for users * Added comments * Temp required extension in the array so I can show output :) * Added ascii x * removed extra line break * Made error message clearer * Remove extra line * Removed farts * Changed phrasing for PHP upgrade warning * Small tweaks per PR review * Some spacing fixes * Added confirmation of the either/ors * Minor formatting tweaks * Fixed weird indenting? * Fixed missing $unused_file variable --- upgrade.php | 217 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 125 insertions(+), 92 deletions(-) diff --git a/upgrade.php b/upgrade.php index a55c85ca4f..013b819536 100644 --- a/upgrade.php +++ b/upgrade.php @@ -19,73 +19,117 @@ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { // otherwise just use master (array_key_exists('1', $argv)) ? $branch = $argv[1] : $branch = 'master'; -echo "Welcome to the Snipe-IT upgrader.\n\n"; -echo "Please note that this script will not download the latest Snipe-IT \n"; -echo "files for you unless you have git installed. \n"; -echo "It simply runs the standard composer and artisan \n"; -echo "commands needed to finalize the upgrade after. \n\n"; - -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"; -echo "!! If you have any encrypted custom fields, BE SURE TO run the recrypter if upgrading from v3 to v4. \n"; -echo "!! See the Snipe-IT documentation for help: \n"; -echo "!! https://snipe-it.readme.io/docs/upgrading-to-v4\n"; -echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"; +echo "--------------------------------------------------------\n"; +echo "WELCOME TO THE SNIPE-IT UPGRADER! \n"; +echo "--------------------------------------------------------\n\n"; +echo "This script will attempt to: \n\n"; +echo "- check your PHP version and extension requirements \n"; +echo "- do a git pull to bring you to the latest version \n"; +echo "- run composer install to get your vendors up to date \n"; +echo "- run migrations to get your schema up to date \n"; +echo "- clear out old cache settings\n\n"; echo "--------------------------------------------------------\n"; echo "STEP 1: Checking PHP requirements: \n"; echo "--------------------------------------------------------\n\n"; -echo "Current PHP version: " . PHP_VERSION . "\n\n"; - if (version_compare(PHP_VERSION, $required_version, '<')) { echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ERROR !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"; - echo "This version of PHP is not compatible with Snipe-IT.\n"; + echo "This version of PHP (".PHP_VERSION.") is not compatible with Snipe-IT.\n"; echo "Snipe-IT requires PHP version ".$required_version." or greater. Please upgrade \n"; - echo "your server's version of PHP (mod and cli) and try running this script again.\n\n\n"; + echo "your version of PHP (web/php-fcgi and cli) and try running this script again.\n\n\n"; exit; } else { - echo "PHP version: " . PHP_VERSION . " is at least ".$required_version." - continuing... \n"; - echo sprintf("The php.ini used by PHP: %s\n\n", get_cfg_var('cfg_file_path'))."\n\n"; + echo "Current PHP version: (" . PHP_VERSION . ") is at least ".$required_version." - continuing... \n"; + echo sprintf("FYI: The php.ini used by this PHP is: %s\n\n", get_cfg_var('cfg_file_path')); } -$ext_check = ''; -if ((!extension_loaded('gd')) || (!extension_loaded('imagick'))) { - $ext_check .= "PHP extension MISSING: gd or imagick \n"; + +echo "Checking Required PHP extensions... \n\n"; + +// Get the list of installed extensions +$loaded_exts_array = get_loaded_extensions(); + +// The PHP extensions PHP is *required* to have enabled in order to run +$required_exts_array = + [ + 'bcmath', + 'curl', + 'fileinfo', + 'gd|imagick', + 'json', + 'ldap', + 'mbstring', + 'mysqli|pgsql', + 'openssl', + 'PDO', + 'tokenizer', + 'xml', + 'zip', + ]; + +$ext_missing = ''; +$ext_installed = ''; + +// Loop through the required extensions +foreach ($required_exts_array as $required_ext) { + + // If we don't find the string in the array.... + if (!in_array($required_ext, $loaded_exts_array)) { + + // Let's check for any options with pipes in them - those mean you can have either or + if (strpos($required_ext, '|')) { + + // Split the either/ors by their pipe and put them into an array + $require_either = explode("|", $required_ext); + + // Now loop through the either/or array and see whether any of the options match + foreach ($require_either as $require_either_value) { + + if (in_array($require_either_value, $loaded_exts_array)) { + $ext_installed .= '√ '.$require_either_value." is installed!\n"; + break; + // If no match, add it to the string for errors + } else { + $ext_missing .= '✘ MISSING PHP EXTENSION: '.str_replace("|", " OR ", $required_ext)."\n"; + break; + } + } + + // If this isn't an either/or option, just add it to the string of errors conventionally + } else { + $ext_missing .= '✘ MISSING PHP EXTENSION: '.$required_ext."\n"; + } + + // The required extension string was found in the array of installed extensions - yay! + } else { + $ext_installed .= '√ '.$required_ext." is installed!\n"; + } } -if (!extension_loaded('ldap')) { - $ext_check .= "PHP extension MISSING: php-ldap \n"; -} +// Print out a useful error message and abort the install +if ($ext_missing!='') { + echo "--------------------- !! ERROR !! ----------------------\n"; + echo $ext_missing; + echo "--------------------------------------------------------\n\n"; + echo "You have the following extensions installed: \n\n"; -if (!extension_loaded('json')) { - $ext_check .= "PHP extension MISSING: php-json \n"; -} + foreach ($loaded_exts_array as $loaded_ext) { + echo "- ".$loaded_ext."\n"; + } -if (!extension_loaded('fileinfo')) { - $ext_check .= "PHP extension MISSING: php-fileinfo \n"; -} - -if (!extension_loaded('openssl')) { - $ext_check .= "PHP extension MISSING: php-openssl \n"; -} - -if (!extension_loaded('curl')) { - $ext_check .= "PHP extension MISSING: php-curl \n"; -} - -if (!extension_loaded('mbstring')) { - $ext_check .= "PHP extension MISSING: php-mbstring \n"; -} - -if ($ext_check!='') { - echo "--------------------------------------------------------\n"; - echo $ext_check; - echo "ABORTING. Please install the extensions above and re-run this script."; - echo "--------------------------------------------------------\n"; + echo "------------------------- :( ---------------------------\n"; + echo "ABORTING THE INSTALLER \n"; + echo "Please install the extensions above and re-run this script.\n"; + echo "------------------------- :( ---------------------------\n"; exit; +} else { + echo $ext_installed."\n"; + } + echo "--------------------------------------------------------\n"; echo "STEP 2: Backing up database: \n"; echo "--------------------------------------------------------\n\n"; @@ -96,7 +140,7 @@ echo "--------------------------------------------------------\n"; echo "STEP 3: Putting application into maintenance mode: \n"; echo "--------------------------------------------------------\n\n"; $down = shell_exec('php artisan down'); -echo '-- '.$down."\n\n"; +echo '-- '.$down."\n"; echo "--------------------------------------------------------\n"; @@ -110,42 +154,42 @@ if ((strpos('git version', $git_version)) === false) { $git_checkout = shell_exec('git checkout '.$branch); $git_stash = shell_exec('git stash'); $git_pull = shell_exec('git pull'); - echo '-- '.$git_fetch; + echo $git_fetch; echo '-- '.$git_stash; echo '-- '.$git_checkout; - echo '-- '.$git_pull; + echo '-- '.$git_pull."\n"; } else { echo "Git is NOT installed. You can still use this upgrade script to run common \n"; echo "migration commands, but you will have to manually download the updated files. \n\n"; -} + echo "Please note that this script will not download the latest Snipe-IT \n"; + echo "files for you unless you have git installed. \n"; + echo "It simply runs the standard composer, artisan, and migration \n"; + echo "commands needed to finalize the upgrade after. \n\n"; +} echo "--------------------------------------------------------\n"; echo "Step 5: Cleaning up old cached files:\n"; echo "--------------------------------------------------------\n\n"; +// Build an array of the files we generally want to delete because they +// can cause issues with funky caching +$unused_files = [ + "bootstrap/cache/compiled.php", + "bootsrap/cache/services.php", + "bootstrap/cache/config.php", +]; -if (file_exists('bootstrap/cache/compiled.php')) { - echo "-- Deleting bootstrap/cache/compiled.php. It is no longer used.\n"; - @unlink('bootstrap/cache/compiled.php'); -} else { - echo "-- No bootstrap/cache/compiled.php, so nothing to delete.\n"; -} - -if (file_exists('bootstrap/cache/services.php')) { - echo "-- Deleting bootstrap/cache/services.php. It it no longer used.\n"; - @unlink('bootstrap/cache/services.php'); -} else { - echo "-- No bootstrap/cache/services.php, so nothing to delete.\n"; -} - -if (file_exists('bootstrap/cache/config.php')) { - echo "-- Deleting bootstrap/cache/config.php. It it no longer used.\n"; - @unlink('bootstrap/cache/config.php'); -} else { - echo "-- No bootstrap/cache/config.php, so nothing to delete.\n"; +foreach ($unused_files as $unused_file) { + if (file_exists($unused_file)) { + echo "√ Deleting ".$unused_file.". It is no longer used.\n"; + @unlink($unused_file); + } else { + echo "√ No ".$unused_file.", so nothing to delete.\n"; + } } +echo "\n"; $config_clear = shell_exec('php artisan config:clear'); $cache_clear = shell_exec('php artisan cache:clear'); @@ -165,7 +209,7 @@ echo "--------------------------------------------------------\n\n"; // Composer install if (file_exists('composer.phar')) { - echo "-- Local composer.phar detected, so we'll use that.\n\n"; + echo "√ Local composer.phar detected, so we'll use that.\n\n"; echo "-- Updating local composer.phar\n\n"; $composer_update = shell_exec('php composer.phar self-update'); echo $composer_update."\n\n"; @@ -174,13 +218,13 @@ if (file_exists('composer.phar')) { $composer = shell_exec('php composer.phar install --no-dev --prefer-source'); } else { - echo "-- We couldn't find a local composer.phar - trying globally.\n\n"; + echo "-- We couldn't find a local composer.phar. No worries, trying globally.\n\n"; $composer_dump = shell_exec('composer dump'); $composer = shell_exec('composer install --no-dev --prefer-source'); } -echo $composer_dump."\n\n"; -echo $composer."\n\n"; +echo $composer_dump."\n"; +echo $composer; echo "--------------------------------------------------------\n"; @@ -188,7 +232,7 @@ echo "Step 7: Migrating database:\n"; echo "--------------------------------------------------------\n\n"; $migrations = shell_exec('php artisan migrate --force'); -echo '-- '.$migrations."\n\n"; +echo $migrations."\n"; echo "--------------------------------------------------------\n"; @@ -201,33 +245,22 @@ if ((!file_exists('storage/oauth-public.key')) || (!file_exists('storage/oauth-p $passport = shell_exec('php artisan passport:install'); echo $passport; } else { - echo "- OAuth keys detected. Skipping passport install.\n\n"; + echo "√ OAuth keys detected. Skipping passport install.\n\n"; } echo "--------------------------------------------------------\n"; -echo "Step 9: Caching routes and config:\n"; -echo "--------------------------------------------------------\n\n"; -$config_cache = shell_exec('php artisan config:cache'); -$route_cache = shell_exec('php artisan route:cache'); -echo '-- '.$config_cache; -echo '-- '.$route_cache; -echo "\n"; - - - -echo "--------------------------------------------------------\n"; -echo "Step 10: Taking application out of maintenance mode:\n"; +echo "Step 9: Taking application out of maintenance mode:\n"; echo "--------------------------------------------------------\n\n"; $up = shell_exec('php artisan up'); -echo '-- '.$up."\n\n"; +echo '-- '.$up."\n"; -echo "--------------------------------------------------------\n"; -echo "FINISHED! Clear your browser cookies and re-login to use :\n"; -echo "your upgraded Snipe-IT.\n"; +echo "---------------------- FINISHED! -----------------------\n"; +echo "All done! Clear your browser cookies and re-login to use \n"; +echo "your upgraded Snipe-IT!\n"; echo "--------------------------------------------------------\n\n";