782 lines
42 KiB
PHP
782 lines
42 KiB
PHP
|
<?php
|
||
|
/*********************************************************************************
|
||
|
*
|
||
|
* TimeTrex is a Workforce Management program developed by
|
||
|
* TimeTrex Software Inc. Copyright (C) 2003 - 2021 TimeTrex Software Inc.
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify it under
|
||
|
* the terms of the GNU Affero General Public License version 3 as published by
|
||
|
* the Free Software Foundation with the addition of the following permission
|
||
|
* added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
|
||
|
* WORK IN WHICH THE COPYRIGHT IS OWNED BY TIMETREX, TIMETREX DISCLAIMS THE
|
||
|
* WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||
|
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||
|
* details.
|
||
|
*
|
||
|
*
|
||
|
* You should have received a copy of the GNU Affero General Public License along
|
||
|
* with this program; if not, see http://www.gnu.org/licenses or write to the Free
|
||
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||
|
* 02110-1301 USA.
|
||
|
*
|
||
|
*
|
||
|
* You can contact TimeTrex headquarters at Unit 22 - 2475 Dobbin Rd. Suite
|
||
|
* #292 West Kelowna, BC V4T 2E9, Canada or at email address info@timetrex.com.
|
||
|
*
|
||
|
*
|
||
|
* The interactive user interfaces in modified source and object code versions
|
||
|
* of this program must display Appropriate Legal Notices, as required under
|
||
|
* Section 5 of the GNU Affero General Public License version 3.
|
||
|
*
|
||
|
*
|
||
|
* In accordance with Section 7(b) of the GNU Affero General Public License
|
||
|
* version 3, these Appropriate Legal Notices must retain the display of the
|
||
|
* "Powered by TimeTrex" logo. If the display of the logo is not reasonably
|
||
|
* feasible for technical reasons, the Appropriate Legal Notices must display
|
||
|
* the words "Powered by TimeTrex".
|
||
|
*
|
||
|
********************************************************************************/
|
||
|
|
||
|
//This must go above include for global.inc.php
|
||
|
if ( isset( $argv ) && in_array( '--config', $argv ) ) {
|
||
|
$_SERVER['TT_CONFIG_FILE'] = trim( $argv[( array_search( '--config', $argv ) + 1 )] );
|
||
|
}
|
||
|
|
||
|
//If requirements only check is enabled, do not connect to the database just in case the database isnt setup yet or setup incorrectly.
|
||
|
if ( isset( $argv ) && in_array( '--requirements_only', $argv ) ) {
|
||
|
$disable_database_connection = true;
|
||
|
}
|
||
|
|
||
|
require_once( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'global.inc.php' );
|
||
|
|
||
|
//Always enable debug logging during upgrade.
|
||
|
Debug::setEnable( true );
|
||
|
Debug::setBufferOutput( true );
|
||
|
Debug::setEnableLog( true );
|
||
|
Debug::setVerbosity( 10 );
|
||
|
ignore_user_abort( true );
|
||
|
ini_set( 'default_socket_timeout', 5 );
|
||
|
ini_set( 'allow_url_fopen', 1 );
|
||
|
ini_set( 'max_execution_time', 0 );
|
||
|
ini_set( 'memory_limit', '2048M' ); //Just in case.
|
||
|
|
||
|
require_once( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'includes' . DIRECTORY_SEPARATOR . 'CLI.inc.php' );
|
||
|
|
||
|
//Since we aren't including database.inc.php, force the timezone to be set to avoid WARNING(2): getdate(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set()
|
||
|
//Sometimes scripts won't make a database connection
|
||
|
if ( !isset( $config_vars['other']['system_timezone'] ) || ( isset( $config_vars['other']['system_timezone'] ) && $config_vars['other']['system_timezone'] == '' ) ) {
|
||
|
$config_vars['other']['system_timezone'] = @date( 'e' );
|
||
|
}
|
||
|
if ( $config_vars['other']['system_timezone'] == '' ) {
|
||
|
$config_vars['other']['system_timezone'] = 'GMT';
|
||
|
}
|
||
|
TTDate::setTimeZone( $config_vars['other']['system_timezone'], false, false ); //Don't force SQL to be executed here, as an optimization to avoid DB connections when calling things like getProgressBar()
|
||
|
|
||
|
//Re-initialize install object with new config file.
|
||
|
$install_obj = new Install();
|
||
|
|
||
|
if ( isset( $config_vars['other']['primary_company_id'] ) ) {
|
||
|
$company_id = $config_vars['other']['primary_company_id'];
|
||
|
} else {
|
||
|
$company_id = null;
|
||
|
}
|
||
|
|
||
|
//The installer already checks the cache directory to make sure its writable, so use that as the upgrade staging directory.
|
||
|
//The cache dir does get cleaned once per week though, but if an upgrade failed that may be helpful.
|
||
|
if ( !isset( $config_vars['cache']['dir'] ) ) { //Just in case the cache directory is not set.
|
||
|
$config_vars['cache']['dir'] = Environment::getBasePath();
|
||
|
}
|
||
|
$upgrade_staging_dir = $config_vars['cache']['dir'] . DIRECTORY_SEPARATOR . 'upgrade_staging' . DIRECTORY_SEPARATOR;
|
||
|
$upgrade_staging_latest_dir = $upgrade_staging_dir . DIRECTORY_SEPARATOR . 'latest_version';
|
||
|
$upgrade_file_name = $config_vars['cache']['dir'] . DIRECTORY_SEPARATOR . 'UPGRADE.ZIP';
|
||
|
$php_cli = $config_vars['path']['php_cli'];
|
||
|
|
||
|
function moveUpgradeFiles( $upgrade_staging_latest_dir ) {
|
||
|
$latest_file_list = Misc::getFileList( $upgrade_staging_latest_dir, null, true );
|
||
|
if ( is_array( $latest_file_list ) && count( $latest_file_list ) > 0 ) {
|
||
|
foreach ( $latest_file_list as $latest_file ) {
|
||
|
$new_file = str_replace( $upgrade_staging_latest_dir, Environment::getBasePath(), $latest_file );
|
||
|
|
||
|
//Check if directory exists.
|
||
|
if ( !is_dir( dirname( $new_file ) ) ) {
|
||
|
Debug::Text( 'Creating new directory: ' . dirname( $new_file ), __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
if ( @mkdir( dirname( $new_file ), 0755, true ) == false ) { //Read+Write+Execute for owner, Read/Execute for all others.
|
||
|
Debug::Text( 'ERROR: FAILED TO CREATE DIRECTORY: ' . $new_file, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
}
|
||
|
}
|
||
|
Debug::Text( 'Moving: ' . $latest_file . ' To: ' . $new_file, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
if ( Misc::rename( $latest_file, $new_file ) == false ) {
|
||
|
Debug::Text( 'ERROR: FAILED TO MOVE: ' . $latest_file . ' To: ' . $new_file, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
Debug::Text( 'No files to move... Are we running --stage2 perhaps?', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
}
|
||
|
|
||
|
clearstatcache();
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function setAutoUpgradeFailed( $value = 1 ) {
|
||
|
//When upgrading from pre-UUID versions, its possible if a failure occurs before the schema version upgrade has fully completed,
|
||
|
// setSystemSetting() will then fail with a PHP fatal error saying it can't find class TTUUID, preventing the error log from being captured.
|
||
|
if ( class_exists( 'TTUUID' ) == true ) {
|
||
|
SystemSettingFactory::setSystemSetting( 'auto_upgrade_failed', $value );
|
||
|
if ( $value == 1 ) {
|
||
|
// Auto upgrade failed
|
||
|
if ( DEMO_MODE == false && PRODUCTION == true ) {
|
||
|
global $db;
|
||
|
|
||
|
//Make sure the notification table exists so when upgrading from versions without notifications, to versions with notifications,
|
||
|
// if the system requirements check or schema fails we don't trigger a SQL exception attempting to send a notification.
|
||
|
$install_obj = new Install();
|
||
|
$install_obj->setDatabaseConnection( $db ); //Default connection
|
||
|
if ( $install_obj->checkTableExists( 'notification' ) == true ) {
|
||
|
|
||
|
Debug::Text( ' Notification table exists, sending notifications about the upgrade failure...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
$notification_data = [
|
||
|
'object_id' => TTUUID::getNotExistID( 1110 ),
|
||
|
'object_type_id' => 0,
|
||
|
'type_id' => 'system',
|
||
|
'title_short' => TTi18n::getText( 'Automatic upgrade failed' ),
|
||
|
'body_short' => TTi18n::getText( 'WARNING: %1 automatic upgrade has failed due to a system error! Please contact your %1 administrator immediately to re-run the %1 installer to correct the issue.', APPLICATION_NAME ),
|
||
|
];
|
||
|
|
||
|
Notification::sendNotificationToAllusers( 80, true, true, $notification_data, 604800 ); //ZZZ REMOVE ME
|
||
|
|
||
|
return true;
|
||
|
} else {
|
||
|
Debug::Text( 'ERROR: Notification table does not exist, unable to send notifications...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Debug::Text( 'ERROR: AutoUpgrade Failed, setting failed flag...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
} else {
|
||
|
Debug::Text( 'AutoUpgrade Success, clearing failed flag...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
|
||
|
//Clear other messages that likely aren't valid anymore.
|
||
|
SystemSettingFactory::setSystemSetting( 'valid_install_requirements', 1 );
|
||
|
SystemSettingFactory::setSystemSetting( 'new_version', 0 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function CLIExit( $code = 0, $delete_lock_file = true ) {
|
||
|
Debug::Display();
|
||
|
Debug::writeToLog();
|
||
|
|
||
|
if ( $delete_lock_file == true ) {
|
||
|
global $lock_file;
|
||
|
if ( is_object( $lock_file ) ) {
|
||
|
$lock_file->delete();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exit( $code );
|
||
|
}
|
||
|
|
||
|
Debug::Text( 'Version: ' . APPLICATION_VERSION . ' (PHP: v' . phpversion() . ') Edition: ' . getTTProductEdition() . ' Production: ' . (int)PRODUCTION . ' Server: ' . ( isset( $_SERVER['SERVER_ADDR'] ) ? $_SERVER['SERVER_ADDR'] : 'N/A' ) . ' Database: Type: ' . ( isset( $config_vars['database']['type'] ) ? $config_vars['database']['type'] : 'N/A' ) . ' Name: ' . ( isset( $config_vars['database']['database_name'] ) ? $config_vars['database']['database_name'] : 'N/A' ) . ' Config: ' . CONFIG_FILE . ' Demo Mode: ' . (int)DEMO_MODE, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
|
||
|
//Force flush after each output line.
|
||
|
ob_implicit_flush( true );
|
||
|
ob_end_flush();
|
||
|
|
||
|
if ( isset( $argv[1] ) && in_array( $argv[1], [ '--help', '-help', '-h', '-?' ] ) ) {
|
||
|
$help_output = "Usage: unattended_upgrade.php\n";
|
||
|
$help_output .= " [--config] = Config file to use.\n";
|
||
|
$help_output .= " [--schema_only] = Run a schema upgrade only.\n";
|
||
|
$help_output .= " [--pre_requirements_update] = Run a pre system requirements update.\n";
|
||
|
$help_output .= " [--requirements_only] = Run a system requirements check only.\n";
|
||
|
$help_output .= " [-f] = Force upgrade even if INSTALL mode is disabled.\n";
|
||
|
echo $help_output;
|
||
|
} else {
|
||
|
//Create lock file so the same clock isn't being synchronized more then once at a time.
|
||
|
// Use arguments in lock file name, so each argument or separate run has a separte lock file.
|
||
|
$lock_file_name = $config_vars['cache']['dir'] . DIRECTORY_SEPARATOR . 'UnAttended_Upgrade_' . crc32( serialize( $argv ) ); //hash the arguments so we always use a different lock file name when using different arguments.
|
||
|
$lock_file = new LockFile( $lock_file_name . '.lock' );
|
||
|
$lock_file->max_lock_file_age = ( 3600 * 3 ); //3 hrs.
|
||
|
Debug::text( 'Lock File: ' . $lock_file->getFileName(), __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
if ( $lock_file->exists() == true ) {
|
||
|
Debug::text( 'Lock File already exists, exiting...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo 'Upgrade is already running, please wait for it to finish...' . "\n";
|
||
|
CLIExit( 253, false ); //Don't delete lock file.
|
||
|
} else {
|
||
|
if ( $lock_file->create() == false ) {
|
||
|
Debug::text( 'Unable to create lock file, likely already exists, exiting...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
}
|
||
|
//Continue trying to run even if we can't create the lock file.
|
||
|
}
|
||
|
unset( $lock_file_name );
|
||
|
|
||
|
$last_arg = ( count( $argv ) - 1 );
|
||
|
|
||
|
if ( in_array( '-f', $argv ) ) {
|
||
|
$force = true;
|
||
|
} else {
|
||
|
$force = false;
|
||
|
}
|
||
|
|
||
|
//Full force mode, forces upgrade even if the file downloaded is the same version.
|
||
|
//Primarily should be used when UPGRADE.ZIP already exists.
|
||
|
if ( in_array( '-ff', $argv ) ) {
|
||
|
$force = true;
|
||
|
$full_force = true;
|
||
|
} else {
|
||
|
$full_force = false;
|
||
|
}
|
||
|
|
||
|
if ( isset( $argv ) && in_array( '--upgrade_file', $argv ) ) { //Allow forcing a specific file to use for upgrading instead of downloading one.
|
||
|
$manual_upgrade_file_name = trim( $argv[( array_search( '--upgrade_file', $argv ) + 1 )] );
|
||
|
}
|
||
|
|
||
|
if ( in_array( '--pre_requirements_update', $argv ) ) {
|
||
|
Debug::Text( 'Running pre-requirements update only...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
if ( $force == true || version_compare( APPLICATION_VERSION, '10.0.0', '>=' ) == true ) {
|
||
|
//Cant enable INTL/ZIP extensions, as they won't load on some stack installs...
|
||
|
// Debug::Text(' Running: v10.0.0 Pre-Requirements Update...', __FILE__, __LINE__, __METHOD__, 10);
|
||
|
//
|
||
|
// //Check if stack installer was used, if so, attempt to enable INTL extension.
|
||
|
// if ( PHP_OS == 'WINNT' ) {
|
||
|
// $full_stack_file = dirname(__FILE__) . DIRECTORY_SEPARATOR .'..'. DIRECTORY_SEPARATOR .'..'. DIRECTORY_SEPARATOR .'..'. DIRECTORY_SEPARATOR .'..'. DIRECTORY_SEPARATOR .'start.bat';
|
||
|
// Debug::Text(' Checking if this is a full stack install or not: '. $full_stack_file, __FILE__, __LINE__, __METHOD__, 10);
|
||
|
// if ( !file_exists( $full_stack_file ) ) {
|
||
|
// $full_stack_file = dirname(__FILE__) . DIRECTORY_SEPARATOR .'..'. DIRECTORY_SEPARATOR .'..'. DIRECTORY_SEPARATOR .'start.bat';
|
||
|
// Debug::Text(' bChecking if this is a full stack install or not: '. $full_stack_file, __FILE__, __LINE__, __METHOD__, 10);
|
||
|
// if ( !file_exists( $full_stack_file ) ) {
|
||
|
// Debug::Text(' This is NOT a full stack install... Exiting...', __FILE__, __LINE__, __METHOD__, 10);
|
||
|
// CLIExit(0); //Exit success as it may not be a stack install.
|
||
|
// }
|
||
|
// }
|
||
|
//
|
||
|
// $stack_install_dir = realpath( dirname( $full_stack_file ) );
|
||
|
// Debug::Text(' Checking full stack install directory: '. $stack_install_dir, __FILE__, __LINE__, __METHOD__, 10);
|
||
|
// if ( file_exists( $stack_install_dir ) ) {
|
||
|
// Debug::Text(' Found full stack install directory: '. $stack_install_dir, __FILE__, __LINE__, __METHOD__, 10);
|
||
|
// $php_ini_file = $stack_install_dir. DIRECTORY_SEPARATOR .'php'. DIRECTORY_SEPARATOR .'php.ini';
|
||
|
// if ( file_exists( $php_ini_file ) ) {
|
||
|
// Debug::Text( ' PHP INI file found: '. $php_ini_file, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
// $php_ini_contents = file_get_contents( $php_ini_file );
|
||
|
//
|
||
|
// //Enable PHP MCRYPT extension. Seems like it was compiled under a wrong version of PHP though, so don't do this.
|
||
|
// //$php_ini_contents = preg_replace('/^;extension=php_mcrypt\.dll/mi', 'extension=php_mcrypt.dll', $php_ini_contents, -1, $replacement_count );
|
||
|
// //Debug::Text( ' PHP.INI replacements: MCRYPT: '. $replacement_count, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
//
|
||
|
// //Enable PHP OPENSSL extension.
|
||
|
// $php_ini_contents = preg_replace('/^;extension=php_openssl\.dll/mi', 'extension=php_openssl.dll', $php_ini_contents, -1, $replacement_count );
|
||
|
// Debug::Text( ' PHP.INI replacements: OPENSSL: '. $replacement_count, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
//
|
||
|
// //Enable PHP ZIP and INTL extensions. Seems like ZIP was compiled under a different version of PHP, so don't enable it.
|
||
|
// //$php_ini_contents = preg_replace('/^;extension=php_zip\.dll/mi', 'extension=php_zip.dll'. PHP_EOL .'extension=php_intl.dll', $php_ini_contents, -1, $replacement_count );
|
||
|
// if ( preg_match( '/^extension=php_intl\.dll/mi', $php_ini_contents ) === 0 ) { //Don't replace it if it already is enabled.
|
||
|
// $php_ini_contents = preg_replace( '/^;extension=php_zip\.dll/mi', ';extension=php_zip.dll' . PHP_EOL . 'extension=php_intl.dll', $php_ini_contents, -1, $replacement_count );
|
||
|
// Debug::Text( ' PHP.INI replacements: ZIP/INTL: ' . $replacement_count, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
// }
|
||
|
//
|
||
|
// if ( $php_ini_contents !== NULL ) {
|
||
|
// Debug::Arr( $php_ini_contents, ' Writing out new PHP.INI contents: ', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
// file_put_contents( $php_ini_file, $php_ini_contents );
|
||
|
//
|
||
|
// system( $stack_install_dir . DIRECTORY_SEPARATOR .'restart.bat', $exit_code );
|
||
|
// Debug::Text( ' Restarting TimeTrex services... Exit Code: '. $exit_code, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
// CLIExit(0);
|
||
|
// } else {
|
||
|
// Debug::Text( ' PHP INI modification failed, or none to make!', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
// CLIExit(0);
|
||
|
// }
|
||
|
// }
|
||
|
// }
|
||
|
// }
|
||
|
}
|
||
|
CLIExit( 0 );
|
||
|
}
|
||
|
|
||
|
if ( in_array( '--requirements_only', $argv ) ) {
|
||
|
Debug::Text( 'Checking requirements only...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
$exclude_requirements = [ 'php_cli_requirements', 'base_url', 'clean_cache' ];
|
||
|
if ( in_array( '--web_installer', $argv ) ) {
|
||
|
Debug::Text( ' Launched from web installer...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
//When run from the web_installer most requirements are already checked, so exclude the slow ones.
|
||
|
$exclude_requirements[] = 'disk_space';
|
||
|
$exclude_requirements[] = 'file_checksums';
|
||
|
$exclude_requirements[] = 'file_permissions';
|
||
|
$exclude_requirements[] = 'clean_cache';
|
||
|
}
|
||
|
|
||
|
$install_obj->cleanCacheDirectory();
|
||
|
if ( $install_obj->checkAllRequirements( false, $exclude_requirements ) == 0 ) {
|
||
|
echo 'Requirements all pass successfully!' . "\n";
|
||
|
CLIExit( 0 );
|
||
|
//CLIExit(1); //Test failed system requirement check...
|
||
|
} else {
|
||
|
echo 'Failed Requirements: ' . implode( ',', $install_obj->getFailedRequirements( false, $exclude_requirements ) ) . "\n";
|
||
|
CLIExit( 1 );
|
||
|
}
|
||
|
unset( $exclude_requirements );
|
||
|
}
|
||
|
|
||
|
if ( $force == true ) {
|
||
|
echo "Force Mode enabled...\n";
|
||
|
//Force installer_enabled to TRUE so we don't have to manually modify the config file with scripts.
|
||
|
$config_vars['other']['installer_enabled'] = true;
|
||
|
}
|
||
|
$install_obj = new Install(); //Re-initialize install object with new config options set above. (force)
|
||
|
|
||
|
|
||
|
if ( in_array( '--schema_only', $argv ) ) {
|
||
|
if ( $install_obj->isInstallMode() == false ) {
|
||
|
echo "ERROR: Install mode is not enabled in the timetrex.ini.php file!\n";
|
||
|
CLIExit( 1 );
|
||
|
} else {
|
||
|
$install_obj->cleanCacheDirectory();
|
||
|
if ( $install_obj->checkAllRequirements( true ) == 0 ) {
|
||
|
$install_obj->setDatabaseConnection( $db ); //Default connection
|
||
|
|
||
|
//Make sure at least one company exists in the database, this only works for upgrades, not initial installs.
|
||
|
if ( $install_obj->checkDatabaseExists( $config_vars['database']['database_name'] ) == true ) {
|
||
|
if ( $install_obj->checkTableExists( 'company' ) == true ) {
|
||
|
//Check to see if the DB schema is before the UUID upgrade (schema 1070 or older) and set the $PRIMARY_KEY_IS_UUID accordingly.
|
||
|
// THIS IS in tools/unattended_install.php, tools/unattended_upgrade.php, includes/database.inc.php as well.
|
||
|
// Must go after we check that the database and company table exist, otherwise it will just cause a SQL exception.
|
||
|
if ( (int)SystemSettingFactory::getSystemSettingValueByKey( 'schema_version_group_A' ) < 1100 ) {
|
||
|
Debug::Text( 'Setting PRIMARY_KEY_IS_UUID to FALSE due to pre-UUID schema version: ' . SystemSettingFactory::getSystemSettingValueByKey( 'schema_version_group_A' ), __FILE__, __LINE__, __METHOD__, 1 );
|
||
|
$PRIMARY_KEY_IS_UUID = false;
|
||
|
}
|
||
|
|
||
|
//Table could be created, but check to make sure a company actually exists too.
|
||
|
$clf = TTnew( 'CompanyListFactory' );
|
||
|
$clf->getAll();
|
||
|
if ( $clf->getRecordCount() >= 1 ) {
|
||
|
$install_obj->setIsUpgrade( true );
|
||
|
} else {
|
||
|
//No company exists, send them to the create company page.
|
||
|
$install_obj->setIsUpgrade( false );
|
||
|
}
|
||
|
} else {
|
||
|
$install_obj->setIsUpgrade( false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( $install_obj->getIsUpgrade() == true ) {
|
||
|
if ( $install_obj->checkDatabaseExists( $config_vars['database']['database_name'] ) == true ) {
|
||
|
//Create SQL, always try to install every schema version, as
|
||
|
//installSchema() will check if its already been installed or not.
|
||
|
$install_obj->setDatabaseDriver( $config_vars['database']['type'] );
|
||
|
$retval = $install_obj->createSchemaRange( null, null ); //All schema versions
|
||
|
if ( $retval == true ) {
|
||
|
$install_obj->setVersions();
|
||
|
|
||
|
//Clear all cache. -- This is already done in createSchemaRange() too. But setVersions() could create additional cache files we want to clear.
|
||
|
$install_obj->cleanCacheDirectory();
|
||
|
$cache->clean();
|
||
|
|
||
|
echo "Upgrade successfull!\n";
|
||
|
CLIExit( 0 );
|
||
|
} else {
|
||
|
Debug::Text( 'ERROR: Unable to upgrade database schema.', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "ERROR: Unable to upgrade database schema!\n";
|
||
|
}
|
||
|
} else {
|
||
|
Debug::Text( 'ERROR: Database does not exist.', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "ERROR: Database does not exists!\n";
|
||
|
}
|
||
|
} else {
|
||
|
echo "ERROR: No company exists for upgrading!\n";
|
||
|
}
|
||
|
} else {
|
||
|
echo "ERROR: System requirements are not satisfied, or a new version exists!\n";
|
||
|
}
|
||
|
}
|
||
|
CLIExit( 1 );
|
||
|
}
|
||
|
|
||
|
//Upgrade Stage2
|
||
|
if ( in_array( '--stage2', $argv ) ) {
|
||
|
/*
|
||
|
Steps to do full upgrade:
|
||
|
- Check if new version is available, send FORCE flag to help update some clients sooner if required.
|
||
|
- If new version exists:
|
||
|
- Enable logging (in memory), don't modify config file.
|
||
|
- Check existing system requirements/checksums to make sure no files have been changed and system requirements are still met.
|
||
|
This should also check permissions to make sure the files are all writable by the user who is running the script.
|
||
|
- Download new version .ZIP file, extract to 'upgrade_staging' directory.
|
||
|
- Run system requirement check for new version in staging directory, to make sure we can upgrade to that version.
|
||
|
- (?)Force a database backup if possible.
|
||
|
- Copy main directory to 'upgrade_rollback' directory.
|
||
|
- Move staging directory over top of main directory
|
||
|
- Run schema upgrade.
|
||
|
- Done.
|
||
|
*/
|
||
|
|
||
|
Debug::Text( 'AutoUpgrade Stage2... Version: ' . APPLICATION_VERSION, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
if ( $force == false && ( PRODUCTION == false || DEPLOYMENT_ON_DEMAND == true ) ) { //Allow FORCE=TRUE to override this.
|
||
|
echo "ERROR: Not doing full upgrade when PRODUCTION mode is disabled, or in ONDEMAND mode... Use FORCE argument to override.\n";
|
||
|
CLIExit( 1 );
|
||
|
}
|
||
|
|
||
|
$config_vars['other']['installer_enabled'] = true;
|
||
|
|
||
|
echo "Performing any necessary corrections from previous version...\n";
|
||
|
//From v7.3.1 to 7.3.2 some files weren't getting copied if they were new in this version and created a new directory.
|
||
|
//So do the copy again in stage2 just in case.
|
||
|
moveUpgradeFiles( $upgrade_staging_latest_dir );
|
||
|
|
||
|
echo "Upgrading database schema...\n";
|
||
|
//Don't check file_checksums, as the script is run from the old version and therefore the checksum version match will fail everytime.
|
||
|
//They should have been checked above anyways, so in theory this shouldn't matter.
|
||
|
|
||
|
@file_get_contents( 'http://www.timetrex.com/' . URLBuilder::getURL( [ 'v' => $install_obj->getFullApplicationVersion(), 'page' => 'unattended_upgrade_stage2_requirements' ], 'pre_install.php' ), 'r' );
|
||
|
if ( $install_obj->checkAllRequirements( false, [ 'file_checksums', 'php_cli_requirements', 'base_url', 'clean_cache' ] ) == 0 ) {
|
||
|
$install_obj->setDatabaseConnection( $db ); //Default connection
|
||
|
|
||
|
//Make sure at least one company exists in the database, this only works for upgrades, not initial installs.
|
||
|
if ( $install_obj->checkDatabaseExists( $config_vars['database']['database_name'] ) == true ) {
|
||
|
if ( $install_obj->checkTableExists( 'company' ) == true ) {
|
||
|
//Table could be created, but check to make sure a company actually exists too.
|
||
|
$clf = TTnew( 'CompanyListFactory' );
|
||
|
$clf->getAll();
|
||
|
if ( $clf->getRecordCount() >= 1 ) {
|
||
|
$install_obj->setIsUpgrade( true );
|
||
|
} else {
|
||
|
//No company exists, send them to the create company page.
|
||
|
$install_obj->setIsUpgrade( false );
|
||
|
}
|
||
|
} else {
|
||
|
$install_obj->setIsUpgrade( false );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( $install_obj->getIsUpgrade() == true ) {
|
||
|
if ( $install_obj->checkDatabaseExists( $config_vars['database']['database_name'] ) == true ) {
|
||
|
Debug::Text( 'Upgrading schema now...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
//Create SQL, always try to install every schema version, as
|
||
|
//installSchema() will check if its already been installed or not.
|
||
|
$install_obj->setDatabaseDriver( $config_vars['database']['type'] );
|
||
|
$install_obj->createSchemaRange( null, null ); //All schema versions
|
||
|
$install_obj->setVersions();
|
||
|
|
||
|
Debug::Text( 'Upgrading database schema successful!', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "Upgrading database schema successful!\n";
|
||
|
@file_get_contents( 'http://www.timetrex.com/' . URLBuilder::getURL( [ 'v' => $install_obj->getFullApplicationVersion(), 'page' => 'unattended_upgrade_new_schema' ], 'pre_install.php' ), 'r' );
|
||
|
|
||
|
Debug::Text( 'Cleaning up temporary files...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "Cleaning up temporary files...\n";
|
||
|
//Send version data before and after upgrade.
|
||
|
$ttsc = new TimeTrexSoapClient();
|
||
|
$ttsc->sendCompanyData( $company_id, true );
|
||
|
$ttsc->sendCompanyVersionData( $company_id );
|
||
|
|
||
|
//Attempt to update license file if necessary.
|
||
|
$license = new TTLicense();
|
||
|
$license->getLicenseFile( false );
|
||
|
|
||
|
//Clear all cache.
|
||
|
$install_obj->cleanCacheDirectory();
|
||
|
$cache->clean();
|
||
|
|
||
|
Misc::cleanDir( $upgrade_staging_dir, true, true, true );
|
||
|
@unlink( $upgrade_file_name );
|
||
|
|
||
|
Debug::Text( 'Stage 2 Successfull!', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "Stage 2 Successfull!\n";
|
||
|
@file_get_contents( 'http://www.timetrex.com/' . URLBuilder::getURL( [ 'v' => $install_obj->getFullApplicationVersion(), 'page' => 'unattended_upgrade_done' ], 'pre_install.php' ), 'r' );
|
||
|
|
||
|
//Make sure we disable the installer even if an error has occurred.
|
||
|
//Since v7.3.0 had a bug where the installer never disabled, force it disabled here for at least one version just in case.
|
||
|
//Even though we have switched to using the variable only, and this isn't needed anymore.
|
||
|
$data['other']['installer_enabled'] = 'FALSE';
|
||
|
$data['other']['default_interface'] = 'html5';
|
||
|
$install_obj->writeConfigFile( $data );
|
||
|
|
||
|
CLIExit( 0 );
|
||
|
} else {
|
||
|
Debug::Text( 'ERROR: Database does not exist.', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "ERROR: Database does not exists!\n";
|
||
|
}
|
||
|
} else {
|
||
|
Debug::Text( 'ERROR: No company exists for upgrading', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "ERROR: No company exists for upgrading!\n";
|
||
|
}
|
||
|
} else {
|
||
|
Debug::Text( 'ERROR: New system requirements are not satisfied!', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "ERROR: New system requirements are not satisfied!\n";
|
||
|
}
|
||
|
|
||
|
CLIExit( 1 );
|
||
|
}
|
||
|
|
||
|
//Stage 1, Full upgrade, including downloading the file.
|
||
|
if ( in_array( '--schema_only', $argv ) == false && in_array( '--stage2', $argv ) == false ) {
|
||
|
if ( $force == false && ( PRODUCTION == false || DEPLOYMENT_ON_DEMAND == true ) ) { //Allow FORCE=TRUE to override this.
|
||
|
echo "ERROR: Not doing full upgrade when PRODUCTION mode is disabled, or in ONDEMAND mode... Use FORCE argument to override.\n";
|
||
|
CLIExit( 1 );
|
||
|
}
|
||
|
|
||
|
Debug::Text( 'New version available, check current system requirements...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
if ( disk_free_space( Environment::getBasePath() ) < ( 1000 * 1024000 ) ) { //1000MB
|
||
|
Debug::Text( 'Disk space available: ' . disk_free_space( Environment::getBasePath() ), __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "Less than 1000MB of disk space available, unable to perform upgrade...\n";
|
||
|
CLIExit( 1 );
|
||
|
}
|
||
|
|
||
|
//No need to write install file, as it just adds potential for problems if it doesn't get disabled again.
|
||
|
$config_vars['other']['installer_enabled'] = true;
|
||
|
|
||
|
Debug::Text( 'Checking if new version is available, current version: ' . APPLICATION_VERSION . ' Force: ' . (int)$full_force, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
|
||
|
$ttsc = new TimeTrexSoapClient();
|
||
|
if ( $full_force === true || $ttsc->isNewVersionReadyForUpgrade( $force ) === true ) {
|
||
|
Debug::Text( 'New version available, or force used...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
|
||
|
@file_get_contents( 'http://www.timetrex.com/pre_install.php?v=' . $install_obj->getFullApplicationVersion() . '&os=' . PHP_OS . '&php_version=' . PHP_VERSION . '&web_server=' . urlencode( substr( $_SERVER['SERVER_SOFTWARE'], 0, 20 ) ) . '&page=unattended_upgrade', 'r' );
|
||
|
|
||
|
$install_obj->cleanCacheDirectory();
|
||
|
if ( $install_obj->checkAllRequirements( false, [ 'file_checksums', 'php_cli_requirements', 'base_url', 'clean_cache' ] ) == 0 ) {
|
||
|
Debug::Text( 'New version available, collecting data to download...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "New version available, collecting data to download...\n";
|
||
|
|
||
|
//Send version data before and after upgrade.
|
||
|
$ttsc->sendCompanyData( $company_id, true );
|
||
|
$ttsc->sendCompanyUserLocationData( $company_id );
|
||
|
$ttsc->sendCompanyUserCountData( $company_id );
|
||
|
$ttsc->sendCompanyVersionData( $company_id );
|
||
|
|
||
|
for ( $i = 0; $i < 3; $i++ ) {
|
||
|
$file_url = $ttsc->getUpgradeFileURL( $force );
|
||
|
Debug::Arr( $file_url, 'File Upgrade URL: ', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
if ( !is_soap_fault( $file_url ) && $file_url === false ) {
|
||
|
//Skip retries in case the .ZIP file is already downloaded for testing.
|
||
|
Debug::Text( 'Upgrade URL not available from server, either already running latest version or not ready to upgrade yet, skip retries: ' . $i, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if ( !is_soap_fault( $file_url ) && $file_url !== false && $file_url != '' ) {
|
||
|
$file_url_size = Misc::getRemoteHTTPFileSize( $file_url );
|
||
|
if ( $file_url_size > 0 ) {
|
||
|
Debug::Text( 'Got File Upgrade URL and size, breaking retry loop...' . $i, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
break;
|
||
|
} else {
|
||
|
Debug::Text( 'Unable to get remote File Upgrade URL size, retrying: ' . $i, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
echo " Unable to obtain File Upgrade URL, retrying in 2 minutes: " . $i . "\n";
|
||
|
Debug::Text( 'Unable to obtain File Upgrade URL, retrying: ' . $i, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
sleep( 120 );
|
||
|
}
|
||
|
|
||
|
if ( file_exists( $upgrade_file_name ) || ( !is_soap_fault( $file_url ) && $file_url !== false && $file_url != '' ) ) {
|
||
|
@file_get_contents( 'http://www.timetrex.com/' . URLBuilder::getURL( [ 'v' => $install_obj->getFullApplicationVersion(), 'page' => 'unattended_upgrade_download' ], 'pre_install.php' ), 'r' );
|
||
|
|
||
|
if ( isset( $manual_upgrade_file_name ) && $manual_upgrade_file_name != '' && file_exists( $manual_upgrade_file_name ) && filesize( $manual_upgrade_file_name ) > 0 ) {
|
||
|
Debug::Text( 'Using manual upgrade file: ' . $manual_upgrade_file_name . ' Current Size: ' . filesize( $manual_upgrade_file_name ), __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo 'Using Manual Upgrade File: ' . $manual_upgrade_file_name . "...\n";
|
||
|
$upgrade_file_name = $manual_upgrade_file_name;
|
||
|
} else {
|
||
|
if ( file_exists( $upgrade_file_name ) == false || ( isset( $file_url_size ) && filesize( $upgrade_file_name ) != $file_url_size ) ) {
|
||
|
Debug::Text( 'Attempting to download latest version...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "Attempting to download latest version...\n";
|
||
|
sleep( 5 ); //Sleep for 5 seconds so it can be cancelled easy if needed.
|
||
|
|
||
|
//$bytes_downloaded = @file_put_contents( $upgrade_file_name, fopen( $file_url, 'r') );
|
||
|
$bytes_downloaded = Misc::downloadHTTPFile( $file_url, $upgrade_file_name );
|
||
|
Debug::Text( 'Downloaded file: ' . $upgrade_file_name . ' Size: ' . @filesize( $upgrade_file_name ) . ' Bytes downloaded: ' . $bytes_downloaded . ' Remote Size: ' . $file_url_size, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
if ( $bytes_downloaded != $file_url_size || @filesize( $upgrade_file_name ) <= 0 ) {
|
||
|
Debug::Text( 'ERROR: File did not download correctly...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo 'ERROR: File did not download correctly...' . "\n";
|
||
|
setAutoUpgradeFailed();
|
||
|
CLIExit( 1 );
|
||
|
} else {
|
||
|
echo 'Downloaded file: ' . $upgrade_file_name . ' Size: ' . filesize( $upgrade_file_name ) . "\n";
|
||
|
}
|
||
|
} else {
|
||
|
Debug::Text( 'Upgrade file already exists... Current Size: ' . filesize( $upgrade_file_name ) . ' Remote Size: ' . ( isset( $file_url_size ) ? $file_url_size : 'N/A' ), __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "Upgrade file already exists...\n";
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( file_exists( $upgrade_file_name ) && filesize( $upgrade_file_name ) > 0 ) {
|
||
|
Debug::Text( 'Cleaning staging directory: ' . $upgrade_staging_dir, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo 'Cleaning staging directory: ' . $upgrade_staging_dir . "\n";
|
||
|
Misc::cleanDir( $upgrade_staging_dir, true, true, true );
|
||
|
sleep( 15 ); //Apparently unlink() is async on windows, so wait some random time to hopefully let the operations complete.
|
||
|
|
||
|
Debug::Text( 'Unzipping UPGRADE.ZIP', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "Unzipping UPGRADE.ZIP\n";
|
||
|
$zip = new ZipArchive;
|
||
|
$zip_result = $zip->open( $upgrade_file_name );
|
||
|
if ( $zip_result === true ) {
|
||
|
@file_get_contents( 'http://www.timetrex.com/' . URLBuilder::getURL( [ 'v' => $install_obj->getFullApplicationVersion(), 'page' => 'unattended_upgrade_unzip' ], 'pre_install.php' ), 'r' );
|
||
|
|
||
|
//Hide errors from this, like failed streams, or file already exists warnings and such. Don't think there is anything we can do about them anyways.
|
||
|
//ie: PHP ERROR - WARNING(2): ZipArchive::extractTo(): File exists
|
||
|
// PHP ERROR - WARNING(2): ZipArchive::extractTo(): Unable to open stream
|
||
|
@$zip->extractTo( $upgrade_staging_dir );
|
||
|
$zip->close();
|
||
|
sleep( 15 ); //Maybe this will help prevent access denied (code: 5) errors on windows?
|
||
|
clearstatcache();
|
||
|
|
||
|
Debug::Text( 'Unzipping UPGRADE.ZIP done...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "Unzipping UPGRADE.ZIP done...\n";
|
||
|
} else {
|
||
|
Debug::Text( 'ERROR: Unzipping UPGRADE.ZIP failed... Result: '. $zip_result, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "ERROR: Unzipping UPGRADE.ZIP failed...\n";
|
||
|
}
|
||
|
unset( $zip_result, $zip );
|
||
|
|
||
|
//Rename whatever directory that is in the staging dir to
|
||
|
if ( file_exists( $upgrade_staging_dir ) ) {
|
||
|
if ( $handle = opendir( $upgrade_staging_dir ) ) {
|
||
|
while ( ( $entry = readdir( $handle ) ) !== false ) {
|
||
|
if ( $entry != '.' && $entry != '..' && $entry != 'latest_version' ) { //In case the rename occurred and for some reason those files can't be cleared/deleted, ignore it.
|
||
|
$upgrade_staging_extract_dir = $upgrade_staging_dir . DIRECTORY_SEPARATOR . $entry;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
closedir( $handle );
|
||
|
}
|
||
|
|
||
|
if ( isset( $upgrade_staging_extract_dir ) ) {
|
||
|
@file_get_contents( 'http://www.timetrex.com/' . URLBuilder::getURL( [ 'v' => $install_obj->getFullApplicationVersion(), 'page' => 'unattended_upgrade_rename_dir' ], 'pre_install.php' ), 'r' );
|
||
|
|
||
|
//Make sure the latest directory does not exist before renaming the unzipped directory to it. This may help with some Access Denied errors on Windows.
|
||
|
Misc::cleanDir( $upgrade_staging_latest_dir, true, true, true );
|
||
|
|
||
|
Debug::Text( 'Upgrade Staging Extract Dir: ' . $upgrade_staging_extract_dir . ' Renaming to: ' . $upgrade_staging_latest_dir, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
if ( Misc::rename( $upgrade_staging_extract_dir, $upgrade_staging_latest_dir ) == false ) {
|
||
|
Debug::Text( 'ERROR: Unable to rename: ' . $upgrade_staging_extract_dir . ' to: ' . $upgrade_staging_latest_dir, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo 'ERROR: Unable to rename: ' . $upgrade_staging_extract_dir . ' to: ' . $upgrade_staging_latest_dir . "\n";
|
||
|
}
|
||
|
clearstatcache();
|
||
|
} else {
|
||
|
Debug::Text( 'ERROR: UPGRADE.ZIP extract directory does not exist...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
}
|
||
|
unset( $handle, $entry, $upgrade_staging_extract_dir );
|
||
|
} else {
|
||
|
Debug::Text( 'ERROR: Upgrade staging directory does not exist, cannot continue...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "ERROR: Upgrade staging directory does not exist, cannot continue...\n";
|
||
|
}
|
||
|
|
||
|
if ( isset( $upgrade_staging_latest_dir ) ) {
|
||
|
//Check system requirements of new version.
|
||
|
$latest_unattended_upgrade_tool = $upgrade_staging_latest_dir . DIRECTORY_SEPARATOR . 'tools' . DIRECTORY_SEPARATOR . 'unattended_upgrade.php';
|
||
|
if ( file_exists( $latest_unattended_upgrade_tool ) ) {
|
||
|
if ( is_executable( $php_cli ) ) {
|
||
|
$command = '"' . $php_cli . '" -d opcache.enable_cli=0 "' . $latest_unattended_upgrade_tool . '" --config "' . CONFIG_FILE . '" --pre_requirements_update'; //Make each part is quoted in case there are spaces in the paths.
|
||
|
system( $command, $exit_code );
|
||
|
Debug::Text( 'Running pre-requirements update... Command: ' . $command . ' Exit Code: ' . $exit_code, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
if ( $exit_code == 0 ) {
|
||
|
Debug::Text( 'New version pre-requirements met...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
@file_get_contents( 'http://www.timetrex.com/' . URLBuilder::getURL( [ 'v' => $install_obj->getFullApplicationVersion(), 'page' => 'unattended_upgrade_pre_requirements' ], 'pre_install.php' ), 'r' );
|
||
|
|
||
|
$command = '"' . $php_cli . '" -d opcache.enable_cli=0 "' . $latest_unattended_upgrade_tool . '" --config "' . CONFIG_FILE . '" --requirements_only'; //Make each part is quoted in case there are spaces in the paths.
|
||
|
system( $command, $exit_code );
|
||
|
Debug::Text( 'Checking new version system requirements... Command: ' . $command . ' Exit Code: ' . $exit_code, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
if ( $exit_code == 0 ) {
|
||
|
Debug::Text( 'New version system requirements met...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
@file_get_contents( 'http://www.timetrex.com/' . URLBuilder::getURL( [ 'v' => $install_obj->getFullApplicationVersion(), 'page' => 'unattended_upgrade_new_requirements' ], 'pre_install.php' ), 'r' );
|
||
|
|
||
|
moveUpgradeFiles( $upgrade_staging_latest_dir );
|
||
|
|
||
|
@file_get_contents( 'http://www.timetrex.com/' . URLBuilder::getURL( [ 'v' => $install_obj->getFullApplicationVersion(), 'page' => 'unattended_upgrade_launch_stage2' ], 'pre_install.php' ), 'r' );
|
||
|
|
||
|
$global_class_map['TTUUID'] = 'core/TTUUID.class.php'; //Need to manually map the TTUUID class as it may be required by autoloaded classes in this process.
|
||
|
|
||
|
//Clear OPCACHE to help try to avoid calling ourself with opcached files from the old version.
|
||
|
if ( function_exists( 'opcache_reset' ) ) {
|
||
|
opcache_reset();
|
||
|
}
|
||
|
|
||
|
//Run separate process to finish stage2 of installer so it can be run with the new scripts.
|
||
|
//This allows us more flexibility if an error occurs to finish the install or have the latest version correct problems.
|
||
|
echo "Launching Stage 2...\n";
|
||
|
sleep( 5 );
|
||
|
$command = '"' . $php_cli . '" -d opcache.enable_cli=0 "' . __FILE__ . '" --config "' . CONFIG_FILE . '" --stage2'; //Disable opcache on CLI
|
||
|
|
||
|
//Pass along force argument if it was originally supplied.
|
||
|
if ( $full_force == true ) {
|
||
|
$command .= ' -ff';
|
||
|
} else if ( $force == true ) {
|
||
|
$command .= ' -f';
|
||
|
}
|
||
|
|
||
|
Debug::Text( 'Stage2 Command: ' . $command, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
system( $command, $exit_code );
|
||
|
if ( $exit_code == 0 ) {
|
||
|
Debug::Text( 'Stage2 success!', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
|
||
|
echo "Upgrade successfull!\n";
|
||
|
|
||
|
//Since the --stage2 SQL upgrade is performed in a different process, we have to manually turn UUIDs on for this process before calling any other SQL query like setAutoUpgradeFailed( 0 )
|
||
|
global $PRIMARY_KEY_IS_UUID;
|
||
|
$PRIMARY_KEY_IS_UUID = true;
|
||
|
|
||
|
setAutoUpgradeFailed( 0 ); //Clear auto_upgrade_failed setting if it isn't already.
|
||
|
|
||
|
Install::sendNotification();
|
||
|
|
||
|
CLIExit( 0 );
|
||
|
} else {
|
||
|
Debug::Text( 'Stage2 failed... Exit Code: ' . $exit_code, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
setAutoUpgradeFailed();
|
||
|
}
|
||
|
} else {
|
||
|
Debug::Text( 'ERROR: New version system requirements not met...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "ERROR: New version system requirements not met...\n";
|
||
|
setAutoUpgradeFailed();
|
||
|
}
|
||
|
} else {
|
||
|
Debug::Text( 'ERROR: Pre-Requirements Update failed...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "ERROR: Pre-Requirements Update failed...\n";
|
||
|
setAutoUpgradeFailed();
|
||
|
}
|
||
|
} else {
|
||
|
Debug::text( 'ERROR: PHP CLI is not executable: ' . $php_cli, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "ERROR: PHP CLI is not executable: " . $php_cli . "\n";
|
||
|
setAutoUpgradeFailed();
|
||
|
}
|
||
|
} else {
|
||
|
Debug::Text( 'ERROR: UNATTENDED UPGRADE tool in new version does not exist: ' . $latest_unattended_upgrade_tool, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "ERROR: UNATTENDED UPGRADE tool in new version does not exist: " . $latest_unattended_upgrade_tool . "\n";
|
||
|
setAutoUpgradeFailed();
|
||
|
}
|
||
|
} else {
|
||
|
Debug::Text( 'ERROR: Upgrade staging latest directory does not exist, cannot continue...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "ERROR: Upgrade staging latest directory does not exist, cannot continue...\n";
|
||
|
setAutoUpgradeFailed();
|
||
|
}
|
||
|
} else {
|
||
|
Debug::Text( 'ERROR: UPGRADE.ZIP does not exist or is 0 bytes...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "ERROR: UPGRADE.ZIP does not exist or is 0 bytes...\n";
|
||
|
setAutoUpgradeFailed();
|
||
|
}
|
||
|
} else {
|
||
|
Debug::Text( 'Upgrade File URL not available...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "ERROR: Unable to download upgrade file at this time, please try again later...\n";
|
||
|
setAutoUpgradeFailed();
|
||
|
}
|
||
|
} else {
|
||
|
$failed_requirements = $install_obj->getFailedRequirements( false, [ 'file_checksums', 'php_cli_requirements', 'base_url', 'clean_cache' ] );
|
||
|
Debug::Text( 'ERROR: Current system requirements check failed...', __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
Debug::Text( ' Failed Requirements: ' . implode( ',', $failed_requirements ), __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "ERROR: Current system requirements check failed...\n";
|
||
|
echo ' Failed Requirements: ' . implode( ',', $failed_requirements ) . "\n";
|
||
|
unset( $failed_requirements );
|
||
|
setAutoUpgradeFailed();
|
||
|
}
|
||
|
} else {
|
||
|
Debug::Text( 'Already running latest version: ' . APPLICATION_VERSION, __FILE__, __LINE__, __METHOD__, 10 );
|
||
|
echo "Already running latest version: " . APPLICATION_VERSION . "\n";
|
||
|
setAutoUpgradeFailed( 0 ); //Clear auto_upgrade_failed setting if it isn't already.
|
||
|
}
|
||
|
CLIExit( 1 );
|
||
|
}
|
||
|
}
|
||
|
CLIExit( 1 );
|
||
|
?>
|