Version 5.0.6

This commit is contained in:
Neo committed 2025-12-19 18:55:49 -08:00
1 parent a3a4a9ccbd
commit b89858b2ff
1214 files changed
+92828 -14859

No files matched your search

+132 -175
View File
@@ -88,7 +88,7 @@ class upgrade extends Controller
* @brief Has been CSRF-protected
*/
public static bool $csrfProtected = TRUE;
/**
* @brief Steps that the AdminCP-based upgrader can handle
*/
@@ -98,7 +98,7 @@ class upgrade extends Controller
'lang' => '_upgradeLanguages',
'javascript'=> '_upgradeJavascript',
);
/**
* @brief IPS clientArea Password
*/
@@ -124,53 +124,10 @@ class upgrade extends Controller
protected function manage() : void
{
Dispatcher::i()->checkAcpPermission( 'upgrade_manage', 'core', 'overview' );
if ( NO_WRITES )
{
Output::i()->error( 'no_writes', '1C287/1', 403, '' );
}
$initialData = NULL;
if ( isset( Request::i()->patch ) )
{
$initialData = array( 'patch' => 1 );
}
/* If we are on 4.4.4 and start upgrading to 4.4.5, the initial $steps array will include the upgrade_extra_update key, however during the extraction this file
gets overwritten, and if we are on CiC the new array no longer contains this definition, resulting in an error "Function name must be a string". We need to
inspect the $_SESSION array to see if "upgrade_extract_update" is defined as the next step and use the first array if so. */
$upgradeUrl = Url::internal( 'app=core&module=system&controller=upgrade' );
if( isset( Request::i()->adsess ) )
{
$upgradeUrl = $upgradeUrl->stripQueryString()->setQueryString( array( 'adsess' => Request::i()->adsess, 'app' => 'core', 'module' => 'system', 'controller' => 'upgrade' ) );
}
$forceNormalExtraction = ( isset( $_SESSION[ 'wizard-' . md5( $upgradeUrl ) . '-step' ] ) ) ? ( $_SESSION[ 'wizard-' . md5( $upgradeUrl ) . '-step' ] == 'upgrade_extract_update' ) : FALSE;
if ( !CIC or $forceNormalExtraction )
{
$steps = array(
'upgrade_confirm_update' => array( $this, '_selectVersion' ),
'upgrade_login' => array( $this, '_login' ),
'upgrade_ftp_details' => array( $this, '_ftpDetails' ),
'upgrade_extract_update' => array( $this, '_extractUpdate' ),
'upgrade_upgrade' => array( $this, '_upgrade' ),
);
}
else
{
$steps = array(
'upgrade_confirm_update' => array( $this, '_selectVersion' ),
'upgrade_apply_cic' => array( $this, '_applyCic' ),
'upgrade_upgrade' => array( $this, '_upgrade' )
);
}
$wizard = new Wizard( $steps, $upgradeUrl, TRUE, $initialData );
Output::i()->title = Member::loggedIn()->language()->addToStack('ips_suite_upgrade');
Output::i()->output = (string) $wizard;
Output::i()->redirect( Url::external( "https://community.invisionpower.com/resources/" ) );
}
/**
* Select Version
*
@@ -220,7 +177,7 @@ class upgrade extends Controller
}
}
catch ( \Exception $e ) { }
/* Build form */
$form = new Form( 'select_version' );
$options = array();
@@ -255,14 +212,14 @@ class upgrade extends Controller
$options = array( $latestVersion => $options[ $latestVersion ] ); // CIC can only actually do the actual latest version
}
$form->add( new Radio( 'version', $latestVersion, TRUE, array( 'options' => $options, '_details' => $descriptions ) ) );
/* Handle submissions */
$values = $form->values();
}
/* Do we have a chosen version? */
if ( $values )
{
{
/* Check requirements */
if( !CIC )
{
@@ -290,7 +247,7 @@ class upgrade extends Controller
}
catch ( \Exception $e ) {}
}
/* Do a database check */
if( !IPS_ALPHA_BUILD )
{
@@ -344,7 +301,7 @@ class upgrade extends Controller
$data['changes'][ $k ] = $this->_changeDetails( $data['oldVersion'], $values['version'], $k );
}
}
/* Have we set the complete "kill the automatic upgrader" flag?
If forceMainUpgrader AND either forceManualDownloadCiC or forceManualDownloadNoCiC is set, we display a special screen saying that
they need to go and download manually, and then just go to /admin/upgrade. This can be used for major upgrades where trying to do
@@ -360,11 +317,11 @@ class upgrade extends Controller
Output::i()->redirect( $val );
}
else
{
{
return Theme::i()->getTemplate('system')->manualUpgradeRequired();
}
}
/* Check if we will need any manual queries */
if ( !CIC and $data['info']['steps']['queries'] )
{
@@ -383,12 +340,12 @@ class upgrade extends Controller
}
}
}
$tablesWeWillNeedToDoManualQueriesOn = array_keys( array_filter( $checkedTables ) );
if ( $tablesWeWillNeedToDoManualQueriesOn )
{
sort( $tablesWeWillNeedToDoManualQueriesOn );
if ( isset( Request::i()->skip_large_tables_check ) )
{
$data['largeTables'] = $tablesWeWillNeedToDoManualQueriesOn;
@@ -407,15 +364,15 @@ class upgrade extends Controller
{
$data['largeTables'] = array();
}
/* Return */
return $data;
}
/* Display */
return $form->customTemplate( array( Theme::i()->getTemplate( 'system' ), 'upgradeSelectVersion' ) );
}
/**
* Get details of what has changed between two versions
*
@@ -443,7 +400,7 @@ class upgrade extends Controller
Output::i()->error( 'delta_upgrade_fail_server', '3C287/5', 500, NULL, array(), get_class( $e ) . '::' . $e->getCode() . ": " . $e->getMessage() );
}
}
/* If there is any steps which the AdminCP upgrader cannot handle, set forceMainUpgrader so that they get redirected to the upgrader */
if ( !$item )
{
@@ -451,17 +408,17 @@ class upgrade extends Controller
$stepsThisUpgradeWantsToRun = array_keys( array_filter( $details['steps'], function( $v, $k ) {
return $v;
}, ARRAY_FILTER_USE_BOTH ) );
if ( array_diff( $stepsThisUpgradeWantsToRun, $stepsWeCanHandle ) )
{
$details['forceMainUpgrader'] = TRUE;
}
}
/* Return */
return $details;
}
/**
* Apply files for CiC
*
@@ -496,7 +453,7 @@ class upgrade extends Controller
IPS::applyLatestFilesIPSCloud();
}
catch( \IPS\Http\Request\Exception $e ){}
return Theme::i()->getTemplate('system')->upgradeDeltaFailedCic();
}
elseif ( isset( Request::i()->done ) )
@@ -506,7 +463,7 @@ class upgrade extends Controller
UpgradeClass::setUpgradingFlag( TRUE );
Session::i()->log( 'acplog__upgrade_started' );
/* Check latest version */
$versions = array();
foreach ( Db::i()->select( '*', 'core_applications', Db::i()->in( 'app_directory', IPS::$ipsApps ) ) as $app )
@@ -517,7 +474,7 @@ class upgrade extends Controller
}
}
$version = min( $versions );
$extractUrl = new Url( Settings::i()->base_url . 'admin/upgrade/extractCic.php' );
$extractUrl = $extractUrl
->setScheme( NULL ) // Use protocol-relative in case the AdminCP is being loaded over https but rest of site is not
@@ -525,17 +482,17 @@ class upgrade extends Controller
'account' => IPS::getCicUsername(),
'key' => md5( IPS::getCicUsername() . Settings::i()->sql_pass ),
'version' => $version
)
)
);
/* Send the request */
IPS::applyLatestFilesIPSCloud( $version );
/* NOTE: We still need to use an iframe here, as CiC would still be susceptible to the same failures. */
return Theme::i()->getTemplate('system')->upgradeExtractCic( $extractUrl );
}
}
/**
* Login
*
@@ -550,13 +507,13 @@ class upgrade extends Controller
$data['key'] = 'test';
return $data;
}
/* Build form */
$form = new Form( 'login', 'continue' );
$form->hiddenValues['version'] = $data['version'];
$form->add( new Email( 'ips_email_address', NULL ) );
$form->add( new Password( 'ips_password', NULL ) );
if ( !CIC )
{
$form->add( new YesNo( 'upgrade_confirm_backup', FALSE, TRUE, array(), function( $val ) {
@@ -566,7 +523,7 @@ class upgrade extends Controller
}
} ) );
}
/* Handle submissions */
if ( $values = $form->values() )
{
@@ -601,10 +558,10 @@ class upgrade extends Controller
$form->error = Member::loggedIn()->language()->addToStack('download_upgrade_error');
}
}
return (string) $form;
}
/**
* Get a download key
*
@@ -620,7 +577,7 @@ class upgrade extends Controller
{
$key = IPS::licenseKey();
$url = Url::ips( 'build5/' . $key['key'] )->setQueryString( 'ip', Request::i()->ipAddress() );
if ( USE_DEVELOPMENT_BUILDS )
{
$url = $url->setQueryString( 'development', 1 );
@@ -644,7 +601,7 @@ class upgrade extends Controller
{
$url = $url->setQueryString( 'files', implode( ',', $files ) );
}
$response = $url->request( LONG_REQUEST_TIMEOUT )->login( $clientAreaEmail, $this->_clientAreaPassword )->get();
switch ( $response->httpResponseCode )
{
@@ -657,15 +614,15 @@ class upgrade extends Controller
{
return (string) $response;
}
case 304:
return NULL;
default:
throw new LogicException( (string) $response );
}
}
/**
* Get FTP Details
*
@@ -707,7 +664,7 @@ class upgrade extends Controller
throw new DomainException('delta_upgrade_ftp_details_err');
}
};
/* If we have details stored, retreive them */
$decodedFtpDetails = NULL;
if ( Settings::i()->upgrade_ftp_details )
@@ -735,12 +692,12 @@ class upgrade extends Controller
'path' => str_replace( '/home/' . @get_current_user(), '', \IPS\ROOT_PATH )
);
}
/* Build the form */
$form = new Form( 'ftp_details', 'continue' );
$form->add( new Ftp( 'delta_upgrade_ftp_details', $defaultDetails, TRUE, array( 'rejectUnsupportedSftp' => TRUE, 'allowBypassValidation' => FALSE ), $validateCallback ) );
$form->add( new Checkbox( 'delta_upgrade_ftp_remember', TRUE ) );
/* Handle submissions */
if ( $values = $form->values() )
{
@@ -749,11 +706,11 @@ class upgrade extends Controller
$encrypted = Encrypt::fromPlaintext( json_encode( $values['delta_upgrade_ftp_details'] ) );
Settings::i()->changeValues( array( 'upgrade_ftp_details' => $encrypted->tag() ) );
}
$data['ftpDetails'] = 1;
return $data;
}
/* Display the form */
return Theme::i()->getTemplate('system')->upgradeDeltaFtp( (string) $form );
}
@@ -791,16 +748,16 @@ class upgrade extends Controller
return Theme::i()->getTemplate('system')->upgradeDeltaFailed( 'exception', isset( $data['key'] ) ? Url::ips("download/{$data['key']}") : NULL );
}
}
/* Download & Extract */
if ( $data['key'] and !isset( Request::i()->check ) )
{
{
/* If we've asked to do it manually, just show that screen */
if ( isset( $data['manual'] ) and $data['manual'] )
{
return Theme::i()->getTemplate('system')->upgradeDeltaFailed( NULL, Url::ips("download/{$data['key']}") );
}
/* Multiple Redirector */
$url = Url::internal('app=core&module=system&controller=upgrade');
return (string) new MultipleRedirect( $url, function( $mrData ) use ( $data )
@@ -814,9 +771,9 @@ class upgrade extends Controller
elseif ( $mrData['status'] == 'download' )
{
if ( !isset( $mrData['tmpFileName'] ) )
{
{
$mrData['tmpFileName'] = tempnam( TEMP_DIRECTORY, 'IPS' ) . '.zip';
return array( $mrData, Member::loggedIn()->language()->addToStack('delta_upgrade_downloading'), 0 );
}
else
@@ -835,11 +792,11 @@ class upgrade extends Controller
}
$startRange = $mrData['range'];
$endRange = $startRange + 1000000 - 1;
$response = Url::ips("download/{$data['key']}")->request( LONG_REQUEST_TIMEOUT )->setHeaders( array( 'Range' => "bytes={$startRange}-{$endRange}" ) )->get();
Log::debug( "Fetching download [range={$startRange}-{$endRange}] with a response code: " . $response->httpResponseCode, 'auto_upgrade' );
if ( $response->httpResponseCode == 404 )
{
if ( isset( $mrData['tmpFileName'] ) )
@@ -848,7 +805,7 @@ class upgrade extends Controller
}
Log::log( "Cannot fetch delta download: " . var_export( $response, TRUE ), 'auto_upgrade' );
if( CIC )
{
try
@@ -871,7 +828,7 @@ class upgrade extends Controller
$fh = fopen( $mrData['tmpFileName'], 'a' );
fwrite( $fh, (string) $response );
fclose( $fh );
$mrData['range'] = $endRange + 1;
$complete = 100 / $totalFileSize * $mrData['range'];
@@ -899,9 +856,9 @@ class upgrade extends Controller
'container' => $data['key'],
'key' => md5( Settings::i()->board_start . $mrData['tmpFileName'] . Settings::i()->sql_pass ),
'ftp' => ( isset( $data['ftpDetails'] ) ) ? $data['ftpDetails'] : ''
)
)
);
return array( Theme::i()->getTemplate('system')->upgradeExtract( $extractUrl ) );
}
},
@@ -910,7 +867,7 @@ class upgrade extends Controller
Output::i()->redirect( Url::internal('app=core&module=system&controller=upgrade&check=1') );
} );
}
/* Run md5 check */
try
{
@@ -919,13 +876,13 @@ class upgrade extends Controller
{
/* Log */
Log::debug( "MD5 check of delta download failed with " . count( $files ) . " reported as modified", 'auto_upgrade' );
/* If we'rve already tried to fix them and failed, show an error */
if ( isset( $data['md5Fix'] ) and $data['md5Fix'] )
{
return Theme::i()->getTemplate('system')->upgradeDeltaFailed( 'exception', NULL );
}
/* Otherwise try to just fix them - first get a new download key */
$files = array_map( function( $file ) {
return str_replace( \IPS\ROOT_PATH, '', $file );
@@ -938,17 +895,17 @@ class upgrade extends Controller
$data['key'] = $newDownloadKey;
$data['md5Fix'] = TRUE;
$_SESSION[ 'wizard-' . md5( Url::internal( 'app=core&module=system&controller=upgrade' ) ) . '-data' ] = $data;
/* Redirect back in */
Output::i()->redirect( Url::internal('app=core&module=system&controller=upgrade') );
}
}
catch ( \Exception $e ) {}
/* Nope, we're good! */
return $data;
}
/**
* Upgrade
*
@@ -959,7 +916,7 @@ class upgrade extends Controller
{
/* Resync */
IPS::resyncIPSCloud('Uploaded new version');
/* If we cannot handle this in the AdminCP, redirect them to the upgrader */
if ( $data['info']['forceMainUpgrader'] )
{
@@ -971,7 +928,7 @@ class upgrade extends Controller
{
Output::i()->redirect( 'upgrade/?autologin=1' );
}
/* Otherwise let's do the upgrade! */
$url = Url::internal('app=core&module=system&controller=upgrade');
return (string) new MultipleRedirect( $url, function( $mrData ) use ( $data )
@@ -981,7 +938,7 @@ class upgrade extends Controller
return array( array( 'step' => 0 ), Member::loggedIn()->language()->addToStack('delta_upgrade_processing'), 0 );
}
else
{
{
$steps = array();
foreach ( $data['info']['steps'] as $step => $v )
{
@@ -997,7 +954,7 @@ class upgrade extends Controller
}
}
}
if ( count( $steps ) AND array_key_exists( $mrData['step'], $steps ) )
{
$perStepPercentage = ( 100 / count( $steps ) );
@@ -1005,10 +962,10 @@ class upgrade extends Controller
$step = $steps[ $mrData['step'] ];
$percentage = $perStepPercentage * intval( $mrData['step'] );
$stepData = $mrData[$step] ?? array();
$return = $this->$step( $data, $stepData );
if ( $return === NULL )
{
{
unset( $mrData[ $step ] );
$mrData['step']++;
$percentage += $perStepPercentage;
@@ -1022,13 +979,13 @@ class upgrade extends Controller
$mrData[ $step ] = $return[1];
$percentage += ( $return[0] / ( 100 / $perStepPercentage ) );
}
return array( $mrData, Member::loggedIn()->language()->addToStack( 'delta_upgrade' . $step ), round( $percentage, 2 ) );
}
else
{
UpgradeClass::setUpgradingFlag( FALSE );
$databaseErrors = FALSE;
foreach ( Application::applications() as $app )
{
@@ -1057,9 +1014,9 @@ class upgrade extends Controller
unset( Store::i()->applications, Store::i()->updatecount_applications );
Zapier::rebuildRESTApiPermissions();
AdminNotification::remove( 'core', 'NewVersion' );
return array( Theme::i()->getTemplate('system')->upgradeFinished( $databaseErrors ) );
}
}
@@ -1069,7 +1026,7 @@ class upgrade extends Controller
Output::i()->redirect( 'upgrade/?autologin=1' );
} );
}
/**
* Upgrade: Queries
*
@@ -1080,7 +1037,7 @@ class upgrade extends Controller
public function _upgradeQueries( array $data, array $stepData ) : ?array
{
return $this->_appLoop( 'queries', $data, $stepData, function( $app, $data, $stepData )
{
{
/* If this is the first run, work out how many things we have to do, and remove any that need removing */
if ( !isset( $stepData['offset'] ) )
{
@@ -1096,14 +1053,14 @@ class upgrade extends Controller
return array( 0, $stepData );
}
}
/* Get the next query */
$queriesToRun = array_values( $data['changes']['queries'][ $app ] );
if ( isset( $queriesToRun[ $stepData['offset'] ] ) )
{
$method = $queriesToRun[ $stepData['offset'] ]['method'];
$params = $queriesToRun[ $stepData['offset'] ]['params'];
/* Is it for a table that we need to run manual queries on? */
$tableName = ( isset( $params[0] ) and is_string( $params[0] ) ) ? $params[0] : $params[0]['name'];
if ( !isset( Request::i()->runQuery ) and in_array( $tableName, $data['largeTables'] ) )
@@ -1117,13 +1074,13 @@ class upgrade extends Controller
else
{
$stepData['offset']++;
return array( 100 / $stepData['count'] * $stepData['offset'], $stepData );
return array( 100 / $stepData['count'] * $stepData['offset'], $stepData );
}
}
/* Nope, we can run it manually */
else
{
{
try
{
Db::i()->$method( ...$params );
@@ -1136,26 +1093,26 @@ class upgrade extends Controller
{
Output::i()->json( array( 'runManualQuery' => FALSE ) );
}
return Theme::i()->getTemplate('system')->upgradeDeltaQueryFailed( Request::i()->mr, $e );
}
}
if ( isset( Request::i()->runQuery ) )
{
Output::i()->json( array( 'runManualQuery' => TRUE ) );
}
$stepData['offset']++;
return array( 100 / $stepData['count'] * $stepData['offset'], $stepData );
return array( 100 / $stepData['count'] * $stepData['offset'], $stepData );
}
}
/* If there isn't one, we're done - run a final database check */
return NULL;
} );
}
/**
* Upgrade: HTML and CSS
*
@@ -1164,37 +1121,37 @@ class upgrade extends Controller
* @return array|null array( percentage of this step complete, $stepData ) OR NULL if this step is complete
*/
public function _upgradeTheme( array $data, array $stepData ) : ?array
{
{
return $this->_appLoop( 'theme', $data, $stepData, function( $app, $data, $stepData )
{
{
/* If this is the first run, work out how many things we have to do, and remove any that need removing */
if ( !isset( $stepData['offset'] ) )
{
$numberOfChangesInThisApp = 0;
/* HTML */
$templateGroupsToClear = array();
foreach ( $data['changes']['theme'][ $app ]['html'] as $type => $templates )
{
$numberOfChangesInThisApp += count( $templates );
if ( $type == 'removed' )
{
foreach ( $templates as $template )
{
$exploded = explode( '/', $template );
$templateGroupsToClear[ $exploded[0] ][ $exploded[1] ] = TRUE;
Theme::removeTemplates( $app, $exploded[0], $exploded[1], NULL, FALSE, $exploded[2] );
}
}
}
/* CSS */
foreach ( $data['changes']['theme'][ $app ]['css'] as $type => $cssFiles )
{
$numberOfChangesInThisApp += count( $cssFiles );
if ( $type == 'removed' )
{
foreach ( $cssFiles as $cssFile )
@@ -1205,12 +1162,12 @@ class upgrade extends Controller
}
}
}
/* Resources */
foreach ( $data['changes']['theme'][ $app ]['resources'] as $type => $resources )
{
$numberOfChangesInThisApp += count( $resources );
if ( $type == 'removed' )
{
foreach ( $resources as $resource )
@@ -1221,7 +1178,7 @@ class upgrade extends Controller
}
}
}
/* Return those details so the next step can actually begin the import */
if ( !$numberOfChangesInThisApp )
{
@@ -1235,8 +1192,8 @@ class upgrade extends Controller
return array( 0, $stepData );
}
}
/* Import new stuff */
/* Import new stuff */
$perLoop = 150;
$i = 0;
$done = 0;
@@ -1258,10 +1215,10 @@ class upgrade extends Controller
continue;
}
}
/* Templates */
if( $xml->name == 'template' )
{
{
if ( $location = $xml->getAttribute('template_location') and $group = $xml->getAttribute('template_group') and $template = $xml->getAttribute('template_name') )
{
$templateKey = "{$location}/{$group}/{$template}";
@@ -1322,7 +1279,7 @@ class upgrade extends Controller
Theme::removeResources( $app, $location, $path, NULL, FALSE, $name );
}
if ( in_array( $resourceKey, $data['changes']['theme'][ $app ]['resources']['added'] ) or in_array( $resourceKey, $data['changes']['theme'][ $app ]['resources']['edited'] ) )
{
{
Theme::addResource( array(
'app' => $app,
'location' => $location,
@@ -1334,16 +1291,16 @@ class upgrade extends Controller
}
}
}
/* Have we done the most we're allowed per loop? */
if( $done >= $perLoop )
{
$stepData['offset'] = $i;
$stepData['done'] = isset( $stepData['done'] ) ? ( $stepData['done'] + $done ) : $done;
return array( 100 / $stepData['count'] * $stepData['done'], $stepData );
return array( 100 / $stepData['count'] * $stepData['done'], $stepData );
}
}
/* If we're still here, this app is complete - do cleanup */
foreach ( $stepData['templateGroupsToClear'] as $location => $groups )
{
@@ -1362,7 +1319,7 @@ class upgrade extends Controller
return NULL;
} );
}
/**
* Upgrade: Languages
*
@@ -1375,7 +1332,7 @@ class upgrade extends Controller
return $this->_appLoop( 'lang', $data, $stepData, function( $app, $data, $stepData )
{
$languages = array_keys( Lang::languages() );
/* Remove old */
if ( $data['changes']['lang'][ $app ]['normal']['removed'] )
{
@@ -1388,7 +1345,7 @@ class upgrade extends Controller
if ( !isset( $stepData['offset'] ) )
{
$numberOfChangesInThisApp = 0;
foreach ( $data['changes']['lang'][ $app ] as $jsOrNormal => $types )
{
foreach ( $types as $type => $langKeys )
@@ -1418,8 +1375,8 @@ class upgrade extends Controller
return array( 0, $stepData );
}
}
/* Import new stuff */
/* Import new stuff */
$perLoop = 150;
$batchSize = 25;
$i = 0;
@@ -1429,7 +1386,7 @@ class upgrade extends Controller
$xml->read();
$xml->read();
$xml->read();
$version = $xml->getAttribute('version');
$version = $xml->getAttribute('version');
while ( $xml->read() )
{
/* Skip to where we need to be */
@@ -1446,10 +1403,10 @@ class upgrade extends Controller
continue;
}
}
/* Templates */
if( $xml->name == 'word' )
{
{
if ( $langKey = $xml->getAttribute('key') )
{
$js = $xml->getAttribute('js');
@@ -1472,7 +1429,7 @@ class upgrade extends Controller
}
}
}
/* Have we got enough for a batch? */
if ( $done >= $batchSize )
{
@@ -1483,7 +1440,7 @@ class upgrade extends Controller
}
$batchesDone++;
}
/* Have we done the most we're allowed per loop? */
if( $done >= $perLoop )
{
@@ -1491,13 +1448,13 @@ class upgrade extends Controller
{
Db::i()->insert( 'core_sys_lang_words', $inserts, TRUE );
}
$stepData['offset'] = $i;
$stepData['done'] = isset( $stepData['done'] ) ? ( $stepData['done'] + $done ) : $done;
return array( 100 / $stepData['count'] * $stepData['done'], $stepData );
return array( 100 / $stepData['count'] * $stepData['done'], $stepData );
}
}
/* If we're still here, this app is complete */
if ( count( $inserts ) )
{
@@ -1506,7 +1463,7 @@ class upgrade extends Controller
return NULL;
} );
}
/**
* Upgrade: Javascript
*
@@ -1517,11 +1474,11 @@ class upgrade extends Controller
public function _upgradeJavascript( array $data, array $stepData ) : ?array
{
return $this->_appLoop( 'javascript', $data, $stepData, function( $app, $data, $stepData )
{
{
if ( !isset( $stepData['offset'] ) )
{
$numberOfChangesInThisApp = 0;
foreach ( $data['changes']['javascript'][ $app ]['files'] as $type => $files )
{
if ( $type === 'removed' )
@@ -1553,8 +1510,8 @@ class upgrade extends Controller
return array( 0, $stepData );
}
}
/* Import new stuff */
/* Import new stuff */
$perLoop = 150;
$i = 0;
$done = 0;
@@ -1576,13 +1533,13 @@ class upgrade extends Controller
continue;
}
}
if( $xml->name == 'file' )
{
{
if ( $location = $xml->getAttribute('javascript_location') and $path = $xml->getAttribute('javascript_path') and $name = $xml->getAttribute('javascript_name') )
{
$filePath = "{$app}/{$location}/{$path}/{$name}";
if ( in_array( $filePath, $data['changes']['javascript'][ $app ]['files']['added'] ) or in_array( $filePath, $data['changes']['javascript'][ $app ]['files']['edited'] ) )
{
Db::i()->replace( 'core_javascript', array(
@@ -1600,13 +1557,13 @@ class upgrade extends Controller
}
}
}
/* Have we done the most we're allowed per loop? */
if( $done >= $perLoop )
{
$stepData['offset'] = $i;
$stepData['done'] = isset( $stepData['done'] ) ? ( $stepData['done'] + $done ) : $done;
return array( 100 / $stepData['count'] * $stepData['done'], $stepData );
return array( 100 / $stepData['count'] * $stepData['done'], $stepData );
}
}
@@ -1615,7 +1572,7 @@ class upgrade extends Controller
return NULL;
} );
}
/**
* App Looper
*
@@ -1626,28 +1583,28 @@ class upgrade extends Controller
* @return array|string|null array( percentage of this step complete, $stepData ) OR NULL if this step is complete
*/
protected function _appLoop( string $step, array $data, array $stepData, callable $code ) : array|string|null
{
{
$returnNext = FALSE;
$apps = array_keys( Application::applications() );
$percentage = 0;
$perAppPercentage = ( 100 / count( $apps ) );
foreach ( $apps as $app )
{
if( !in_array( $app, IPS::$ipsApps ) or !isset( $data['changes'][ $step ][ $app ] ) )
{
continue;
}
if ( !isset( $stepData['app'] ) )
{
$stepData['app'] = $app;
}
if ( $stepData['app'] == $app )
{
$val = call_user_func( $code, $app, $data, $stepData );
if ( is_string( $val ) )
{
return $val;
@@ -1665,7 +1622,7 @@ class upgrade extends Controller
else
{
$percentage += $perAppPercentage;
if ( $returnNext )
{
$stepData = array( 'app' => $app );
@@ -1673,7 +1630,7 @@ class upgrade extends Controller
}
}
}
return NULL;
}