1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-09-30 09:49:32 +02:00

Compare commits

..

23 Commits

Author SHA1 Message Date
Marc Alexander
b5fb91f071 Merge branch '3.3.x' 2025-09-29 20:24:25 +00:00
Marc Alexander
b0e97f5baa Merge pull request #6863 from marc1706/ticket/17555
[ticket/17555] Adapt windows runner tests to prevent random failures
2025-09-29 22:22:28 +02:00
Marc Alexander
12026b5378 Merge pull request #6865 from marc1706/ticket/17555-master
[ticket/17555] Adapt windows runner tests to prevent random failures -- master versions
2025-09-29 22:21:57 +02:00
Marc Alexander
31712bde02 Merge branch '3.3.x' 2025-09-29 19:04:48 +00:00
Marc Alexander
8ce7e83985 Merge pull request #6866 from Noxwizard/ticket/17477
[ticket/17477] Support non-prefixed whois servers
2025-09-29 20:59:52 +02:00
Marc Alexander
d50f878101 Merge branch 'ticket/17555' into ticket/17555-master 2025-09-29 20:55:55 +02:00
Marc Alexander
dc22ad07a2 [ticket/17555] Apply windows runner adjustments from master
PHPBB-17555
2025-09-29 20:10:27 +02:00
Marc Alexander
47a842071f Merge pull request #6871 from iMattPro/ticket/17555
[ticket/17555] Optimize windows functional tests
2025-09-29 19:20:06 +02:00
Matt Friedman
3a105548a9 [ticket/17555] Optimize windows tests
PHPBB-17555
2025-09-28 13:19:12 -07:00
Patrick Webster
74b1de0bc2 [ticket/17477] Support non-prefixed whois servers
Referral servers lacking the whois:// prefix are not currently supported.
This ticket adds support for those servers. At the moment, this is mainly an
issue for RIPE entries on ARIN. They will now be detected and followed.

PHPBB-17477
2025-09-27 17:07:36 -05:00
Marc Alexander
736ec35734 Merge pull request #6847 from iMattPro/ticket/17541
[ticket/17541] Fix and optimize issues in ext catalog installer
2025-09-27 15:01:22 +02:00
Derk
2ce5cffbb5 Merge pull request #6187 from rubencm/ticket/16005
[ticket/16005] Remove phpBB2 converter
2025-09-27 14:53:58 +02:00
Marc Alexander
391bda011e [ticket/16005] Remove references that don't make sense anymore
PHPBB-16005
2025-09-27 14:25:01 +02:00
rubencm
aa674a42a0 [ticket/16005] Remove phpbb2 converter
PHPBB3-16005
2025-09-27 14:24:58 +02:00
Marc Alexander
d54cb419c0 [master] Update versions to 4.0.0-a2-dev 2025-09-27 12:49:41 +02:00
Marc Alexander
ab1891b4bd Merge branch 'prep-release-4.0.0-a1' 2025-09-27 12:44:21 +02:00
Matt Friedman
a0aadd3f27 [ticket/17541] Add a comment for consitency with similar logic
PHPBB-17541
2025-09-23 13:17:52 -07:00
Matt Friedman
535fc2917f [ticket/17541] Remove unused code leftovers
PHPBB-17541
2025-09-23 11:08:40 -07:00
Matt Friedman
b7f381fe45 [ticket/17541] Fix snake cased variable names
PHPBB-17541
2025-09-23 11:08:19 -07:00
Matt Friedman
3c9bbee5c1 Merge branch 'master' into ticket/17541 2025-09-23 10:40:43 -07:00
Matt Friedman
0021db6a30 Merge branch 'master' into ticket/17541 2025-09-18 12:28:40 -07:00
Matt Friedman
30b69b6403 [ticket/17541] Ensure highest compat. ver. ext is installed
PHPBB-17541
2025-09-13 21:39:27 -07:00
Matt Friedman
1af2f922b5 [ticket/17541] Avoid variable naming conflicts in loop
PHPBB-17541
2025-09-13 14:03:32 -07:00
13 changed files with 282 additions and 2998 deletions

View File

@@ -7,7 +7,10 @@
bootstrap="../tests/bootstrap.php"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
cacheDirectory=".phpunit.cache"
backupStaticProperties="false">
backupStaticProperties="false"
timeoutForSmallTests="60"
timeoutForMediumTests="300"
timeoutForLargeTests="600">
<testsuites>
<testsuite name="phpBB Test Suite">
<directory suffix="_test.php">../tests</directory>

View File

