Browse Source

Properly handle db ports, per #1402

Signed-off-by: Michael Eshom <[email protected]>
Michael Eshom 10 years ago
parent
commit
4821c267c3
6 changed files with 82 additions and 14 deletions
  1. 17 3
      Sources/Load.php
  2. 3 0
      Sources/Subs-Db-mysql.php
  3. 4 1
      Sources/Subs-Db-mysqli.php
  4. 2 2
      Sources/Subs-Db-postgresql.php
  5. 42 7
      other/install.php
  6. 14 1
      other/upgrade.php

+ 17 - 3
Sources/Load.php

@@ -2703,7 +2703,7 @@ function template_include($filename, $once = false)
 function loadDatabase()
 {
 	global $db_persist, $db_connection, $db_server, $db_user, $db_passwd;
-	global $db_type, $db_name, $ssi_db_user, $ssi_db_passwd, $sourcedir, $db_prefix;
+	global $db_type, $db_name, $ssi_db_user, $ssi_db_passwd, $sourcedir, $db_prefix, $db_port;
 
 	// Figure out what type of database we are using.
 	if (empty($db_type) || !file_exists($sourcedir . '/Subs-Db-' . $db_type . '.php'))
@@ -2712,13 +2712,27 @@ function loadDatabase()
 	// Load the file for the database.
 	require_once($sourcedir . '/Subs-Db-' . $db_type . '.php');
 
+	$db_options = array();
+
+	// Add in the port if needed	
+	if (!empty($db_port))
+		$db_options['port'] = $db_port;
+
 	// If we are in SSI try them first, but don't worry if it doesn't work, we have the normal username and password we can use.
 	if (SMF == 'SSI' && !empty($ssi_db_user) && !empty($ssi_db_passwd))
-		$db_connection = smf_db_initiate($db_server, $db_name, $ssi_db_user, $ssi_db_passwd, $db_prefix, array('persist' => $db_persist, 'non_fatal' => true, 'dont_select_db' => true));
+	{
+		$options = array_merge($db_options, array('persist' => $db_persist, 'non_fatal' => true, 'dont_select_db' => true));
+		
+		$db_connection = smf_db_initiate($db_server, $db_name, $ssi_db_user, $ssi_db_passwd, $db_prefix, $options);
+	}
 
 	// Either we aren't in SSI mode, or it failed.
 	if (empty($db_connection))
-		$db_connection = smf_db_initiate($db_server, $db_name, $db_user, $db_passwd, $db_prefix, array('persist' => $db_persist, 'dont_select_db' => SMF == 'SSI'));
+	{
+		$options = array_merge($db_options, array('persist' => $db_persist, 'dont_select_db' => SMF == 'SSI'));
+
+		$db_connection = smf_db_initiate($db_server, $db_name, $db_user, $db_passwd, $db_prefix, $options);
+	}
 
 	// Safe guard here, if there isn't a valid connection lets put a stop to it.
 	if (!$db_connection)

+ 3 - 0
Sources/Subs-Db-mysql.php

@@ -58,6 +58,9 @@ function smf_db_initiate($db_server, $db_name, $db_user, $db_passwd, $db_prefix,
 			'db_escape_wildcard_string' => 'smf_db_escape_wildcard_string',
 		);
 
+	if (!empty($db_options['port']))
+		$db_server .= ':' . $db_options['port'];
+
 	if (!empty($db_options['persist']))
 		$connection = @mysql_pconnect($db_server, $db_user, $db_passwd);
 	else

+ 4 - 1
Sources/Subs-Db-mysqli.php

@@ -59,7 +59,10 @@ function smf_db_initiate($db_server, $db_name, $db_user, $db_passwd, $db_prefix,
 		);
 
 	if (!empty($db_options['persist']))
-		$connection = @mysqli_connect('p:' . $db_server, $db_user, $db_passwd);
+		$db_server = 'p:' . $db_server;
+
+	if (!empty($db_options['port']))
+		$connection = @mysqli_connect($db_server, $db_user, $db_passwd, '', $db_options['port']);
 	else
 		$connection = @mysqli_connect($db_server, $db_user, $db_passwd);
 

+ 2 - 2
Sources/Subs-Db-postgresql.php

@@ -60,9 +60,9 @@ function smf_db_initiate($db_server, $db_name, $db_user, $db_passwd, &$db_prefix
 		);
 
 	if (!empty($db_options['persist']))
-		$connection = @pg_pconnect('host=' . $db_server . ' dbname=' . $db_name . ' user=\'' . $db_user . '\' password=\'' . $db_passwd . '\'');
+		$connection = @pg_pconnect('host=' . $db_server . ' dbname=' . $db_name . ' user=\'' . $db_user . '\' password=\'' . $db_passwd . '\'' . (empty($db_options['port']) ? '' : ' port=\'' . $db_options['port'] . '\''));
 	else
-		$connection = @pg_connect( 'host=' . $db_server . ' dbname=' . $db_name . ' user=\'' . $db_user . '\' password=\'' . $db_passwd . '\'');
+		$connection = @pg_connect( 'host=' . $db_server . ' dbname=' . $db_name . ' user=\'' . $db_user . '\' password=\'' . $db_passwd . '\'' . (empty($db_options['port']) ? '' : ' port=\'' . $db_options['port'] . '\''));
 
 	// Something's wrong, show an error if its fatal (which we assume it is)
 	if (!$connection)

+ 42 - 7
other/install.php

@@ -391,7 +391,7 @@ function load_lang_file()
 function load_database()
 {
 	global $db_prefix, $db_connection, $db_character_set, $sourcedir, $language;
-	global $smcFunc, $mbname, $scripturl, $boardurl, $modSettings, $db_type, $db_name, $db_user, $db_persist;
+	global $smcFunc, $mbname, $scripturl, $boardurl, $modSettings, $db_type, $db_name, $db_user, $db_persist, $db_port;
 
 	if (empty($sourcedir))
 		$sourcedir = dirname(__FILE__) . '/Sources';
@@ -412,8 +412,28 @@ function load_database()
 		if (version_compare(PHP_VERSION, '5', '<'))
 			require_once($sourcedir . '/Subs-Compat.php');
 
+		$db_options = array('persist' => $db_persist);
+		$port = '';
+
+		// Figure out the port...
+		if (!empty($_POST['db_port']))
+		{
+			if ($db_type == 'mysql' || $db_type == 'mysqli')
+			{
+				$port = ((int) $_POST['db_port'] == ini_get($db_type . 'default_port')) ? '' : (int) $_POST['db_port'];
+			}
+			elseif ($db_type == 'postgresql')
+			{
+				// PostgreSQL doesn't have a default port setting in php.ini, so just check against the default
+				$port = ((int) $_POST['db_port'] == 5432) ? '' : (int) $_POST['db_port'];
+			}
+		}
+
+		if (!empty($port))
+			$db_options['port'] = $port;
+
 		if (!$db_connection)
-			$db_connection = smf_db_initiate($db_server, $db_name, $db_user, $db_passwd, $db_prefix, array('persist' => $db_persist));
+			$db_connection = smf_db_initiate($db_server, $db_name, $db_user, $db_passwd, $db_prefix, $db_options);
 	}
 }
 
