Version 5.0.0 beta 1

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

No files matched your search

@@ -12,16 +12,45 @@
namespace IPS\convert\Software\Core;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use DomainException;
use Exception;
use InvalidArgumentException;
use IPS\Application\Module;
use IPS\Content\Search\Index;
use IPS\convert\App;
use IPS\convert\Software;
use IPS\core\Ignore;
use IPS\Data\Cache;
use IPS\Data\Store;
use IPS\Db;
use IPS\Http\Url;
use IPS\Member;
use IPS\Patterns\ActiveRecordIterator;
use IPS\Request;
use IPS\Task;
use OutOfRangeException;
use PasswordHash;
use UnderflowException;
use function count;
use function defined;
use function in_array;
use function is_null;
use function strpos;
use function unserialize;
use const ENT_HTML5;
use const ENT_QUOTES;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* vBulletin 5 Core Converter
*/
class _Vbulletin5 extends \IPS\convert\Software
class Vbulletin5 extends Software
{
/**
* @brief is vB 5.5.3 or newer
@@ -31,12 +60,12 @@ class _Vbulletin5 extends \IPS\convert\Software
/**
* Constructor
*
* @param \IPS\convert\App $app The application to reference for database and other information.
* @param App $app The application to reference for database and other information.
* @param bool $needDB Establish a DB connection
* @return void
* @throws \InvalidArgumentException
* @throws InvalidArgumentException
*/
public function __construct( \IPS\convert\App $app, $needDB=TRUE )
public function __construct( App $app, $needDB=TRUE )
{
$return = parent::__construct( $app, $needDB );
@@ -51,7 +80,7 @@ class _Vbulletin5 extends \IPS\convert\Software
static::$skipCustomProfilePic = version_compare( $version, '5.5.3', '>=' );
}
}
catch( \Exception $e ) {} # If we can't query, we won't be able to do anything anyway
catch( Exception $e ) {} # If we can't query, we won't be able to do anything anyway
}
return $return;
@@ -164,20 +193,20 @@ class _Vbulletin5 extends \IPS\convert\Software
return $this->db->select( 'COUNT(*)', 'privatemessage', array( "privatemessage.msgtype=? AND node.parentid=?", 'message', $node ) )->join( 'node', 'privatemessage.nodeid = node.nodeid' )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
return 0;
}
catch( \Exception $e )
catch( Exception $e )
{
throw new \IPS\convert\Exception( sprintf( \IPS\Member::loggedIn()->language()->get( 'could_not_count_rows' ), $table ) );
throw new \IPS\convert\Exception( sprintf( Member::loggedIn()->language()->get( 'could_not_count_rows' ), $table ) );
}
break;
case 'node':
if ( $where === 'clubs' )
{
return \count( $this->fetchClubs() );
return count( $this->fetchClubs() );
}
else
{
@@ -201,9 +230,9 @@ class _Vbulletin5 extends \IPS\convert\Software
{
return $this->db->select( 'count(changeid)', 'userchangelog', array( $this->db->in( 'fieldname', array_keys( static::$changeLogTypes ) ) ) )->first();
}
catch( \Exception $e )
catch( Exception $e )
{
throw new \IPS\convert\Exception( sprintf( \IPS\Member::loggedIn()->language()->get( 'could_not_count_rows' ), $table ) );
throw new \IPS\convert\Exception( sprintf( Member::loggedIn()->language()->get( 'could_not_count_rows' ), $table ) );
}
break;
@@ -249,7 +278,7 @@ class _Vbulletin5 extends \IPS\convert\Software
{
$setting = $this->db->select( 'varname, value', 'setting', array( "varname=?", $theirs ) )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
continue;
}
@@ -258,12 +287,12 @@ class _Vbulletin5 extends \IPS\convert\Software
{
$title = $this->db->select( 'text', 'phrase', array( "varname=?", "setting_{$setting['varname']}_title" ) )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
$title = $setting['varname'];
}
$settings[$setting['varname']] = array( 'title' => $title, 'value' => $setting['value'], 'our_key' => $ours, 'our_title' => \IPS\Member::loggedIn()->language()->addToStack( $ours ) );
$settings[$setting['varname']] = array( 'title' => $title, 'value' => $setting['value'], 'our_key' => $ours, 'our_title' => Member::loggedIn()->language()->addToStack( $ours ) );
}
return $settings;
@@ -315,8 +344,8 @@ class _Vbulletin5 extends \IPS\convert\Software
'field_default' => NULL,
'field_required' => TRUE,
'field_extra' => array(),
'field_hint' => \IPS\Member::loggedIn()->language()->addToStack('convert_vb5_smilie_path'),
'field_validation' => function( $value ) { if ( !@is_dir( $value ) ) { throw new \DomainException( 'path_invalid' ); } },
'field_hint' => Member::loggedIn()->language()->addToStack('convert_vb5_smilie_path'),
'field_validation' => function( $value ) { if ( !@is_dir( $value ) ) { throw new DomainException( 'path_invalid' ); } },
),
'keep_existing_emoticons' => array(
'field_class' => 'IPS\\Helpers\\Form\\Checkbox',
@@ -332,8 +361,8 @@ class _Vbulletin5 extends \IPS\convert\Software
$return['convertProfileFieldGroups'] = array();
$options = array();
$options['none'] = \IPS\Member::loggedIn()->language()->addToStack( 'none' );
foreach( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_pfields_groups' ), 'IPS\core\ProfileFields\Group' ) AS $group )
$options['none'] = Member::loggedIn()->language()->addToStack( 'none' );
foreach( new ActiveRecordIterator( Db::i()->select( '*', 'core_pfields_groups' ), 'IPS\core\ProfileFields\Group' ) AS $group )
{
$options[$group->_id] = $group->_title;
}
@@ -344,14 +373,14 @@ class _Vbulletin5 extends \IPS\convert\Software
try
{
\IPS\Member::loggedIn()->language()->words["map_pfgroup_{$id}"] = $this->db->select( 'text', 'phrase', array( "varname=?", "category{$id}_title" ) )->first();
Member::loggedIn()->language()->words["map_pfgroup_{$id}"] = $this->db->select( 'text', 'phrase', array( "varname=?", "category{$id}_title" ) )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
\IPS\Member::loggedIn()->language()->words["map_pfgroup_{$id}"] = "vBulletin Profile Group {$id}";
Member::loggedIn()->language()->words["map_pfgroup_{$id}"] = "vBulletin Profile Group {$id}";
}
\IPS\Member::loggedIn()->language()->words["map_pfgroup_{$id}_desc"] = \IPS\Member::loggedIn()->language()->addToStack( 'map_pfgroup_desc' );
Member::loggedIn()->language()->words["map_pfgroup_{$id}_desc"] = Member::loggedIn()->language()->addToStack( 'map_pfgroup_desc' );
$return['convertProfileFieldGroups']["map_pfgroup_{$group['profilefieldcategoryid']}"] = array(
'field_class' => 'IPS\\Helpers\\Form\\Select',
@@ -367,8 +396,8 @@ class _Vbulletin5 extends \IPS\convert\Software
$return['convertProfileFields'] = array();
$options = array();
$options['none'] = \IPS\Member::loggedIn()->language()->addToStack( 'none' );
foreach( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_pfields_data' ), 'IPS\core\ProfileFields\Field' ) AS $field )
$options['none'] = Member::loggedIn()->language()->addToStack( 'none' );
foreach( new ActiveRecordIterator( Db::i()->select( '*', 'core_pfields_data' ), 'IPS\core\ProfileFields\Field' ) AS $field )
{
$options[$field->_id] = $field->_title;
}
@@ -377,13 +406,13 @@ class _Vbulletin5 extends \IPS\convert\Software
{
try
{
\IPS\Member::loggedIn()->language()->words["map_pfield_{$field['profilefieldid']}"] = $this->db->select( 'text', 'phrase', array( "varname=?", "field{$field['profilefieldid']}_title" ) )->first();
Member::loggedIn()->language()->words["map_pfield_{$field['profilefieldid']}"] = $this->db->select( 'text', 'phrase', array( "varname=?", "field{$field['profilefieldid']}_title" ) )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
\IPS\Member::loggedIn()->language()->words["map_pfield_{$field['profilefieldid']}"] = "vBulletin Profile Field {$field['profilefieldid']}";
Member::loggedIn()->language()->words["map_pfield_{$field['profilefieldid']}"] = "vBulletin Profile Field {$field['profilefieldid']}";
}
\IPS\Member::loggedIn()->language()->words["map_pfield_{$field['profilefieldid']}_desc"] = \IPS\Member::loggedIn()->language()->addToStack( 'map_pfield_desc' );
Member::loggedIn()->language()->words["map_pfield_{$field['profilefieldid']}_desc"] = Member::loggedIn()->language()->addToStack( 'map_pfield_desc' );
$return['convertProfileFields']["map_pfield_{$field['profilefieldid']}"] = array(
'field_class' => 'IPS\\Helpers\\Form\\Select',
@@ -400,15 +429,15 @@ class _Vbulletin5 extends \IPS\convert\Software
$options = array();
$options['none'] = 'None';
foreach( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'core_groups' ), 'IPS\Member\Group' ) AS $group )
foreach( new ActiveRecordIterator( Db::i()->select( '*', 'core_groups' ), 'IPS\Member\Group' ) AS $group )
{
$options[$group->g_id] = $group->name;
}
foreach( $this->db->select( '*', 'usergroup' ) AS $group )
{
\IPS\Member::loggedIn()->language()->words["map_group_{$group['usergroupid']}"] = $group['title'];
\IPS\Member::loggedIn()->language()->words["map_group_{$group['usergroupid']}_desc"] = \IPS\Member::loggedIn()->language()->addToStack( 'map_group_desc' );
Member::loggedIn()->language()->words["map_group_{$group['usergroupid']}"] = $group['title'];
Member::loggedIn()->language()->words["map_group_{$group['usergroupid']}_desc"] = Member::loggedIn()->language()->addToStack( 'map_group_desc' );
$return['convertGroups']["map_group_{$group['usergroupid']}"] = array(
'field_class' => 'IPS\\Helpers\\Form\\Select',
@@ -428,7 +457,7 @@ class _Vbulletin5 extends \IPS\convert\Software
'field_class' => 'IPS\\Helpers\\Form\\Radio',
'field_default' => 'avatars',
'field_required' => TRUE,
'field_extra' => array( 'options' => array( 'avatars' => \IPS\Member::loggedIn()->language()->addToStack( 'avatars' ), 'profile_photos' => \IPS\Member::loggedIn()->language()->addToStack( 'profile_photos' ) ) ),
'field_extra' => array( 'options' => array( 'avatars' => Member::loggedIn()->language()->addToStack( 'avatars' ), 'profile_photos' => Member::loggedIn()->language()->addToStack( 'profile_photos' ) ) ),
'field_hint' => NULL,
);
@@ -439,28 +468,28 @@ class _Vbulletin5 extends \IPS\convert\Software
'field_required' => TRUE,
'field_extra' => array(
'options' => array(
'database' => \IPS\Member::loggedIn()->language()->addToStack( 'conv_store_database' ),
'file_system' => \IPS\Member::loggedIn()->language()->addToStack( 'conv_store_file_system' ),
'database' => Member::loggedIn()->language()->addToStack( 'conv_store_database' ),
'file_system' => Member::loggedIn()->language()->addToStack( 'conv_store_file_system' ),
),
'userSuppliedInput' => 'file_system',
),
'field_hint' => NULL,
'field_validation' => function( $value ) { if ( $value != 'database' AND !@is_dir( $value ) ) { throw new \DomainException( 'path_invalid' ); } },
'field_validation' => function( $value ) { if ( $value != 'database' AND !@is_dir( $value ) ) { throw new DomainException( 'path_invalid' ); } },
);
/* And decide what to do about these... */
foreach( array( 'homepage', 'icq', 'aim', 'yahoo', 'msn', 'skype', 'google', 'user_title' ) AS $field )
{
\IPS\Member::loggedIn()->language()->words["field_{$field}"] = \IPS\Member::loggedIn()->language()->addToStack( 'pseudo_field', FALSE, array( 'sprintf' => $field ) );
\IPS\Member::loggedIn()->language()->words["field_{$field}_desc"] = \IPS\Member::loggedIn()->language()->addToStack( 'pseudo_field_desc' );
Member::loggedIn()->language()->words["field_{$field}"] = Member::loggedIn()->language()->addToStack( 'pseudo_field', FALSE, array( 'sprintf' => $field ) );
Member::loggedIn()->language()->words["field_{$field}_desc"] = Member::loggedIn()->language()->addToStack( 'pseudo_field_desc' );
$return['convertMembers']["field_{$field}"] = array(
'field_class' => 'IPS\\Helpers\\Form\\Radio',
'field_default' => 'no_convert',
'field_required' => TRUE,
'field_extra' => array(
'options' => array(
'no_convert' => \IPS\Member::loggedIn()->language()->addToStack( 'no_convert' ),
'create_field' => \IPS\Member::loggedIn()->language()->addToStack( 'create_field' ),
'no_convert' => Member::loggedIn()->language()->addToStack( 'no_convert' ),
'create_field' => Member::loggedIn()->language()->addToStack( 'create_field' ),
),
'userSuppliedInput' => 'create_field'
),
@@ -470,7 +499,7 @@ class _Vbulletin5 extends \IPS\convert\Software
break;
case 'convertClubs':
\IPS\Member::loggedIn()->language()->words['club_photo_location'] = \IPS\Member::loggedIn()->language()->addToStack( 'photo_location' );
Member::loggedIn()->language()->words['club_photo_location'] = Member::loggedIn()->language()->addToStack( 'photo_location' );
$return['convertClubs'] = array();
$return['convertClubs']['club_photo_location'] = array(
@@ -479,13 +508,13 @@ class _Vbulletin5 extends \IPS\convert\Software
'field_required' => TRUE,
'field_extra' => array(
'options' => array(
'database' => \IPS\Member::loggedIn()->language()->addToStack( 'conv_store_database' ),
'file_system' => \IPS\Member::loggedIn()->language()->addToStack( 'conv_store_file_system' ),
'database' => Member::loggedIn()->language()->addToStack( 'conv_store_database' ),
'file_system' => Member::loggedIn()->language()->addToStack( 'conv_store_file_system' ),
),
'userSuppliedInput' => 'file_system',
),
'field_hint' => NULL,
'field_validation' => function( $value ) { if ( $value != 'database' AND !@is_dir( $value ) ) { throw new \DomainException( 'path_invalid' ); } },
'field_validation' => function( $value ) { if ( $value != 'database' AND !@is_dir( $value ) ) { throw new DomainException( 'path_invalid' ); } },
);
break;
}
@@ -501,45 +530,47 @@ class _Vbulletin5 extends \IPS\convert\Software
public function finish()
{
/* Search Index Rebuild */
\IPS\Content\Search\Index::i()->rebuild();
Index::i()->rebuild();
/* Clear Cache and Store */
\IPS\Data\Store::i()->clearAll();
\IPS\Data\Cache::i()->clearAll();
Store::i()->clearAll();
Cache::i()->clearAll();
/* Non-Content Rebuilds */
\IPS\Task::queue( 'convert', 'RebuildProfilePhotos', array( 'app' => $this->app->app_id ), 5, array( 'app' ) );
\IPS\Task::queue( 'convert', 'RebuildNonContent', array( 'app' => $this->app->app_id, 'link' => 'core_message_posts', 'extension' => 'core_Messaging' ), 2, array( 'app', 'link', 'extension' ) );
\IPS\Task::queue( 'convert', 'RebuildNonContent', array( 'app' => $this->app->app_id, 'link' => 'core_members', 'extension' => 'core_Signatures' ), 2, array( 'app', 'link', 'extension' ) );
Task::queue( 'convert', 'RebuildProfilePhotos', array( 'app' => $this->app->app_id ), 5, array( 'app' ) );
Task::queue( 'convert', 'RebuildNonContent', array( 'app' => $this->app->app_id, 'link' => 'core_message_posts', 'extension' => 'core_Messaging' ), 2, array( 'app', 'link', 'extension' ) );
Task::queue( 'convert', 'RebuildNonContent', array( 'app' => $this->app->app_id, 'link' => 'core_members', 'extension' => 'core_Signatures' ), 2, array( 'app', 'link', 'extension' ) );
/* Content Counts */
\IPS\Task::queue( 'core', 'RecountMemberContent', array( 'app' => $this->app->app_id ), 4, array( 'app' ) );
Task::queue( 'core', 'RecountMemberContent', array( 'app' => $this->app->app_id ), 4, array( 'app' ) );
/* Clubs */
\IPS\Task::queue( 'convert', 'RecountClubMembers', array( 'app' => $this->app->app_id ), 2, array( 'app' ) );
Task::queue( 'convert', 'RecountClubMembers', array( 'app' => $this->app->app_id ), 2, array( 'app' ) );
/* First Post Data */
\IPS\Task::queue( 'convert', 'RebuildConversationFirstIds', array( 'app' => $this->app->app_id ), 2, array( 'app' ) );
Task::queue( 'convert', 'RebuildConversationFirstIds', array( 'app' => $this->app->app_id ), 2, array( 'app' ) );
/* Attachments */
\IPS\Task::queue( 'core', 'RebuildAttachmentThumbnails', array( 'app' => $this->app->app_id ), 1, array( 'app' ) );
Task::queue( 'core', 'RebuildAttachmentThumbnails', array( 'app' => $this->app->app_id ), 1, array( 'app' ) );
return array( "f_search_index_rebuild", "f_clear_caches", "f_rebuild_pms", "f_signatures_rebuild" );
}
/**
* Fix post data
* Pre-process content for the Invision Community text parser
*
* @param string $post Raw post data
* @return string Parsed post data
* @param string The post
* @param string|null Content Classname passed by post-conversion rebuild
* @param int|null Content ID passed by post-conversion rebuild
* @return string The converted post
*/
public static function fixPostData( $post )
public static function fixPostData( string $post, ?string $className=null, ?int $contentId=null ): string
{
/* IMG2 BBcode - Needs to be ran before htmlspecialchars due to it containing JSON */
$matches = array();
preg_match_all( "/\[IMG2=JSON](.+?)\[\/IMG2\]/i", $post, $matches );
if ( \count( $matches ) )
if ( count( $matches ) )
{
foreach( $matches[0] as $k => $v )
{
@@ -548,7 +579,7 @@ class _Vbulletin5 extends \IPS\convert\Software
/* Make sure the JSON value exists */
if( !isset( $matches[1][ $k ] ) )
{
throw new \DomainException;
throw new DomainException;
}
$decoded = json_decode( $matches[1][ $k ], TRUE );
@@ -556,12 +587,12 @@ class _Vbulletin5 extends \IPS\convert\Software
/* Make sure the JSON is valid and contains src */
if( !isset( $decoded['src'] ) OR empty( $decoded['src'] ) )
{
throw new \DomainException;
throw new DomainException;
}
$post = str_replace( $v, "[img]{$decoded['src']}[/img]", $post );
}
catch( \DomainException $e )
catch( DomainException $e )
{
continue;
}
@@ -572,10 +603,10 @@ class _Vbulletin5 extends \IPS\convert\Software
$matches = array();
preg_match_all( '#\[user(=\"?(\d+)\"?)?\](.+?)\[\/user\]#i', $post, $matches ); // this purposefully matches more than the default vB mention.
if ( \count( $matches ) )
if ( count( $matches ) )
{
/* Make sure we actually have mention data */
if ( isset( $matches[1] ) AND \count( $matches[1] ) )
if ( isset( $matches[1] ) AND count( $matches[1] ) )
{
$mentions = array();
foreach ( $matches[1] AS $k => $v )
@@ -586,7 +617,7 @@ class _Vbulletin5 extends \IPS\convert\Software
}
}
$maps = iterator_to_array( \IPS\Db::i()->select( 'name, member_id', 'core_members', array( \IPS\Db::i()->in( 'name', array_keys( $mentions ) ) ) )->setKeyField( 'name' )->setValueField( 'member_id' ) );
$maps = iterator_to_array( Db::i()->select( 'name, member_id', 'core_members', array( Db::i()->in( 'name', array_keys( $mentions ) ) ) )->setKeyField( 'name' )->setValueField( 'member_id' ) );
foreach ( $mentions AS $memberName => $memberId )
{
@@ -642,7 +673,7 @@ class _Vbulletin5 extends \IPS\convert\Software
{
$imageCategory = $this->db->select( '*', 'imagecategory', array( "imagecategoryid=?", $emoticon['imagecategoryid'] ) )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
$imageCategory = array(
'title' => "Converted",
@@ -679,7 +710,7 @@ class _Vbulletin5 extends \IPS\convert\Software
{
$name = $this->db->select( 'text', 'phrase', array( "varname=?", "category{$group['profilefieldcategoryid']}_title" ) )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
$name = "vBulletin Profile Group {$group['profilefieldcategoryid']}";
}
@@ -713,7 +744,7 @@ class _Vbulletin5 extends \IPS\convert\Software
{
$name = $this->db->select( 'text', 'phrase', array( "varname=?", "field{$field['profilefieldid']}_title" ) )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
$name = "vBulletin Profile Field {$field['profilefieldid']}";
}
@@ -722,16 +753,16 @@ class _Vbulletin5 extends \IPS\convert\Software
{
$desc = $this->db->select( 'text', 'phrase', array( "varname=?", "field{$field['profilefieldid']}_desc" ) )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
$desc = "";
}
$merge = ( $this->app->_session['more_info']['convertProfileFields']["map_pfield_{$field['profilefieldid']}"] != 'none' ) ? $this->app->_session['more_info']['convertProfileFields']["map_pfield_{$field['profilefieldid']}"] : NULL;
if ( \in_array( mb_strtolower( $field['type'] ), array( 'select', 'radio', 'checkbox', 'select_multiple' ) ) )
if ( in_array( mb_strtolower( $field['type'] ), array( 'select', 'radio', 'checkbox', 'select_multiple' ) ) )
{
$content = json_encode( @\unserialize( $field['data'] ) );
$content = json_encode( @unserialize( $field['data'] ) );
}
else
{
@@ -752,7 +783,7 @@ class _Vbulletin5 extends \IPS\convert\Software
'pf_desc' => $desc,
'pf_type' => $type,
'pf_content' => $content,
'pf_not_null' => ( \in_array( $field['required'], array( 1, 3 ) ) ) ? 1 : 0,
'pf_not_null' => ( in_array( $field['required'], array( 1, 3 ) ) ) ? 1 : 0,
'pf_member_hide' => $field['hidden'] ? 'hide' : 'all',
'pf_max_input' => $field['maxlength'],
'pf_member_edit' => ( $field['editable'] >= 1 ) ? 1 : 0,
@@ -835,7 +866,7 @@ class _Vbulletin5 extends \IPS\convert\Software
$promotion = $this->db->select( '*', 'userpromotion', array( "usergroupid=?", $group['usergroupid'] ) )->first();
/* We only support Posts or Join Date */
if ( \in_array( $promotion['strategy'], array( 17, 18 ) ) )
if ( in_array( $promotion['strategy'], array( 17, 18 ) ) )
{
switch( $promotion['strategy'] )
{
@@ -850,7 +881,7 @@ class _Vbulletin5 extends \IPS\convert\Software
}
}
}
catch( \UnderflowException $e ) {}
catch( UnderflowException $e ) {}
/* Work out photo vars - vBulletin has a concept of avatars and profile photos, so we are just going to use the larger of the two */
$g_max_photo_vars = array();
@@ -909,10 +940,8 @@ class _Vbulletin5 extends \IPS\convert\Software
'g_signature_limits' => $g_signature_limits,
'g_bitoptions' => array(
'gbw_promote_unit_type' => $gbw_promote_unit, // Type of group promotion to use. 1 is days since joining, 0 is content count. Corresponds to g_promotion
'gbw_no_status_update' => !$checkpermission( 'visitormessagepermissions', 'canmessageownprofile' ), // Can NOT post status updates
'gbw_allow_upload_bgimage' => 1, // Can upload a cover photo?
'gbw_view_reps' => $checkpermission( 'genericpermissions2', 'canprofilerep' ), // Can view who gave reputation?
'gbw_no_status_import' => !$checkpermission( 'visitormessagepermissions', 'canmessageownprofile' ), // Can NOT import status updates from Facebook/Twitter
'gbw_disable_tagging' => !$checkpermission( 'genericpermissions', 'cancreatetag' ), // Can NOT use tags
'gbw_disable_prefixes' => !$checkpermission( 'genericpermissions', 'cancreatetag' ), // Can NOT use prefixes
'gbw_pm_override_inbox_full'=> $checkpermission( 'pmpermissions', 'canignorequota' ), // 1 means this group can send other members PMs even when that member's inbox is full
@@ -921,8 +950,7 @@ class _Vbulletin5 extends \IPS\convert\Software
'g_hide_own_posts' => $checkpermission( 'forumpermissions', 'candeletepost' ),
'g_pm_flood_mins' => $this->_setting( 'pmfloodtime' ) / 60,
'g_post_polls' => $checkpermission( 'forumpermissions', 'canpostpoll' ) ? 1 : 0,
'g_vote_polls' => $checkpermission( 'forumpermissions', 'canvote' ) ? 1 : 0,
'g_topic_rate_setting' => $checkpermission( 'forumpermissions', 'canthreadrate' ) ? 1 : 0
'g_vote_polls' => $checkpermission( 'forumpermissions', 'canvote' ) ? 1 : 0
);
$merge = ( $this->app->_session['more_info']['convertGroups']["map_group_{$group['usergroupid']}"] != 'none' ) ? $this->app->_session['more_info']['convertGroups']["map_group_{$group['usergroupid']}"] : NULL;
@@ -933,7 +961,7 @@ class _Vbulletin5 extends \IPS\convert\Software
}
/* Now check for group promotions */
if( \count( $libraryClass->groupPromotions ) )
if( count( $libraryClass->groupPromotions ) )
{
foreach( $libraryClass->groupPromotions as $groupPromotion )
{
@@ -1026,7 +1054,7 @@ class _Vbulletin5 extends \IPS\convert\Software
{
$warn_lastwarn = $this->db->select( 'actiondateline', 'infraction', array( "infracteduserid=?", $user['userid'] ), "actiondateline DESC", 1 )->first();
}
catch( \UnderflowException $e ) {}
catch( UnderflowException $e ) {}
/* Birthday */
if ( $user['birthday'] )
@@ -1071,7 +1099,7 @@ class _Vbulletin5 extends \IPS\convert\Software
$temp_ban = -1;
}
}
catch( \UnderflowException $e ) {}
catch( UnderflowException $e ) {}
/* Figure Out Password - they differ between 5.0 and 5.1 */
if ( !isset( $user['password'] ) AND ( isset( $user['token'] ) AND isset( $user['scheme'] ) ) )
@@ -1090,7 +1118,7 @@ class _Vbulletin5 extends \IPS\convert\Software
'member_id' => $user['userid'],
'member_group_id' => $user['usergroupid'],
'mgroup_others' => $user['membergroupids'],
'name' => html_entity_decode( $user['username'], \ENT_QUOTES | \ENT_HTML5, 'UTF-8' ),
'name' => html_entity_decode( $user['username'], ENT_QUOTES | ENT_HTML5, 'UTF-8' ),
'email' => $user['email'],
'joined' => $user['joindate'],
'ip_address' => $user['ipaddress'],
@@ -1131,7 +1159,7 @@ class _Vbulletin5 extends \IPS\convert\Software
$info['members_bitoptions']['validating'] = TRUE;
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
$activation = NULL;
}
@@ -1150,7 +1178,7 @@ class _Vbulletin5 extends \IPS\convert\Software
$profileFields[ str_replace( 'field', '', $key ) ] = $value;
}
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
$profileFields = array();
}
@@ -1170,7 +1198,7 @@ class _Vbulletin5 extends \IPS\convert\Software
/* We don't actually need this, but we need to make sure the field was created */
$fieldId = $this->app->getLink( $pseudo, 'core_pfields_data' );
}
catch( \OutOfRangeException $e )
catch( OutOfRangeException $e )
{
$libraryClass->convertProfileField( array(
'pf_id' => $pseudo,
@@ -1187,7 +1215,7 @@ class _Vbulletin5 extends \IPS\convert\Software
if( $pseudo == 'user_title' )
{
$profileFields[ $pseudo ] = \in_array( $user['usertitle'], $userTitles ) ? NULL : $user['usertitle'];
$profileFields[ $pseudo ] = in_array( $user['usertitle'], $userTitles ) ? NULL : $user['usertitle'];
}
else
{
@@ -1209,7 +1237,7 @@ class _Vbulletin5 extends \IPS\convert\Software
{
if( $firstTable === FALSE )
{
throw new \UnderflowException();
throw new UnderflowException();
}
foreach( $this->db->select( 'filedata, filename', $firstTable, array( "userid=?", $user['userid'] ) )->first() AS $key => $value )
@@ -1225,13 +1253,13 @@ class _Vbulletin5 extends \IPS\convert\Software
}
$filepath = NULL;
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
try
{
if( $secondTable === FALSE )
{
throw new \UnderflowException();
throw new UnderflowException();
}
foreach( $this->db->select( 'filedata, filename', $secondTable, array( "userid=?", $user['userid'] ) )->first() AS $key => $value )
@@ -1247,7 +1275,7 @@ class _Vbulletin5 extends \IPS\convert\Software
}
$filepath = NULL;
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
list( $filedata, $filename, $filepath ) = array( NULL, NULL, NULL );
}
@@ -1271,7 +1299,7 @@ class _Vbulletin5 extends \IPS\convert\Software
{
if( $firstTable === FALSE )
{
throw new \UnderflowException();
throw new UnderflowException();
}
$ext = $this->db->select( 'filename', $firstTable, array( "userid=?", $user['userid'] ) )->first();
@@ -1285,14 +1313,14 @@ class _Vbulletin5 extends \IPS\convert\Software
else
{
/* Throw an exception so we can try the other */
throw new \UnderflowException;
throw new UnderflowException;
}
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
if( $secondTable === FALSE )
{
throw new \UnderflowException();
throw new UnderflowException();
}
$ext = $this->db->select( 'filename', $secondTable, array( "userid=?", $user['userid'] ) )->first();
@@ -1306,11 +1334,11 @@ class _Vbulletin5 extends \IPS\convert\Software
else
{
/* Throw an exception so we can try the other */
throw new \UnderflowException;
throw new UnderflowException;
}
}
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
list( $filedata, $filename, $filepath ) = array( NULL, NULL, NULL );
}
@@ -1321,7 +1349,7 @@ class _Vbulletin5 extends \IPS\convert\Software
/* If we are validating, store our validation row entry */
if( $activation !== NULL AND $memberId )
{
\IPS\Db::i()->replace( 'core_validating', array(
Db::i()->replace( 'core_validating', array(
'vid' => md5( $activation['activationid'] . $activation['useractivationid'] ),
'member_id' => $memberId,
'entry_date' => $activation['dateline'],
@@ -1352,7 +1380,7 @@ class _Vbulletin5 extends \IPS\convert\Software
{
$node = $this->db->select( 'userid, description', 'node', array( "nodeid=?", $warn['nodeid'] ) )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
continue;
}
@@ -1402,12 +1430,12 @@ class _Vbulletin5 extends \IPS\convert\Software
{
$setting = $this->db->select( 'value', 'setting', array( "varname=?", $theirs ) )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
continue;
}
\IPS\Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $setting ), array( "conf_key=?", $ours ) );
Db::i()->update( 'core_sys_conf_settings', array( 'conf_value' => $setting ), array( "conf_key=?", $ours ) );
}
}
@@ -1428,7 +1456,7 @@ class _Vbulletin5 extends \IPS\convert\Software
'ignore_ignore_id' => $ignore['relationid'],
);
foreach( \IPS\core\Ignore::types() AS $type )
foreach( Ignore::types() AS $type )
{
$info['ignore_' . $type] = 1;
}
@@ -1456,7 +1484,7 @@ class _Vbulletin5 extends \IPS\convert\Software
{
$replies = $this->db->select( 'COUNT(*)', 'node', array( "parentid=?", $pm['nodeid'] ) )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
$replies = 1;
}
@@ -1466,7 +1494,7 @@ class _Vbulletin5 extends \IPS\convert\Software
foreach( $this->db->select( 'userid', 'node', array( "parentid=?", $pm['nodeid'] ) ) AS $userid )
{
$to[$userid] = $userid;
if ( \is_null( $toId ) AND $userid != $pm['userid'] )
if ( is_null( $toId ) AND $userid != $pm['userid'] )
{
$toId = $userid;
}
@@ -1479,7 +1507,7 @@ class _Vbulletin5 extends \IPS\convert\Software
'mt_starter_id' => $pm['userid'],
'mt_start_time' => $pm['publishdate'],
'mt_last_post_time' => $pm['lastcontent'],
'mt_to_count' => \count( $to ),
'mt_to_count' => count( $to ),
'mt_to_member_id' => $toId,
'mt_replies' => $replies,
'mt_first_msg_id' => $pm['nodeid'],
@@ -1537,7 +1565,7 @@ class _Vbulletin5 extends \IPS\convert\Software
{
$pm['rawtext'] = $this->db->select( 'message', 'pmtext', array( "pmtextid=?", $pm['oldid'] ) )->first();
}
catch( \UnderflowException $e ) { }
catch( UnderflowException $e ) { }
}
$libraryClass->convertPrivateMessageReply( array(
@@ -1567,7 +1595,7 @@ class _Vbulletin5 extends \IPS\convert\Software
{
$mainNodeId = $this->db->select( 'nodeid', 'channel', array( "guid=?", static::$guids['clubs'] ) )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
/* shrug */
throw new \IPS\convert\Software\Exception;
@@ -1600,7 +1628,7 @@ class _Vbulletin5 extends \IPS\convert\Software
{
$channel = $this->db->select( '*', 'channel', array( "nodeid=?", $row['nodeid'] ) )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
$channel = array( 'filedataid' => 0 );
}
@@ -1612,7 +1640,7 @@ class _Vbulletin5 extends \IPS\convert\Software
{
$filedata = $this->db->select( '*', 'filedata', array( "filedataid=?", $channel['filedataid'] ) )->first();
}
catch( \UnderflowException $e ) {}
catch( UnderflowException $e ) {}
}
$info = array(
@@ -1677,7 +1705,7 @@ class _Vbulletin5 extends \IPS\convert\Software
* @brief Silly Bit Options for Groups. Typically we would leave out app specific options (such as Forums here) however we need them for some general permissions, like uploading.
* @note This is public simply because I do not want to do this ever again if it ever changes.
*/
public static $bitOptions = array(
public static array $bitOptions = array(
'forumpermissions' => array(
'canview' => 1,
'canviewothers' => 2,
@@ -1885,7 +1913,7 @@ class _Vbulletin5 extends \IPS\convert\Software
$this->settingsCache[$key] = $setting['defaultvalue'];
}
}
catch( \UnderflowException $e )
catch( UnderflowException $e )
{
/* If we failed to find it, we probably will fail again on later attempts */
$this->settingsCache[$key] = NULL;
@@ -1946,7 +1974,7 @@ class _Vbulletin5 extends \IPS\convert\Software
$clubs[ $row['nodeid'] ] = $row;
}
}
catch( \UnderflowException $e ) { /* Just in case something goofy happened and there is no main channel */ }
catch( UnderflowException $e ) { /* Just in case something goofy happened and there is no main channel */ }
return $clubs;
}
@@ -1982,26 +2010,26 @@ class _Vbulletin5 extends \IPS\convert\Software
/**
* Check if we can redirect the legacy URLs from this software to the new locations
*
* @return NULL|\IPS\Http\Url
* @return NULL|Url
*/
public function checkRedirects()
{
/* If we can't access profiles, don't bother trying to redirect */
if( !\IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'core', 'members' ) ) )
if( !Member::loggedIn()->canAccessModule( Module::get( 'core', 'members' ) ) )
{
return NULL;
}
$url = \IPS\Request::i()->url();
$url = Request::i()->url();
if( preg_match( '#/member/([0-9]+)\-#i', $url->data[ \IPS\Http\Url::COMPONENT_PATH ], $matches ) )
if( preg_match( '#/member/([0-9]+)\-#i', $url->data[ Url::COMPONENT_PATH ], $matches ) )
{
try
{
$data = (string) $this->app->getLink( $matches[1], array( 'members', 'core_members' ) );
return \IPS\Member::load( $data )->url();
return Member::load( $data )->url();
}
catch( \Exception $e )
catch( Exception $e )
{
return NULL;
}
@@ -2013,16 +2041,16 @@ class _Vbulletin5 extends \IPS\convert\Software
/**
* Process a login
*
* @param \IPS\Member $member The member
* @param Member $member The member
* @param string $password Password from form
* @return bool
*/
public static function login( $member, $password )
{
/* If no algorithm is defined, use the legacy handler */
if ( \strpos( $member->misc, 'blowfish' ) === FALSE and \strpos( $member->misc, 'legacy' ) === FALSE )
if ( strpos( $member->misc, 'blowfish' ) === FALSE and strpos( $member->misc, 'legacy' ) === FALSE )
{
return \IPS\convert\Software\Core\Vbulletin::login( $member, $password );
return Vbulletin::login( $member, $password );
}
/* Which do we need to use? */
@@ -2034,7 +2062,7 @@ class _Vbulletin5 extends \IPS\convert\Software
/* vBulletin uses PasswordHash, however they md5 once the password prior to checking */
$md5_once_password = md5( $password );
require_once \IPS\ROOT_PATH . "/applications/convert/sources/Login/PasswordHash.php";
$ph = new \PasswordHash( $algo[ 1 ], FALSE );
$ph = new PasswordHash( $algo[ 1 ], FALSE );
return $ph->CheckPassword( $md5_once_password, $member->conv_password );
break;
@@ -2043,7 +2071,7 @@ class _Vbulletin5 extends \IPS\convert\Software
$token = explode( ' ', $member->conv_password );
$member->conv_password = $token[0];
$member->conv_password_extra = $token[1];
return \IPS\convert\Software\Core\Vbulletin::login( $member, $password );
return Vbulletin::login( $member, $password );
break;
/** vBulletin 5.6.2 was able to also use the Argon2id password hashing scheme. */
case 'argon2id':