@@ -544,6 +544,9 @@ jobs:
GITHUB_WORKSPACE: ${{ github.workspace }}
TEMP_DIR: ${{ runner.temp }}
run: |
# Disable Windows Defender real-time monitoring early to improve performance
Set-MpPreference -DisableRealtimeMonitoring $true
Enable-WindowsOptionalFeature -Online -FeatureName IIS-WebServerRole, IIS-WebServer, IIS-CommonHttpFeatures, IIS-ManagementConsole, IIS-HttpErrors, IIS-HttpRedirect, IIS-WindowsAuthentication, IIS-StaticContent, IIS-DefaultDocument, IIS-HttpCompressionStatic, IIS-DirectoryBrowsing, IIS-WebServerManagementTools, IIS-CGI -All
Set-Service wuauserv -StartupType Manual
(Get-Content ${env:GITHUB_WORKSPACE}\phpBB\web.config).replace("<configuration>", "<configuration>`n`t<system.web>`n`t`t<customErrors mode=`"Off`"/>`n`t</system.web>") | Set-Content ${env:GITHUB_WORKSPACE}\phpBB\web.config
@@ -564,16 +567,38 @@ jobs:
New-WebHandler -Name "PHP-FastCGI" -Path "*.php" -Modules FastCgiModule -ScriptProcessor "C:\tools\php\php-cgi.exe" -Verb '*' -ResourceType Either
iisreset
NET START W3SVC
mkdir "${env:GITHUB_WORKSPACE}\phpBB\cache\test"
mkdir "${env:GITHUB_WORKSPACE}\phpBB\cache\installer"
icacls "${env:GITHUB_WORKSPACE}\phpBB\cache" /grant Users:F /T
icacls "${env:GITHUB_WORKSPACE}\phpBB\files" /grant Users:F /T
icacls "${env:GITHUB_WORKSPACE}\phpBB\store" /grant Users:F /T
icacls "${env:GITHUB_WORKSPACE}\phpBB\ext" /grant Users:F /T
icacls "${env:GITHUB_WORKSPACE}\phpBB\vendor-ext" /grant Users:F /T
icacls "${env:GITHUB_WORKSPACE}\phpBB\composer-ext.json" /grant Users:F /T
icacls "${env:GITHUB_WORKSPACE}\phpBB\composer-ext.lock" /grant Users:F /T
icacls "${env:GITHUB_WORKSPACE}\phpBB\images\avatars\upload" /grant Users:F /T
# Wait for IIS to be ready and test connectivity
Start-Sleep -Seconds 10
try {
$response = Invoke-WebRequest -Uri "http://phpbb.test/" -UseBasicParsing -TimeoutSec 30
Write-Host "Web server is responding: $($response.StatusCode)"
} catch {
Write-Host "Web server test failed: $_"
}
# Create directories and set permissions more efficiently
$dirs = @("cache\test", "cache\installer")
foreach ($dir in $dirs) {
New-Item -Path "${env:GITHUB_WORKSPACE}\phpBB\$dir" -ItemType Directory -Force
}
# Set permissions in batch for better performance
$paths = @("cache", "files", "store", "ext", "vendor-ext", "images\avatars\upload")
foreach ($path in $paths) {
if (Test-Path "${env:GITHUB_WORKSPACE}\phpBB\$path") {
icacls "${env:GITHUB_WORKSPACE}\phpBB\$path" /grant Users:F /T /Q
}
}
# Set permissions for specific files
$files = @("composer-ext.json", "composer-ext.lock")
foreach ($file in $files) {
if (Test-Path "${env:GITHUB_WORKSPACE}\phpBB\$file") {
icacls "${env:GITHUB_WORKSPACE}\phpBB\$file" /grant Users:F /Q
}
}
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("IIS_IUSRS", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow")
$acl = Get-ACL "${env:TEMP_DIR}"
$acl.AddAccessRule($accessRule)
@@ -586,7 +611,7 @@ jobs:
$postgreSqlSvc = Get-Service "postgresql*"
Set-Service $postgreSqlSvc.Name -StartupType manual
$runningStatus = [System.ServiceProcess.ServiceControllerStatus]::Running
$maxStartTimeout = New-TimeSpan -Seconds 30
$maxStartTimeout = New-TimeSpan -Seconds 120
try {
$postgreSqlSvc.Start()
$postgreSqlSvc.WaitForStatus($runningStatus, $maxStartTimeout)
@@ -595,12 +620,17 @@ jobs:
}
[System.Environment]::SetEnvironmentVariable('PATH',$Env:PATH+";${env:PGBIN}")
$env:PGPASSWORD = 'root'
psql -c 'ALTER SYSTEM SET hot_standby = on;' -U postgres
psql -c 'ALTER SYSTEM SET wal_level = minimal;' -U postgres
# Optimize PostgreSQL for testing performance
psql -c "ALTER SYSTEM SET fsync = off;" -U postgres
psql -c "ALTER SYSTEM SET synchronous_commit = off;" -U postgres
psql -c "ALTER SYSTEM SET checkpoint_completion_target = 0.9;" -U postgres
psql -c "ALTER SYSTEM SET wal_buffers = '16MB';" -U postgres
psql -c "ALTER SYSTEM SET shared_buffers = '128MB';" -U postgres
psql -c 'DROP DATABASE IF EXISTS phpbb_tests;' -U postgres
psql -c 'create database phpbb_tests;' -U postgres
Set-MpPreference -ExclusionPath "${env:PGDATA}" # Exclude PGDATA directory from Windows Defender
Set-MpPreference -DisableRealtimeMonitoring $true
- name: Setup node
uses: actions/setup-node@v4
@@ -615,5 +645,11 @@ jobs:
phpBB/vendor/bin/phpunit --configuration .github/phpunit-psql-windows-github.xml --display-all-issues --stop-on-error --exclude-group functional,slow
- name: Run functional tests
if: ${{ matrix.type == 'functional' }}
timeout-minutes: 45
env:
PHPBB_FUNCTIONAL_TIMEOUT: 30
SYMFONY_DEPRECATIONS_HELPER: disabled
PHPBB_TEST_REDIS_HOST: ''
PHPBB_TEST_MEMCACHED_HOST: ''
run: |
phpBB/vendor/bin/phpunit --configuration .github/phpunit-psql-windows-github.xml --display-all-issues --stop-on-error --group functional

View File

@@ -2,9 +2,9 @@
<project name="phpBB" description="The phpBB forum software" default="all" basedir="../">
<!-- a few settings for the build -->
<property name="newversion" value="4.0.0-a1" />
<property name="newversion" value="4.0.0-a2-dev" />
<property name="prevversion" value="3.3.15" />
<property name="olderversions" value="3.1.12, 3.2.11, 3.3.14" />
<property name="olderversions" value="3.1.12, 3.2.11, 3.3.14, 4.0.0-a1" />
<!-- no configuration should be needed beyond this point -->
<property name="oldversions" value="${olderversions}, ${prevversion}" />

View File

@@ -28,7 +28,7 @@ if (!defined('IN_PHPBB'))
*/
// phpBB Version
@define('PHPBB_VERSION', '4.0.0-a1');
@define('PHPBB_VERSION', '4.0.0-a2-dev');
// QA-related
// define('PHPBB_QA', 1);

View File

@@ -1022,7 +1022,7 @@ function user_group_auth($group, $select_query, $use_src_db)
/**
* Retrieves configuration information from the source forum and caches it as an array
* Both database and file driven configuration formats can be handled
* (the type used is specified in $config_schema, see convert_phpbb20.php for more details)
* (the type used is specified in $config_schema)
*/
function get_config()
{
@@ -1110,7 +1110,7 @@ function get_config()
/**
* Transfers the relevant configuration information from the source forum
* The mapping of fields is specified in $config_schema, see convert_phpbb20.php for more details
* The mapping of fields is specified in $config_schema
*/
function restore_config($schema)
{

View File

@@ -1026,7 +1026,8 @@ function user_ipwhois($ip)
$match = array();
// Test for referrals from $whois_host to other whois databases, roll on rwhois
if (preg_match('#ReferralServer:[\x20]*whois://(.+)#im', $ipwhois, $match))
// Search for referral servers with or without the "whois://" prefix
if (preg_match('#ReferralServer:[\x20]*whois://(.+)#im', $ipwhois, $match) || preg_match('#ReferralServer:[\x20]*([^/]+)$#im', $ipwhois, $match))
{
if (strpos($match[1], ':') !== false)
{

View File

@@ -1,984 +0,0 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/
use phpbb\messenger\method\messenger_interface;
/**
* NOTE to potential convertor authors. Please use this file to get
* familiar with the structure since we added some bare explanations here.
*
* Since this file gets included more than once on one page you are not able to add functions to it.
* Instead use a functions_ file.
*
* @ignore
*/
if (!defined('IN_PHPBB'))
{
exit;
}
$phpbb_config_php_file = new \phpbb\config_php_file($phpbb_root_path, $phpEx);
extract($phpbb_config_php_file->get_all());
unset($dbpasswd);
$dbms = \phpbb\config_php_file::convert_30_dbms_to_31($dbms);
/**
* $convertor_data provides some basic information about this convertor which is
* used on the initial list of convertors and to populate the default settings
*/
$convertor_data = array(
'forum_name' => 'phpBB 2.0.x',
'version' => '1.0.3',
'phpbb_version' => '4.0.0',
'author' => '<a href="https://www.phpbb.com/">phpBB Limited</a>',
'dbms' => $dbms,
'dbhost' => $dbhost,
'dbport' => $dbport,
'dbuser' => $dbuser,
'dbpasswd' => '',
'dbname' => $dbname,
'table_prefix' => 'phpbb_',
'forum_path' => '../forums',
'author_notes' => '',
);
/**
* $tables is a list of the tables (minus prefix) which we expect to find in the
* source forum. It is used to guess the prefix if the specified prefix is incorrect
*/
$tables = array(
'auth_access',
'banlist',
'categories',
'disallow',
'forum_prune',
'forums',
'groups',
'posts',
'posts_text',
'privmsgs',
'privmsgs_text',
'ranks',
'smilies',
'topics',
'topics_watch',
'user_group',
'users',
'vote_desc',
'vote_results',
'vote_voters',
'words'
);
/**
* $config_schema details how the board configuration information is stored in the source forum.
*
* 'table_format' can take the value 'file' to indicate a config file. In this case array_name
* is set to indicate the name of the array the config values are stored in
* Example of using a file:
* $config_schema = array(
* 'table_format' => 'file',
* 'filename' => 'NAME OF FILE', // If the file is not in the root directory, the path needs to be added with no leading slash
* 'array_name' => 'NAME OF ARRAY', // Only used if the configuration file stores the setting in an array.
* 'settings' => array(
* 'board_email' => 'SUPPORT_EMAIL', // target config name => source target name
* )
* );
* 'table_format' can be an array if the values are stored in a table which is an assosciative array
* (as per phpBB 2.0.x)
* If left empty, values are assumed to be stored in a table where each config setting is
* a column (as per phpBB 1.x)
*
* In either of the latter cases 'table_name' indicates the name of the table in the database
*
* 'settings' is an array which maps the name of the config directive in the source forum
* to the config directive in phpBB. It can either be a direct mapping or use a function.
* Please note that the contents of the old config value are passed to the function, therefore
* an in-built function requiring the variable passed by reference is not able to be used. Since
* empty() is such a function we created the function is_empty() to be used instead.
*/
$config_schema = array(
'table_name' => 'config',
'table_format' => array('config_name' => 'config_value'),
'settings' => array(
'allow_bbcode' => 'allow_bbcode',
'allow_smilies' => 'allow_smilies',
'allow_sig' => 'allow_sig',
'allow_namechange' => 'allow_namechange',
'allow_avatar_local' => 'allow_avatar_local',
'allow_avatar_upload' => 'allow_avatar_upload',
'board_disable' => 'board_disable',
'sitename' => 'phpbb_set_encoding(sitename)',
'site_desc' => 'phpbb_set_encoding(site_desc)',
'session_length' => 'session_length',
'board_email_sig' => 'phpbb_set_encoding(board_email_sig)',
'posts_per_page' => 'posts_per_page',
'topics_per_page' => 'topics_per_page',
'enable_confirm' => 'enable_confirm',
'board_email_form' => 'board_email_form',
'override_user_style' => 'override_user_style',
'hot_threshold' => 'hot_threshold',
'max_poll_options' => 'max_poll_options',
'max_sig_chars' => 'max_sig_chars',
'pm_max_msgs' => 'max_inbox_privmsgs',
'smtp_delivery' => 'smtp_delivery',
'smtp_host' => 'smtp_host',
'smtp_username' => 'smtp_username',
'smtp_password' => 'smtp_password',
'require_activation' => 'require_activation',
'flood_interval' => 'flood_interval',
'avatar_filesize' => 'avatar_filesize',
'avatar_max_width' => 'avatar_max_width',
'avatar_max_height' => 'avatar_max_height',
'default_dateformat' => 'phpbb_set_encoding(default_dateformat)',
'board_timezone' => 'phpbb_convert_timezone(board_timezone)',
'allow_privmsg' => 'not(privmsg_disable)',
'gzip_compress' => 'gzip_compress',
'coppa_enable' => '!is_empty(coppa_mail)',
'coppa_fax' => 'coppa_fax',
'coppa_mail' => 'coppa_mail',
'record_online_users' => 'record_online_users',
'record_online_date' => 'record_online_date',
'board_startdate' => 'board_startdate',
)
);
/**
* $test_file is the name of a file which is present on the source
* forum which can be used to check that the path specified by the
* user was correct
*/
$test_file = 'modcp.php';
/**
* If this is set then we are not generating the first page of information but getting the conversion information.
*/
if (!$get_info)
{
// Test to see if the birthday MOD is installed on the source forum
// Niels' birthday mod
if (get_config_value('birthday_required') !== false || get_config_value('bday_require') !== false)
{
define('MOD_BIRTHDAY', true);
}
// TerraFrost's validated birthday mod
if (get_config_value('bday_require') !== false)
{
define('MOD_BIRTHDAY_TERRA', true);
}
// Test to see if the attachment MOD is installed on the source forum
// If it is, we will convert this data as well
$src_db->sql_return_on_error(true);
$sql = "SELECT config_value
FROM {$convert->src_table_prefix}attachments_config
WHERE config_name = 'upload_dir'";
$result = $src_db->sql_query($sql);
if ($result && $row = $src_db->sql_fetchrow($result))
{
// Here the constant is defined
define('MOD_ATTACHMENT', true);
// Here i add more tables to be checked in the old forum
$tables += array(
'attachments',
'attachments_desc',
'extensions',
'extension_groups'
);
$src_db->sql_freeresult($result);
}
else if ($result)
{
$src_db->sql_freeresult($result);
}
/**
* Tests for further MODs can be included here.
* Please use constants for this, prefixing them with MOD_
*/
$src_db->sql_return_on_error(false);
// Now let us set a temporary config variable for user id incrementing
$sql = "SELECT user_id
FROM {$convert->src_table_prefix}users
WHERE user_id = 1";
$result = $src_db->sql_query($sql);
$user_id = (int) $src_db->sql_fetchfield('user_id');
$src_db->sql_freeresult($result);
// If there is a user id 1, we need to increment user ids. :/
if ($user_id === 1)
{
// Try to get the maximum user id possible...
$sql = "SELECT MAX(user_id) AS max_user_id
FROM {$convert->src_table_prefix}users";
$result = $src_db->sql_query($sql);
$user_id = (int) $src_db->sql_fetchfield('max_user_id');
$src_db->sql_freeresult($result);
$config->set('increment_user_id', ($user_id + 1), false);
}
else
{
$config->set('increment_user_id', 0, false);
}
// Overwrite maximum avatar width/height
@define('DEFAULT_AVATAR_X_CUSTOM', get_config_value('avatar_max_width'));
@define('DEFAULT_AVATAR_Y_CUSTOM', get_config_value('avatar_max_height'));
// additional table used only during conversion
@define('USERCONV_TABLE', $table_prefix . 'userconv');
/**
* Description on how to use the convertor framework.
*
* 'schema' Syntax Description
* -> 'target' => Target Table. If not specified the next table will be handled
* -> 'primary' => Primary Key. If this is specified then this table is processed in batches
* -> 'query_first' => array('target' or 'src', Query to execute before beginning the process
* (if more than one then specified as array))
* -> 'function_first' => Function to execute before beginning the process (if more than one then specified as array)
* (This is mostly useful if variables need to be given to the converting process)
* -> 'test_file' => This is not used at the moment but should be filled with a file from the old installation
*
* // DB Functions
* 'distinct' => Add DISTINCT to the select query
* 'where' => Add WHERE to the select query
* 'group_by' => Add GROUP BY to the select query
* 'left_join' => Add LEFT JOIN to the select query (if more than one joins specified as array)
* 'having' => Add HAVING to the select query
*
* // DB INSERT array
* This one consist of three parameters
* First Parameter:
* The key need to be filled within the target table
* If this is empty, the target table gets not assigned the source value
* Second Parameter:
* Source value. If the first parameter is specified, it will be assigned this value.
* If the first parameter is empty, this only gets added to the select query
* Third Parameter:
* Custom Function. Function to execute while storing source value into target table.
* The functions return value get stored.
* The function parameter consist of the value of the second parameter.
*
* types:
* - empty string == execute nothing
* - string == function to execute
* - array == complex execution instructions
*
* Complex execution instructions:
* @todo test complex execution instructions - in theory they will work fine
*
* By defining an array as the third parameter you are able to define some statements to be executed. The key
* is defining what to execute, numbers can be appended...
*
* 'function' => execute function
* 'execute' => run code, whereby all occurrences of {VALUE} get replaced by the last returned value.
* The result *must* be assigned/stored to {RESULT}.
* 'typecast' => typecast value
*
* The returned variables will be made always available to the next function to continue to work with.
*
* example (variable inputted is an integer of 1):
*
* array(
* 'function1' => 'increment_by_one', // returned variable is 2
* 'typecast' => 'string', // typecast variable to be a string
* 'execute' => '{RESULT} = {VALUE} . ' is good';', // returned variable is '2 is good'
* 'function2' => 'replace_good_with_bad', // returned variable is '2 is bad'
* ),
*
*/
$convertor = array(
'test_file' => 'viewtopic.php',
'avatar_path' => get_config_value('avatar_path') . '/',
'avatar_gallery_path' => get_config_value('avatar_gallery_path') . '/',
'smilies_path' => get_config_value('smilies_path') . '/',
'upload_path' => (defined('MOD_ATTACHMENT')) ? phpbb_get_files_dir() . '/' : '',
'thumbnails' => (defined('MOD_ATTACHMENT')) ? array('thumbs/', 't_') : '',
'ranks_path' => false, // phpBB 2.0.x had no config value for a ranks path
// We empty some tables to have clean data available
'query_first' => array(
array('target', $convert->truncate_statement . SEARCH_RESULTS_TABLE),
array('target', $convert->truncate_statement . SEARCH_WORDLIST_TABLE),
array('target', $convert->truncate_statement . SEARCH_WORDMATCH_TABLE),
array('target', $convert->truncate_statement . LOG_TABLE),
),
// with this you are able to import all attachment files on the fly. For large boards this is not an option, therefore commented out by default.
// Instead every file gets copied while processing the corresponding attachment entry.
// if (defined("MOD_ATTACHMENT")) { import_attachment_files(); phpbb_copy_thumbnails(); }
// phpBB2 allowed some similar usernames to coexist which would have the same
// username_clean in phpBB which is not possible, so we'll give the admin a list
// of user ids and usernames and let him deicde what he wants to do with them
'execute_first' => '
phpbb_create_userconv_table();
import_avatar_gallery();
if (defined("MOD_ATTACHMENT")) phpbb_import_attach_config();
phpbb_insert_forums();
',
'execute_last' => array('
add_bots();
', '
update_folder_pm_count();
', '
update_unread_count();
', (defined('MOD_ATTACHMENT')) ? '
phpbb_attachment_extension_group_name();
' : '
', '
phpbb_convert_authentication(\'start\');
', '
phpbb_convert_authentication(\'first\');
', '
phpbb_convert_authentication(\'second\');
', '
phpbb_convert_authentication(\'third\');
'),
'schema' => array(
array(
'target' => USERCONV_TABLE,
'query_first' => array('target', $convert->truncate_statement . USERCONV_TABLE),
array('user_id', 'users.user_id', ''),
array('username_clean', 'users.username', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_clean_string')),
),
array(
'target' => (defined('MOD_ATTACHMENT')) ? ATTACHMENTS_TABLE : '',
'primary' => 'attachments.attach_id',
'query_first' => (defined('MOD_ATTACHMENT')) ? array('target', $convert->truncate_statement . ATTACHMENTS_TABLE) : '',
'autoincrement' => 'attach_id',
array('attach_id', 'attachments.attach_id', ''),
array('post_msg_id', 'attachments.post_id', ''),
array('topic_id', 'posts.topic_id', ''),
array('in_message', 0, ''),
array('is_orphan', 0, ''),
array('poster_id', 'attachments.user_id_1 AS poster_id', 'phpbb_user_id'),
array('physical_filename', 'attachments_desc.physical_filename', 'import_attachment'),
array('real_filename', 'attachments_desc.real_filename', 'phpbb_set_encoding'),
array('download_count', 'attachments_desc.download_count', ''),
array('attach_comment', 'attachments_desc.comment', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')),
array('extension', 'attachments_desc.extension', ''),
array('mimetype', 'attachments_desc.mimetype', ''),
array('filesize', 'attachments_desc.filesize', ''),
array('filetime', 'attachments_desc.filetime', ''),
array('thumbnail', 'attachments_desc.thumbnail', ''),
'where' => 'attachments_desc.attach_id = attachments.attach_id AND attachments.privmsgs_id = 0 AND posts.post_id = attachments.post_id',
'group_by' => 'attachments.attach_id'
),
array(
'target' => (defined('MOD_ATTACHMENT')) ? ATTACHMENTS_TABLE : '',
'primary' => 'attachments.attach_id',
'autoincrement' => 'attach_id',
array('attach_id', 'attachments.attach_id', ''),
array('post_msg_id', 'attachments.privmsgs_id', ''),
array('topic_id', 0, ''),
array('in_message', 1, ''),
array('is_orphan', 0, ''),
array('poster_id', 'attachments.user_id_1 AS poster_id', 'phpbb_user_id'),
array('physical_filename', 'attachments_desc.physical_filename', 'import_attachment'),
array('real_filename', 'attachments_desc.real_filename', 'phpbb_set_encoding'),
array('download_count', 'attachments_desc.download_count', ''),
array('attach_comment', 'attachments_desc.comment', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')),
array('extension', 'attachments_desc.extension', ''),
array('mimetype', 'attachments_desc.mimetype', ''),
array('filesize', 'attachments_desc.filesize', ''),
array('filetime', 'attachments_desc.filetime', ''),
array('thumbnail', 'attachments_desc.thumbnail', ''),
'where' => 'attachments_desc.attach_id = attachments.attach_id AND attachments.post_id = 0',
'group_by' => 'attachments.attach_id'
),
array(
'target' => (defined('MOD_ATTACHMENT')) ? EXTENSIONS_TABLE : '',
'query_first' => (defined('MOD_ATTACHMENT')) ? array('target', $convert->truncate_statement . EXTENSIONS_TABLE) : '',
'autoincrement' => 'extension_id',
array('extension_id', 'extensions.ext_id', ''),
array('group_id', 'extensions.group_id', ''),
array('extension', 'extensions.extension', ''),
),
array(
'target' => (defined('MOD_ATTACHMENT')) ? EXTENSION_GROUPS_TABLE : '',
'query_first' => (defined('MOD_ATTACHMENT')) ? array('target', $convert->truncate_statement . EXTENSION_GROUPS_TABLE) : '',
'autoincrement' => 'group_id',
array('group_id', 'extension_groups.group_id', ''),
array('group_name', 'extension_groups.group_name', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')),
array('cat_id', 'extension_groups.cat_id', 'phpbb_attachment_category'),
array('allow_group', 'extension_groups.allow_group', ''),
array('upload_icon', '', ''),
array('max_filesize', 'extension_groups.max_filesize', ''),
array('allowed_forums', 'extension_groups.forum_permissions', 'phpbb_attachment_forum_perms'),
array('allow_in_pm', 1, ''),
),
array(
'target' => BANS_TABLE,
'execute_first' => 'phpbb_check_username_collisions();',
'query_first' => array('target', $convert->truncate_statement . BANS_TABLE),
array('ban_mode', 'user', ''),
array('ban_item', 'banlist.ban_userid', 'phpbb_user_id'),
array('ban_userid', 'banlist.ban_userid', 'phpbb_user_id'),
array('ban_reason', '', ''),
array('ban_reason_display', '', ''),
'where' => "banlist.ban_ip NOT LIKE '%.%'
AND banlist.ban_userid <> 0",
),
array(
'target' => BANS_TABLE,
array('ban_mode', 'email', ''),
array('ban_item', 'banlist.ban_email', ''),
array('ban_reason', '', ''),
array('ban_reason_display', '', ''),
'where' => "banlist.ban_ip NOT LIKE '%.%'
AND banlist.ban_email <> ''",
),
array(
'target' => BANS_TABLE,
array('ban_mode', 'ip', ''),
array('ban_item', 'banlist.ban_ip', 'decode_ban_ip'),
array('ban_reason', '', ''),
array('ban_reason_display', '', ''),
'where' => "banlist.ban_userid = 0
AND banlist.ban_ip <> ''",
),
array(
'target' => DISALLOW_TABLE,
'query_first' => array('target', $convert->truncate_statement . DISALLOW_TABLE),
array('disallow_username', 'disallow.disallow_username', 'phpbb_disallowed_username'),
),
array(
'target' => RANKS_TABLE,
'query_first' => array('target', $convert->truncate_statement . RANKS_TABLE),
'autoincrement' => 'rank_id',
array('rank_id', 'ranks.rank_id', ''),
array('rank_title', 'ranks.rank_title', array('function1' => 'phpbb_set_default_encoding', 'function2' => 'utf8_htmlspecialchars')),
array('rank_min', 'ranks.rank_min', array('typecast' => 'int', 'execute' => '{RESULT} = ({VALUE}[0] < 0) ? 0 : {VALUE}[0];')),
array('rank_special', 'ranks.rank_special', ''),
array('rank_image', 'ranks.rank_image', 'import_rank'),
),
array(
'target' => TOPICS_TABLE,
'query_first' => array('target', $convert->truncate_statement . TOPICS_TABLE),
'primary' => 'topics.topic_id',
'autoincrement' => 'topic_id',
array('topic_id', 'topics.topic_id', ''),
array('forum_id', 'topics.forum_id', ''),
array('icon_id', 0, ''),
array('topic_poster', 'topics.topic_poster AS poster_id', 'phpbb_user_id'),
array('topic_attachment', ((defined('MOD_ATTACHMENT')) ? 'topics.topic_attachment' : 0), ''),
array('topic_title', 'topics.topic_title', 'phpbb_set_encoding'),
array('topic_time', 'topics.topic_time', ''),
array('topic_views', 'topics.topic_views', ''),
array('topic_posts_approved', 'topics.topic_replies', 'phpbb_topic_replies_to_posts'),
array('topic_posts_unapproved', 0, ''),
array('topic_posts_softdeleted',0, ''),
array('topic_last_post_id', 'topics.topic_last_post_id', ''),
array('topic_status', 'topics.topic_status', 'is_topic_locked'),
array('topic_moved_id', 0, ''),
array('topic_type', 'topics.topic_type', 'phpbb_convert_topic_type'),
array('topic_first_post_id', 'topics.topic_first_post_id', ''),
array('topic_last_view_time', 'posts.post_time', 'intval'),
array('topic_visibility', ITEM_APPROVED, ''),
array('poll_title', 'vote_desc.vote_text', array('function1' => 'null_to_str', 'function2' => 'phpbb_set_encoding', 'function3' => 'htmlspecialchars_decode', 'function4' => 'utf8_htmlspecialchars')),
array('poll_start', 'vote_desc.vote_start', 'null_to_zero'),
array('poll_length', 'vote_desc.vote_length', 'null_to_zero'),
array('poll_max_options', 1, ''),
array('poll_vote_change', 0, ''),
'left_join' => array ( 'topics LEFT JOIN vote_desc ON topics.topic_id = vote_desc.topic_id AND topics.topic_vote = 1',
'topics LEFT JOIN posts ON topics.topic_last_post_id = posts.post_id',
),
'where' => 'topics.topic_moved_id = 0',
),
array(
'target' => TOPICS_TABLE,
'primary' => 'topics.topic_id',
'autoincrement' => 'topic_id',
array('topic_id', 'topics.topic_id', ''),
array('forum_id', 'topics.forum_id', ''),
array('icon_id', 0, ''),
array('topic_poster', 'topics.topic_poster AS poster_id', 'phpbb_user_id'),
array('topic_attachment', ((defined('MOD_ATTACHMENT')) ? 'topics.topic_attachment' : 0), ''),
array('topic_title', 'topics.topic_title', 'phpbb_set_encoding'),
array('topic_time', 'topics.topic_time', ''),
array('topic_views', 'topics.topic_views', ''),
array('topic_posts_approved', 'topics.topic_replies', 'phpbb_topic_replies_to_posts'),
array('topic_posts_unapproved', 0, ''),
array('topic_posts_softdeleted',0, ''),
array('topic_last_post_id', 'topics.topic_last_post_id', ''),
array('topic_status', ITEM_MOVED, ''),
array('topic_moved_id', 'topics.topic_moved_id', ''),
array('topic_type', 'topics.topic_type', 'phpbb_convert_topic_type'),
array('topic_first_post_id', 'topics.topic_first_post_id', ''),
array('topic_visibility', ITEM_APPROVED, ''),
array('poll_title', 'vote_desc.vote_text', array('function1' => 'null_to_str', 'function2' => 'phpbb_set_encoding', 'function3' => 'htmlspecialchars_decode', 'function4' => 'utf8_htmlspecialchars')),
array('poll_start', 'vote_desc.vote_start', 'null_to_zero'),
array('poll_length', 'vote_desc.vote_length', 'null_to_zero'),
array('poll_max_options', 1, ''),
array('poll_vote_change', 0, ''),
'left_join' => 'topics LEFT JOIN vote_desc ON topics.topic_id = vote_desc.topic_id AND topics.topic_vote = 1',
'where' => 'topics.topic_moved_id <> 0',
),
array(
'target' => TOPICS_WATCH_TABLE,
'primary' => 'topics_watch.topic_id',
'query_first' => array('target', $convert->truncate_statement . TOPICS_WATCH_TABLE),
array('topic_id', 'topics_watch.topic_id', ''),
array('user_id', 'topics_watch.user_id', 'phpbb_user_id'),
array('notify_status', 'topics_watch.notify_status', ''),
),
array(
'target' => SMILIES_TABLE,
'query_first' => array('target', $convert->truncate_statement . SMILIES_TABLE),
'autoincrement' => 'smiley_id',
array('smiley_id', 'smilies.smilies_id', ''),
array('code', 'smilies.code', array('function1' => 'phpbb_smilie_html_decode', 'function2' => 'phpbb_set_encoding', 'function3' => 'utf8_htmlspecialchars')),
array('emotion', 'smilies.emoticon', 'phpbb_set_encoding'),
array('smiley_url', 'smilies.smile_url', 'import_smiley'),
array('smiley_width', 'smilies.smile_url', 'get_smiley_width'),
array('smiley_height', 'smilies.smile_url', 'get_smiley_height'),
array('smiley_order', 'smilies.smilies_id', ''),
array('display_on_posting', 'smilies.smilies_id', 'get_smiley_display'),
'order_by' => 'smilies.smilies_id ASC',
),
array(
'target' => POLL_OPTIONS_TABLE,
'primary' => 'vote_results.vote_option_id',
'query_first' => array('target', $convert->truncate_statement . POLL_OPTIONS_TABLE),
array('poll_option_id', 'vote_results.vote_option_id', ''),
array('topic_id', 'vote_desc.topic_id', ''),
array('', 'topics.topic_poster AS poster_id', 'phpbb_user_id'),
array('poll_option_text', 'vote_results.vote_option_text', array('function1' => 'phpbb_set_encoding', 'function2' => 'htmlspecialchars_decode', 'function3' => 'utf8_htmlspecialchars')),
array('poll_option_total', 'vote_results.vote_result', ''),
'where' => 'vote_results.vote_id = vote_desc.vote_id',
'left_join' => 'vote_desc LEFT JOIN topics ON topics.topic_id = vote_desc.topic_id',
),
array(
'target' => POLL_VOTES_TABLE,
'primary' => 'vote_desc.topic_id',
'query_first' => array('target', $convert->truncate_statement . POLL_VOTES_TABLE),
array('poll_option_id', VOTE_CONVERTED, ''),
array('topic_id', 'vote_desc.topic_id', ''),
array('vote_user_id', 'vote_voters.vote_user_id', 'phpbb_user_id'),
array('vote_user_ip', 'vote_voters.vote_user_ip', 'decode_ip'),
'where' => 'vote_voters.vote_id = vote_desc.vote_id',
),
array(
'target' => WORDS_TABLE,
'primary' => 'words.word_id',
'query_first' => array('target', $convert->truncate_statement . WORDS_TABLE),
'autoincrement' => 'word_id',
array('word_id', 'words.word_id', ''),
array('word', 'words.word', 'phpbb_set_encoding'),
array('replacement', 'words.replacement', 'phpbb_set_encoding'),
),
array(
'target' => POSTS_TABLE,
'primary' => 'posts.post_id',
'autoincrement' => 'post_id',
'query_first' => array('target', $convert->truncate_statement . POSTS_TABLE),
'execute_first' => '
$config["max_post_chars"] = 0;
$config["min_post_chars"] = 0;
$config["max_quote_depth"] = 0;
',
array('post_id', 'posts.post_id', ''),
array('topic_id', 'posts.topic_id', ''),
array('forum_id', 'posts.forum_id', ''),
array('poster_id', 'posts.poster_id', 'phpbb_user_id'),
array('icon_id', 0, ''),
array('poster_ip', 'posts.poster_ip', 'decode_ip'),
array('post_time', 'posts.post_time', ''),
array('enable_bbcode', 'posts.enable_bbcode', ''),
array('', 'posts.enable_html', ''),
array('enable_smilies', 'posts.enable_smilies', ''),
array('enable_sig', 'posts.enable_sig', ''),
array('enable_magic_url', 1, ''),
array('post_username', 'posts.post_username', 'phpbb_set_encoding'),
array('post_subject', 'posts_text.post_subject', 'phpbb_set_encoding'),
array('post_attachment', ((defined('MOD_ATTACHMENT')) ? 'posts.post_attachment' : 0), ''),
array('post_edit_time', 'posts.post_edit_time', array('typecast' => 'int')),
array('post_edit_count', 'posts.post_edit_count', ''),
array('post_edit_reason', '', ''),
array('post_edit_user', '', 'phpbb_post_edit_user'),
array('post_visibility', ITEM_APPROVED, ''),
array('bbcode_uid', 'posts.post_time', 'make_uid'),
array('post_text', 'posts_text.post_text', 'phpbb_prepare_message'),
array('', 'posts_text.bbcode_uid AS old_bbcode_uid', ''),
array('bbcode_bitfield', '', 'get_bbcode_bitfield'),
array('post_checksum', '', ''),
// Commented out inline search indexing, this takes up a LOT of time. :D
// @todo We either need to enable this or call the rebuild search functionality post convert
/* array('', '', 'search_indexing'),
array('', 'posts_text.post_text AS message', ''),
array('', 'posts_text.post_subject AS title', ''),*/
'where' => 'posts.post_id = posts_text.post_id'
),
array(
'target' => PRIVMSGS_TABLE,
'primary' => 'privmsgs.privmsgs_id',
'autoincrement' => 'msg_id',
'query_first' => array(
array('target', $convert->truncate_statement . PRIVMSGS_TABLE),
array('target', $convert->truncate_statement . PRIVMSGS_RULES_TABLE),
),
'execute_first' => '
$config["max_post_chars"] = 0;
$config["min_post_chars"] = 0;
$config["max_quote_depth"] = 0;
',
array('msg_id', 'privmsgs.privmsgs_id', ''),
array('root_level', 0, ''),
array('author_id', 'privmsgs.privmsgs_from_userid AS poster_id', 'phpbb_user_id'),
array('icon_id', 0, ''),
array('author_ip', 'privmsgs.privmsgs_ip', 'decode_ip'),
array('message_time', 'privmsgs.privmsgs_date', ''),
array('enable_bbcode', 'privmsgs.privmsgs_enable_bbcode AS enable_bbcode', ''),
array('', 'privmsgs.privmsgs_enable_html AS enable_html', ''),
array('enable_smilies', 'privmsgs.privmsgs_enable_smilies AS enable_smilies', ''),
array('enable_magic_url', 1, ''),
array('enable_sig', 'privmsgs.privmsgs_attach_sig', ''),
array('message_subject', 'privmsgs.privmsgs_subject', 'phpbb_set_encoding'), // Already specialchared in 2.0.x
array('message_attachment', ((defined('MOD_ATTACHMENT')) ? 'privmsgs.privmsgs_attachment' : 0), ''),
array('message_edit_reason', '', ''),
array('message_edit_user', 0, ''),
array('message_edit_time', 0, ''),
array('message_edit_count', 0, ''),
array('bbcode_uid', 'privmsgs.privmsgs_date AS post_time', 'make_uid'),
array('message_text', 'privmsgs_text.privmsgs_text', 'phpbb_prepare_message'),
array('', 'privmsgs_text.privmsgs_bbcode_uid AS old_bbcode_uid', ''),
array('bbcode_bitfield', '', 'get_bbcode_bitfield'),
array('to_address', 'privmsgs.privmsgs_to_userid', 'phpbb_privmsgs_to_userid'),
array('bcc_address', '', ''),
'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id'
),
array(
'target' => PRIVMSGS_FOLDER_TABLE,
'primary' => 'users.user_id',
'query_first' => array('target', $convert->truncate_statement . PRIVMSGS_FOLDER_TABLE),
array('user_id', 'users.user_id', 'phpbb_user_id'),
array('folder_name', $user->lang['CONV_SAVED_MESSAGES'], ''),
array('pm_count', 0, ''),
'where' => 'users.user_id <> -1',
),
// Inbox
array(
'target' => PRIVMSGS_TO_TABLE,
'primary' => 'privmsgs.privmsgs_id',
'query_first' => array('target', $convert->truncate_statement . PRIVMSGS_TO_TABLE),
array('msg_id', 'privmsgs.privmsgs_id', ''),
array('user_id', 'privmsgs.privmsgs_to_userid', 'phpbb_user_id'),
array('author_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'),
array('pm_deleted', 0, ''),
array('pm_new', 'privmsgs.privmsgs_type', 'phpbb_new_pm'),
array('pm_unread', 'privmsgs.privmsgs_type', 'phpbb_unread_pm'),
array('pm_replied', 0, ''),
array('pm_marked', 0, ''),
array('pm_forwarded', 0, ''),
array('folder_id', PRIVMSGS_INBOX, ''),
'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id
AND (privmsgs.privmsgs_type = 0 OR privmsgs.privmsgs_type = 1 OR privmsgs.privmsgs_type = 5)',
),
// Outbox
array(
'target' => PRIVMSGS_TO_TABLE,
'primary' => 'privmsgs.privmsgs_id',
array('msg_id', 'privmsgs.privmsgs_id', ''),
array('user_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'),
array('author_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'),
array('pm_deleted', 0, ''),
array('pm_new', 0, ''),
array('pm_unread', 0, ''),
array('pm_replied', 0, ''),
array('pm_marked', 0, ''),
array('pm_forwarded', 0, ''),
array('folder_id', PRIVMSGS_OUTBOX, ''),
'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id
AND (privmsgs.privmsgs_type = 1 OR privmsgs.privmsgs_type = 5)',
),
// Sentbox
array(
'target' => PRIVMSGS_TO_TABLE,
'primary' => 'privmsgs.privmsgs_id',
array('msg_id', 'privmsgs.privmsgs_id', ''),
array('user_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'),
array('author_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'),
array('pm_deleted', 0, ''),
array('pm_new', 'privmsgs.privmsgs_type', 'phpbb_new_pm'),
array('pm_unread', 'privmsgs.privmsgs_type', 'phpbb_unread_pm'),
array('pm_replied', 0, ''),
array('pm_marked', 0, ''),
array('pm_forwarded', 0, ''),
array('folder_id', PRIVMSGS_SENTBOX, ''),
'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id
AND privmsgs.privmsgs_type = 2',
),
// Savebox (SAVED IN)
array(
'target' => PRIVMSGS_TO_TABLE,
'primary' => 'privmsgs.privmsgs_id',
array('msg_id', 'privmsgs.privmsgs_id', ''),
array('user_id', 'privmsgs.privmsgs_to_userid', 'phpbb_user_id'),
array('author_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'),
array('pm_deleted', 0, ''),
array('pm_new', 'privmsgs.privmsgs_type', 'phpbb_new_pm'),
array('pm_unread', 'privmsgs.privmsgs_type', 'phpbb_unread_pm'),
array('pm_replied', 0, ''),
array('pm_marked', 0, ''),
array('pm_forwarded', 0, ''),
array('folder_id', 'privmsgs.privmsgs_to_userid', 'phpbb_get_savebox_id'),
'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id
AND privmsgs.privmsgs_type = 3',
),
// Savebox (SAVED OUT)
array(
'target' => PRIVMSGS_TO_TABLE,
'primary' => 'privmsgs.privmsgs_id',
array('msg_id', 'privmsgs.privmsgs_id', ''),
array('user_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'),
array('author_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'),
array('pm_deleted', 0, ''),
array('pm_new', 'privmsgs.privmsgs_type', 'phpbb_new_pm'),
array('pm_unread', 'privmsgs.privmsgs_type', 'phpbb_unread_pm'),
array('pm_replied', 0, ''),
array('pm_marked', 0, ''),
array('pm_forwarded', 0, ''),
array('folder_id', 'privmsgs.privmsgs_from_userid', 'phpbb_get_savebox_id'),
'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id
AND privmsgs.privmsgs_type = 4',
),
array(
'target' => GROUPS_TABLE,
'autoincrement' => 'group_id',
'query_first' => array(
array('target', $convert->truncate_statement . GROUPS_TABLE),
array('target', $convert->truncate_statement . TEAMPAGE_TABLE),
),
array('group_id', 'groups.group_id', ''),
array('group_type', 'groups.group_type', 'phpbb_convert_group_type'),
array('group_display', 0, ''),
array('group_legend', 0, ''),
array('group_name', 'groups.group_name', 'phpbb_convert_group_name'), // phpbb_set_encoding called in phpbb_convert_group_name
array('group_desc', 'groups.group_description', 'phpbb_set_encoding'),
'where' => 'groups.group_single_user = 0',
),
array(
'target' => USER_GROUP_TABLE,
'query_first' => array('target', $convert->truncate_statement . USER_GROUP_TABLE),
'execute_first' => '
add_default_groups();
add_groups_to_teampage();
',
array('group_id', 'groups.group_id', ''),
array('user_id', 'groups.group_moderator', 'phpbb_user_id'),
array('group_leader', 1, ''),
array('user_pending', 0, ''),
'where' => 'groups.group_single_user = 0 AND groups.group_moderator <> 0',
),
array(
'target' => USER_GROUP_TABLE,
array('group_id', 'user_group.group_id', ''),
array('user_id', 'user_group.user_id', 'phpbb_user_id'),
array('group_leader', 0, ''),
array('user_pending', 'user_group.user_pending', ''),
'where' => 'user_group.group_id = groups.group_id AND groups.group_single_user = 0 AND groups.group_moderator <> user_group.user_id',
),
array(
'target' => USERS_TABLE,
'primary' => 'users.user_id',
'autoincrement' => 'user_id',
'query_first' => array(
array('target', 'DELETE FROM ' . USERS_TABLE . ' WHERE user_id <> ' . ANONYMOUS),
array('target', $convert->truncate_statement . BOTS_TABLE),
array('target', $convert->truncate_statement . USER_NOTIFICATIONS_TABLE),
),
'execute_last' => '
remove_invalid_users();
',
array('user_id', 'users.user_id', 'phpbb_user_id'),
array('', 'users.user_id AS poster_id', 'phpbb_user_id'),
array('user_type', 'users.user_active', 'set_user_type'),
array('group_id', 'users.user_level', 'phpbb_set_primary_group'),
array('user_regdate', 'users.user_regdate', ''),
array('username', 'users.username', 'phpbb_set_default_encoding'), // recode to utf8 with default lang
array('username_clean', 'users.username', array('function1' => 'phpbb_set_default_encoding', 'function2' => 'utf8_clean_string')),
array('user_password', 'users.user_password', 'phpbb_convert_password_hash'),
array('user_posts', 'users.user_posts', 'intval'),
array('user_email', 'users.user_email', 'strtolower'),
array('user_birthday', ((defined('MOD_BIRTHDAY')) ? 'users.user_birthday' : ''), 'phpbb_get_birthday'),
array('user_lastvisit', 'users.user_lastvisit', 'intval'),
array('user_last_active', 'users.user_lastvisit', 'intval'),
array('user_lastmark', 'users.user_lastvisit', 'intval'),
array('user_lang', $config['default_lang'], ''),
array('', 'users.user_lang', ''),
array('user_timezone', 'users.user_timezone', 'phpbb_convert_timezone'),
array('user_dateformat', 'users.user_dateformat', array('function1' => 'phpbb_set_encoding', 'function2' => 'fill_dateformat')),
array('user_inactive_reason', '', 'phpbb_inactive_reason'),
array('user_inactive_time', '', 'phpbb_inactive_time'),
array('user_rank', 'users.user_rank', 'intval'),
array('user_permissions', '', ''),
array('user_avatar', 'users.user_avatar', 'phpbb_import_avatar'),
array('user_avatar_type', 'users.user_avatar_type', 'phpbb_avatar_type'),
array('user_avatar_width', 'users.user_avatar', 'phpbb_get_avatar_width'),
array('user_avatar_height', 'users.user_avatar', 'phpbb_get_avatar_height'),
array('user_new_privmsg', 'users.user_new_privmsg', ''),
array('user_unread_privmsg', 0, ''), //'users.user_unread_privmsg'
array('user_last_privmsg', 'users.user_last_privmsg', 'intval'),
array('user_emailtime', 'users.user_emailtime', 'null_to_zero'),
array('user_notify', 'users.user_notify', 'intval'),
array('user_notify_pm', 'users.user_notify_pm', 'intval'),
array('user_allow_pm', 'users.user_allow_pm', 'intval'),
array('user_allow_viewonline', 'users.user_allow_viewonline', 'intval'),
array('user_allow_viewemail', 'users.user_viewemail', 'intval'),
array('user_actkey', 'users.user_actkey', ''),
array('user_newpasswd', '', ''), // Users need to re-request their password...
array('user_style', $config['default_style'], ''),
array('user_options', '', 'set_user_options'),
array('', 'users.user_popup_pm AS popuppm', ''),
array('', 'users.user_allowhtml AS html', ''),
array('', 'users.user_allowbbcode AS bbcode', ''),
array('', 'users.user_allowsmile AS smile', ''),
array('', 'users.user_attachsig AS attachsig',''),
array('user_sig_bbcode_uid', 'users.user_regdate', 'make_uid'),
array('user_sig', 'users.user_sig', 'phpbb_prepare_message'),
array('', 'users.user_sig_bbcode_uid AS old_bbcode_uid', ''),
array('user_sig_bbcode_bitfield', '', 'get_bbcode_bitfield'),
array('', 'users.user_regdate AS post_time', ''),
array('', 'users.user_notify_pm', 'phpbb_add_notification_options'),
'where' => 'users.user_id <> -1',
),
array(
'target' => PROFILE_FIELDS_DATA_TABLE,
'primary' => 'users.user_id',
'query_first' => array(
array('target', $convert->truncate_statement . PROFILE_FIELDS_DATA_TABLE),
),
array('user_id', 'users.user_id', 'phpbb_user_id'),
array('pf_phpbb_occupation', 'users.user_occ', array('function1' => 'phpbb_set_encoding')),
array('pf_phpbb_interests', 'users.user_interests', array('function1' => 'phpbb_set_encoding')),
array('pf_phpbb_location', 'users.user_from', array('function1' => 'phpbb_set_encoding')),
array('pf_phpbb_icq', 'users.user_icq', array('function1' => 'phpbb_set_encoding')),
array('pf_phpbb_yahoo', 'users.user_yim', array('function1' => 'phpbb_set_encoding')),
array('pf_phpbb_website', 'users.user_website', 'validate_website'),
'where' => 'users.user_id <> -1',
),
),
);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
</body>
</html>

View File

@@ -299,7 +299,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('update_hashes_last
INSERT INTO phpbb_config (config_name, config_value) VALUES ('update_hashes_lock', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('use_system_cron', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '4.0.0-a1');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '4.0.0-a2-dev');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_repositories', '[]');

View File

@@ -390,22 +390,22 @@ class installer
}
}
foreach ($compatible_packages as $name => $versions)
foreach ($compatible_packages as $package_name => $package_versions)
{
// Determine the highest version of the package
/** @var CompletePackage|CompleteAliasPackage $highest_version */
$highest_version = null;
// Sort the versions array in descending order
usort($versions, function ($a, $b)
usort($package_versions, function ($a, $b)
{
return version_compare($b->getVersion(), $a->getVersion());
});
// The first element in the sorted array is the highest version
if (!empty($versions))
if (!empty($package_versions))
{
$highest_version = $versions[0];
$highest_version = $package_versions[0];
// If highest version is a non-numeric dev branch, it's an instance of CompleteAliasPackage,
// so we need to get the package being aliased in order to show the true non-numeric version.
@@ -416,23 +416,23 @@ class installer
}
// Generates the entry
$available[$name] = [];
$available[$name]['name'] = $highest_version->getPrettyName();
$available[$name]['display_name'] = $highest_version->getExtra()['display-name'];
$available[$name]['composer_name'] = $highest_version->getName();
$available[$name]['version'] = $highest_version->getPrettyVersion();
$available[$package_name] = [];
$available[$package_name]['name'] = $highest_version->getPrettyName();
$available[$package_name]['display_name'] = $highest_version->getExtra()['display-name'];
$available[$package_name]['composer_name'] = $highest_version->getName();
$available[$package_name]['version'] = $highest_version->getPrettyVersion();
if ($highest_version instanceof CompletePackage)
{
$available[$name]['description'] = $highest_version->getDescription();
$available[$name]['url'] = $highest_version->getHomepage();
$available[$name]['authors'] = $highest_version->getAuthors();
$available[$package_name]['description'] = $highest_version->getDescription();
$available[$package_name]['url'] = $highest_version->getHomepage();
$available[$package_name]['authors'] = $highest_version->getAuthors();
}
else
{
$available[$name]['description'] = '';
$available[$name]['url'] = '';
$available[$name]['authors'] = [];
$available[$package_name]['description'] = '';
$available[$package_name]['url'] = '';
$available[$package_name]['authors'] = [];
}
}
@@ -545,8 +545,6 @@ class installer
*/
protected function generate_ext_json_file(array $packages)
{
$io = new NullIO();
$composer = $this->get_composer(null);
$core_packages = $this->get_core_packages($composer);
@@ -587,8 +585,148 @@ class installer
$lockFile->write([]);
}
// First pass write: base file with requested packages as provided
$json_file->write($ext_json_data);
$this->ext_json_file_backup = $ext_json_file_backup;
// Second pass: resolve and pin the highest compatible versions for unconstrained requested packages
try
{
// Build a list of requested packages without explicit constraints
$unconstrained = [];
foreach ($packages as $name => $constraint)
{
// The $packages array can be either ['vendor/package' => '^1.2'] or ['vendor/package'] (numeric keys).
if (is_int($name))
{
// Numeric key means just a name
$package_name = $constraint;
$unconstrained[$package_name] = true;
}
else
{
// If constraint is empty or '*' treat as unconstrained
if ($constraint === '' || $constraint === '*' || $constraint === null)
{
$unconstrained[$name] = true;
}
}
}
if (!empty($unconstrained))
{
// Load composer on the just-written file so repositories and core constraints are available
$ext_composer = $this->get_composer($this->get_composer_ext_json_filename());
/** @var ConstraintInterface $core_constraint */
$core_constraint = $ext_composer->getPackage()->getRequires()['phpbb/phpbb']->getConstraint();
$core_stability = $ext_composer->getPackage()->getMinimumStability();
// Resolve highest compatible versions for each unconstrained package
$pins = $this->resolve_highest_versions(array_keys($unconstrained), $ext_composer, $core_constraint, $core_stability);
if (!empty($pins))
{
// Merge pins into require section, overwriting unconstrained entries
foreach ($pins as $pkg => $version)
{
$ext_json_data['require'][$pkg] = $version;
}
// Rewrite composer-ext.json with pinned versions
$json_file->write($ext_json_data);
}
}
}
catch (\Exception $e)
{
// If resolution fails for any reason, keep the first-pass file intact (Composer will still resolve).
// Intentionally swallow to avoid breaking installation flow.
}
}
/**
* Resolve the highest compatible versions for the given package names
* based on repositories and phpBB/PHP constraints from the provided Composer instance.
*
* @param array $package_names list of package names to resolve
* @param Composer|PartialComposer $composer Composer instance configured with repositories
* @param ConstraintInterface $core_constraint phpBB version constraint
* @param string $core_stability minimum stability
* @return array [packageName => prettyVersion]
*/
protected function resolve_highest_versions(array $package_names, $composer, ConstraintInterface $core_constraint, $core_stability): array
{
$compatible_packages = [];
$repositories = $composer->getRepositoryManager()->getRepositories();
foreach ($repositories as $repository)
{
try
{
if ($repository instanceof ComposerRepository)
{
foreach ($package_names as $name)
{
$versions = $repository->findPackages($name);
if (!empty($versions))
{
$compatible_packages = $this->get_compatible_versions($compatible_packages, $core_constraint, $core_stability, $name, $versions);
}
}
}
else
{
// Preload and filter by name for non-composer repositories
$package_name = [];
foreach ($repository->getPackages() as $package)
{
$name = $package->getName();
if (in_array($name, $package_names, true))
{
$package_name[$name][] = $package;
}
}
foreach ($package_name as $name => $versions)
{
$compatible_packages = $this->get_compatible_versions($compatible_packages, $core_constraint, $core_stability, $name, $versions);
}
}
}
catch (\Exception $e)
{
// If a repo fails, just skip it.
continue;
}
}
$pins = [];
foreach ($package_names as $name)
{
if (empty($compatible_packages[$name]))
{
continue;
}
$package_versions = $compatible_packages[$name];
// Sort descending by normalized version
usort($package_versions, function ($a, $b) {
return version_compare($b->getVersion(), $a->getVersion());
});
$highest = $package_versions[0];
if ($highest instanceof CompleteAliasPackage)
{
$highest = $highest->getAliasOf();
}
// Pin to the resolved highest compatible version using its pretty version
$pins[$name] = $highest->getPrettyVersion();
}
return $pins;
}
/**

View File

@@ -33,8 +33,10 @@ class phpbb_functions_user_whois_test extends phpbb_test_case
public static function ips_data()
{
return [
['2001:4860:4860::8888'], // Google public DNS
['64.233.161.139'], // google.com
['2001:4860:4860::8888'], // Google public DNS (ARIN)
['64.233.161.139'], // google.com (ARIN)
['1.1.1.1'], // Cloudflare (APNIC via whois:// referral)
['213.133.116.44'], // Hetzner (RIPE via non-whois:// referral)
];
}
@@ -47,5 +49,6 @@ class phpbb_functions_user_whois_test extends phpbb_test_case
$this->assertStringNotContainsString('Query terms are ambiguous', $ip_whois);
$this->assertStringNotContainsString('no entries found', $ip_whois);
$this->assertStringNotContainsString('ERROR', $ip_whois);
$this->assertStringNotContainsString('Allocated to RIPE NCC', $ip_whois); // This only shows if the referral isn't found
}
}

View File

@@ -129,11 +129,17 @@ class phpbb_functional_test_case extends phpbb_test_case
$this->bootstrap();
self::$cookieJar = new CookieJar;
// Force native client on windows platform
self::$http_client = strtolower(substr(PHP_OS, 0, 3)) === 'win' ? new NativeHttpClient() : HttpClient::create();
self::$http_client->withOptions([
// Optimize HTTP client for Windows platform
if (strtolower(substr(PHP_OS, 0, 3)) === 'win') {
self::$http_client = new NativeHttpClient([
'timeout' => 30,
'max_duration' => 60,
]);
} else {
self::$http_client = HttpClient::create([
'timeout' => 60,
]);
}
self::$client = new HttpBrowser(self::$http_client, null, self::$cookieJar);
// Clear the language array so that things