@@ -759,7 +779,9 @@ function DatabaseSettings()
 				if (isset($db['default_password']))
 					$incontext['db']['pass'] = ini_get($db['default_password']);
 				if (isset($db['default_port']))
-					$db_port = ini_get($db['default_port']);
+					$incontext['db_port'] = ini_get($db['default_port']);
+				elseif ($key == 'postgresql')
+					$incontext['db_port'] = 5432;
 
 				$incontext['db']['type'] = $key;
 				$foundOne = true;
@@ -774,14 +796,11 @@ function DatabaseSettings()
 		$incontext['db']['name'] = ($_POST['db_type'] == 'sqlite' || $_POST['db_type'] == 'sqlite3') && isset($_POST['db_filename']) ? $_POST['db_filename'] : $_POST['db_name'];
 		$incontext['db']['server'] = $_POST['db_server'];
 		$incontext['db']['prefix'] = $_POST['db_prefix'];
+		$incontext['db']['port'] = empty($_POST['db_port']) ? '' : $_POST['db_port'];
 	}
 	else
 	{
 		$incontext['db']['prefix'] = 'smf_';
-
-		// Should we use a non standard port?
-		if (!empty($db_port))
-			$incontext['db']['server'] .= ':' . $db_port;
 	}
 
 	// Are we submitting?
