Version 5.0.0 beta 1

This commit is contained in:
Neo committed 2025-12-19 16:27:35 -08:00
1 parent 25ddeb65d6
commit 15c7beabc5
6736 files changed
+627902 -497943

No files matched your search

@@ -11,50 +11,72 @@
namespace IPS\core\modules\setup\upgrade;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\Application;
use IPS\core\Setup\Upgrade;
use IPS\Data\Store;
use IPS\Db;
use IPS\Dispatcher\Controller;
use IPS\Http\Url;
use IPS\IPS;
use IPS\Member;
use IPS\Output;
use IPS\Request;
use IPS\Theme;
use IPS\Xml\XMLReader;
use OutOfRangeException;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Upgrader: Applications
*/
class _applications extends \IPS\Dispatcher\Controller
class applications extends Controller
{
/**
* Show Form
*
* @return void
*/
public function manage()
public function manage() : void
{
$apps = array();
/* Update old app keys or everything gets confused */
\IPS\Db::i()->update( 'core_applications', array( 'app_directory' => 'cms' ), array( 'app_directory=?', 'ccs' ) );
\IPS\Db::i()->update( 'core_applications', array( 'app_directory' => 'chat' ), array( 'app_directory=?', 'ipchat' ) );
/* We had a bug in an earlier beta where the version may not have updated properly, so we need to account for that but it has to happen before we load version files */
/* @todo We may want to remove those down the road as it should only affect users who have upgraded to early betas */
if( \IPS\Db::i()->checkForTable( 'core_widgets' ) AND !\IPS\Db::i()->checkForColumn( 'core_widgets', 'embeddable' ) )
/* Stop here if we are trying to upgrade from a version older than 4.5 */
if( Application::load( 'core' )->long_version < 105100 )
{
\IPS\Db::i()->update( 'core_applications', array( 'app_version' => '4.0.0 Beta 1', 'app_long_version' => '100001' ) );
Upgrade::setUpgradingFlag( FALSE );
Output::i()->title = Member::loggedIn()->language()->addToStack('applications');
Output::i()->output = Theme::i()->getTemplate( 'global' )->block( 'applications', Theme::i()->getTemplate( 'forms' )->minversioncheck() );
return;
}
/* If we are upgrading from a version older than v5, disable all 3rd party apps */
if( Application::load( 'core' )->long_version < 200000 )
{
Db::i()->update( 'core_applications', array( 'app_enabled' => 0, 'app_requires_manual_intervention' => 1 ), Db::i()->in( 'app_directory', IPS::$ipsApps, true ) );
}
/* Clear any caches or else we might not see new versions */
if ( isset( \IPS\Data\Store::i()->applications ) )
if ( isset( Store::i()->applications ) )
{
unset( \IPS\Data\Store::i()->applications );
unset( Store::i()->applications );
}
if ( isset( \IPS\Data\Store::i()->modules ) )
if ( isset( Store::i()->modules ) )
{
unset( \IPS\Data\Store::i()->modules );
unset( Store::i()->modules );
}
foreach( \IPS\Application::applications() as $app => $data )
foreach( Application::applications() as $app => $data )
{
$path = \IPS\Application::getRootPath( $app ) . '/applications/' . $app;
$path = Application::getRootPath( $app ) . '/applications/' . $app;
if ( $app == 'chat' )
{
@@ -76,15 +98,15 @@ class _applications extends \IPS\Dispatcher\Controller
}
/* Figure out of an upgrade is even available */
$currentVersion = \IPS\Application::load( $app )->long_version;
$availableVersion = \IPS\Application::getAvailableVersion( $app );
$currentVersion = Application::load( $app )->long_version;
$availableVersion = Application::getAvailableVersion( $app );
$name = $data->_title;
/* Get app name */
if ( file_exists( $path . '/data/lang.xml' ) )
{
$xml = \IPS\Xml\XMLReader::safeOpen( $path . '/data/lang.xml' );
$xml = XMLReader::safeOpen( $path . '/data/lang.xml' );
$xml->read();
$xml->read();
@@ -104,14 +126,14 @@ class _applications extends \IPS\Dispatcher\Controller
'name' => $name,
'disabled' => ( !empty( $errors ) OR $availableVersion <= $currentVersion ),
'errors' => $errors,
'current' => \IPS\Application::load( $app )->version,
'available' => \IPS\Application::getAvailableVersion( $app, TRUE )
'current' => Application::load( $app )->version,
'available' => Application::getAvailableVersion( $app, TRUE )
);
}
}
if( \count( $apps ) )
if( count( $apps ) )
{
/* Make sure the core app is the first index */
if( isset( $apps['core'] ) )
@@ -122,8 +144,8 @@ class _applications extends \IPS\Dispatcher\Controller
$_SESSION['apps'] = $apps;
$warnings = array();
$coreVersion = array_key_exists( 'core', $_SESSION['apps'] ) ? \IPS\Application::getAvailableVersion( 'core' ) : \IPS\Application::load( 'core' )->long_version;
foreach ( \IPS\IPS::$ipsApps as $key )
$coreVersion = array_key_exists( 'core', $_SESSION['apps'] ) ? Application::getAvailableVersion( 'core' ) : Application::load( 'core' )->long_version;
foreach ( IPS::$ipsApps as $key )
{
if ( $key == 'chat' )
{
@@ -132,35 +154,35 @@ class _applications extends \IPS\Dispatcher\Controller
try
{
$appVersion = array_key_exists( $key, $_SESSION['apps'] ) ? \IPS\Application::getAvailableVersion( $key ) : \IPS\Application::load( $key )->long_version;
$appVersion = array_key_exists( $key, $_SESSION['apps'] ) ? Application::getAvailableVersion( $key ) : Application::load( $key )->long_version;
if ( $appVersion != $coreVersion )
{
$warnings[] = $key;
}
}
catch( \OutOfRangeException $e )
catch( OutOfRangeException $e )
{
/* The application is not installed */
continue;
}
}
if ( \count( $warnings ) )
if ( count( $warnings ) )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "controller=applications&do=warning" )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'warnings' => implode( ',', $warnings ) ) ) );
Output::i()->redirect( Url::internal( "controller=applications&do=warning" )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'warnings' => implode( ',', $warnings ) ) ) );
}
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "controller=customoptions" )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
Output::i()->redirect( Url::internal( "controller=customoptions" )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
}
else
{
$form = \IPS\Theme::i()->getTemplate( 'forms' )->noapps();
$form = Theme::i()->getTemplate( 'forms' )->noapps();
\IPS\core\Setup\Upgrade::setUpgradingFlag( FALSE );
Upgrade::setUpgradingFlag( FALSE );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('applications');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->block( 'applications', $form );
Output::i()->title = Member::loggedIn()->language()->addToStack('applications');
Output::i()->output = Theme::i()->getTemplate( 'global' )->block( 'applications', $form );
}
/**
@@ -168,18 +190,18 @@ class _applications extends \IPS\Dispatcher\Controller
*
* @return void
*/
public function warning()
public function warning() : void
{
$apps = array();
foreach ( explode( ',', \IPS\Request::i()->warnings ) as $key )
foreach ( explode( ',', Request::i()->warnings ) as $key )
{
try
{
$name = \IPS\Application::load( $key )->_title;
$name = Application::load( $key )->_title;
$path = \IPS\ROOT_PATH . '/applications/' . $key;
if ( file_exists( $path . '/data/lang.xml' ) )
{
$xml = \IPS\Xml\XMLReader::safeOpen( $path . '/data/lang.xml' );
$xml = XMLReader::safeOpen( $path . '/data/lang.xml' );
$xml->read();
$xml->read();
@@ -194,10 +216,10 @@ class _applications extends \IPS\Dispatcher\Controller
}
$apps[] = $name;
}
catch ( \Exception $e ) { }
catch ( Exception $e ) { }
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('applications');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->block( 'applications', \IPS\Theme::i()->getTemplate( 'global' )->appWarnings( $apps ) );
Output::i()->title = Member::loggedIn()->language()->addToStack('applications');
Output::i()->output = Theme::i()->getTemplate( 'global' )->block( 'applications', Theme::i()->getTemplate( 'global' )->appWarnings( $apps ) );
}
}
@@ -11,23 +11,31 @@
namespace IPS\core\modules\setup\upgrade;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Db;
use IPS\Dispatcher\Controller;
use IPS\Member;
use IPS\Output;
use IPS\Theme;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Upgrader: Confirm
*/
class _confirm extends \IPS\Dispatcher\Controller
class confirm extends Controller
{
/**
* Show Form
*
* @return void
*/
public function manage()
public function manage() : void
{
/* reset a few things */
$_SESSION['lastJsonIndex'] = 0;
@@ -35,9 +43,9 @@ class _confirm extends \IPS\Dispatcher\Controller
$_SESSION['sqlFinished'] = array();
/* Create our temporary upgrade data storage table */
if( !\IPS\Db::i()->checkForTable( 'upgrade_temp' ) )
if( !Db::i()->checkForTable( 'upgrade_temp' ) )
{
\IPS\Db::i()->createTable( array(
Db::i()->createTable( array(
'name' => 'upgrade_temp',
'columns' => array(
'id' => array(
@@ -73,7 +81,7 @@ class _confirm extends \IPS\Dispatcher\Controller
) );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('confirmpage');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->confirm();
Output::i()->title = Member::loggedIn()->language()->addToStack('confirmpage');
Output::i()->output = Theme::i()->getTemplate( 'global' )->confirm();
}
}
@@ -11,37 +11,46 @@
namespace IPS\core\modules\setup\upgrade;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Db;
use IPS\Dispatcher\Controller;
use IPS\Http\Url;
use IPS\Output;
use UnderflowException;
use function defined;
use function is_array;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Upgrader: Continue Upgrade
*/
class _continueupgrade extends \IPS\Dispatcher\Controller
class continueupgrade extends Controller
{
/**
* Show Form
*
* @return void
*/
public function manage()
public function manage() : void
{
/* Best check for the upgrade file first */
try
{
$json = json_decode( \IPS\Db::i()->select( 'upgrade_data', 'upgrade_temp' )->first(), TRUE );
$json = json_decode( Db::i()->select( 'upgrade_data', 'upgrade_temp' )->first(), TRUE );
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
$json = NULL;
}
if ( \is_array( $json ) and isset( $json['session'] ) and isset( $json['data'] ) )
if ( is_array( $json ) and isset( $json['session'] ) and isset( $json['data'] ) )
{
$url = \IPS\Http\Url::internal( "controller=upgrade" )->setQueryString( 'key', $_SESSION['uniqueKey'] );
$url = Url::internal( "controller=upgrade" )->setQueryString( 'key', $_SESSION['uniqueKey'] );
/* Update session */
foreach( $json['session'] as $k => $v )
@@ -54,11 +63,11 @@ class _continueupgrade extends \IPS\Dispatcher\Controller
/* Populate the MR data */
$_SESSION[ 'mr-' . md5( $url ) ] = json_encode( $json['data'] );
\IPS\Output::i()->redirect( $url );
Output::i()->redirect( $url );
}
else
{
\IPS\Output::i()->error( 'cannot_continue_upgrade', '', 403, '' );
Output::i()->error( 'cannot_continue_upgrade', '', 403, '' );
}
}
}
@@ -11,23 +11,37 @@
namespace IPS\core\modules\setup\upgrade;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Application;
use IPS\Data\Store;
use IPS\Db;
use IPS\Dispatcher\Controller;
use IPS\Helpers\Form;
use IPS\Http\Url;
use IPS\Member;
use IPS\Output;
use IPS\Request;
use IPS\Theme;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Upgrader: Custom Upgrade Options
*/
class _customoptions extends \IPS\Dispatcher\Controller
class customoptions extends Controller
{
/**
* Show Form
*
* @return void
*/
public function manage()
public function manage() : void
{
$elements = array();
@@ -38,7 +52,7 @@ class _customoptions extends \IPS\Dispatcher\Controller
At the same time we look for any pre-upgrade checks, which completely halt everything. */
foreach( $_SESSION['apps'] as $app => $upgrade )
{
$application = \IPS\Application::load( $app );
$application = Application::load( $app );
$steps = $application->getUpgradeSteps( $application->long_version );
foreach( $steps as $step )
@@ -50,8 +64,8 @@ class _customoptions extends \IPS\Dispatcher\Controller
if( $output !== NULL )
{
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('admin');
\IPS\Output::i()->output = $output;
Output::i()->title = Member::loggedIn()->language()->addToStack('admin');
Output::i()->output = $output;
return;
}
}
@@ -79,27 +93,27 @@ class _customoptions extends \IPS\Dispatcher\Controller
}
/* Do we need to disable any apps? */
if( isset( \IPS\Request::i()->disable ) )
if( isset( Request::i()->disable ) )
{
foreach( explode( ',', \IPS\Request::i()->disable ) as $app )
foreach( explode( ',', Request::i()->disable ) as $app )
{
\IPS\Db::i()->update( 'core_applications', array( 'app_enabled' => 0 ), array( 'app_directory=?', $app ) );
Db::i()->update( 'core_applications', array( 'app_enabled' => 0 ), array( 'app_directory=?', $app ) );
}
if ( isset( \IPS\Data\Store::i()->applications ) )
if ( isset( Store::i()->applications ) )
{
unset( \IPS\Data\Store::i()->applications );
unset( Store::i()->applications );
}
}
/* If there are no options, no need to show an empty/blank form */
if( !\count( $elements ) )
if( !count( $elements ) )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "controller=confirm" )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
Output::i()->redirect( Url::internal( "controller=confirm" )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
}
/* Otherwise, show the form */
$form = new \IPS\Helpers\Form( 'options', 'continue' );
$form = new Form( 'options', 'continue' );
foreach( $elements as $element )
{
@@ -120,10 +134,10 @@ class _customoptions extends \IPS\Dispatcher\Controller
$_SESSION['upgrade_options'][ $app ][ $version ][ $key ] = $value;
}
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "controller=confirm" )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
Output::i()->redirect( Url::internal( "controller=confirm" )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('admin');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->block( 'admin', $form );
Output::i()->title = Member::loggedIn()->language()->addToStack('admin');
Output::i()->output = Theme::i()->getTemplate( 'global' )->block( 'admin', $form );
}
}
@@ -11,31 +11,46 @@
namespace IPS\core\modules\setup\upgrade;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use DateInterval;
use IPS\Application;
use IPS\core\AdminNotification;
use IPS\Data\Store;
use IPS\DateTime;
use IPS\Db;
use IPS\Dispatcher\Controller;
use IPS\IPS;
use IPS\Member;
use IPS\Output;
use IPS\Settings;
use IPS\Theme;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Upgrader: Finished Screen
*/
class _done extends \IPS\Dispatcher\Controller
class done extends Controller
{
/**
* Finished
*
* @return void
*/
public function manage()
public function manage() : void
{
\IPS\Output::clearJsFiles();
Output::clearJsFiles();
/* Get rid of temporary upgrade data */
\IPS\Db::i()->dropTable( 'upgrade_temp', TRUE );
Db::i()->dropTable( 'upgrade_temp', TRUE );
/* Reset theme maps to make sure bad data hasn't been cached by visits mid-setup */
foreach( \IPS\Theme::themes() as $id => $set )
foreach( Theme::themes() as $id => $set )
{
/* Update mappings */
$set->css_map = array();
@@ -43,6 +58,8 @@ class _done extends \IPS\Dispatcher\Controller
}
/* Delete some variables we stored in our session */
unset( $_SESSION['apps'] );
if( isset( $_SESSION['upgrade_options'] ) )
{
unset( $_SESSION['upgrade_options'] );
@@ -61,105 +78,24 @@ class _done extends \IPS\Dispatcher\Controller
unset( $_SESSION['key'] );
/* Clear recent datastore logs to prevent an error message displaying immediately after upgrade */
\IPS\Db::i()->delete( 'core_log', array( '`category`=? AND `time`>?', 'datastore', \IPS\DateTime::create()->sub( new \DateInterval( 'PT1H' ) )->getTimestamp() ) );
Db::i()->delete( 'core_log', array( '`category`=? AND `time`>?', 'datastore', DateTime::create()->sub( new DateInterval( 'PT1H' ) )->getTimestamp() ) );
/* Unset settings datastore to prevent any upgrade settings that were overridden becoming persistent */
\IPS\Settings::i()->clearCache();
Settings::i()->clearCache();
/* IPS Cloud Sync */
\IPS\IPS::resyncIPSCloud('Upgraded community');
IPS::resyncIPSCloud('Upgraded community');
/* Remove any new version ACP Notifications */
\IPS\core\AdminNotification::remove( 'core', 'NewVersion' );
AdminNotification::remove( 'core', 'NewVersion' );
/* Send v5 notification if the version actually changed */
if( !empty( $_SESSION['apps']['core'] ) AND $_SESSION['apps']['core']['current'] !== $_SESSION['apps']['core']['available'] AND !\IPS\IPS::isManaged() )
{
\IPS\core\AdminNotification::send( 'core', 'VersionFive', NULL, TRUE );
}
/* Clear any previous editor plugins */
Application::resetEditorPlugins();
unset( $_SESSION['apps'] );
/* Check for php8 method substitution issues */
if ( \IPS\Application\Scanner::scanCustomizationIssues( false, true ) !== null )
{
$foundIssues = \IPS\Application\Scanner::scanCustomizationIssues()[0];
$disabledApps = array();
$disabledPlugins = array();
foreach ( $foundIssues as $appOrPlugin => $classes )
{
$components = explode( "-", $appOrPlugin );
$isApp = \mb_strtolower( trim( $components[0] ) ) === 'app';
$appDir = trim( $components[1] );
/* Disable the plugin/app and flag for manual intervention */
if ( $isApp and ( empty( $disabledApps[$appDir] ) ) )
{
/* IPS Code is flawless, skip it */
if ( \in_array( $appDir, \IPS\IPS::$ipsApps ) )
{
continue;
}
try
{
$app = \IPS\Application::load( $appDir );
$app->_enabled = false;
if ( ! \IPS\IN_DEV )
{
$app->requires_manual_intervention = 1;
}
$app->save();
$disabledApps[$appDir] = $app->_title;
}
catch ( \InvalidArgumentException|\OutOfRangeException $e )
{
/* This still won't work, so don't leave it empty */
$disabledApps[$appDir] = $appDir;
continue;
}
}
elseif ( empty( $disabledPlugins[$appDir] ) )
{
try
{
$pluginId = \IPS\Db::i()->select( 'plugin_id', 'core_plugins', [ 'plugin_location=?', $appDir ], null, 1 )->first();
$plugin = \IPS\Plugin::load( $pluginId );
$plugin->_enabled = false;
if ( ! \IPS\IN_DEV )
{
$plugin->requires_manual_intervention = 1;
}
$plugin->save();
$disabledPlugins[$appDir] = $plugin->name;
}
catch ( \UnderflowException|\InvalidArgumentException|\OutOfRangeException $e )
{
/* This still won't work, so don't leave it empty */
$disabledPlugins[$appDir] = $appDir;
continue;
}
}
}
if ( \count( $disabledPlugins ) OR \count( $disabledApps ) )
{
\IPS\core\AdminNotification::send( 'core', 'ManualInterventionMessage' );
$_SESSION['upgrade_postUpgrade']['core'][] = \IPS\Theme::i()->getTemplate( 'global' )->methodIssues(
\IPS\Theme::i()->getTemplate( 'global' )->disabled3rdParty( array_keys( $disabledApps ), array_keys( $disabledPlugins ), false )
);
}
}
/* And show the complete page - the template handles this step special already so we don't have to output anything */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('done');
Output::i()->title = Member::loggedIn()->language()->addToStack('done');
/* The upgrader will cause a few syncs on Cloud2, but we don't have to wait for those. Clear the flag here. */
unset( \IPS\Data\Store::i()->syncCompleted );
unset( Store::i()->syncCompleted );
}
}
@@ -11,16 +11,31 @@
namespace IPS\core\modules\setup\upgrade;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\Data\Store;
use IPS\Db;
use IPS\Dispatcher\Controller;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Text;
use IPS\Http\Url;
use IPS\IPS;
use IPS\Member;
use IPS\Output;
use IPS\Settings;
use IPS\Theme;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Upgrader: License
*/
class _license extends \IPS\Dispatcher\Controller
class license extends Controller
{
/**
@@ -28,12 +43,12 @@ class _license extends \IPS\Dispatcher\Controller
*
* @return void
*/
public function manage()
public function manage() : void
{
/* Check license key */
if( \IPS\Db::i()->checkForTable( 'core_store' ) )
if( Db::i()->checkForTable( 'core_store' ) )
{
$licenseData = \IPS\IPS::licenseKey( TRUE );
$licenseData = IPS::licenseKey( TRUE );
}
else
{
@@ -41,10 +56,10 @@ class _license extends \IPS\Dispatcher\Controller
try
{
$license = \IPS\Db::i()->select( '*', 'cache_store', array( 'cs_key=?', 'licenseData' ) )->first();
$license = Db::i()->select( '*', 'cache_store', array( 'cs_key=?', 'licenseData' ) )->first();
$licenseData = unserialize( $license['cs_value'] );
}
catch( \Exception $e ){}
catch( Exception $e ){}
}
if( isset( $licenseData['key'] ) AND !isset( $licenseData['expires'] ) )
@@ -64,10 +79,9 @@ class _license extends \IPS\Dispatcher\Controller
if ( !$active )
{
$response = NULL;
$active = NULL;
$form = new \IPS\Helpers\Form( 'licensekey', 'continue' );
$form->add( new \IPS\Helpers\Form\Text( 'ipb_reg_number', NULL, TRUE, array(), function( $val ){
\IPS\IPS::checkLicenseKey( $val, \IPS\Settings::i()->base_url );
$form = new Form( 'licensekey', 'continue' );
$form->add( new Text( 'ipb_reg_number', NULL, TRUE, array(), function( $val ){
IPS::checkLicenseKey( $val, Settings::i()->base_url );
} ) );
if( $values = $form->values() )
@@ -83,10 +97,10 @@ class _license extends \IPS\Dispatcher\Controller
$form->saveAsSettings( $values );
/* Refresh the locally stored license info */
if( \IPS\Db::i()->checkForTable( 'core_store' ) )
if( Db::i()->checkForTable( 'core_store' ) )
{
unset( \IPS\Data\Store::i()->license_data );
$licenseData = \IPS\IPS::licenseKey();
unset( Store::i()->license_data );
$licenseData = IPS::licenseKey();
}
else
{
@@ -107,29 +121,29 @@ class _license extends \IPS\Dispatcher\Controller
if( $active )
{
/* Clear any caches or else we might not see new versions on the next screen */
if ( isset( \IPS\Data\Store::i()->applications ) )
if ( isset( Store::i()->applications ) )
{
unset( \IPS\Data\Store::i()->applications );
unset( Store::i()->applications );
}
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "controller=applications" )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
Output::i()->redirect( Url::internal( "controller=applications" )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('license');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->license( $form, $active );
Output::i()->title = Member::loggedIn()->language()->addToStack('license');
Output::i()->output = Theme::i()->getTemplate( 'global' )->license( $form, $active );
}
/**
* Retrieve license data from license server
*
* @return mixed
* @return array|null
*/
protected function getLicenseData()
protected function getLicenseData() : ?array
{
/* Call the main server */
try
{
$response = \IPS\Http\Url::ips( 'license/' . \IPS\Settings::i()->ipb_reg_number )->request()->get();
$response = Url::ips( 'license/' . Settings::i()->ipb_reg_number )->request()->get();
if ( $response->httpResponseCode == 404 )
{
$licenseData = NULL;
@@ -139,7 +153,7 @@ class _license extends \IPS\Dispatcher\Controller
$licenseData = $response->decodeJson();
}
}
catch ( \Exception $e )
catch ( Exception $e )
{
$licenseData = NULL;
}
+101 -46
View File
@@ -11,27 +11,56 @@
namespace IPS\core\modules\setup\upgrade;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Application;
use IPS\core\Setup\Upgrade;
use IPS\Data\Cache;
use IPS\Data\Store;
use IPS\Db;
use IPS\Dispatcher\Controller;
use IPS\Http\Url;
use IPS\IPS;
use IPS\Login as LoginClass;
use IPS\Member;
use IPS\Output;
use IPS\Request;
use IPS\Settings;
use IPS\Theme;
use OutOfRangeException;
use UnderflowException;
use function count;
use function defined;
use const IPS\BYPASS_UPGRADER_LOGIN;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Upgrader: Login
*/
class _login extends \IPS\Dispatcher\Controller
class login extends Controller
{
/**
* Anything lower than this will cause the upgrader to disable
* non-1st party apps
*
* @var int
*/
protected static int $minimumv5 = 5000015;
/**
* Show login form and/or process login form
*
* @todo [Upgrade] Will also need to account for things in the input (e.g. password) that would be replaced, like & to &amp;
* @return void
*/
public function manage()
public function manage() : void
{
/* Clear previous session data */
if( !isset( \IPS\Request::i()->sessionCheck ) AND \count( $_SESSION ) )
if( !isset( Request::i()->sessionCheck ) AND count( $_SESSION ) )
{
foreach( $_SESSION as $k => $v )
{
@@ -40,52 +69,78 @@ class _login extends \IPS\Dispatcher\Controller
}
/* Store a session variable and then check it on the next page load to make sure PHP sessions are working */
if( !isset( \IPS\Request::i()->sessionCheck ) )
if( !isset( Request::i()->sessionCheck ) )
{
$_SESSION['sessionCheck'] = TRUE;
\IPS\Output::i()->redirect( \IPS\Request::i()->url()->setQueryString( 'sessionCheck', 1 ), NULL, 307 ); // 307 instructs the browser to resubmit the form as a POST request maintaining all the values from before
Output::i()->redirect( Request::i()->url()->setQueryString( 'sessionCheck', 1 ), NULL, 307 ); // 307 instructs the browser to resubmit the form as a POST request maintaining all the values from before
}
else
{
if( !isset( $_SESSION['sessionCheck'] ) OR !$_SESSION['sessionCheck'] )
{
\IPS\Output::i()->error( 'session_check_fail', '5C289/1', 500, '' );
Output::i()->error( 'session_check_fail', '5C289/1', 500, '' );
}
}
/* Are we automatically logging in? */
if ( isset( \IPS\Request::i()->autologin ) and isset( \IPS\Request::i()->cookie['IPSSessionAdmin'] ) )
if ( isset( Request::i()->autologin ) and isset( Request::i()->cookie['IPSSessionAdmin'] ) )
{
try
{
$session = \IPS\Db::i()->select( '*', 'core_sys_cp_sessions', array( 'session_id=?', \IPS\Request::i()->cookie['IPSSessionAdmin'] ) )->first();
$member = $session['session_member_id'] ? \IPS\Member::load( $session['session_member_id'] ) : new \IPS\Member;
if ( $member->member_id and $this->_memberHasUpgradePermission( $member ) and ( !\IPS\Settings::i()->match_ipaddress or ( $session['session_ip_address'] === \IPS\Request::i()->ipAddress() ) ) )
$session = Db::i()->select( '*', 'core_sys_cp_sessions', array( 'session_id=?', Request::i()->cookie['IPSSessionAdmin'] ) )->first();
$member = $session['session_member_id'] ? Member::load( $session['session_member_id'] ) : new Member;
if ( $member->member_id and $this->_memberHasUpgradePermission( $member ) and ( !Settings::i()->match_ipaddress or ( $session['session_ip_address'] === Request::i()->ipAddress() ) ) )
{
$_SESSION['uniqueKey'] = \IPS\Login::generateRandomString();
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "controller=systemcheck" )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
$_SESSION['uniqueKey'] = LoginClass::generateRandomString();
Output::i()->redirect( Url::internal( "controller=systemcheck" )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
}
}
catch( \UnderflowException $e ) {}
catch( UnderflowException $e ) {}
}
if ( \IPS\BYPASS_UPGRADER_LOGIN )
if ( BYPASS_UPGRADER_LOGIN )
{
$_SESSION['uniqueKey'] = \IPS\Login::generateRandomString();
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "controller=systemcheck" )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
$_SESSION['uniqueKey'] = LoginClass::generateRandomString();
Output::i()->redirect( Url::internal( "controller=systemcheck" )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
}
/* Drop the data store before we continue */
/* Before going any further, make sure there is an actual upgrade to be done. This both provides a nicer experience (so
people don't log in ust to be told there's nothing to upgrade) and prevents having a permenantly available login
screen which doesn't use locking (which could be use to bruteforce an account) */
$canUpgrade = FALSE;
foreach( \IPS\Application::applications() as $app => $data )
$currentBaseVersion = Db::i()->select( 'app_long_version', 'core_applications', [ 'app_directory=?', 'core' ] )->first();
/* If we are upgrading from a version earlier than v5, disable and lock anything that isn't 1st party */
if( $currentBaseVersion < static::$minimumv5 )
{
$path = \IPS\Application::getRootPath( $app ) . '/applications/' . $app;
Db::i()->update( 'core_applications', [ 'app_enabled' => 0, 'app_requires_manual_intervention' => 1 ], Db::i()->in( 'app_directory', IPS::$ipsApps, true ) );
Cache::i()->clearAll();
Store::i()->clearAll();
}
foreach( Application::getStore() as $data )
{
$app = $data['app_directory'];
/* If we are upgrading from a version earlier than v5, only check 1st party apps */
if( $currentBaseVersion < static::$minimumv5 and !in_array( $app, IPS::$ipsApps ) )
{
continue;
}
/* Skip anything that is locked */
if( $data['app_requires_manual_intervention'] )
{
continue;
}
$path = Application::getRootPath( $app ) . '/applications/' . $app;
if ( $app != 'chat' and is_dir( $path . '/data' ) )
{
$currentVersion = \IPS\Application::load( $app )->long_version;
$availableVersion = \IPS\Application::getAvailableVersion( $app );
$currentVersion = Application::load( $app )->long_version;
$availableVersion = Application::getAvailableVersion( $app );
if ( empty( $errors ) AND $availableVersion > $currentVersion )
{
@@ -95,44 +150,44 @@ class _login extends \IPS\Dispatcher\Controller
}
/* We need to allow logins if the previous upgrade wasn't finished */
if( \IPS\Db::i()->checkForTable( 'upgrade_temp' ) )
if( Db::i()->checkForTable( 'upgrade_temp' ) )
{
$canUpgrade = TRUE;
}
if ( !$canUpgrade )
{
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'forms' )->noapps();
Output::i()->output .= Theme::i()->getTemplate( 'forms' )->noapps();
/* We do this just to be 100% certain the flag didn't get "stuck" and needs to be reset. */
\IPS\core\Setup\Upgrade::setUpgradingFlag( FALSE );
Upgrade::setUpgradingFlag( FALSE );
return;
}
/* Nope, show a form */
$error = NULL;
if ( isset( \IPS\Request::i()->auth ) and isset( \IPS\Request::i()->password ) )
if ( isset( Request::i()->auth ) and isset( Request::i()->password ) )
{
$table = 'core_members';
if ( \IPS\Db::i()->checkForTable( 'members' ) AND !\IPS\Db::i()->checkForTable( 'core_members' ) )
if ( Db::i()->checkForTable( 'members' ) AND !Db::i()->checkForTable( 'core_members' ) )
{
$table = 'members';
}
$memberRows = \IPS\Db::i()->select( '*', $table, array( 'email=? OR email=? OR name=? OR name=?', \IPS\Request::i()->auth, \IPS\Request::legacyEscape( \IPS\Request::i()->auth ), \IPS\Request::i()->auth, \IPS\Request::legacyEscape( \IPS\Request::i()->auth ) ) );
if ( \count( $memberRows ) )
$memberRows = Db::i()->select( '*', $table, array( 'email=? OR email=?', Request::i()->auth, Request::legacyEscape( Request::i()->auth ) ) );
if ( count( $memberRows ) )
{
foreach( $memberRows as $memberRow )
{
$member = \IPS\Member::constructFromData( $memberRow );
$member = Member::constructFromData( $memberRow );
if ( password_verify( \IPS\Request::i()->password, $member->members_pass_hash ) or $member->verifyLegacyPassword( \IPS\Request::i()->protect('password') ) )
if ( password_verify( Request::i()->password, $member->members_pass_hash ) or $member->verifyLegacyPassword( Request::i()->protect('password') ) )
{
if ( $this->_memberHasUpgradePermission( $member ) )
{
$_SESSION['uniqueKey'] = \IPS\Login::generateRandomString();
\IPS\IPS::resyncIPSCloud('Beginning upgrade');
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "controller=systemcheck" )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
$_SESSION['uniqueKey'] = LoginClass::generateRandomString();
IPS::resyncIPSCloud('Beginning upgrade');
Output::i()->redirect( Url::internal( "controller=systemcheck" )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
}
else
{
@@ -153,26 +208,26 @@ class _login extends \IPS\Dispatcher\Controller
if ( $error )
{
$error = \IPS\Member::loggedIn()->language()->addToStack( $error, FALSE, array( 'pluralize' => array( 3 ) ) );
$error = Member::loggedIn()->language()->addToStack( $error, FALSE, array( 'pluralize' => array( 3 ) ) );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('login');
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'forms' )->login( $error );
Output::i()->title = Member::loggedIn()->language()->addToStack('login');
Output::i()->output .= Theme::i()->getTemplate( 'forms' )->login( $error );
}
/**
* Can member log into upgrader?
*
* @param \IPS\Member $member The member
* @param Member $member The member
* @return bool
*/
protected function _memberHasUpgradePermission( \IPS\Member $member )
protected function _memberHasUpgradePermission( Member $member ) : bool
{
/* 4.x */
if ( \IPS\Db::i()->checkForTable( 'core_admin_permission_rows' ) )
if ( Db::i()->checkForTable( 'core_admin_permission_rows' ) )
{
/* This permission was added in 4.1.6, so if we have it, use it */
if ( \IPS\Application::load('core')->long_version > 101021 )
if ( Application::load('core')->long_version > 101021 )
{
return $member->hasAcpRestriction( 'core', 'overview', 'upgrade_manage' );
}
@@ -188,11 +243,11 @@ class _login extends \IPS\Dispatcher\Controller
/* Does our primary group have permission? */
try
{
$admin = (bool) \IPS\Db::i()->select( 'g_access_cp', 'groups', array( 'g_id=?', $member->member_group_id ) )->first();
$admin = (bool) Db::i()->select( 'g_access_cp', 'groups', array( 'g_id=?', $member->member_group_id ) )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
throw new \OutOfRangeException( 'upgrade_group_not_exist' );
throw new OutOfRangeException( 'upgrade_group_not_exist' );
}
if( $admin )
@@ -208,7 +263,7 @@ class _login extends \IPS\Dispatcher\Controller
{
try
{
$admin = (bool) \IPS\Db::i()->select( 'g_access_cp', 'groups', array( 'g_id=?', $group ) )->first();
$admin = (bool) Db::i()->select( 'g_access_cp', 'groups', array( 'g_id=?', $group ) )->first();
if( $admin )
{
@@ -216,7 +271,7 @@ class _login extends \IPS\Dispatcher\Controller
}
}
/* It is possible the user has an old group that no longer exists defined as a secondary group */
catch( \UnderflowException $e ){}
catch( UnderflowException $e ){}
}
}
@@ -11,87 +11,116 @@
namespace IPS\core\modules\setup\upgrade;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\Application;
use IPS\core\Setup\Upgrade;
use IPS\Db;
use IPS\Dispatcher\Controller;
use IPS\Http\Url;
use IPS\Member;
use IPS\Output;
use IPS\Request;
use IPS\Settings;
use IPS\Theme;
use UnderflowException;
use function count;
use function defined;
use function is_array;
use const IPS\UPGRADE_MD5_CHECK;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Upgrader: System Check
*/
class _systemcheck extends \IPS\Dispatcher\Controller
class systemcheck extends Controller
{
/**
* Show Form
*
* @return void
*/
public function manage()
public function manage() : void
{
/* Do we have an older upgrade session hanging around? */
if ( ! isset( \IPS\Request::i()->skippreviousupgrade ) AND \IPS\Db::i()->checkForTable( 'upgrade_temp' ) )
if ( ! isset( Request::i()->skippreviousupgrade ) AND Db::i()->checkForTable( 'upgrade_temp' ) )
{
try
{
$row = \IPS\Db::i()->select( '*', 'upgrade_temp' )->first();
$row = Db::i()->select( '*', 'upgrade_temp' )->first();
$json = json_decode( $row['upgrade_data'], TRUE );
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
$json = NULL;
}
if ( \is_array( $json ) and isset( $json['session'] ) and isset( $json['data'] ) )
if ( is_array( $json ) and isset( $json['session'] ) and isset( $json['data'] ) )
{
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('unfinished_upgrade');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->unfinishedUpgrade( $json, $row['lastaccess'] );
Output::i()->title = Member::loggedIn()->language()->addToStack('unfinished_upgrade');
Output::i()->output = Theme::i()->getTemplate( 'global' )->unfinishedUpgrade( $json, $row['lastaccess'] );
return;
}
}
elseif( isset( \IPS\Request::i()->skippreviousupgrade ) AND \IPS\Request::i()->skippreviousupgrade )
elseif( isset( Request::i()->skippreviousupgrade ) AND Request::i()->skippreviousupgrade )
{
/* If we skip the previous upgrade remove the temp upgrade data now. That way if we hit utf8 upgrader and come back to upgrader we are
not prompted again to continue our upgrade we already elected to start over */
\IPS\Db::i()->dropTable( 'upgrade_temp', TRUE );
Db::i()->dropTable( 'upgrade_temp', TRUE );
}
/* Do we need to disable designer mode? */
if ( isset( \IPS\Request::i()->disableDesignersMode ) )
if ( isset( Request::i()->disableDesignersMode ) )
{
\IPS\Settings::i()->changeValues( array( 'theme_designers_mode' => 0 ) );
Settings::i()->changeValues( array( 'theme_designer_mode' => 0 ) );
}
/* Get requirements */
$requirements = \IPS\core\Setup\Upgrade::systemRequirements();
$designersModeEnabled = ( \IPS\Application::load('core')->long_version >= 40000 and \IPS\Theme::designersModeEnabled() ) ? TRUE : FALSE;
$requirements = Upgrade::systemRequirements();
/* Can we just skip this screen? */
$canProceed = FALSE;
if ( !$designersModeEnabled )
$canProceed = !isset( $requirements['advice'] ) or !count( $requirements['advice'] );
if ( $canProceed )
{
$canProceed = !isset( $requirements['advice'] ) or !\count( $requirements['advice'] );
if ( $canProceed )
foreach ( $requirements['requirements'] as $k => $_requirements )
{
foreach ( $requirements['requirements'] as $k => $_requirements )
foreach ( $_requirements as $item )
{
foreach ( $_requirements as $item )
if ( !$item['success'] )
{
if ( !$item['success'] )
{
$canProceed = FALSE;
}
$canProceed = FALSE;
}
}
}
}
/* Check we have the latest version and run an md5 check */
$incorrectFiles = array();
if ( UPGRADE_MD5_CHECK )
{
try
{
$incorrectFiles = Application::md5Check( Application::getAvailableVersion('core') );
if ( count( $incorrectFiles ) )
{
$canProceed = FALSE;
}
}
catch ( Exception $e ) { }
}
/* Display */
if ( $canProceed )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal("controller=license&key={$_SESSION['uniqueKey']}") );
Output::i()->redirect( Url::internal("controller=license&key={$_SESSION['uniqueKey']}") );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('healthcheck');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->healthcheck( $requirements, $designersModeEnabled );
Output::i()->title = Member::loggedIn()->language()->addToStack('healthcheck');
Output::i()->output = Theme::i()->getTemplate( 'global' )->healthcheck( $requirements, $incorrectFiles );
}
}
@@ -11,73 +11,86 @@
namespace IPS\core\modules\setup\upgrade;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use BadMethodCallException;
use Exception;
use IPS\core\Setup\Upgrade as UpgradeClass;
use IPS\Dispatcher\Controller;
use IPS\Helpers\MultipleRedirect;
use IPS\Http\Url;
use IPS\Log;
use IPS\Member;
use IPS\Output;
use IPS\Theme;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Upgrader: Perform Upgrade
*/
class _upgrade extends \IPS\Dispatcher\Controller
class upgrade extends Controller
{
/**
* Upgrade
*
* @return void
*/
public function manage()
public function manage() : void
{
$multipleRedirect = new \IPS\Helpers\MultipleRedirect(
\IPS\Http\Url::internal( 'controller=upgrade' )->setQueryString( 'key', $_SESSION['uniqueKey'] ),
$multipleRedirect = new MultipleRedirect(
Url::internal( 'controller=upgrade' )->setQueryString( 'key', $_SESSION['uniqueKey'] ),
function( $data )
{
try
{
$upgrader = new \IPS\core\Setup\Upgrade( array_keys( $_SESSION['apps'] ) );
$upgrader = new UpgradeClass( array_keys( $_SESSION['apps'] ) );
}
catch ( \Exception $e )
catch ( Exception $e )
{
\IPS\Output::i()->error( 'error', '2C222/1', 403, '' );
Output::i()->error( 'error', '2C222/1', 403, '' );
}
try
{
return $upgrader->process( $data );
}
catch( \Exception $e )
catch( BadMethodCallException $e )
{
\IPS\Log::log( $e, 'upgrade_error' );
/* Allow multi-redirect handle this */
throw $e;
}
catch( Exception $e )
{
Log::log( $e, 'upgrade_error' );
/* Error thrown that we want to handle differently */
$key = 'mr-' . md5( \IPS\Http\Url::internal( 'controller=upgrade' )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
$key = 'mr-' . md5( Url::internal( 'controller=upgrade' )->setQueryString( 'key', $_SESSION['uniqueKey'] ) );
if ( isset( $_SESSION['updatedData'] ) and isset( $_SESSION['updatedData'][1] ) )
{
$_SESSION[ $key ] = json_encode( $_SESSION['updatedData'] );
}
$continueUrl = \IPS\Http\Url::internal( 'controller=upgrade' )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'mr' => 1, 'mr_continue' => 1 ) );
$retryUrl = \IPS\Http\Url::internal( 'controller=upgrade' )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'mr' => 1 ) );
$continueUrl = Url::internal( 'controller=upgrade' )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'mr' => 1, 'mr_continue' => 1 ) );
$retryUrl = Url::internal( 'controller=upgrade' )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'mr' => 1 ) );
$error = \IPS\Theme::i()->getTemplate( 'global' )->upgradeError( $e, $continueUrl, $retryUrl );
$error = Theme::i()->getTemplate( 'global' )->upgradeError( $e, $continueUrl, $retryUrl );
return array( \IPS\Theme::i()->getTemplate( 'global' )->block( 'install', $error, FALSE ) );
}
catch( \BadMethodCallException $e )
{
/* Allow multi-redirect handle this */
throw $e;
return array( Theme::i()->getTemplate( 'global' )->block( 'install', $error, FALSE ) );
}
},
function()
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'controller=done' ) );
Output::i()->redirect( Url::internal( 'controller=done' ) );
}
);
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('upgrade');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global' )->block( 'upgrade', $multipleRedirect, FALSE );
Output::i()->title = Member::loggedIn()->language()->addToStack('upgrade');
Output::i()->output = Theme::i()->getTemplate( 'global' )->block( 'upgrade', $multipleRedirect, FALSE );
}
}