Version 4.3.0

This commit is contained in:
Neo committed 2025-12-19 05:47:12 -08:00
1 parent 96997ddd8e
commit fe1acf984a
1349 files changed
+116159 -67711

No files matched your search

+10 -7
View File
@@ -82,6 +82,15 @@ class _Upgrade
$did++;
/* Make sure the users aren't orphaned */
$requester = \IPS\Member::load( $friend['friends_friend_id'] );
$requestee = \IPS\Member::load( $friend['friends_member_id'] );
if( !$requestee->member_id OR !$requester->member_id )
{
continue;
}
/* Follower */
$follower = array(
'follow_id' => md5( 'core;member;' . $friend['friends_friend_id'] . ';' . $friend['friends_member_id'] ),
@@ -152,8 +161,7 @@ class _Upgrade
{
if ( \IPS\Db::i()->select( 'COUNT(*)', 'core_advertisements', 'ad_active=1' )->first() )
{
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 1 ), array( 'conf_key=?', 'ads_exist' ) );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->changeValues( array( 'ads_exist' => 1 ) );
}
return true;
@@ -228,11 +236,6 @@ class _Upgrade
$memberCleanup[] = "CHANGE COLUMN last_post member_last_post INT(10) null DEFAULT null";
}
if( !\IPS\Db::i()->checkForIndex( 'core_members', 'ipsconnect_id' ) )
{
$memberCleanup[] = "ADD INDEX ipsconnect_id (ipsconnect_id)";
}
if( count( $memberCleanup ) )
{
$toRun = \IPS\core\Setup\Upgrade::runManualQueries( array( array(
+2 -16
View File
@@ -22,27 +22,13 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
*/
class _Upgrade
{
/**
* Step 1
* Fix IPS Connect Slave Count
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => \IPS\Db::i()->select( 'COUNT(*)', 'core_ipsconnect_slaves' )->first() ), array( 'conf_key=?', 'connect_slaves' ) );
unset( \IPS\Data\Store::i()->settings );
return TRUE;
}
/**
* Step 2
* Fix the imported ipb3 words
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step2()
public function step1()
{
$existingApplications = array_keys( \IPS\Application::applications() );
\IPS\Db::i()->delete( 'core_sys_lang_words', 'word_plugin <> NULL AND ' . \IPS\Db::i()->in( 'word_app', $existingApplications, TRUE ) );
@@ -56,7 +42,7 @@ class _Upgrade
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step3()
public function step2()
{
\IPS\Db::i()->delete('core_tasks', array('`key`=? and app=?', 'searchcleanup', 'core' ) );
@@ -51,8 +51,7 @@ class _Upgrade
}
$customDefinitions = count( $customDefinitions ) ? json_encode( $customDefinitions ) : NULL;
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $customDefinitions ), array( 'conf_key=?', 'furl_configuration' ) );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->changeValues( array( 'furl_configuration' => $customDefinitions ) );
return TRUE;
}
@@ -81,11 +81,14 @@ class _Upgrade
{
foreach ( \IPS\Content::routedClasses( FALSE, TRUE ) as $class )
{
try
if ( isset( $class::$databaseColumnMap['content'] ) )
{
\IPS\Task::queue( 'core', 'RestoreBrokenAttachments', array( 'class' => $class ), 3 );
try
{
\IPS\Task::queue( 'core', 'RestoreBrokenAttachments', array( 'class' => $class ), 3 );
}
catch( \OutOfRangeException $ex ) { }
}
catch( \OutOfRangeException $ex ) { }
}
\IPS\Db::i()->delete( 'core_attachments_map', "location_key=1" );
@@ -67,12 +67,6 @@ class _Upgrade
unset( \IPS\Data\Store::i()->storageConfigurations );
}
/* Unset emoticons cache */
if ( isset( \IPS\Data\Store::i()->emoticons ) )
{
unset( \IPS\Data\Store::i()->emoticons );
}
/* Kick off the tasks */
\IPS\core\Setup\Upgrade::repairFileUrls('core');
\IPS\Task::queue( 'core', 'RebuildContentImages', array( 'class' => 'IPS\core\Statuses\Status' ), 3, array( 'class' ) );
@@ -56,8 +56,7 @@ class _Upgrade
\IPS\Db::i()->insert( 'core_sys_conf_settings', $insert );
}
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => \IPS\Settings::i()->max_video_width . 'px' ), array( 'conf_key=?', 'max_video_width_css' ) );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->changeValues( array( 'max_video_width_css' => \IPS\Settings::i()->max_video_width . 'px' ) );
}
return TRUE;
+11 -1
View File
@@ -68,7 +68,17 @@ class _Upgrade
$poll->votes = $numberOfVotes;
}
}
$poll->save();
try
{
$poll->save();
}
catch( \IPS\Db\Exception $e )
{
\IPS\Log::log( $e, 'upgrade_error' );
continue;
}
}
}
@@ -148,8 +148,7 @@ class _Upgrade
$domains[ $domain ] = $domain;
}
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => json_encode( array_values( $domains ) ) ), array( 'conf_key=?', 'posts_add_nofollow_exclude' ) );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->changeValues( array( 'posts_add_nofollow_exclude' => json_encode( array_values( $domains ) ) ) );
}
return TRUE;
+13 -1
View File
@@ -66,7 +66,19 @@ if ( $application->long_version >= 40000 and !\IPS\NO_WRITES )
if ( $plugin->enabled )
{
$plugin->enabled = FALSE;
$plugin->save();
try
{
$plugin->save();
}
catch( \IPS\Db\Exception $e )
{
/* Column may be missing from a table, i.e. upgrading from an old version where set_cache_key doesn't exist */
if( $e->getCode() != 1054 )
{
throw $e;
}
}
$disabledPluginNames[] = $plugin->_title;
}
@@ -69,7 +69,7 @@ class _Upgrade
public function step2()
{
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => \IPS\Settings::i()->email_in ), "conf_key = 'upgrade_email'" );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
return TRUE;
}
@@ -169,7 +169,7 @@ class _Upgrade
public function step5()
{
/* Init */
$perCycle = 250;
$perCycle = 500;
$did = 0;
$limit = intval( \IPS\Request::i()->extra );
@@ -311,7 +311,7 @@ class _Upgrade
/* And update */
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $host ), "conf_key = 'smtp_host'" );
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $protocol ), "conf_key = 'smtp_protocol'" );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
}
return TRUE;
+20 -9
View File
@@ -38,6 +38,8 @@ class _Upgrade
$hasChanges = FALSE;
$applications = array();
$_SESSION['repairFileUrls'] = false;
/* Loop over all file storage extensions */
foreach ( \IPS\Application::allExtensions( 'core', 'FileStorage', FALSE, NULL, NULL, TRUE ) as $name => $obj )
{
@@ -45,22 +47,15 @@ class _Upgrade
{
$settings[ "filestorage__{$name}" ] = $defaultSetting;
$hasChanges = TRUE;
$_extension = explode( '_', $name );
$applications[ $_extension[0] ] = $_extension[0];
}
}
/* Now, if we have changes, update the setting and reinitiate the RepairFileUrls background queue task for the affected application(s) */
if( $hasChanges )
{
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => json_encode( $settings ) ), array( 'conf_key=?', 'upload_settings' ) );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->changeValues( array( 'upload_settings' => json_encode( $settings ) ) );
foreach( $applications as $app )
{
\IPS\core\Setup\Upgrade::repairFileUrls( $app );
}
$_SESSION['repairFileUrls'] = true;
}
/* That's all ... easy peasy */
@@ -113,4 +108,20 @@ class _Upgrade
{
return "Removing orphaned personal message maps";
}
/**
* Repair URLs
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function finish()
{
if( isset( $_SESSION['repairFileUrls'] ) AND $_SESSION['repairFileUrls'] )
{
foreach( \IPS\Application::applications() as $app )
{
\IPS\core\Setup\Upgrade::repairFileUrls( $app->directory );
}
}
}
}
@@ -1,61 +0,0 @@
<?php
/**
* @brief 4.1.0 Beta 5 Upgrade Code
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 15 Oct 2015
*/
namespace IPS\core\setup\upg_101004;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.1.0 Beta 5 Upgrade Code
*/
class _Upgrade
{
/**
* If there are follows for member records that no longer exists, this causes an error when trying to send the non-existent user a notification later
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
$toRunQueries = array(
array(
'table' => 'core_follow',
'query' => "DELETE FROM " . \IPS\Db::i()->prefix . "core_follow WHERE follow_member_id NOT IN(SELECT member_id FROM " . \IPS\Db::i()->prefix . "core_members)",
)
);
$toRun = \IPS\core\Setup\Upgrade::runManualQueries( $toRunQueries );
if ( count( $toRun ) )
{
\IPS\core\Setup\Upgrade::adjustMultipleRedirect( array( 'extra' => array( '_upgradeStep' => 2 ) ) );
/* Queries to run manually */
return array( 'html' => \IPS\Theme::i()->getTemplate( 'forms' )->queries( $toRun, \IPS\Http\Url::internal( 'controller=upgrade' )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'mr_continue' => 1, 'mr' => \IPS\Request::i()->mr ) ) ) );
}
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
return "Removing orphaned follows";
}
}
@@ -216,9 +216,7 @@ class _Upgrade
}
}
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => json_encode( $json ) ), array( 'conf_key=?', 'furl_configuration' ) );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->changeValues( array( 'furl_configuration' => json_encode( $json ) ) );
}
}
catch( \UnderflowException $e ) { }
@@ -68,9 +68,7 @@ class _Upgrade
}
}
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => json_encode( $json ) ), array( 'conf_key=?', 'furl_configuration' ) );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->changeValues( array( 'furl_configuration' => json_encode( $json ) ) );
}
}
catch( \UnderflowException $e ) { }
@@ -49,8 +49,7 @@ class _Upgrade
}
}
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => json_encode( $newValueToSave ) ), array( 'conf_key=?', 'furl_configuration' ) );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->changeValues( array( 'furl_configuration' => json_encode( $newValueToSave ) ) );
\IPS\Data\Cache::i()->clearAll();
return true;
@@ -91,30 +91,6 @@ class _Upgrade
return "Creating Security Questions";
}
/**
* Recount IPS Connect slaves
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step3()
{
\IPS\Db::i()->update( 'core_sys_conf_settings', array(
'conf_value' => (int) \IPS\Db::i()->select( 'count(*)', 'core_ipsconnect_slaves' )->first()
), array( 'conf_key=?', 'connect_slaves' ) );
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step3CustomTitle()
{
return "Resetting IPS Connect slave count";
}
/**
* Finish - This is run after all apps have been upgraded
*
+6 -11
View File
@@ -57,8 +57,7 @@ class _Upgrade
$settings['filestorage__core_Imageproxycache'] = $settings['filestorage__core_Attachment'];
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => json_encode( $settings ) ), array( 'conf_key=?', 'upload_settings' ) );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->changeValues( array( 'upload_settings' => json_encode( $settings ) ) );
/* That's all ... easy peasy */
return TRUE;
@@ -96,24 +95,21 @@ class _Upgrade
if ( mb_strpos( \IPS\Settings::i()->ipseo_ga, 'i,s,o,g,r,a,m' ) !== FALSE )
{
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 'ga' ), array( 'conf_key=?', 'ipbseo_ga_provider' ) );
\IPS\Settings::i()->changeValues( array( 'ipbseo_ga_provider' => 'ga' ) );
}
else if ( mb_strpos( \IPS\Settings::i()->ipseo_ga, 'piwik.js' ) !== FALSE )
{
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 'piwik' ), array( 'conf_key=?', 'ipbseo_ga_provider' ) );
\IPS\Settings::i()->changeValues( array( 'ipbseo_ga_provider' => 'piwik' ) );
}
else if ( \IPS\Settings::i()->ipseo_ga )
{
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 'custom' ), array( 'conf_key=?', 'ipbseo_ga_provider' ) );
\IPS\Settings::i()->changeValues( array( 'ipbseo_ga_provider' => 'custom' ) );
}
else
{
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 'none' ), array( 'conf_key=?', 'ipbseo_ga_provider' ) );
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => '0' ), array( 'conf_key=?', 'ipbseo_ga_enabled' ) );
\IPS\Settings::i()->changeValues( array( 'ipbseo_ga_provider' => 'none', 'ipbseo_ga_enabled' => '0' ) );
}
unset( \IPS\Data\Store::i()->settings );
return TRUE;
}
@@ -158,8 +154,7 @@ class _Upgrade
{
if ( \IPS\Settings::i()->mail_method == 'mail' )
{
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 'php' ), array( 'conf_key=?', 'mail_method' ) );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->changeValues( array( 'mail_method' => 'php' ) );
}
return TRUE;
}
@@ -57,7 +57,7 @@ class _Upgrade
{
if ( \IPS\Settings::i()->prune_log_system > 30 )
{
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 30 ), array( 'conf_key=?', 'prune_log_system' ) );
\IPS\Settings::i()->changeValues( array( 'prune_log_system' => 30 ) );
}
\IPS\Db::i()->insert( 'core_sys_conf_settings', array(
@@ -67,8 +67,6 @@ class _Upgrade
'conf_app' => 'core'
) );
unset( \IPS\Data\Store::i()->settings );
return TRUE;
}
@@ -33,7 +33,7 @@ class _Upgrade
if ( \IPS\Db::i()->select( 'COUNT(*)', 'core_announcements', 'announce_active=1' )->first() )
{
\IPS\Db::i()->replace( 'core_sys_conf_settings', array( 'conf_value' => 1, 'conf_key' => 'announcements_exist', 'conf_app' => 'core', 'conf_default' => 0 ) );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
}
return true;
@@ -2686,5 +2686,179 @@
]
}
]
},
"49": {
"method": "createTable",
"params": [
{
"name": "core_member_history",
"columns": {
"log_id": {
"allow_null": false,
"auto_increment": true,
"binary": false,
"comment": "ID Number",
"decimals": null,
"default": null,
"length": 20,
"name": "log_id",
"type": "BIGINT",
"unsigned": true,
"values": [],
"zerofill": false
},
"log_app": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "Application",
"decimals": null,
"default": "",
"length": 250,
"name": "log_app",
"type": "VARCHAR",
"unsigned": false,
"values": [],
"zerofill": false
},
"log_member": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "Member ID",
"decimals": null,
"default": "0",
"length": 20,
"name": "log_member",
"type": "BIGINT",
"unsigned": true,
"values": [],
"zerofill": false
},
"log_by": {
"allow_null": true,
"auto_increment": false,
"binary": false,
"comment": "Action performed by",
"decimals": null,
"default": null,
"length": 20,
"name": "log_by",
"type": "BIGINT",
"unsigned": true,
"values": [],
"zerofill": false
},
"log_type": {
"allow_null": true,
"auto_increment": false,
"binary": false,
"comment": "Log Type",
"decimals": null,
"default": null,
"length": 32,
"name": "log_type",
"type": "VARCHAR",
"unsigned": false,
"values": [],
"zerofill": false
},
"log_data": {
"allow_null": true,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": null,
"length": 0,
"name": "log_data",
"type": "TEXT",
"unsigned": false,
"values": [],
"zerofill": false
},
"log_date": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "0",
"length": 10,
"name": "log_date",
"type": "INT",
"unsigned": false,
"values": [],
"zerofill": false
},
"log_ip_address": {
"allow_null": true,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": null,
"length": 46,
"name": "log_ip_address",
"type": "VARCHAR",
"unsigned": false,
"values": [],
"zerofill": false
}
},
"indexes": {
"PRIMARY": {
"type": "primary",
"name": "PRIMARY",
"length": [
null
],
"columns": [
"log_id"
]
},
"application": {
"type": "key",
"name": "application",
"length": [
null
],
"columns": [
"log_app"
]
},
"log_member": {
"type": "key",
"name": "log_member",
"length": [
null
],
"columns": [
"log_member"
]
},
"log_ip_address": {
"type": "key",
"name": "log_ip_address",
"length": [
null
],
"columns": [
"log_ip_address"
]
},
"log_date": {
"type": "key",
"name": "log_date",
"length": [
null
],
"columns": [
"log_date"
]
}
}
}
]
}
}
+78 -433
View File
@@ -41,8 +41,8 @@ class _Upgrade
'conf_default' => 'letters',
'conf_value' => $_SESSION['upgrade_options']['core']['101100']['letter_photos'] ? 'letters' : 'default',
'conf_app' => 'core'
) );
unset( \IPS\Data\Store::i()->settings );
), TRUE );
\IPS\Settings::i()->clearCache();
return true;
}
@@ -140,394 +140,13 @@ class _Upgrade
{
return "Removing orphaned data";
}
/**
* Create/Convert Member History Table
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step3()
{
/* This step is different if Commerce is already installed */
if( \IPS\Db::i()->checkForTable( 'nexus_customer_history' ) )
{
$_SESSION['convertedMemberHistory'] = TRUE;
\IPS\Db::i()->renameTable( 'nexus_customer_history', 'core_member_history' );
\IPS\Db::i()->addColumn( 'core_member_history',
array(
'name' => 'log_app',
'type' => 'VARCHAR',
'length' => 250,
'allow_null' => FALSE,
'default' => '',
'comment' => 'Application'
)
);
}
else
{
\IPS\Db::i()->createTable( array(
'name' => 'core_member_history',
'columns' =>
array(
'log_id' =>
array(
'allow_null' => false,
'auto_increment' => true,
'binary' => false,
'comment' => 'ID Number',
'decimals' => NULL,
'default' => NULL,
'length' => 20,
'name' => 'log_id',
'type' => 'BIGINT',
'unsigned' => true,
'values' => array(),
'zerofill' => false,
),
'log_app' =>
array(
'allow_null' => false,
'auto_increment' => false,
'binary' => false,
'comment' => 'Application',
'decimals' => NULL,
'default' => '',
'length' => 250,
'name' => 'log_app',
'type' => 'VARCHAR',
'unsigned' => false,
'values' => array(),
'zerofill' => false,
),
'log_member' =>
array(
'allow_null' => false,
'auto_increment' => false,
'binary' => false,
'comment' => 'Member ID',
'decimals' => NULL,
'default' => '0',
'length' => 20,
'name' => 'log_member',
'type' => 'BIGINT',
'unsigned' => true,
'values' => array(),
'zerofill' => false,
),
'log_by' =>
array(
'allow_null' => true,
'auto_increment' => false,
'binary' => false,
'comment' => 'Action performed by',
'decimals' => NULL,
'default' => NULL,
'length' => 20,
'name' => 'log_by',
'type' => 'BIGINT',
'unsigned' => true,
'values' => array(),
'zerofill' => false,
),
'log_type' =>
array(
'allow_null' => true,
'auto_increment' => false,
'binary' => false,
'comment' => 'Log Type',
'decimals' => NULL,
'default' => NULL,
'length' => 32,
'name' => 'log_type',
'type' => 'VARCHAR',
'unsigned' => false,
'values' => array(),
'zerofill' => false,
),
'log_data' =>
array(
'allow_null' => true,
'auto_increment' => false,
'binary' => false,
'comment' => '',
'decimals' => NULL,
'default' => NULL,
'length' => 0,
'name' => 'log_data',
'type' => 'TEXT',
'unsigned' => false,
'values' => array(),
'zerofill' => false,
),
'log_date' =>
array(
'allow_null' => false,
'auto_increment' => false,
'binary' => false,
'comment' => '',
'decimals' => NULL,
'default' => '0',
'length' => 10,
'name' => 'log_date',
'type' => 'INT',
'unsigned' => false,
'values' => array(),
'zerofill' => false,
),
'log_ip_address' =>
array(
'allow_null' => true,
'auto_increment' => false,
'binary' => false,
'comment' => '',
'decimals' => NULL,
'default' => NULL,
'length' => 46,
'name' => 'log_ip_address',
'type' => 'VARCHAR',
'unsigned' => false,
'values' => array(),
'zerofill' => false,
)
),
'indexes' =>
array(
'PRIMARY' =>
array(
'type' => 'primary',
'name' => 'PRIMARY',
'length' =>
array(
0 => NULL,
),
'columns' =>
array(
0 => 'log_id',
),
),
'application' =>
array(
'type' => 'key',
'name' => 'application',
'length' =>
array(
0 => NULL,
),
'columns' =>
array(
0 => 'log_app',
),
),
'log_member' =>
array(
'type' => 'key',
'name' => 'log_member',
'length' =>
array(
0 => NULL,
),
'columns' =>
array(
0 => 'log_member',
),
),
'log_ip_address' =>
array(
'type' => 'key',
'name' => 'log_ip_address',
'length' =>
array(
0 => NULL,
),
'columns' =>
array(
0 => 'log_ip_address',
),
),
'log_date' =>
array(
'type' => 'key',
'name' => 'log_date',
'length' =>
array(
0 => NULL,
),
'columns' =>
array(
0 => 'log_date',
),
)
)
) );
}
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step3CustomTitle()
{
return "Setting up Member History";
}
/**
* Add index and set log_app
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step4()
{
/* Only perform this if converting from Nexus */
if( isset( $_SESSION['convertedMemberHistory'] ) )
{
\IPS\Db::i()->returnQuery = TRUE;
$queryApplication = \IPS\Db::i()->addIndex( 'core_member_history', array(
'type' => 'key',
'name' => 'application',
'length' =>
array(
0 => NULL,
),
'columns' =>
array(
0 => 'log_app',
)
) );
\IPS\Db::i()->returnQuery = FALSE;
\IPS\Db::i()->returnQuery = TRUE;
$updateQuery = \IPS\Db::i()->update( 'core_member_history', array( 'log_app' => 'nexus' ) );
\IPS\Db::i()->returnQuery = FALSE;
$toRun = \IPS\core\Setup\Upgrade::runManualQueries( array(
array(
'table' => 'core_member_history',
'query' => $queryApplication ),
array(
'table' => 'core_member_history',
'query' => $updateQuery )
) );
if ( count( $toRun ) )
{
\IPS\core\Setup\Upgrade::adjustMultipleRedirect( array( 'extra' => array( '_upgradeStep' => 5 ) ) );
/* Queries to run manually */
return array( 'html' => \IPS\Theme::i()->getTemplate( 'forms' )->queries( $toRun, \IPS\Http\Url::internal( 'controller=upgrade' )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'mr_continue' => 1, 'mr' => \IPS\Request::i()->mr ) ) ) );
}
}
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step4CustomTitle()
{
return "Checking indexes";
}
/**
* Update Nexus 'info' types
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step5()
{
/* Only perform this if converting from Nexus */
if( isset( $_SESSION['convertedMemberHistory'] ) )
{
/* Some init */
$did = 0;
$limit = 0;
if( isset( \IPS\Request::i()->extra ) )
{
$limit = \IPS\Request::i()->extra;
}
/* Try to prevent timeouts to the extent possible */
$cutOff = \IPS\core\Setup\Upgrade::determineCutoff();
foreach( \IPS\Db::i()->select( '*', 'core_member_history', array( 'log_type=?', 'info' ), 'log_id ASC', array( $limit, 500 ) ) as $log )
{
if( $cutOff !== null AND time() >= $cutOff )
{
return ( $limit + $did );
}
$did++;
$data = json_decode( $log['log_data'], TRUE );
if( isset( $data['email'] ) )
{
\IPS\Db::i()->update( 'core_member_history', array(
'log_app' => 'core',
'log_type' => 'email_change',
'log_data' => json_encode( array( 'old' => $data['email'], 'new' => '' ) )
),
array( 'log_id=?', $log['log_id'] )
);
}
elseif( isset( $data['password'] ) )
{
\IPS\Db::i()->update( 'core_member_history', array(
'log_app' => 'core',
'log_type' => 'password_change',
'log_data' => json_encode( array( 'password' => '' ) )
),
array( 'log_id=?', $log['log_id'] )
);
}
}
if( $did )
{
return $limit + $did;
}
else
{
unset( $_SESSION['_step5Count'], $_SESSION['convertedMemberHistory'] );
return TRUE;
}
}
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step5CustomTitle()
{
$limit = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
if( !isset( $_SESSION['_step5Count'] ) )
{
$_SESSION['_step5Count'] = \IPS\Db::i()->select( 'COUNT(*)', 'core_member_history', array( 'log_type=?', 'info' ) )->first();
}
return "Converting customer history log types (Converted so far: " . ( ( $limit > $_SESSION['_step5Count'] ) ? $_SESSION['_step5Count'] : $limit ) . ' out of ' . $_SESSION['_step5Count'] . ')';
}
/**
* Move Display Name history to the Member History Table
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step6()
public function step3()
{
/* Some init */
$did = 0;
@@ -570,7 +189,7 @@ class _Upgrade
/* Delete table */
\IPS\Db::i()->dropTable( 'core_dnames_change' );
unset( $_SESSION['_step6Count'] );
unset( $_SESSION['_step3Count'] );
return TRUE;
}
}
@@ -580,16 +199,16 @@ class _Upgrade
*
* @return string
*/
public function step6CustomTitle()
public function step3CustomTitle()
{
$limit = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
if( !isset( $_SESSION['_step6Count'] ) )
if( !isset( $_SESSION['_step3Count'] ) )
{
$_SESSION['_step6Count'] = \IPS\Db::i()->select( 'COUNT(*)', 'core_dnames_change' )->first();
$_SESSION['_step3Count'] = \IPS\Db::i()->select( 'COUNT(*)', 'core_dnames_change' )->first();
}
return "Moving Display Name history to the Member History system (Converted so far: " . ( ( $limit > $_SESSION['_step6Count'] ) ? $_SESSION['_step6Count'] : $limit ) . ' out of ' . $_SESSION['_step6Count'] . ')';
return "Moving Display Name history to the Member History system (Converted so far: " . ( ( $limit > $_SESSION['_step3Count'] ) ? $_SESSION['_step3Count'] : $limit ) . ' out of ' . $_SESSION['_step3Count'] . ')';
}
@@ -598,7 +217,7 @@ class _Upgrade
*
* @return bool
*/
public function step7()
public function step4()
{
\IPS\Db::i()->delete( 'core_moderators', array( 'type=? AND ' . \IPS\Db::i()->in( 'id', iterator_to_array( \IPS\Db::i()->select('g_id', 'core_groups' ) ), TRUE ), 'g' ) );
unset ( \IPS\Data\Store::i()->moderators );
@@ -611,7 +230,7 @@ class _Upgrade
*
* @return string
*/
public function step7CustomTitle()
public function step4CustomTitle()
{
return "Removing non-existent moderator groups";
}
@@ -622,7 +241,7 @@ class _Upgrade
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step8()
public function step5()
{
/* Populate the table */
if ( ! \IPS\Db::i()->select( 'COUNT(*)', 'core_social_promote_sharers' )->first() )
@@ -644,7 +263,7 @@ class _Upgrade
*
* @return string
*/
public function step8CustomTitle()
public function step5CustomTitle()
{
return "Setting up defaults for promotion";
}
@@ -655,11 +274,19 @@ class _Upgrade
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step9()
public function step6()
{
$position = 0;
/* Path fallback if a custom AdminCP directory is used. */
$path = \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY;
if( \IPS\CP_DIRECTORY != 'admin' AND !file_exists( \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY . '/install/reaction' ) )
{
$path = \IPS\ROOT_PATH . '/admin';
}
/* Go ahead and insert the default "Like" - if we aren't use likes, leave it disabled. */
$fileObj = \IPS\File::create( 'core_Reaction', 'react_like.png', file_get_contents( \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY . '/install/reaction/react_like.png' ), 'reactions', FALSE, NULL, FALSE );
$fileObj = \IPS\File::create( 'core_Reaction', 'react_like.png', file_get_contents( $path . '/install/reaction/react_like.png' ), 'reactions', FALSE, NULL, FALSE );
$id = \IPS\Db::i()->insert( 'core_reactions', array(
'reaction_value' => 1,
'reaction_icon' => (string) $fileObj,
@@ -670,7 +297,7 @@ class _Upgrade
foreach( array( 'thanks', 'haha', 'confused', 'sad' ) AS $reaction )
{
$fileObj = \IPS\File::create( 'core_Reaction', "react_{$reaction}.png", file_get_contents( \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY . "/install/reaction/react_{$reaction}.png" ), 'reactions', FALSE, NULL, FALSE );
$fileObj = \IPS\File::create( 'core_Reaction', "react_{$reaction}.png", file_get_contents( $path . "/install/reaction/react_{$reaction}.png" ), 'reactions', FALSE, NULL, FALSE );
$id = \IPS\Db::i()->insert( 'core_reactions', array(
'reaction_value' => ( in_array( $reaction, array( 'confused', 'sad' ) ) ) ? 0 : 1,
'reaction_icon' => (string) $fileObj,
@@ -688,7 +315,7 @@ class _Upgrade
*
* @return string
*/
public function step9CustomTitle()
public function step6CustomTitle()
{
return "Creating default reactions";
}
@@ -699,15 +326,22 @@ class _Upgrade
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step10()
public function step7()
{
$position = \IPS\Db::i()->select( 'max(reaction_position)', 'core_reactions' )->first();
/* Path fallback if a custom AdminCP directory is used. */
$path = \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY;
if( \IPS\CP_DIRECTORY != 'admin' AND !file_exists( \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY . '/install/reaction' ) )
{
$path = \IPS\ROOT_PATH . '/admin';
}
/* Now insert a positive or negative row based on settings and then run queries to adjust current reputation */
switch( \IPS\Settings::i()->reputation_point_types )
{
case 'positive':
$fileObj = \IPS\File::create( 'core_Reaction', 'react_up.png', file_get_contents( \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY . '/install/reaction/react_up.png' ), 'reactions', FALSE, NULL, FALSE );
$fileObj = \IPS\File::create( 'core_Reaction', 'react_up.png', file_get_contents( $path . '/install/reaction/react_up.png' ), 'reactions', FALSE, NULL, FALSE );
$id = \IPS\Db::i()->insert( 'core_reactions', array(
'reaction_value' => 1,
'reaction_icon' => (string) $fileObj,
@@ -718,7 +352,7 @@ class _Upgrade
break;
case 'negative':
$fileObj = \IPS\File::create( 'core_Reaction', 'react_down.png', file_get_contents( \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY . '/install/reaction/react_down.png' ), 'reactions', FALSE, NULL, FALSE );
$fileObj = \IPS\File::create( 'core_Reaction', 'react_down.png', file_get_contents( $path . '/install/reaction/react_down.png' ), 'reactions', FALSE, NULL, FALSE );
$id = \IPS\Db::i()->insert( 'core_reactions', array(
'reaction_value' => -1,
'reaction_icon' => (string) $fileObj,
@@ -729,7 +363,7 @@ class _Upgrade
break;
case 'both':
$fileObj = \IPS\File::create( 'core_Reaction', 'react_up.png', file_get_contents( \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY . '/install/reaction/react_up.png' ), 'reactions', FALSE, NULL, FALSE );
$fileObj = \IPS\File::create( 'core_Reaction', 'react_up.png', file_get_contents( $path . '/install/reaction/react_up.png' ), 'reactions', FALSE, NULL, FALSE );
$posId = \IPS\Db::i()->insert( 'core_reactions', array(
'reaction_value' => 1,
'reaction_icon' => (string) $fileObj,
@@ -738,7 +372,7 @@ class _Upgrade
) );
\IPS\Lang::saveCustom( 'core', 'reaction_title_' . $posId, 'Upvote' );
$fileObj = \IPS\File::create( 'core_Reaction', 'react_down.png', file_get_contents( \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY . '/install/reaction/react_down.png' ), 'reactions', FALSE, NULL, FALSE );
$fileObj = \IPS\File::create( 'core_Reaction', 'react_down.png', file_get_contents( $path . '/install/reaction/react_down.png' ), 'reactions', FALSE, NULL, FALSE );
$negId = \IPS\Db::i()->insert( 'core_reactions', array(
'reaction_value' => -1,
'reaction_icon' => (string) $fileObj,
@@ -757,7 +391,7 @@ class _Upgrade
*
* @return string
*/
public function step10CustomTitle()
public function step7CustomTitle()
{
return "Creating default reactions";
}
@@ -768,7 +402,7 @@ class _Upgrade
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step11()
public function step8()
{
/* Now insert a positive or negative row based on settings and then run queries to adjust current reputation */
switch( \IPS\Settings::i()->reputation_point_types )
@@ -811,7 +445,7 @@ class _Upgrade
if ( count( $toRun ) )
{
\IPS\core\Setup\Upgrade::adjustMultipleRedirect( array( 1 => 'core', 'extra' => array( '_upgradeStep' => 12 ) ) );
\IPS\core\Setup\Upgrade::adjustMultipleRedirect( array( 1 => 'core', 'extra' => array( '_upgradeStep' => 9 ) ) );
/* Queries to run manually */
return array( 'html' => \IPS\Theme::i()->getTemplate( 'forms' )->queries( $toRun, \IPS\Http\Url::internal( 'controller=upgrade' )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'mr_continue' => 1, 'mr' => \IPS\Request::i()->mr ) ) ) );
@@ -825,7 +459,7 @@ class _Upgrade
*
* @return string
*/
public function step11CustomTitle()
public function step8CustomTitle()
{
return "Mapping existing reactions";
}
@@ -836,7 +470,7 @@ class _Upgrade
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step12()
public function step9()
{
\IPS\Db::i()->update( 'core_member_ranks', 'pips=100', array('pips>?', 100 ) );
@@ -848,7 +482,7 @@ class _Upgrade
*
* @return string
*/
public function step12CustomTitle()
public function step9CustomTitle()
{
return 'Fixing ranks';
}
@@ -859,7 +493,7 @@ class _Upgrade
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step13()
public function step10()
{
$position = 1;
@@ -869,7 +503,7 @@ class _Upgrade
{
list( $gid, $gUnit ) = explode( '&', $group['g_promotion'] );
if ( $gid > 0 and $gUnit > 0)
if ( $gid > 0 and $gUnit > 0 )
{
$filters = array();
@@ -881,12 +515,12 @@ class _Upgrade
/* Reputation */
elseif( $group['g_promotion_type'] == 2 )
{
$filters['core_Reputation'] = array( 'reputation_operator' => 'gt', 'reputation_score' => $gUnit );
$filters['core_Reputation'] = array( 'reputation_operator' => ( $gUnit == 1 ) ? 'eq' : 'gt', 'reputation_score' => ( $gUnit == 1 ) ? $gUnit : ( $gUnit - 1 ) );
}
/* Post count */
else
{
$filters['core_Content'] = array( 'content_count_operator' => 'gt', 'content_count_score' => $gUnit );
$filters['core_Content'] = array( 'content_count_operator' => ( $gUnit == 1 ) ? 'eq' : 'gt', 'content_count_score' => ( $gUnit == 1 ) ? $gUnit : ( $gUnit - 1 ) );
}
$filters['core_Group'] = array( 'groups' => $group['g_id'] );
@@ -931,7 +565,7 @@ class _Upgrade
*
* @return string
*/
public function step13CustomTitle()
public function step10CustomTitle()
{
return 'Converting group promotion rules';
}
@@ -942,7 +576,7 @@ class _Upgrade
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step14()
public function step11()
{
if ( \IPS\Settings::i()->use_coppa OR \IPS\Settings::i()->minimum_age )
{
@@ -963,12 +597,11 @@ class _Upgrade
\IPS\Db::i()->insert( 'core_sys_conf_settings', $insert );
}
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 0 ), array( 'conf_key=?', 'quick_register' ) );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->changeValues( array( 'quick_register' => 0 ) );
}
$required = array();
foreach( \IPS\Db::i()->select( '*', 'core_pfields_data', array( "pf_not_null=?", 1 ) ) AS $row )
foreach( \IPS\Db::i()->select( '*', 'core_pfields_data', array( "pf_not_null=? AND pf_admin_only!=?", 1, 1 ) ) AS $row )
{
$required[] = "core_pfield_{$row['pf_id']}";
}
@@ -987,7 +620,7 @@ class _Upgrade
}
$optional = array();
foreach( \IPS\Db::i()->select( '*', 'core_pfields_data', array( "pf_show_on_reg=? AND pf_not_null=?", 1, 0 ) ) AS $row )
foreach( \IPS\Db::i()->select( '*', 'core_pfields_data', array( "pf_show_on_reg=? AND pf_not_null=? AND pf_admin_only!=?", 1, 0, 1 ) ) AS $row )
{
$optional[] = "core_pfield_{$row['pf_id']}";
}
@@ -1013,7 +646,7 @@ class _Upgrade
*
* @return string
*/
public function step14CustomTitle()
public function step11CustomTitle()
{
return 'Setting up Profile Completion';
}
@@ -1024,7 +657,7 @@ class _Upgrade
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step15()
public function step12()
{
foreach( \IPS\Db::i()->select( 'row_id', 'core_admin_permission_rows', array( 'row_id_type=?', 'group' ) ) as $admin )
{
@@ -1039,7 +672,7 @@ class _Upgrade
*
* @return string
*/
public function step15CustomTitle()
public function step12CustomTitle()
{
return 'Enabling social promotion for administrators';
}
@@ -1050,7 +683,7 @@ class _Upgrade
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step16()
public function step13()
{
/* Remove the offending entries */
\IPS\Db::i()->returnQuery = TRUE;
@@ -1064,7 +697,7 @@ class _Upgrade
if ( count( $toRun ) )
{
\IPS\core\Setup\Upgrade::adjustMultipleRedirect( array( 1 => 'core', 'extra' => array( '_upgradeStep' => 17 ) ) );
\IPS\core\Setup\Upgrade::adjustMultipleRedirect( array( 1 => 'core', 'extra' => array( '_upgradeStep' => 14 ) ) );
/* Queries to run manually */
return array( 'html' => \IPS\Theme::i()->getTemplate( 'forms' )->queries( $toRun, \IPS\Http\Url::internal( 'controller=upgrade' )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'mr_continue' => 1, 'mr' => \IPS\Request::i()->mr ) ) ) );
@@ -1078,7 +711,7 @@ class _Upgrade
*
* @return string
*/
public function step16CustomTitle()
public function step13CustomTitle()
{
return 'Removing orphaned moderator logs';
}
@@ -1089,7 +722,7 @@ class _Upgrade
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step17()
public function step14()
{
$max = \IPS\Db::i()->select( 'MAX(set_order)', 'core_themes' )->first();
@@ -1105,13 +738,25 @@ class _Upgrade
$theme->order = $max + 1;
$theme->is_default = FALSE;
$theme->is_acp_default = TRUE;
$theme->save();
$theme->installThemeSettings();
$theme->copyResourcesFromSet();
try
{
$theme->save();
/* Name */
\IPS\Lang::saveCustom( 'core', "core_theme_set_title_{$theme->id}", "4.2" );
$theme->installThemeSettings();
$theme->copyResourcesFromSet();
/* Name */
\IPS\Lang::saveCustom( 'core', "core_theme_set_title_{$theme->id}", "4.2" );
}
catch( \IPS\Db\Exception $e )
{
/* Column does not exist, set_customized was added in 4.3, so may not yet exist */
if( $e->getCode() != 1054 )
{
throw $e;
}
}
return TRUE;
}
@@ -1121,7 +766,7 @@ class _Upgrade
*
* @return string
*/
public function step17CustomTitle()
public function step14CustomTitle()
{
return 'Creating 4.2 theme';
}
@@ -1132,7 +777,7 @@ class _Upgrade
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step18()
public function step15()
{
\IPS\core\FrontNavigation::insertMenuItem( NULL, array( 'app' => 'core', 'key' => 'Clubs' ), \IPS\Db::i()->select( 'MAX(position)', 'core_menu' )->first() );
@@ -1144,7 +789,7 @@ class _Upgrade
*
* @return string
*/
public function step18CustomTitle()
public function step15CustomTitle()
{
return 'Adding clubs menu item';
}
@@ -0,0 +1,11 @@
{
"1": {
"method": "update",
"params": [
"core_members",
{
"permission_array": null
}
]
}
}
@@ -0,0 +1,28 @@
{
"1": {
"method": "delete",
"params": [
"core_tasks",
[
"app=?",
"chat"
]
]
},
"2": {
"method": "addIndex",
"params": [
"core_search_index",
{
"type": "key",
"name": "index_club_id",
"columns": [
"index_club_id"
],
"length": [
null
]
}
]
}
}
@@ -0,0 +1,13 @@
{
"1": {
"method": "delete",
"params": [
"core_modules",
[
"sys_module_application=? AND sys_module_area=? AND sys_module_key IN('activity', 'dashboard', 'discovery' )",
"core",
"front"
]
]
}
}
@@ -0,0 +1,66 @@
<?php
/**
* @brief 4.2.2 Upgrade Code
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 02 Aug 2017
*/
namespace IPS\core\setup\upg_102007;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.2.2 Upgrade Code
*/
class _Upgrade
{
/**
* If (our) chat is installed, we need to uninstall it completely
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
$applications = \IPS\Application::applications();
if( isset( $applications['chat'] ) )
{
try
{
/* Delete the app */
$applications['chat']->delete();
}
catch( \Exception $e )
{
/* It may be a legacy record, in which case we just want to delete it */
\IPS\Db::i()->delete( 'core_applications', array( 'app_directory=?', 'chat' ) );
}
/* Clear guest page caches */
\IPS\Data\Cache::i()->clearAll();
/* Clear datastore */
\IPS\Data\Store::i()->clearAll();
}
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
return "Removing Chat";
}
}
@@ -0,0 +1,88 @@
{
"1": {
"method": "update",
"params": [
"core_members",
{
"pp_thumb_photo": null
},
[
"pp_photo_type=?",
"letter"
]
]
},
"2": {
"method": "changeIndex",
"params": [
"core_javascript",
"javascript_lookup",
{
"type": "unique",
"name": "javascript_lookup",
"columns": [
"javascript_app",
"javascript_location",
"javascript_path",
"javascript_name"
],
"length": [
null,
null,
null,
null
]
}
]
},
"3": {
"method": "changeIndex",
"params": [
"core_members_known_devices",
"member_id",
{
"type": "key",
"name": "member_id",
"columns": [
"member_id",
"last_seen"
],
"length": [
null,
null
]
}
]
},
"4": {
"method": "addIndex",
"params": [
"core_members_known_ip_addresses",
{
"type": "key",
"name": "member_id",
"columns": [
"member_id",
"last_seen"
],
"length": [
null,
null
]
}
]
},
"5": {
"method": "delete",
"params": [
"core_sys_lang_words",
[
"word_app IS NOT NULL AND word_app NOT IN(?)",
{
"query": "SELECT app_directory FROM `core_applications` AS `core_applications`",
"binds": []
}
]
]
}
}
@@ -0,0 +1,211 @@
<?php
/**
* @brief 4.2.3 Upgrade Code
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 31 Jul 2017
*/
namespace IPS\core\setup\upg_102010;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.2.3 Upgrade Code
*/
class _Upgrade
{
/**
* Clean up orphaned reactions
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
/* First, see if we have any to even worry about */
$orphaned = \IPS\Db::i()->select( 'count(*)', 'core_reputation_index', array( 'reaction=?', '0' ) )->first();
if( !$orphaned )
{
return TRUE;
}
/* Figure out highest position in case we have to insert any reactions */
$position = \IPS\Db::i()->select( 'max(reaction_position)', 'core_reactions' )->first();
/* Path fallback if a custom AdminCP directory is used. */
$path = \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY;
if( \IPS\CP_DIRECTORY != 'admin' AND !file_exists( \IPS\ROOT_PATH . '/' . \IPS\CP_DIRECTORY . '/install/reaction' ) )
{
$path = \IPS\ROOT_PATH . '/admin';
}
/* Do we have any negative reputations that need to be fixed? */
$negative = \IPS\Db::i()->select( 'count(*)', 'core_reputation_index', array( 'reaction=? and rep_rating=?', '0', '-1' ) )->first();
if( $negative )
{
/* Do we have a negative reaction? If not create one, but disable it */
try
{
$id = \IPS\Db::i()->select( 'reaction_id', 'core_reactions', array( "reaction_icon LIKE CONCAT( '%', ? )", 'react_down.png' ) )->first();
}
catch( \UnderflowException $e )
{
$fileObj = \IPS\File::create( 'core_Reaction', 'react_down.png', file_get_contents( $path . '/install/reaction/react_down.png' ), 'reactions', FALSE, NULL, FALSE );
$id = \IPS\Db::i()->insert( 'core_reactions', array(
'reaction_value' => -1,
'reaction_icon' => (string) $fileObj,
'reaction_position' => ++$position,
'reaction_enabled' => 0,
) );
\IPS\Lang::saveCustom( 'core', 'reaction_title_' . $id, 'Downvote' );
}
\IPS\Db::i()->update( 'core_reputation_index', array( 'reaction' => $id ), array( 'reaction=? and rep_rating=?', '0', '-1' ) );
}
/* Do we have any positive reputations that need to be fixed? */
$positive = \IPS\Db::i()->select( 'count(*)', 'core_reputation_index', array( 'reaction=? and rep_rating=?', '0', '1' ) )->first();
if( $positive )
{
/* If the old method was 'like' just use that, otherwise we need to use the react_up positive reaction. */
if( \IPS\Settings::i()->reputation_point_types == 'like' )
{
$id = 1;
}
else
{
try
{
$id = \IPS\Db::i()->select( 'reaction_id', 'core_reactions', array( "reaction_icon LIKE CONCAT( '%', ? )", 'react_up.png' ) )->first();
}
catch( \UnderflowException $e )
{
$fileObj = \IPS\File::create( 'core_Reaction', 'react_up.png', file_get_contents( $path . '/install/reaction/react_up.png' ), 'reactions', FALSE, NULL, FALSE );
$id = \IPS\Db::i()->insert( 'core_reactions', array(
'reaction_value' => 1,
'reaction_icon' => (string) $fileObj,
'reaction_position' => ++$position,
'reaction_enabled' => 0,
) );
\IPS\Lang::saveCustom( 'core', 'reaction_title_' . $id, 'Upvote' );
}
}
\IPS\Db::i()->update( 'core_reputation_index', array( 'reaction' => $id ), array( 'reaction=? and rep_rating=?', '0', '1' ) );
}
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
return "Fixing orphaned reputation";
}
/**
* Step 2
* Clean up deletion logs
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step2()
{
/* Remove not existing deletion log records */
$perCycle = 500;
$did = 0;
$limit = intval( \IPS\Request::i()->extra );
/* Try to prevent timeouts to the extent possible */
$cutOff = \IPS\core\Setup\Upgrade::determineCutoff();
$toDelete = array();
foreach( \IPS\Db::i()->select( '*', 'core_deletion_log', null, 'dellog_id ASC', array( $limit, $perCycle ) ) as $record )
{
if( $cutOff !== null AND time() >= $cutOff )
{
return ( $limit + $did );
}
$class = $record['dellog_content_class'];
if( class_exists( $class ) )
{
try
{
$item = $class::load( $record['dellog_content_id'] );
}
/* Item may no longer exist */
catch ( \OutOfRangeException $e)
{
$toDelete[] = $record['dellog_id'];
}
}
else
{
/* App doesn't exist anymore, so it's save to delete it */
$toDelete[] = $record['dellog_id'];
}
$did++;
}
if ( count( $toDelete ) > 0 )
{
\IPS\Db::i()->delete( 'core_deletion_log', \IPS\Db::i()->in( 'dellog_id', $toDelete) );
}
if( $did )
{
return ( $limit + $did );
}
else
{
return TRUE;
}
}
/**
* Custom title for this step
*
* @return string
*/
public function step2CustomTitle()
{
$limit = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
return "Fixing orphaned deletion log (" . $limit . " processed so far)";
}
/**
* Repair Custom Field URL's
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function finish()
{
$profile = new \IPS\core\extensions\core\FileStorage\ProfileField;
\IPS\Task::queue( 'core', 'RepairFileUrls', array( 'storageExtension' => 'filestorage__core_ProfileField', 'count' => $profile->count() ), 1 );
$club = new \IPS\core\extensions\core\FileStorage\Clubs;
\IPS\Task::queue( 'core', 'RepairFileUrls', array( 'storageExtension' => 'filestorage__core_Clubs', 'count' => $club->count() ), 1 );
$clubFields = new \IPS\core\extensions\core\FileStorage\ClubField;
\IPS\Task::queue( 'core', 'RepairFileUrls', array( 'storageExtension' => 'filestorage__core_ClubField', 'count' => $clubFields->count() ), 1 );
return TRUE;
}
}
@@ -0,0 +1,44 @@
{
"1": {
"method": "update",
"params": [
"core_members",
"last_visit=joined",
"last_visit=0"
]
},
"2": {
"method": "delete",
"params": [
"core_sys_lang_words",
"word_app='core' AND ( word_key IN ( 'acplogs__themeset_delete', 'acplogs__themeset_updated' ) )"
]
},
"3": {
"method": "delete",
"params": [
"core_admin_logs",
"appcomponent='core' AND ( lang_key IN ( 'acplogs__themeset_delete', 'acplogs__themeset_updated' ) )"
]
},
"4": {
"method": "addColumn",
"params": [
"core_validating",
{
"name": "reg_cancelled",
"type": "INT",
"length": 1,
"decimals": null,
"values": null,
"allow_null": false,
"default": "0",
"comment": "Flag to see if the user likes soup. Kidding, timestamp of when they have cancelled their reg.",
"unsigned": true,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
}
}
@@ -0,0 +1,75 @@
[
{
"method": "changeIndex",
"params": [
"core_reputation_index",
"member_received",
{
"type": "key",
"name": "member_received",
"columns": [
"member_received",
"rep_date",
"rep_class",
"rep_rating"
],
"length": [
null,
null,
null,
null
]
}
]
},
{
"method": "createTable",
"params": [
{
"name": "core_members_feature_seen",
"columns": {
"member_id": {
"name": "member_id",
"type": "BIGINT",
"length": 20,
"decimals": null,
"values": null,
"allow_null": false,
"default": null,
"comment": "Member ID",
"unsigned": true,
"zerofill": false,
"auto_increment": false,
"binary": false
},
"feature_id": {
"name": "feature_id",
"type": "BIGINT",
"length": null,
"decimals": null,
"values": null,
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": true,
"zerofill": false,
"auto_increment": false,
"binary": false
}
},
"indexes": {
"PRIMARY": {
"type": "primary",
"name": "PRIMARY",
"columns": [
"member_id"
],
"length": [
null
]
}
}
}
]
}
]
@@ -0,0 +1,78 @@
<?php
/**
* @brief 4.2.6 Beta 1 Upgrade Code
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 31 May 2017
*/
namespace IPS\core\setup\upg_102030;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.2.6 Beta 1 Upgrade Code
*/
class _Upgrade
{
/**
* Restore missing entries to the deletion log
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function finish()
{
foreach( \IPS\Application::allExtensions( 'core', 'ContentRouter', FALSE ) as $object )
{
foreach( $object->classes as $itemClass )
{
try
{
$commentClass = NULL;
$reviewClass = NULL;
if ( isset( $itemClass::$commentClass ) )
{
$commentClass = $itemClass::$commentClass;
}
if ( isset( $itemClass::$reviewClass ) )
{
$reviewClass = $itemClass::$reviewClass;
}
\IPS\Task::queue( 'core', 'FixDeletionLog', array( 'class' => $itemClass ), 4, array( 'class' ) );
if ( $commentClass )
{
\IPS\Task::queue( 'core', 'FixDeletionLog', array( 'class' => $commentClass ), 4, array( 'class' ) );
}
if ( $reviewClass )
{
\IPS\Task::queue( 'core', 'FixDeletionLog', array( 'class' => $reviewClass ), 4, array( 'class' ) );
}
}
catch( \Exception $e ) { }
}
}
$profile = new \IPS\core\extensions\core\FileStorage\ProfileField;
\IPS\Task::queue( 'core', 'RepairFileUrls', array( 'storageExtension' => 'filestorage__core_ProfileField', 'count' => $profile->count() ), 1 );
$club = new \IPS\core\extensions\core\FileStorage\Clubs;
\IPS\Task::queue( 'core', 'RepairFileUrls', array( 'storageExtension' => 'filestorage__core_Clubs', 'count' => $club->count() ), 1 );
$clubFields = new \IPS\core\extensions\core\FileStorage\ClubField;
\IPS\Task::queue( 'core', 'RepairFileUrls', array( 'storageExtension' => 'filestorage__core_ClubField', 'count' => $clubFields->count() ), 1 );
return TRUE;
}
}
@@ -0,0 +1,42 @@
{
"1": {
"method": "changeColumn",
"params": [
"core_queue",
"offset",
{
"name": "offset",
"type": "BIGINT",
"length": null,
"decimals": null,
"values": [],
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
},
"2": {
"method": "changeColumn",
"params": [
"core_deletion_log",
"dellog_content_permissions",
{
"name": "dellog_content_permissions",
"type": "TEXT",
"decimals": null,
"values": null,
"allow_null": false,
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
}
}
@@ -0,0 +1,41 @@
<?php
/**
* @brief 4.2.7 Beta 1 Upgrade Code
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 06 Nov 2017
*/
namespace IPS\core\setup\upg_102037;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.2.7 Beta 1 Upgrade Code
*/
class _Upgrade
{
/**
* Enable clearcache task
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
\IPS\Db::i()->update( 'core_tasks', array( 'enabled' => 1 ), "`key`='clearcache'" );
return TRUE;
}
// You can create as many additional methods (step2, step3, etc.) as is necessary.
// Each step will be executed in a new HTTP request
}
@@ -0,0 +1,89 @@
<?php
/**
* @brief Upgrader: Custom Upgrade Options
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 3 Aug 2017
*/
$options = array();
/* Usage reporting */
$options[] = new \IPS\Helpers\Form\YesNo( '103000_usage_reporting', TRUE );
/* Is IPS Connect enabled? */
$ipsConnectEnabled = FALSE;
try
{
$ipsConnectEnabled = (bool) \IPS\Db::i()->select( 'COUNT(*)', 'core_login_handlers', array( 'login_key=? AND login_enabled=1', 'Ipsconnect' ) )->first();
}
catch ( \IPS\Db\Exception $e )
{
try
{
$ipsConnectEnabled = (bool) \IPS\Db::i()->select( 'COUNT(*)', 'login_methods', array( 'login_folder_name=? AND login_enabled=1', 'ipsconnect' ) )->first();
}
catch ( \IPS\Db\Exception $e ) { }
}
if( $ipsConnectEnabled )
{
$options[] = new \IPS\Helpers\Form\Custom( 'ipsconnect', null, FALSE, array( 'getHtml' => function( $element ) use ( $members ){
$url = \IPS\Http\Url::ips('docs/login_invision');
return "<br>IPS Connect has been replaced with a new OAuth-based system for connecting two or more communities.<br><br><strong>If you have already upgraded the master install in your IPS Connect network</strong> follow the <a href='{$url}' target='_blank'>Connect Two Invision Communities</a> guide to get the Client Identifier and Client Secret and enter them below.<br><strong>If you have not yet upgraded the master install in your IPS Connect network or do not want to enter these details yet</strong> you can leave the settings below blank, but make sure you have bookmarked the <a href='{$url}' target='_blank'>Connect Two Invision Communities</a> guide to refer to after you have finished the upgrade.<br><br><strong class='ipsType_warning'><i class='fa fa-exclamation-triangle'></i> If you do not provide these details now you will not be able to log in using IPS Connect once the upgrade is complete. If you find yourself unable to log in after the upgrade, use the Forgot Password tool to regain access to your account.</strong>";
} ), function( $val ) {}, NULL, NULL, 'ipsconnect' );
$row = \IPS\Db::i()->select( '*', 'core_login_handlers', array( 'login_key=? AND login_enabled=1', 'Ipsconnect' ) )->first();
$settings = json_decode( $row['login_settings'], TRUE );
$options[] = new \IPS\Helpers\Form\Text( '103000_ipsconnect_url', preg_replace( '/applications\/core\/interface\/ipsconnect\/ipsconnect\.php$/', '', $settings['url'] ) );
$options[] = new \IPS\Helpers\Form\Text( '103000_ipsconnect_client_id' );
$options[] = new \IPS\Helpers\Form\Text( '103000_ipsconnect_client_secret' );
}
/* Login over HTTPs */
if( \IPS\Settings::i()->logins_over_https OR ( \IPS\Settings::i()->nexus_https AND \IPS\Application::appIsEnabled( 'nexus' ) ) )
{
$setting = array();
if( \IPS\Settings::i()->logins_over_https )
{
$setting[] = '"Use https for logins and the AdminCP?"';
}
if( \IPS\Application::appIsEnabled( 'nexus' ) AND \IPS\Settings::i()->nexus_https )
{
$setting[] = '"Use a secure connection for checkout?"';
}
$options[] = new \IPS\Helpers\Form\Custom( 'https_settings_changes', null, FALSE, array( 'getHtml' => function( ) use ( $setting ){
$url = \IPS\Http\Url::ips('docs/https');
$settingString = implode( ' and ', $setting );
$pluralS = count( $setting ) > 1 ? 's' : '';
$pluralThis = count( $setting ) > 1 ? 'these' : 'this';
$pluralIs = count( $setting ) > 1 ? 'are' : 'is';
return "You currently have the {$settingString} setting{$pluralS} enabled. Due to recent changes to some browsers, {$pluralThis} feature{$pluralS} can cause browser warnings and so {$pluralIs} no longer supported in Invision Community. To keep the security benefits, we recommend moving your entire community to using https after this upgrade is complete. <a href='{$url}' rel='external' target='_blank'>Learn how</a>";
} ), function( $val ) {}, NULL, NULL, 'https_settings_changes' );
}
/* Is the link to the admin directory hidden? */
if( \IPS\Settings::i()->security_remove_acp_link )
{
$options[] = new \IPS\Helpers\Form\Custom( 'admincp_hide_deprecate', null, FALSE, array( 'getHtml' => function( $element ) use ( $members ){
$url = \IPS\Http\Url::ips('docs/hide_acp');
return "<br>The setting to hide the link to the AdminCP has been removed. After completing the upgrade, follow the <a href='{$url}' target='_blank'>Hiding the AdminCP</a> guide to retain this functionality.<br><br><strong class='ipsType_warning'><i class='fa fa-exclamation-triangle'></i> Before continuing, ensure you have bookmarked this guide to refer to after you have finished the upgrade.</strong>";
} ), function( $val ) {}, NULL, NULL, 'admincp_hide_deprecate' );
}
/* reCAPTCHA v1 Removed */
if( \IPS\Settings::i()->bot_antispam_type === 'recaptcha' )
{
$options[] = new \IPS\Helpers\Form\Custom( 'recaptcha_v1_removed', null, FALSE, array( 'getHtml' => function( $element ) use ( $members ){
$url = \IPS\Http\Url::ips('docs/captcha_recaptcha_invisible');
return "<br>Your community was set to use reCAPTCHA 1, a CAPTCHA method where the user is shown two distorted words and must type the displayed words. Google recently retired this service so we are automatically upgrading you to the latest <a href='{$url}' target='_blank'>Invisible reCAPTCHA</a> method. This doesn't require user input as the system intelligently detects if the user is human in the background.";
} ), function( $val ) {}, NULL, NULL, 'recaptcha_v1_removed' );
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,641 @@
<?php
/**
* @brief 4.3.0 Beta 1 Upgrade Code
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 19 Oct 2017
*/
namespace IPS\core\setup\upg_103000;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.3.0 Beta 1 Upgrade Code
*/
class _Upgrade
{
/**
* Step 1
* Move login handlers
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
foreach ( \IPS\Db::i()->select( '*', 'core_login_handlers' ) as $row )
{
$settings = ( isset( $row['login_settings'] ) and $row['login_settings'] ) ? json_decode( $row['login_settings'], TRUE ) : array();
$title = $row['login_key'];
switch ( mb_strtolower( $row['login_key'] ) )
{
case 'internal':
$classname = 'IPS\\Login\\Handler\\Standard';
$title = "Standard";
/* This may not be set for some communities - check that it's valid */
if( !isset( $settings['auth_types'] ) )
{
$settings['auth_types'] = \IPS\Login::AUTH_TYPE_USERNAME;
}
break;
case 'facebook':
$classname = 'IPS\\Login\\Handler\\OAuth2\\Facebook';
$settings['client_id'] = isset( $settings['app_id'] ) ? $settings['app_id'] : NULL;
$settings['client_secret'] = isset( $settings['app_secret'] ) ? $settings['app_secret'] : NULL;
$settings['legacy_redirect'] = TRUE;
$title = "Facebook";
break;
case 'google':
$classname = 'IPS\\Login\\Handler\\OAuth2\\Google';
$settings['legacy_redirect'] = TRUE;
$title = "Google";
break;
case 'linkedin':
$classname = 'IPS\\Login\\Handler\\OAuth2\\LinkedIn';
$settings['client_id'] = isset( $settings['api_key'] ) ? $settings['api_key'] : NULL;
$settings['client_secret'] = isset( $settings['secret_key'] ) ? $settings['secret_key'] : NULL;
$settings['legacy_redirect'] = TRUE;
$title = "LinkedIn";
break;
case 'live':
case 'microsoft':
$classname = 'IPS\\Login\\Handler\\OAuth2\\Microsoft';
$settings['legacy_redirect'] = TRUE;
$title = "Microsoft";
break;
case 'twitter':
$classname = 'IPS\\Login\\Handler\\OAuth1\\Twitter';
$title = "Twitter";
break;
case 'external':
$classname = 'IPS\\Login\\Handler\\ExternalDatabase';
$title = "MySQL Database";
break;
case 'ldap':
$classname = 'IPS\\Login\\Handler\\LDAP';
$title = "LDAP";
break;
case 'ipsconnect':
$classname = 'IPS\\Login\\Handler\\OAuth2\\Invision';
$title = "Invision Community";
$oldsettings = $settings;
$settings = array();
$settings['url'] = $_SESSION['upgrade_options']['core']['103000']['ipsconnect_url'];
$settings['grant_type'] = 'password';
$settings['client_id'] = $_SESSION['upgrade_options']['core']['103000']['ipsconnect_client_id'];
$settings['client_secret'] = $_SESSION['upgrade_options']['core']['103000']['ipsconnect_client_secret'];
$settings['auth_types'] = $oldsettings['auth_types'];
$settings['button_color'] = '#3e4148';
$settings['button_text'] = NULL;
$settings['button_icon'] = '';
$settings['show_in_ucp'] = 'loggedin';
$settings['update_name_changes'] = ( defined( '\IPS\CONNECT_NOSYNC_NAMES' ) and \IPS\CONNECT_NOSYNC_NAMES ) ? 'disabled' : 'force';
$settings['update_email_changes'] = 'force';
break;
case 'convert':
continue 2;
break;
default:
$classname = 'IPS\\Login\\' . $row['login_key'];
break;
}
$id = \IPS\Db::i()->insert( 'core_login_methods', array(
'login_classname' => $classname,
'login_order' => $row['login_order'],
'login_acp' => $row['login_acp'],
'login_settings' => json_encode( $settings ),
'login_enabled' => $row['login_enabled'],
/* If we are coming from 3.x the setting will not exist yet, so we should default to 1. There was previously a no_reg setting in 3.x,
however it is removed during 40000/step21 so we can't check it. */
'login_register' => ( isset( \IPS\Settings::i()->allow_reg ) ) ? \IPS\Settings::i()->allow_reg : 1
) );
\IPS\Lang::saveCustom( 'core', "login_method_{$id}", $title );
\IPS\Db::i()->update( 'core_members_known_devices', array( 'login_handler' => $id ), array( 'login_handler=?', $row['login_key'] ) );
}
return true;
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
return 'Updating login handlers';
}
/**
* Step 2
* Update Login IDs
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step2()
{
$loginMethods = iterator_to_array( \IPS\Db::i()->select( '*', 'core_login_methods' )->setKeyField('login_classname') );
/* Some init */
$did = 0;
$limit = 0;
if( isset( \IPS\Request::i()->extra ) )
{
$limit = \IPS\Request::i()->extra;
}
/* Try to prevent timeouts to the extent possible */
$cutOff = \IPS\core\Setup\Upgrade::determineCutoff();
$where = array();
if ( \IPS\Db::i()->checkForColumn( 'core_members', 'fb_uid' ) )
{
$where[] = 'fb_uid>0';
}
if ( \IPS\Db::i()->checkForColumn( 'core_members', 'live_id' ) )
{
$where[] = 'live_id IS NOT NULL';
}
if ( \IPS\Db::i()->checkForColumn( 'core_members', 'twitter_id' ) )
{
$where[] = "twitter_id<>''";
}
if ( \IPS\Db::i()->checkForColumn( 'core_members', 'google_id' ) )
{
$where[] = 'google_id IS NOT NULL';
}
if ( \IPS\Db::i()->checkForColumn( 'core_members', 'linkedin_id' ) )
{
$where[] = 'linkedin_id IS NOT NULL';
}
if ( \IPS\Db::i()->checkForColumn( 'core_members', 'ipsconnect_id' ) )
{
$where[] = 'ipsconnect_id>0';
}
if ( $where )
{
foreach( \IPS\Db::i()->select( '*', 'core_members', implode( $where, ' OR ' ), 'member_id ASC', array( $limit, 500 ) ) as $member )
{
if( $cutOff !== null AND time() >= $cutOff )
{
return ( $limit + $did );
}
$did++;
if ( isset( $member['fb_uid'] ) and $member['fb_uid'] and isset( $loginMethods['IPS\\Login\\Handler\\OAuth2\\Facebook'] ) )
{
\IPS\Db::i()->insert( 'core_login_links', array(
'token_login_method' => $loginMethods['IPS\\Login\\Handler\\OAuth2\\Facebook']['login_id'],
'token_member' => $member['member_id'],
'token_identifier' => $member['fb_uid'],
'token_linked' => TRUE,
'token_access_token' => $member['fb_token'],
), FALSE, TRUE );
}
if ( isset( $member['live_id'] ) and $member['live_id'] and isset( $loginMethods['IPS\\Login\\Handler\\OAuth2\\Microsoft'] ) )
{
\IPS\Db::i()->insert( 'core_login_links', array(
'token_login_method' => $loginMethods['IPS\\Login\\Handler\\OAuth2\\Microsoft']['login_id'],
'token_member' => $member['member_id'],
'token_identifier' => $member['live_id'],
'token_linked' => TRUE,
'token_access_token' => $member['live_token'],
), FALSE, TRUE );
}
if ( isset( $member['twitter_id'] ) and $member['twitter_id'] and isset( $loginMethods['IPS\\Login\\Handler\\OAuth1\\Twitter'] ) )
{
\IPS\Db::i()->insert( 'core_login_links', array(
'token_login_method' => $loginMethods['IPS\\Login\\Handler\\OAuth1\\Twitter']['login_id'],
'token_member' => $member['member_id'],
'token_identifier' => $member['twitter_id'],
'token_linked' => TRUE,
'token_access_token' => $member['twitter_token'],
'token_secret' => $member['twitter_secret'],
), FALSE, TRUE );
}
if ( isset( $member['google_id'] ) and $member['google_id'] and isset( $loginMethods['IPS\\Login\\Handler\\OAuth2\\Google'] ) )
{
\IPS\Db::i()->insert( 'core_login_links', array(
'token_login_method' => $loginMethods['IPS\\Login\\Handler\\OAuth2\\Google']['login_id'],
'token_member' => $member['member_id'],
'token_identifier' => $member['google_id'],
'token_linked' => TRUE,
'token_access_token' => $member['google_token'],
), FALSE, TRUE );
}
if ( isset( $member['linkedin_id'] ) and $member['linkedin_id'] and isset( $loginMethods['IPS\\Login\\Handler\\OAuth2\\LinkedIn'] ) )
{
\IPS\Db::i()->insert( 'core_login_links', array(
'token_login_method' => $loginMethods['IPS\\Login\\Handler\\OAuth2\\LinkedIn']['login_id'],
'token_member' => $member['member_id'],
'token_identifier' => $member['linkedin_id'],
'token_linked' => TRUE,
'token_access_token' => $member['linkedin_token'],
), FALSE, TRUE );
}
if ( isset( $member['ipsconnect_id'] ) and $member['ipsconnect_id'] and isset( $loginMethods['IPS\\Login\\Handler\\OAuth2\\Invision'] ) )
{
\IPS\Db::i()->insert( 'core_login_links', array(
'token_login_method' => $loginMethods['IPS\\Login\\Handler\\OAuth2\\Invision']['login_id'],
'token_member' => $member['member_id'],
'token_identifier' => $member['ipsconnect_id'],
'token_linked' => TRUE,
), FALSE, TRUE );
}
}
}
if( $did )
{
return $limit + $did;
}
else
{
unset( $_SESSION['_step2Count'] );
return TRUE;
}
}
/**
* Custom title for this step
*
* @return string
*/
public function step2CustomTitle()
{
$limit = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
if( !isset( $_SESSION['_step2Count'] ) )
{
$where = array();
if ( \IPS\Db::i()->checkForColumn( 'core_members', 'fb_uid' ) )
{
$where[] = 'fb_uid>0';
}
if ( \IPS\Db::i()->checkForColumn( 'core_members', 'live_id' ) )
{
$where[] = 'live_id IS NOT NULL';
}
if ( \IPS\Db::i()->checkForColumn( 'core_members', 'twitter_id' ) )
{
$where[] = "twitter_id<>''";
}
if ( \IPS\Db::i()->checkForColumn( 'core_members', 'google_id' ) )
{
$where[] = 'google_id IS NOT NULL';
}
if ( \IPS\Db::i()->checkForColumn( 'core_members', 'linkedin_id' ) )
{
$where[] = 'linkedin_id IS NOT NULL';
}
if ( $where )
{
$_SESSION['_step2Count'] = \IPS\Db::i()->select( 'COUNT(*)', 'core_members', implode( $where, ' OR ' ) )->first();
}
else
{
$_SESSION['_step2Count'] = 0;
}
}
return 'Converting login handlers for 4.3 (Fixed so far: ' . ( ( $limit > $_SESSION['_step2Count'] ) ? $_SESSION['_step2Count'] : $limit ) . ' out of ' . $_SESSION['_step2Count'] . ')';
}
/**
* Step 3
* Drop old columns
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step3()
{
$columnsToDrop = array();
foreach ( array('fb_uid','fb_token','live_id','live_token','twitter_id','twitter_token','twitter_secret','tc_last_sid_import','tc_photo','tc_bwoptions','fb_photo','fb_photo_thumb','fb_bwoptions','google_id','google_token','linkedin_id','linkedin_token') as $col )
{
if ( \IPS\Db::i()->checkForColumn( 'core_members', $col ) )
{
$columnsToDrop[] = $col;
}
}
\IPS\Db::i()->dropColumn( 'core_members', $columnsToDrop );
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step3CustomTitle()
{
return 'Removing unused login data';
}
/**
* Populate spam defense whitelist with installed domain
*
* @return boolean
*/
public function step4()
{
$domain = rtrim( str_replace( 'www.', '', parse_url( \IPS\Settings::i()->base_url, PHP_URL_HOST ) ), '/' );
\IPS\Db::i()->insert( 'core_spam_whitelist', array( 'whitelist_type' => 'domain', 'whitelist_content' => $domain, 'whitelist_date' => time(), 'whitelist_reason' => 'Install Domain' ) );
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step4CustomTitle()
{
return 'Setting defaults for spam service email address whitelist';
}
/**
* Step 5
* Update Email Settings if Sparkpost is used
*
* @return bool
*/
public function step5()
{
if ( \IPS\Settings::i()->sparkpost_api_key AND \IPS\Settings::i()->sparkpost_use_for )
{
$newSettings = array(
'mail_method' => 'smtp',
'smtp_host' => 'smtp.sparkpostmail.com',
'smtp_port' => '587',
'smtp_protocol' => 'tls',
'smtp_user' => 'SMTP_Injection',
'smtp_pass' => \IPS\Settings::i()->sparkpost_api_key,
);
\IPS\Settings::i()->changeValues( $newSettings );
}
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step5CustomTitle()
{
return 'Checking Sparkpost configuration';
}
/**
* Step 6
* Fix themes
*
* @return bool
*/
public function step6()
{
/* Get rid of any duplicates that will cause a unique key error */
foreach( \IPS\Db::i()->select( '*', 'core_theme_templates', array( 'template_set_id=0 and template_added_to > 0' ) ) as $template )
{
try
{
/* See if we have a 'default' copy of this template yet */
\IPS\Db::i()->select( 'template_id', 'core_theme_templates', array( 'template_set_id=? and template_group=? and template_name=? and template_app=? and template_location=?', $template['template_added_to'], $template['template_group'], $template['template_name'], $template['template_app'], $template['template_location'] ) )->first();
/* If we're here, it means this template exists */
\IPS\Db::i()->delete( 'core_theme_templates', array( 'template_id=?', $template['template_id'] ) );
}
/* We want an underflow exception - it means the template isn't present */
catch( \UnderflowException $e ){}
}
/* Fix template_set_id=0 for non master */
\IPS\Db::i()->update( 'core_theme_templates', 'template_set_id=template_added_to', array( 'template_set_id=0 and template_added_to > 0' ) );
/* Set customized flag */
foreach( \IPS\Db::i()->select( 'set_id', 'core_themes' ) as $theme )
{
\IPS\Theme::setThemeCustomized( $theme['set_id'] );
}
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step6CustomTitle()
{
return 'Flagging customized theme templates';
}
/**
* Step 7
* Settings Changes
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step7()
{
/* Usage reporting settings */
\IPS\Db::i()->replace( 'core_sys_conf_settings', array(
'conf_key' => 'usage_reporting',
'conf_value' => intval( $_SESSION['upgrade_options']['core']['103000']['usage_reporting'] ),
'conf_default' => 1,
'conf_app' => 'core'
) );
/* reCAPTCHA 1 removed */
if ( \IPS\Settings::i()->bot_antispam_type === 'recaptcha' )
{
\IPS\Settings::i()->changeValues( array(
'bot_antispam_type' => 'invisible',
'recaptcha2_public_key' => '6LcH7UEUAAAAAIGWgOoyBKAqjLmOIKzfJTOjyC7z',
'recaptcha2_private_key'=> '6LcH7UEUAAAAANmcQmZErdGW2FXwVhtRBVXBWBUA',
) );
}
\IPS\Db::i()->delete( 'core_sys_lang_words', array( 'word_app=? AND word_key=?', 'core', 'recaptcha2_public_key_desc' ) );
\IPS\Db::i()->delete( 'core_sys_lang_words', array( 'word_app=? AND word_key=?', 'core', 'recaptcha_public_key' ) );
\IPS\Db::i()->delete( 'core_sys_lang_words', array( 'word_app=? AND word_key=?', 'core', 'recaptcha_private_key' ) );
\IPS\Db::i()->delete( 'core_sys_lang_words', array( 'word_app=? AND word_key=?', 'core', 'recaptcha_private_key_desc' ) );
\IPS\Db::i()->delete( 'core_sys_lang_words', array( 'word_app=? AND word_key=?', 'core', 'captcha_type_recaptcha' ) );
\IPS\Db::i()->delete( 'core_sys_lang_words', array( 'word_app=? AND word_key=?', 'core', 'captcha_type_recaptcha_desc' ) );
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step7CustomTitle()
{
return "Updating CAPTCHA settings";
}
/**
* Step 8
* Update positions for profile steps
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step8()
{
$position = 1;
foreach( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_profile_steps' ), 'IPS\Member\ProfileStep' ) AS $step )
{
$step->position = $position;
$step->save();
$position++;
}
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step8CustomTitle()
{
return 'Adjusting profile step configuration';
}
/**
* Step 9
* Remove announcement widgets
*
* @return bool
*/
public function step9()
{
foreach( \IPS\Db::i()->select( 'id, widgets', 'core_widget_areas', array( 'widgets LIKE(?)', '"key": "announcements"' ) )->setKeyField('id')->setValueField( 'widgets' ) as $id => $config )
{
$json = json_decode( $config, TRUE );
foreach( $json as $key => $value )
{
if( $value['key'] == 'announcements' AND $value['app'] == 'core' )
{
unset( $json[ $key ] );
}
}
\IPS\Db::i()->update( 'core_widget_areas', array( 'widgets' => json_encode( $json ) ), array( 'id=?', $id ) );
}
\IPS\Db::i()->delete( 'core_widgets', array( 'app=? AND `key`=?', 'core', 'announcements' ) );
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step9CustomTitle()
{
return "Removing announcement widgets";
}
/**
* Step 10
* Remove orphaned known device data
*
* @return bool
*/
public function step10()
{
$queries = array();
/* Orphaned devices */
try
{
\IPS\Db::i()->select( 'count(*)', 'core_members_known_devices', array( 'member_id NOT IN ( ' . \IPS\Db::i()->select( 'member_id', 'core_members' ) . ' )' ), NULL, 1 )->first();
\IPS\Db::i()->returnQuery = TRUE;
$queries[] = array(
'table' => 'core_members_known_devices',
'query' => \IPS\Db::i()->delete( 'core_members_known_devices', array( 'member_id NOT IN ( ' . \IPS\Db::i()->select( 'member_id', 'core_members' ) . ' )' ) )
);
\IPS\Db::i()->returnQuery = FALSE;
}
catch( \UnderflowException $e ) {}
/* Orphaned ip addresses */
try
{
\IPS\Db::i()->select( 'COUNT(*)', 'core_members_known_ip_addresses', array( 'member_id NOT IN ( ' . \IPS\Db::i()->select( 'member_id', 'core_members' ) . ' )' ), NULL, 1 )->first();
/* Remove the offending entries */
\IPS\Db::i()->returnQuery = TRUE;
$queries[] = array(
'table' => 'core_members_known_ip_addresses',
'query' => \IPS\Db::i()->delete( 'core_members_known_ip_addresses', array( 'member_id NOT IN ( ' . \IPS\Db::i()->select( 'member_id', 'core_members' ) . ' )' ) )
);
\IPS\Db::i()->returnQuery = FALSE;
}
catch( \UnderflowException $e ) {}
/* Is this site affected by any of these issues? */
if( !count( $queries ) )
{
return TRUE;
}
$toRun = \IPS\core\Setup\Upgrade::runManualQueries( $queries );
if ( count( $toRun ) )
{
\IPS\core\Setup\Upgrade::adjustMultipleRedirect( array( 1 => 'core', 'extra' => array( '_upgradeStep' => 11 ) ) );
/* Queries to run manually */
return array( 'html' => \IPS\Theme::i()->getTemplate( 'forms' )->queries( $toRun, \IPS\Http\Url::internal( 'controller=upgrade' )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'mr_continue' => 1, 'mr' => \IPS\Request::i()->mr ) ) ) );
}
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step10CustomTitle()
{
return "Removing orphaned member data";
}
/**
* Rebuild search index
*
* @return boolean
*/
public function finish()
{
\IPS\Content\Search\Index::i()->rebuild();
return TRUE;
}
}
@@ -0,0 +1,16 @@
{
"1": {
"method": "update",
"params": [
"core_login_methods",
{
"login_settings": "{\"auth_types\":1}"
},
[
"login_classname=? AND login_settings=?",
"IPS\\Login\\Handler\\Standard",
"[]"
]
]
}
}
@@ -0,0 +1,74 @@
<?php
/**
* @brief 4.3.0 Beta 3 Upgrade Code
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @since 23 Mar 2018
*/
namespace IPS\core\setup\upg_103003;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.3.0 Beta 3 Upgrade Code
*/
class _Upgrade
{
/**
* Update Reactions Like Mode Setting
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
\IPS\Content\Reaction::updateLikeModeSetting();
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
return 'Caching reaction preferences';
}
/**
* Clean up old language strings
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step2()
{
\IPS\Db::i()->delete(
'core_sys_lang_words',
array(
'word_app IS NOT NULL AND word_app NOT IN(?)',
\IPS\Db::i()->select( 'app_directory', 'core_applications' )
)
);
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step2CustomTitle()
{
return 'Removing orphaned language strings';
}
}
@@ -0,0 +1,139 @@
{
"1": {
"method": "createTable",
"params": [
{
"name": "core_oauth_authorize_prompts",
"columns": {
"session_id": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "The session ID",
"decimals": null,
"default": "",
"length": 128,
"name": "session_id",
"type": "VARCHAR",
"unsigned": false,
"values": [],
"zerofill": false
},
"client_id": {
"name": "client_id",
"type": "CHAR",
"length": 32,
"decimals": null,
"values": null,
"allow_null": false,
"default": null,
"comment": "The client ID",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
},
"response_type": {
"name": "response_type",
"type": "ENUM",
"length": null,
"decimals": null,
"values": [
"code",
"token"
],
"allow_null": false,
"default": null,
"comment": "The response type",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
},
"redirect_uri": {
"name": "redirect_uri",
"type": "TEXT",
"length": null,
"decimals": null,
"values": null,
"allow_null": true,
"default": null,
"comment": "The provided redirect URI",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
},
"scope": {
"name": "scope",
"type": "TEXT",
"length": null,
"decimals": null,
"values": null,
"allow_null": true,
"default": null,
"comment": "space-delimited scope",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
},
"state": {
"name": "state",
"type": "TEXT",
"length": null,
"decimals": null,
"values": null,
"allow_null": true,
"default": null,
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
},
"timestamp": {
"name": "timestamp",
"type": "INT",
"length": 10,
"decimals": null,
"values": null,
"allow_null": false,
"default": null,
"comment": "Unix timestamp of when this prompt was initially shown",
"unsigned": true,
"zerofill": false,
"auto_increment": false,
"binary": false
},
"logged_in": {
"name": "logged_in",
"type": "TINYINT",
"length": 1,
"decimals": null,
"values": null,
"allow_null": false,
"default": "0",
"comment": "Has the user logged in yet (for prompts that require it)?",
"unsigned": true,
"zerofill": false,
"auto_increment": false,
"binary": false
}
},
"indexes": {
"PRIMARY": {
"type": "primary",
"name": "PRIMARY",
"length": [
null
],
"columns": [
"session_id"
]
}
}
}
]
}
}
@@ -0,0 +1,9 @@
{
"1": {
"method": "delete",
"params": [
"core_sys_lang_words",
"word_app='core' AND word_key='emoji_style_disabled_desc'"
]
}
}
@@ -63,7 +63,7 @@ class _Upgrade
\IPS\Db::i()->delete( "core_sys_conf_settings", array( 'conf_key=?', 'spider_suit' ) );
\IPS\Db::i()->delete( "core_sys_conf_settings", array( 'conf_key=?', 'c_cache_days' ) );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
\IPS\Db::i()->changeColumn( 'forums', 'permission_array', array(
'name' => 'permission_array',
@@ -83,7 +83,7 @@ class _Upgrade
\IPS\Db::i()->delete( 'core_sys_conf_settings', array( "conf_key=?", 'seo_r301' ) );
\IPS\Db::i()->delete( 'core_sys_settings_titles', array( "conf_title_keyword=?", 'searchenginespiders' ) );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
\IPS\Db::i()->changeColumn( 'sessions', 'login_type', array(
'name' => 'login_type',
@@ -103,7 +103,7 @@ class _Upgrade
\IPS\Db::i()->dropIndex( 'attachments', 'attach_where' );
\IPS\Db::i()->delete( 'core_sys_conf_settings', array( "conf_key=?", 'acp_tutorial_mode' ) );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
\IPS\Db::i()->update( 'skin_templates', array( 'template_data' => '$required_output=\'\',$optional_output=\'\',$day=\'\',$mon=\'\',$year=\'\'' ), array( 'template_name=?', 'membersProfileForm' ) );
+11 -4
View File
@@ -44,7 +44,7 @@ class _Upgrade
\IPS\Db::i()->delete( 'core_sys_settings_titles', "conf_title_keyword in ( 'ipbportal', 'portal_poll', 'portal_recent_topics', 'portal_blogs', 'newssetup', 'trashcansetup',
'cookies', 'ipbreg', 'twitterconnect' )" );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
\IPS\Db::i()->delete( 'core_applications', "app_directory='portal'" );
\IPS\Db::i()->delete( 'core_sys_module', "sys_module_application='portal'" );
@@ -65,7 +65,15 @@ class _Upgrade
/* We are using a raw query here to ensure the driver doesn't attempt to modify things or help us, like adjusting the table engine */
$toRun = \IPS\core\Setup\Upgrade::runManualQueries( array( array(
'table' => 'reputation_cache',
'query' => "CREATE TABLE " . \IPS\Db::i()->prefix . "reputation_cache2 (SELECT * FROM " . \IPS\Db::i()->prefix . "reputation_cache WHERE id > 0 GROUP BY app, type, type_id);"
'query' => "CREATE TABLE " . \IPS\Db::i()->prefix . "reputation_cache2 (SELECT * FROM " . \IPS\Db::i()->prefix . "reputation_cache WHERE 1=0);"
),
array(
'table' => 'reputation_cache',
'query' => "ALTER TABLE " . \IPS\Db::i()->prefix . "reputation_cache2 ADD UNIQUE INDEX app (app, type, type_id);"
),
array(
'table' => 'reputation_cache',
'query' => "REPLACE INTO " . \IPS\Db::i()->prefix . "reputation_cache2 (SELECT * FROM " . \IPS\Db::i()->prefix . "reputation_cache WHERE id > 0);"
),
array(
'table' => 'reputation_cache',
@@ -78,8 +86,7 @@ class _Upgrade
array(
'table' => 'reputation_cache',
'query' => "ALTER TABLE " . \IPS\Db::i()->prefix . "reputation_cache ADD PRIMARY KEY(id),
CHANGE COLUMN id id BIGINT(20) NOT NULL,
ADD UNIQUE INDEX app (app, type, type_id),
CHANGE COLUMN id id BIGINT(20) NOT NULL,
ADD COLUMN rep_like_cache MEDIUMTEXT NULL DEFAULT NULL,
CHANGE COLUMN rep_points rep_points INT(10) NOT NULL DEFAULT 0;"
) ) );
@@ -35,7 +35,7 @@ class _Upgrade
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_key' => 'member_photo_gif_animate' ), "conf_key='member_photo_gif_no_animate'" );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
\IPS\Db::i()->dropColumn( 'groups', array( 'g_email_friend', 'g_email_limit' ) );
@@ -436,7 +436,7 @@ class _Upgrade
) );
\IPS\Db::i()->delete( 'core_sys_conf_settings', "conf_key IN ('warn_min', 'warn_max', 'warn_past_max', 'warn_mod_ban', 'warn_mod_modq', 'warn_mod_post', 'warn_gmod_ban', 'warn_gmod_modq', 'warn_gmod_post', 'resize_img_percent')" );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
\IPS\Db::i()->update( 'moderators', "mod_bitoptions=mod_bitoptions-496", "mod_bitoptions > 496" );
@@ -904,7 +904,7 @@ class _Upgrade
) );
\IPS\Db::i()->delete( "core_sys_conf_settings", "conf_key IN ('seo_bad_url', 'spider_sense')" );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
\IPS\Db::i()->addColumn( 'announcements', array(
'name' => 'announce_seo_title',
+24 -3
View File
@@ -102,8 +102,6 @@ class _Upgrade
)
) );
\IPS\Db::i()->query( "INSERT INTO " . \IPS\Db::i()->prefix . "reputation_totals SELECT MD5( CONCAT( app, ';', type, ';', type_id) ), MD5( CONCAT( app, ';', type ) ), SUM(rep_rating), type_id FROM " . \IPS\Db::i()->prefix . "reputation_index GROUP BY app, type, type_id ON DUPLICATE KEY UPDATE rt_key=rt_key" );
return TRUE;
}
@@ -113,6 +111,29 @@ class _Upgrade
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step2()
{
$query = array( array( 'table' => 'reputation_index', 'query' => "INSERT INTO " . \IPS\Db::i()->prefix . "reputation_totals SELECT MD5( CONCAT( app, ';', type, ';', type_id) ), MD5( CONCAT( app, ';', type ) ), SUM(rep_rating), type_id FROM " . \IPS\Db::i()->prefix . "reputation_index GROUP BY app, type, type_id ON DUPLICATE KEY UPDATE rt_key=rt_key" ) );
$toRun = \IPS\core\Setup\Upgrade::runManualQueries( $query );
if ( count( $toRun ) )
{
\IPS\core\Setup\Upgrade::adjustMultipleRedirect( array( 1 => 'core', 'extra' => array( '_upgradeStep' => 3 ) ) );
/* Queries to run manually */
return array( 'html' => \IPS\Theme::i()->getTemplate( 'forms' )->queries( $toRun, \IPS\Http\Url::internal( 'controller=upgrade' )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'mr_continue' => 1, 'mr' => \IPS\Request::i()->mr ) ) ) );
}
/* Finish */
return TRUE;
}
/**
* Step 3
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step3()
{
/* New blog column */
$addBlogColumn = false;
@@ -148,7 +169,7 @@ class _Upgrade
if ( count( $toRun ) )
{
\IPS\core\Setup\Upgrade::adjustMultipleRedirect( array( 1 => 'core', 'extra' => array( '_upgradeStep' => 3 ) ) );
\IPS\core\Setup\Upgrade::adjustMultipleRedirect( array( 1 => 'core', 'extra' => array( '_upgradeStep' => 4 ) ) );
/* Queries to run manually */
return array( 'html' => \IPS\Theme::i()->getTemplate( 'forms' )->queries( $toRun, \IPS\Http\Url::internal( 'controller=upgrade' )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'mr_continue' => 1, 'mr' => \IPS\Request::i()->mr ) ) ) );
@@ -45,7 +45,7 @@ class _Upgrade
\IPS\Db::i()->delete( 'core_sys_conf_settings', "conf_key IN( 'allow_dynamic_img', 'post_order_column' )" );
\IPS\Db::i()->delete( 'core_share_links_caches', "cache_key='mosttypes'" );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
}
$toRun = \IPS\core\Setup\Upgrade::runManualQueries( array( array(
@@ -30,7 +30,7 @@ class _Upgrade
public function step1()
{
\IPS\Db::i()->delete( 'core_sys_conf_settings', "conf_key IN( 'topic_marking_noquery', 'live_search_disable' )" );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
\IPS\Db::i()->addIndex( 'core_hooks', array(
'type' => 'key',
@@ -412,7 +412,7 @@ class _Upgrade
\IPS\Db::i()->delete( 'core_sys_conf_settings', "conf_key IN( 'seo_index_md', 'seo_index_mk', 'seo_index_title', 'ipseo_ping_services', 'ipseo_guest_skin' )" );
\IPS\Db::i()->delete( 'core_sys_settings_titles', "conf_title_keyword='ipseo'" );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
if ( !\IPS\Db::i()->checkForColumn( 'forums', 'ipseo_priority' ) )
{
@@ -33,7 +33,7 @@ class _Upgrade
{
\IPS\Db::i()->delete( 'core_sys_conf_settings', "conf_key = 'upload_domain'" );
\IPS\Db::i()->delete( 'task_manager', "task_key='mobile_notifications'" );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
\IPS\Db::i()->update( 'core_sys_settings_titles', array( 'conf_title_noshow' => 0 ), "conf_title_keyword='iphoneappsettings'" );
@@ -37,7 +37,7 @@ class _Upgrade
\IPS\Db::i()->delete( 'core_sys_conf_settings', "conf_key IN( 'oth_rand_topics_no_archived_plz', 'oth_rand_topic_fids', 'oth_rand_enabled' )" );
\IPS\Db::i()->delete( 'core_sys_settings_titles', "conf_title_keyword='othRandomTopic'" );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
}
catch( \UnderflowException $e ) {}
@@ -30,7 +30,7 @@ class _Upgrade
public function step1()
{
\IPS\Db::i()->delete( 'core_sys_conf_settings', "conf_key IN ('sl_publicdata','ipb_prune_email')" );
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
/* Finish */
return TRUE;
+1 -1
View File
@@ -9,7 +9,7 @@
*/
/* Clear settings store in case we've already been here */
unset( \IPS\Data\Store::i()->settings );
\IPS\Settings::i()->clearCache();
/* Do this the easy way first... */
if( isset( \IPS\Settings::i()->gb_char_set ) AND ! empty( \IPS\Settings::i()->gb_char_set ) AND mb_strtolower( \IPS\Settings::i()->gb_char_set ) !== 'utf-8' )
+26 -22
View File
@@ -234,7 +234,8 @@ class _Upgrade
/* Import data */
$limit = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
$select = \IPS\Db::i()->select( 'core_members.*, profile_portal.*', 'core_members', NULL, 'core_members.member_id', array( $limit, $perCycle ) )
$_SESSION['upg_40000_member_id'] = isset( $_SESSION['upg_40000_member_id'] ) ? $_SESSION['upg_40000_member_id'] : 0;
$select = \IPS\Db::i()->select( 'core_members.*, profile_portal.*', 'core_members', array( 'core_members.member_id>'. $_SESSION['upg_40000_member_id'] ), 'core_members.member_id', $perCycle )
->join( 'profile_portal', 'profile_portal.pp_member_id=core_members.member_id' );
if ( count( $select ) )
{
@@ -674,6 +675,9 @@ class _Upgrade
}
}
/* Save the last member_id */
$_SESSION['upg_40000_member_id'] = $row['member_id'];
/* Build insert */
try
{
@@ -728,7 +732,7 @@ class _Upgrade
unset( $_SESSION['idm_block_submissions'] );
}
unset( $_SESSION['aboutMe_Field'], $_SESSION['_step1Count'] );
unset( $_SESSION['aboutMe_Field'], $_SESSION['_step1Count'], $_SESSION['upg_40000_member_id'] );
}
$_SESSION['core_40000_step1_finished'] = true;
@@ -819,7 +823,7 @@ class _Upgrade
{
$data = NULL;
$login['login_folder_name'] = ucfirst( $login['login_folder_name'] );
$login['login_folder_name'] = mb_ucfirst( $login['login_folder_name'] );
if( $login['login_folder_name'] == 'internal' )
{
$login['login_folder_name'] = 'Internal';
@@ -2187,6 +2191,7 @@ DROP INDEX like_lookup_area"
case 'custom_pages':
$locationKey = 'nexus_Admin';
$id3 = 'pkg-pg';
break;
case 'packages':
@@ -2833,7 +2838,7 @@ DROP INDEX like_lookup_area"
{
if ( $row['conf_value'] )
{
if ( in_array( $row['conf_key'], array( 'upload_dir', 'gallery_images_path', 'idm_localsspath', 'idm_localfilepath', 'blog_upload_dir' ) ) and !@is_dir( $row['conf_value'] ) )
if ( in_array( $row['conf_key'], array( 'upload_dir', 'gallery_images_path', 'idm_localsspath', 'idm_localfilepath', 'blog_upload_dir' ) ) and !@is_dir( str_replace( array( '{root_path}', '{root}' ), \IPS\ROOT_PATH, $row['conf_value'] ) ) )
{
continue;
}
@@ -2965,21 +2970,21 @@ DROP INDEX like_lookup_area"
}
else if( $settings['idm_filestorage'] == 'db' )
{
$downloads = \IPS\Db::i()->insert( 'core_file_storage', array( 'method' => 'FileSystem', 'configuration' => json_encode( array() ) ) );
$downloads = \IPS\Db::i()->insert( 'core_file_storage', array( 'method' => 'Database', 'configuration' => json_encode( array() ) ) );
$screenshots = $downloads;
if( \IPS\Db::i()->checkForTable( 'downloads_files_records' ) )
{
\IPS\Db::i()->insert( 'core_files',
\IPS\Db::i()->select( "NULL, downloads_files_records.record_realname, MD5( RAND() ), downloads_filestorage.storage_file, NULL", 'downloads_filestorage' )->join( 'downloads_files_records', "downloads_filestorage.storage_id=downloads_files_records.record_id" )
\IPS\Db::i()->select( "NULL, downloads_files_records.record_location, MD5( RAND() ), downloads_filestorage.storage_file, ''", 'downloads_filestorage', "downloads_files_records.record_type='upload' AND downloads_files_records.record_storagetype='db' AND downloads_filestorage.storage_file IS NOT NULL AND downloads_filestorage.storage_file != ''" )->join( 'downloads_files_records', "downloads_filestorage.storage_id=downloads_files_records.record_db_id" )
);
\IPS\Db::i()->insert( 'core_files',
\IPS\Db::i()->select( "NULL, downloads_files_records.record_realname, MD5( RAND() ), downloads_filestorage.storage_ss, NULL", 'downloads_filestorage' )->join( 'downloads_files_records', "downloads_filestorage.storage_id=downloads_files_records.record_id" )
\IPS\Db::i()->select( "NULL, downloads_files_records.record_location, MD5( RAND() ), downloads_filestorage.storage_ss, ''", 'downloads_filestorage', "downloads_files_records.record_type='ssupload' AND downloads_files_records.record_storagetype='db' AND downloads_filestorage.storage_ss IS NOT NULL AND downloads_filestorage.storage_ss != ''" )->join( 'downloads_files_records', "downloads_filestorage.storage_id=downloads_files_records.record_db_id" )
);
\IPS\Db::i()->insert( 'core_files',
\IPS\Db::i()->select( "NULL, downloads_files_records.record_realname, MD5( RAND() ), downloads_filestorage.storage_thumb, NULL", 'downloads_filestorage' )->join( 'downloads_files_records', "downloads_filestorage.storage_id=downloads_files_records.record_id" )
\IPS\Db::i()->select( "NULL, downloads_files_records.record_location, MD5( RAND() ), downloads_filestorage.storage_thumb, ''", 'downloads_filestorage', "downloads_files_records.record_type='ssupload' AND downloads_files_records.record_storagetype='db' AND downloads_filestorage.storage_thumb IS NOT NULL AND downloads_filestorage.storage_thumb != ''" )->join( 'downloads_files_records', "downloads_filestorage.storage_id=downloads_files_records.record_db_id" )
);
}
@@ -3016,7 +3021,7 @@ DROP INDEX like_lookup_area"
'dir' => str_replace( '{root_path}', '{root}', $settings['idm_localsspath'] ),
'url' => '',
'toggle' => 1,
'custom_url' => $_SESSION['screenshots_url'],
'custom_url' => rtrim( \IPS\Settings::i()->base_url, '/' ) . '/' . $_SESSION['screenshots_url'],
);
}
else
@@ -3056,7 +3061,8 @@ DROP INDEX like_lookup_area"
}
}
unset( \IPS\Data\Store::i()->settings, \IPS\Data\Store::i()->storageConfigurations );
unset( \IPS\Data\Store::i()->storageConfigurations );
\IPS\Settings::i()->clearCache();
/* This constant isn't used in 4.0 but may be leftover from 3.x */
$publicPath = ( defined( 'PUBLIC_DIRECTORY' ) ? PUBLIC_DIRECTORY : 'public' );
@@ -3086,7 +3092,7 @@ DROP INDEX like_lookup_area"
{
$pathDetails = explode( '/', $row[ $column ] );
$fileName = array_pop( $pathDetails );
$newPathname = ltrim( implode( '/', $pathDetails ) . '/' . $row['attach_file'] . '.' . md5( uniqid( microtime() ) ), '/' );
$newPathname = ltrim( implode( '/', $pathDetails ) . '/' . $row['attach_file'] . '.' . md5( mt_rand() ), '/' );
if( @rename( $settings['upload_dir'] . '/' . $row[ $column ], $settings['upload_dir'] . '/' . $newPathname ) )
{
@@ -3435,14 +3441,14 @@ DROP INDEX like_lookup_area"
}
/* Make sure license key does not have extra spaces at end */
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => trim( \IPS\Settings::i()->ipb_reg_number ) ), array( 'conf_key=?', 'ipb_reg_number' ) );
\IPS\Settings::i()->changeValues( array( 'ipb_reg_number' => trim( \IPS\Settings::i()->ipb_reg_number ) ) );
/* Settings */
\IPS\Lang::saveCustom( 'core', "copyright_line_value", \IPS\Settings::i()->ipb_reg_name );
try
{
$guidelines = \IPS\Text\Parser::parseStatic( \IPS\Settings::i()->gl_guidelines, TRUE, NULL, NULL, TRUE, TRUE, TRUE );
$guidelines = \IPS\Text\LegacyParser::parseStatic( \IPS\Settings::i()->gl_guidelines, NULL, TRUE );
}
catch( \Exception $e )
{
@@ -3460,7 +3466,7 @@ DROP INDEX like_lookup_area"
try
{
$reg_rules = \IPS\Text\Parser::parseStatic( \IPS\Settings::i()->reg_rules, TRUE, NULL, NULL, TRUE, TRUE, TRUE );
$reg_rules = \IPS\Text\LegacyParser::parseStatic( \IPS\Settings::i()->reg_rules, NULL, TRUE );
}
catch( \Exception $e )
{
@@ -3478,7 +3484,7 @@ DROP INDEX like_lookup_area"
try
{
$priv_body = \IPS\Text\Parser::parseStatic( \IPS\Settings::i()->priv_body, TRUE, NULL, NULL, TRUE, TRUE, TRUE );
$priv_body = \IPS\Text\LegacyParser::parseStatic( \IPS\Settings::i()->priv_body, NULL, TRUE );
}
catch( \Exception $e )
{
@@ -3571,7 +3577,7 @@ DROP INDEX like_lookup_area"
}
/* Disable cron task job */
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 0 ), array( 'conf_key=?', 'task_use_cron' ) );
\IPS\Settings::i()->changeValues( array( 'task_use_cron' => 0 ) );
/* Delete old settings - some of these should not still be present but might have slipped through */
\IPS\Db::i()->delete( 'core_sys_conf_settings', "conf_key IN ('admob_bottom', 'admob_pub_id', 'admob_top', 'ad_code_board_index_footer', 'ad_code_board_index_header', 'ad_code_board_sidebar',
@@ -3644,17 +3650,15 @@ DROP INDEX like_lookup_area"
{
if ( isset( $settings[ $list ] ) AND ! empty( $settings[ $list ] ) )
{
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => implode( ",", explode( "\n", $settings[ $list ] ) ) ), array( 'conf_key=?', $list ) );
\IPS\Settings::i()->changeValues( array( $list => implode( ",", explode( "\n", $settings[ $list ] ) ) ) );
}
}
if ( !isset( $settings['ipb_use_url_filter'] ) OR empty( $settings['ipb_use_url_filter'] ) )
{
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => 'none' ), array( 'conf_key=?', 'ipb_url_filter_option' ) );
\IPS\Settings::i()->changeValues( array( 'ipb_url_filter_option' => 'none' ) );
}
unset( \IPS\Data\Store::i()->settings );
/* Disable all apps not currently being upgraded */
if ( is_array( $_SESSION['apps'] ) )
{
@@ -3671,7 +3675,7 @@ DROP INDEX like_lookup_area"
}
$acpNotes = \IPS\Db::i()->select( 'cs_value', 'cache_store', array( 'cs_key=?', 'adminnotes' ) )->first();
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $acpNotes ), array( 'conf_key=?', 'acp_notes' ) );
\IPS\Settings::i()->changeValues( array( 'acp_notes' => $acpNotes ) );
return TRUE;
}
@@ -3998,7 +4002,7 @@ DROP INDEX like_lookup_area"
{
return "Upgrading commerce customer history";
}
/**
* Finish - This is run after all apps have been upgraded
*