@@ -827,6 +846,16 @@ function DatabaseSettings()
 			'cookiename' => 'SMFCookie' . abs(crc32($_POST['db_name'] . preg_replace('~[^A-Za-z0-9_$]~', '', $_POST['db_prefix'])) % 1000),
 		);
 
+		// Only set the port if we're not using the default
+		if (!empty($_POST['db_port']))
+		{
+			// For MySQL, we can get the "default port" from PHP. PostgreSQL has no such option though.
+			if (($db_type == 'mysql' || $db_type == 'mysqli') && $_POST['db_port'] != ini_get($db_type . '.default_port'))
+				$vars['db_port'] == (int) $_POST['db_port'];
+			elseif ($db_type == 'postgresql' && $_POST['db_port'] != 5432)
+				$vars['db_port'] == (int) $_POST['db_port'];
+		}
+
 		// God I hope it saved!
 		if (!updateSettingsFile($vars) && substr(__FILE__, 1, 2) == ':\\')
 		{
@@ -2397,6 +2426,11 @@ function template_database_settings()
 					<input type="text" name="db_server" id="db_server_input" value="', $incontext['db']['server'], '" size="30" class="input_text" /><br />
 					<div style="font-size: smaller; margin-bottom: 2ex;">', $txt['db_settings_server_info'], '</div>
 				</td>
+			</tr><tr id="db_port_contain">
+				<td width="20%" valign="top" class="textbox"><label for="db_port_input">', $txt['db_settings_port'], ':</label></td>
+				<td>
+					<input type="text" name="db_port" id="db_port_input" value="', $incontext['db']['port'], '</div>
+				</td>
 			</tr><tr id="db_user_contain">
 				<td valign="top" class="textbox"><label for="db_user_input">', $txt['db_settings_username'], ':</label></td>
 				<td>
@@ -2456,6 +2490,7 @@ function template_database_settings()
 			document.getElementById(\'db_name_contain\').style.display = showAll ? \'\' : \'none\';
 			document.getElementById(\'db_filename_contain\').style.display = !showAll ? \'\' : \'none\';
 			document.getElementById(\'db_sqlite_warning\').style.display = !showAll ? \'\' : \'none\';
+			document.getElementById(\'db_port_contain\').style.display = showAll ? \'\' : \'none\';
 			if (document.getElementById(\'db_type_input\').value == \'postgresql\')
 				document.getElementById(\'db_name_info_warning\').style.display = \'none\';
 			else

+ 14 - 1
other/upgrade.php

@@ -1278,7 +1278,7 @@ function checkLogin()
 function UpgradeOptions()
 {
 	global $db_prefix, $command_line, $modSettings, $is_debug, $smcFunc, $packagesdir;
-	global $boarddir, $boardurl, $sourcedir, $maintenance, $mmessage, $cachedir, $upcontext, $db_type;
+	global $boarddir, $boardurl, $sourcedir, $maintenance, $mmessage, $cachedir, $upcontext, $db_type, $db_server;
 
 	$upcontext['sub_template'] = 'upgrade_options';
 	$upcontext['page_title'] = 'Upgrade Options';
@@ -1383,6 +1383,19 @@ function UpgradeOptions()
 	if (!empty($_POST['convertMysql']) && $db_type == 'mysql')
 		$changes['db_type'] = '\'mysqli\'';
 
+	// If they have a "host:port" setup for the host, split that into separate values
+	// You should never have a : in the hostname if you're not on MySQL, but better safe than sorry
+	if (strpos($db_server, ':') !== false && ($db_type == 'mysql' || $db_type == 'mysqli'))
+	{
+		list($db_server, $db_port) = explode(':', $db_server);
+		
+		$changes['db_server'] = '\'' . $db_server . '\'';
+	
+		// Only set this if we're not using the default port
+		if ($db_port != ini_get('mysql' . ($db_type == 'mysqli' || !empty($_POST['convertMysql']) ? 'i' : '') . '.default_port'))
+			$changes['db_port'] = (int) $db_port;
+	}
+
 	// Maybe we haven't had this option yet?
 	if (empty($packagesdir))
 		$changes['packagesdir'] = '\'' . fixRelativePath($boarddir) . '/Packages\'';