aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--phpBB/adm/style/editor.js4
-rw-r--r--phpBB/develop/create_schema_files.php6
-rw-r--r--phpBB/docs/CHANGELOG.html44
-rw-r--r--phpBB/docs/INSTALL.html2
-rw-r--r--phpBB/includes/acp/acp_database.php106
-rw-r--r--phpBB/includes/cache.php5
-rw-r--r--phpBB/includes/db/db_tools.php51
-rw-r--r--phpBB/includes/db/mssqlnative.php610
-rw-r--r--phpBB/includes/functions.php15
-rw-r--r--phpBB/includes/functions_admin.php1
-rw-r--r--phpBB/includes/functions_convert.php1
-rw-r--r--phpBB/includes/functions_install.php12
-rw-r--r--phpBB/includes/message_parser.php1
-rw-r--r--phpBB/includes/ucp/ucp_remind.php11
-rw-r--r--phpBB/install/database_update.php53
-rw-r--r--phpBB/install/install_convert.php2
-rw-r--r--phpBB/install/install_install.php3
-rw-r--r--phpBB/install/schemas/mssql_schema.sql8
-rw-r--r--phpBB/install/schemas/schema_data.sql4
-rw-r--r--phpBB/language/en/acp/board.php2
-rw-r--r--phpBB/language/en/common.php2
-rw-r--r--phpBB/language/en/install.php2
-rw-r--r--phpBB/styles/prosilver/template/editor.js10
-rw-r--r--phpBB/styles/subsilver2/template/editor.js4
24 files changed, 903 insertions, 56 deletions
diff --git a/phpBB/adm/style/editor.js b/phpBB/adm/style/editor.js
index cd4e75f51f..7e3ce1c708 100644
--- a/phpBB/adm/style/editor.js
+++ b/phpBB/adm/style/editor.js
@@ -152,7 +152,7 @@ function insert_text(text, spaces, popup)
var sel_start = textarea.selectionStart;
var sel_end = textarea.selectionEnd;
- mozWrap(textarea, text, '')
+ mozWrap(textarea, text, '');
textarea.selectionStart = sel_start + text.length;
textarea.selectionEnd = sel_end + text.length;
}
@@ -269,7 +269,7 @@ function mozWrap(txtarea, open, close)
}
var s1 = (txtarea.value).substring(0,selStart);
- var s2 = (txtarea.value).substring(selStart, selEnd)
+ var s2 = (txtarea.value).substring(selStart, selEnd);
var s3 = (txtarea.value).substring(selEnd, selLength);
txtarea.value = s1 + open + s2 + close + s3;
diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php
index 03932bcc13..0515d801f2 100644
--- a/phpBB/develop/create_schema_files.php
+++ b/phpBB/develop/create_schema_files.php
@@ -266,7 +266,8 @@ foreach ($supported_dbms as $dbms)
case 'mssql':
$line = "/*\n\n \$I" . "d: $\n\n*/\n\n";
- $line .= "BEGIN TRANSACTION\nGO\n\n";
+ // no need to do this, no transaction support for schema changes
+ //$line .= "BEGIN TRANSACTION\nGO\n\n";
break;
case 'oracle':
@@ -749,7 +750,8 @@ foreach ($supported_dbms as $dbms)
switch ($dbms)
{
case 'mssql':
- $line = "\nCOMMIT\nGO\n\n";
+ // No need to do this, no transaction support for schema changes
+ //$line = "\nCOMMIT\nGO\n\n";
break;
case 'sqlite':
diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html
index 6b0c0f08bd..4e9adaa1f9 100644
--- a/phpBB/docs/CHANGELOG.html
+++ b/phpBB/docs/CHANGELOG.html
@@ -53,6 +53,7 @@
<ol>
<li><a href="#changelog">Changelog</a>
<ol style="list-style-type: lower-roman;">
+ <li><a href="#v307">Changes since 3.0.7</a></li>
<li><a href="#v306">Changes since 3.0.6</a></li>
<li><a href="#v305">Changes since 3.0.5</a></li>
<li><a href="#v304">Changes since 3.0.4</a></li>
@@ -86,7 +87,20 @@
<div class="inner"><span class="corners-top"><span></span></span>
<div class="content">
- <a name="v306"></a><h3>1.i. Changes since 3.0.6</h3>
+
+ <a name="v307"></a><h3>1.i. Changes since 3.0.7</h3>
+
+ <ul>
+ <li>[Fix] Correctly sort database backup file list by date on database restore page. (Bug #57385)</li>
+ <li>[Fix] Take admin's time zone settings into account when listing database backup files. (Bug #57385)</li>
+ <li>[Fix] Honor minimum and maximum password length in generated passwords as much as we can. (Bug #13181)</li>
+ <li>[Fix] No longer return the character O in generated random strings and passwords. (Bug #57345)</li>
+ <li>[Fix] Allow redirect() function to redirect across directories. (Bug #56965)</li>
+ <li>[Fix] Add terminating semicolons to JavaScript code. (Bug #58085 - Patch by nn-)</li>
+ <li>[Feature] Support for Microsoft's Native SQL Server Driver for PHP (Bug #57055 - Patch by Chris Pucci at Microsoft)</li>
+ </ul>
+
+ <a name="v306"></a><h3>1.ii. Changes since 3.0.6</h3>
<ul>
<li>[Fix] Allow ban reason and length to be selected and copied in ACP and subsilver2 MCP. (Bug #51095)</li>
@@ -190,7 +204,7 @@
</ul>
- <a name="v305"></a><h3>1.ii. Changes since 3.0.5</h3>
+ <a name="v305"></a><h3>1.iii. Changes since 3.0.5</h3>
<ul>
<li>[Fix] Allow whitespaces in avatar gallery names. (Bug #44955)</li>
@@ -412,7 +426,7 @@
<li>[Feature] Send anonymous statistical information to phpBB on installation and update (optional).</li>
</ul>
- <a name="v304"></a><h3>1.iii. Changes since 3.0.4</h3>
+ <a name="v304"></a><h3>1.iv. Changes since 3.0.4</h3>
<ul>
<li>[Fix] Delete user entry from ban list table upon user deletion (Bug #40015 - Patch by TerraFrost)</li>
@@ -501,7 +515,7 @@
<li>[Sec] Only use forum id supplied for posting if global announcement detected. (Reported by nickvergessen)</li>
</ul>
- <a name="v303"></a><h3>1.iv. Changes since 3.0.3</h3>
+ <a name="v303"></a><h3>1.v. Changes since 3.0.3</h3>
<ul>
<li>[Fix] Allow mixed-case template directories to be inherited (Bug #36725)</li>
@@ -533,7 +547,7 @@
<li>[Sec] Ask for forum password if post within passworded forum quoted in private message. (Reported by nickvergessen)</li>
</ul>
- <a name="v302"></a><h3>1.v. Changes since 3.0.2</h3>
+ <a name="v302"></a><h3>1.vi. Changes since 3.0.2</h3>
<ul>
<li>[Fix] Correctly set topic starter if first post in topic removed (Bug #30575 - Patch by blueray2048)</li>
@@ -632,7 +646,7 @@
<li>[Sec Precaution] Stricter validation of the HTTP_HOST header (Thanks to Techie-Micheal et al for pointing out possible issues in derived code)</li>
</ul>
- <a name="v301"></a><h3>1.vi. Changes since 3.0.1</h3>
+ <a name="v301"></a><h3>1.vii. Changes since 3.0.1</h3>
<ul>
<li>[Fix] Ability to set permissions on non-mysql dbms (Bug #24955)</li>
@@ -680,7 +694,7 @@
<li>[Sec] Only allow urls gone through redirect() being used within login_box(). (thanks nookieman)</li>
</ul>
- <a name="v300"></a><h3>1.vii Changes since 3.0.0</h3>
+ <a name="v300"></a><h3>1.viii Changes since 3.0.0</h3>
<ul>
<li>[Change] Validate birthdays (Bug #15004)</li>
@@ -751,7 +765,7 @@
<li>[Fix] Find and display colliding usernames correctly when converting from one database to another (Bug #23925)</li>
</ul>
- <a name="v30rc8"></a><h3>1.viii. Changes since 3.0.RC8</h3>
+ <a name="v30rc8"></a><h3>1.ix. Changes since 3.0.RC8</h3>
<ul>
<li>[Fix] Cleaned usernames contain only single spaces, so &quot;a_name&quot; and &quot;a__name&quot; are treated as the same name (Bug #15634)</li>
@@ -760,7 +774,7 @@
<li>[Fix] Call garbage_collection() within database updater to correctly close connections (affects Oracle for example)</li>
</ul>
- <a name="v30rc7"></a><h3>1.ix. Changes since 3.0.RC7</h3>
+ <a name="v30rc7"></a><h3>1.x. Changes since 3.0.RC7</h3>
<ul>
<li>[Fix] Fixed MSSQL related bug in the update system</li>
@@ -795,7 +809,7 @@
<li>[Fix] No duplication of active topics (Bug #15474)</li>
</ul>
- <a name="v30rc6"></a><h3>1.x. Changes since 3.0.RC6</h3>
+ <a name="v30rc6"></a><h3>1.xi. Changes since 3.0.RC6</h3>
<ul>
<li>[Fix] Submitting language changes using acp_language (Bug #14736)</li>
@@ -805,7 +819,7 @@
<li>[Fix] Able to request new password (Bug #14743)</li>
</ul>
- <a name="v30rc5"></a><h3>1.xi. Changes since 3.0.RC5</h3>
+ <a name="v30rc5"></a><h3>1.xii. Changes since 3.0.RC5</h3>
<ul>
<li>[Feature] Removing constant PHPBB_EMBEDDED in favor of using an exit_handler(); the constant was meant to achive this more or less.</li>
@@ -868,7 +882,7 @@
<li>[Sec] New password hashing mechanism for storing passwords (#i42)</li>
</ul>
- <a name="v30rc4"></a><h3>1.xii. Changes since 3.0.RC4</h3>
+ <a name="v30rc4"></a><h3>1.xiii. Changes since 3.0.RC4</h3>
<ul>
<li>[Fix] MySQL, PostgreSQL and SQLite related database fixes (Bug #13862)</li>
@@ -919,7 +933,7 @@
<li>[Fix] odbc_autocommit causing existing result sets to be dropped (Bug #14182)</li>
</ul>
- <a name="v30rc3"></a><h3>1.xiii. Changes since 3.0.RC3</h3>
+ <a name="v30rc3"></a><h3>1.xiv. Changes since 3.0.RC3</h3>
<ul>
<li>[Fix] Fixing some subsilver2 and prosilver style issues</li>
@@ -1028,7 +1042,7 @@
</ul>
- <a name="v30rc2"></a><h3>1.xiv. Changes since 3.0.RC2</h3>
+ <a name="v30rc2"></a><h3>1.xv. Changes since 3.0.RC2</h3>
<ul>
<li>[Fix] Re-allow searching within the memberlist</li>
@@ -1074,7 +1088,7 @@
</ul>
- <a name="v30rc1"></a><h3>1.xv. Changes since 3.0.RC1</h3>
+ <a name="v30rc1"></a><h3>1.xvi. Changes since 3.0.RC1</h3>
<ul>
<li>[Fix] (X)HTML issues within the templates (Bug #11255, #11255)</li>
diff --git a/phpBB/docs/INSTALL.html b/phpBB/docs/INSTALL.html
index f9d4e28c27..c434686357 100644
--- a/phpBB/docs/INSTALL.html
+++ b/phpBB/docs/INSTALL.html
@@ -285,7 +285,7 @@
<p>The patch file is one solution for those with many Modifications (MODs) or other changes who do not want to re-add them back to all the changed files if they use the method explained above. To use this you will need command line access to a standard UNIX type <strong>patch</strong> application. If you do not have access to such an application but still want to use this update approach, we strongly recommend the <a href="#update_auto">Automatic update package</a> explained below. It is also the recommended update method.</p>
- <p>A number of patch files are provided to allow you to update from previous stable releases. Select the correct patch, e.g. if your current version is 3.0.5 you need the phpBB-3.0.6_to_3.0.7.patch file. Place the correct patch in the parent directory containing the phpBB3 core files (i.e. index.php, viewforum.php, etc.). With this done you should run the following command: <strong>patch -cl -d [PHPBB DIRECTORY] -p1 &lt; [PATCH NAME]</strong> (where PHPBB DIRECTORY is the directory name your phpBB Installation resides in, for example phpBB3, and where PATCH NAME is the relevant filename of the selected patch file). This should complete quickly, hopefully without any HUNK FAILED comments.</p>
+ <p>A number of patch files are provided to allow you to update from previous stable releases. Select the correct patch, e.g. if your current version is 3.0.6 you need the phpBB-3.0.6_to_3.0.7.patch file. Place the correct patch in the parent directory containing the phpBB3 core files (i.e. index.php, viewforum.php, etc.). With this done you should run the following command: <strong>patch -cl -d [PHPBB DIRECTORY] -p1 &lt; [PATCH NAME]</strong> (where PHPBB DIRECTORY is the directory name your phpBB Installation resides in, for example phpBB3, and where PATCH NAME is the relevant filename of the selected patch file). This should complete quickly, hopefully without any HUNK FAILED comments.</p>
<p>If you do get failures you should look at using the <a href="#update_files">Changed files only</a> package to replace the files which failed to patch, please note that you will need to manually re-add any Modifications (MODs) to these particular files. Alternatively if you know how you can examine the .rej files to determine what failed where and make manual adjustments to the relevant source.</p>
diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php
index 5d7450bdfd..abfad2b90b 100644
--- a/phpBB/includes/acp/acp_database.php
+++ b/phpBB/includes/acp/acp_database.php
@@ -109,6 +109,7 @@ class acp_database
case 'mssql':
case 'mssql_odbc':
+ case 'mssqlnative':
$extractor = new mssql_extractor($download, $store, $format, $filename, $time);
break;
@@ -138,6 +139,7 @@ class acp_database
case 'mssql':
case 'mssql_odbc':
+ case 'mssqlnative':
$extractor->flush('TRUNCATE TABLE ' . $table_name . "GO\n");
break;
@@ -435,7 +437,7 @@ class acp_database
{
if (in_array($matches[2], $methods))
{
- $backup_files[gmdate("d-m-Y H:i:s", $matches[1])] = $file;
+ $backup_files[(int) $matches[1]] = $file;
}
}
}
@@ -450,7 +452,7 @@ class acp_database
{
$template->assign_block_vars('files', array(
'FILE' => $file,
- 'NAME' => $name,
+ 'NAME' => $user->format_date($name, 'd-m-Y H:i:s', true),
'SUPPORTED' => true,
));
}
@@ -1509,6 +1511,10 @@ class mssql_extractor extends base_extractor
{
$this->write_data_mssql($table_name);
}
+ else if($db->sql_layer === 'mssqlnative')
+ {
+ $this->write_data_mssqlnative($table_name);
+ }
else
{
$this->write_data_odbc($table_name);
@@ -1608,7 +1614,103 @@ class mssql_extractor extends base_extractor
}
$this->flush($sql_data);
}
+
+ function write_data_mssqlnative($table_name)
+ {
+ global $db;
+ $ary_type = $ary_name = $meta_array = array();
+ $ident_set = false;
+ $sql_data = '';
+
+ // Grab all of the data from current table.
+ $sql = "SELECT * FROM $table_name";
+ $result = $db->sql_query($sql);
+
+ $retrieved_data = $db->mssqlnative_num_rows($result);
+
+ $meta_array = sqlsrv_field_metadata($result);
+ $i_num_fields = sqlsrv_num_fields($result);
+
+ for ($i = 0; $i < $i_num_fields; $i++)
+ {
+ $info = $db->mssqlnative_fieldInfo($table_name, $meta_array[$i]['Name']);
+ $ary_type[$i] = $info->type();
+ $ary_name[$i] = $info->name();
+ }
+
+ if ($retrieved_data)
+ {
+ $sql = "SELECT 1 as has_identity
+ FROM INFORMATION_SCHEMA.COLUMNS
+ WHERE COLUMNPROPERTY(object_id('$table_name'), COLUMN_NAME, 'IsIdentity') = 1";
+ $result2 = $db->sql_query($sql);
+ $row2 = $db->sql_fetchrow($result2);
+
+ if (!empty($row2['has_identity']))
+ {
+ $sql_data .= "\nSET IDENTITY_INSERT $table_name ON\nGO\n";
+ $ident_set = true;
+ }
+ $db->sql_freeresult($result2);
+ }
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $schema_vals = $schema_fields = array();
+ // Build the SQL statement to recreate the data.
+ for ($i = 0; $i < $i_num_fields; $i++)
+ {
+ $str_val = $row[$ary_name[$i]];
+
+ if (preg_match('#char|text|bool|varbinary#i', $ary_type[$i]))
+ {
+ $str_quote = '';
+ $str_empty = "''";
+ $str_val = sanitize_data_mssql(str_replace("'", "''", $str_val));
+ }
+ else if (preg_match('#date|timestamp#i', $ary_type[$i]))
+ {
+ if (empty($str_val))
+ {
+ $str_quote = '';
+ }
+ else
+ {
+ $str_quote = "'";
+ }
+ }
+ else
+ {
+ $str_quote = '';
+ $str_empty = 'NULL';
+ }
+
+ if (empty($str_val) && $str_val !== '0' && !(is_int($str_val) || is_float($str_val)))
+ {
+ $str_val = $str_empty;
+ }
+
+ $schema_vals[$i] = $str_quote . $str_val . $str_quote;
+ $schema_fields[$i] = $ary_name[$i];
+ }
+
+ // Take the ordered fields and their associated data and build it
+ // into a valid sql statement to recreate that field in the data.
+ $sql_data .= "INSERT INTO $table_name (" . implode(', ', $schema_fields) . ') VALUES (' . implode(', ', $schema_vals) . ");\nGO\n";
+
+ $this->flush($sql_data);
+ $sql_data = '';
+ }
+ $db->sql_freeresult($result);
+
+ if ($retrieved_data && $ident_set)
+ {
+ $sql_data .= "\nSET IDENTITY_INSERT $table_name OFF\nGO\n";
+ }
+ $this->flush($sql_data);
+ }
+
function write_data_odbc($table_name)
{
global $db;
diff --git a/phpBB/includes/cache.php b/phpBB/includes/cache.php
index a0142292ed..6b1e078ca4 100644
--- a/phpBB/includes/cache.php
+++ b/phpBB/includes/cache.php
@@ -82,9 +82,11 @@ class cache extends acm
$result = $db->sql_query($sql);
$censors = array();
+ $unicode = ((version_compare(PHP_VERSION, '5.1.0', '>=') || (version_compare(PHP_VERSION, '5.0.0-dev', '<=') && version_compare(PHP_VERSION, '4.4.0', '>='))) && @preg_match('/\p{L}/u', 'a') !== false) ? true : false;
+
while ($row = $db->sql_fetchrow($result))
{
- if ((version_compare(PHP_VERSION, '5.1.0', '>=') || (version_compare(PHP_VERSION, '5.0.0-dev', '<=') && version_compare(PHP_VERSION, '4.4.0', '>='))) && @preg_match('/\p{L}/u', 'a') !== false)
+ if ($unicode)
{
$censors['match'][] = '#(?<![\p{Nd}\p{L}_])(' . str_replace('\*', '[\p{Nd}\p{L}_]*?', preg_quote($row['word'], '#')) . ')(?![\p{Nd}\p{L}_])#iu';
}
@@ -297,6 +299,7 @@ class cache extends acm
{
case 'mssql':
case 'mssql_odbc':
+ case 'mssqlnative':
$sql = 'SELECT user_id, bot_agent, bot_ip
FROM ' . BOTS_TABLE . '
WHERE bot_active = 1
diff --git a/phpBB/includes/db/db_tools.php b/phpBB/includes/db/db_tools.php
index 7123c83e51..819ef69c96 100644
--- a/phpBB/includes/db/db_tools.php
+++ b/phpBB/includes/db/db_tools.php
@@ -160,6 +160,36 @@ class phpbb_db_tools
'VARBINARY' => '[varchar] (255)',
),
+ 'mssqlnative' => array(
+ 'INT:' => '[int]',
+ 'BINT' => '[float]',
+ 'UINT' => '[int]',
+ 'UINT:' => '[int]',
+ 'TINT:' => '[int]',
+ 'USINT' => '[int]',
+ 'BOOL' => '[int]',
+ 'VCHAR' => '[varchar] (255)',
+ 'VCHAR:' => '[varchar] (%d)',
+ 'CHAR:' => '[char] (%d)',
+ 'XSTEXT' => '[varchar] (1000)',
+ 'STEXT' => '[varchar] (3000)',
+ 'TEXT' => '[varchar] (8000)',
+ 'MTEXT' => '[text]',
+ 'XSTEXT_UNI'=> '[varchar] (100)',
+ 'STEXT_UNI' => '[varchar] (255)',
+ 'TEXT_UNI' => '[varchar] (4000)',
+ 'MTEXT_UNI' => '[text]',
+ 'TIMESTAMP' => '[int]',
+ 'DECIMAL' => '[float]',
+ 'DECIMAL:' => '[float]',
+ 'PDECIMAL' => '[float]',
+ 'PDECIMAL:' => '[float]',
+ 'VCHAR_UNI' => '[varchar] (255)',
+ 'VCHAR_UNI:'=> '[varchar] (%d)',
+ 'VCHAR_CI' => '[varchar] (255)',
+ 'VARBINARY' => '[varchar] (255)',
+ ),
+
'oracle' => array(
'INT:' => 'number(%d)',
'BINT' => 'number(20)',
@@ -261,7 +291,7 @@ class phpbb_db_tools
* A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules.
* @var array
*/
- var $supported_dbms = array('firebird', 'mssql', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite');
+ var $supported_dbms = array('firebird', 'mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite');
/**
* This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array).
@@ -307,6 +337,10 @@ class phpbb_db_tools
$this->sql_layer = 'mssql';
break;
+ case 'mssqlnative':
+ $this->sql_layer = 'mssqlnative';
+ break;
+
default:
$this->sql_layer = $this->db->sql_layer;
break;
@@ -368,6 +402,7 @@ class phpbb_db_tools
switch ($this->sql_layer)
{
case 'mssql':
+ case 'mssqlnative':
$table_sql = 'CREATE TABLE [' . $table_name . '] (' . "\n";
break;
@@ -386,6 +421,7 @@ class phpbb_db_tools
switch ($this->sql_layer)
{
case 'mssql':
+ case 'mssqlnative':
$columns[] = "\t [{$column_name}] " . $prepared_column['column_type_sql_default'];
break;
@@ -425,6 +461,7 @@ class phpbb_db_tools
break;
case 'mssql':
+ case 'mssqlnative':
$table_sql .= "\n) ON [PRIMARY]" . (($create_textimage) ? ' TEXTIMAGE_ON [PRIMARY]' : '');
$statements[] = $table_sql;
break;
@@ -453,6 +490,7 @@ class phpbb_db_tools
case 'firebird':
case 'mssql':
+ case 'mssqlnative':
// We need the data here
$old_return_statements = $this->return_statements;
$this->return_statements = true;
@@ -970,6 +1008,7 @@ class phpbb_db_tools
// same deal with PostgreSQL, we must perform more complex operations than
// we technically could
case 'mssql':
+ case 'mssqlnative':
$sql = "SELECT c.name
FROM syscolumns c
LEFT JOIN sysobjects o ON c.id = o.id
@@ -1187,6 +1226,7 @@ class phpbb_db_tools
break;
case 'mssql':
+ case 'mssqlnative':
$sql .= " {$column_type} ";
$sql_default = " {$column_type} ";
@@ -1335,6 +1375,7 @@ class phpbb_db_tools
break;
case 'mssql':
+ case 'mssqlnative':
$statements[] = 'ALTER TABLE [' . $table_name . '] ADD [' . $column_name . '] ' . $column_data['column_type_sql_default'];
break;
@@ -1455,6 +1496,7 @@ class phpbb_db_tools
break;
case 'mssql':
+ case 'mssqlnative':
$statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']';
break;
@@ -1549,6 +1591,7 @@ class phpbb_db_tools
switch ($this->sql_layer)
{
case 'mssql':
+ case 'mssqlnative':
$statements[] = 'DROP INDEX ' . $table_name . '.' . $index_name;
break;
@@ -1652,6 +1695,7 @@ class phpbb_db_tools
break;
case 'mssql':
+ case 'mssqlnative':
$sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD ";
$sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED (";
$sql .= '[' . implode("],\n\t\t[", $column) . ']';
@@ -1745,6 +1789,7 @@ class phpbb_db_tools
break;
case 'mssql':
+ case 'mssqlnative':
$statements[] = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]';
break;
}
@@ -1774,6 +1819,7 @@ class phpbb_db_tools
break;
case 'mssql':
+ case 'mssqlnative':
$statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]';
break;
}
@@ -1791,7 +1837,7 @@ class phpbb_db_tools
{
$index_array = array();
- if ($this->sql_layer == 'mssql')
+ if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative')
{
$sql = "EXEC sp_statistics '$table_name'";
$result = $this->db->sql_query($sql);
@@ -1900,6 +1946,7 @@ class phpbb_db_tools
break;
case 'mssql':
+ case 'mssqlnative':
$statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql'];
if (!empty($column_data['default']))
diff --git a/phpBB/includes/db/mssqlnative.php b/phpBB/includes/db/mssqlnative.php
new file mode 100644
index 0000000000..08ee70907c
--- /dev/null
+++ b/phpBB/includes/db/mssqlnative.php
@@ -0,0 +1,610 @@
+<?php
+/**
+*
+* @package dbal
+* @version $Id$
+* @copyright (c) 2010 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License
+*
+* This is the MS SQL Server Native database abstraction layer.
+* PHP mssql native driver required.
+* @author Chris Pucci
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+include_once($phpbb_root_path . 'includes/db/dbal.' . $phpEx);
+
+/**
+ * Prior to version 1.1 the SQL Server Native PHP driver didn't support sqlsrv_num_rows, or cursor based seeking so we recall all rows into an array
+ * and maintain our own cursor index into that array.
+ */
+class result_mssqlnative
+{
+ public function result_mssqlnative($queryresult = false)
+ {
+ $this->m_cursor = 0;
+ $this->m_rows = array();
+ $this->m_num_fields = sqlsrv_num_fields($queryresult);
+ $this->m_field_meta = sqlsrv_field_metadata($queryresult);
+
+ while ($row = sqlsrv_fetch_array($queryresult, SQLSRV_FETCH_ASSOC))
+ {
+ if ($row !== null)
+ {
+ foreach($row as $k => $v)
+ {
+ if (is_object($v) && method_exists($v, 'format'))
+ {
+ $row[$k] = $v->format("Y-m-d\TH:i:s\Z");
+ }
+ }
+ $this->m_rows[] = $row;//read results into memory, cursors are not supported
+ }
+ }
+
+ $this->m_row_count = count($this->m_rows);
+ sqlsrv_free_stmt($queryresult);
+ }
+
+ private function array_to_obj($array, &$obj)
+ {
+ foreach ($array as $key => $value)
+ {
+ if (is_array($value))
+ {
+ $obj->$key = new stdClass();
+ array_to_obj($value, $obj->$key);
+ }
+ else
+ {
+ $obj->$key = $value;
+ }
+ }
+ return $obj;
+ }
+
+ public function fetch($mode = SQLSRV_FETCH_BOTH, $object_class = 'stdClass')
+ {
+ if ($this->m_cursor >= $this->m_row_count || $this->m_row_count == 0)
+ {
+ return false;
+ }
+
+ $ret = false;
+ $arr_num = array();
+
+ if ($mode == SQLSRV_FETCH_NUMERIC || $mode == SQLSRV_FETCH_BOTH)
+ {
+ foreach($this->m_rows[$this->m_cursor] as $key => $value)
+ {
+ $arr_num[] = $value;
+ }
+ }
+
+ switch ($mode)
+ {
+ case SQLSRV_FETCH_ASSOC:
+ $ret = $this->m_rows[$this->m_cursor];
+ break;
+ case SQLSRV_FETCH_NUMERIC:
+ $ret = $arr_num;
+ break;
+ case 'OBJECT':
+ $ret = $this->array_to_obj($this->m_rows[$this->m_cursor], $o = new $object_class);
+ break;
+ case SQLSRV_FETCH_BOTH:
+ default:
+ $ret = $this->m_rows[$this->m_cursor] + $arr_num;
+ break;
+ }
+ $this->m_cursor++;
+ return $ret;
+ }
+
+ public function get($pos, $fld)
+ {
+ return $this->m_rows[$pos][$fld];
+ }
+
+ public function num_rows()
+ {
+ return $this->m_row_count;
+ }
+
+ public function seek($iRow)
+ {
+ $this->m_cursor = min($iRow, $this->m_row_count);
+ }
+
+ public function num_fields()
+ {
+ return $this->m_num_fields;
+ }
+
+ public function field_name($nr)
+ {
+ $arr_keys = array_keys($this->m_rows[0]);
+ return $arr_keys[$nr];
+ }
+
+ public function field_type($nr)
+ {
+ $i = 0;
+ $int_type = -1;
+ $str_type = '';
+
+ foreach ($this->m_field_meta as $meta)
+ {
+ if ($nr == $i)
+ {
+ $int_type = $meta['Type'];
+ break;
+ }
+ $i++;
+ }
+
+ //http://msdn.microsoft.com/en-us/library/cc296183.aspx contains type table
+ switch ($int_type)
+ {
+ case SQLSRV_SQLTYPE_BIGINT: $str_type = 'bigint'; break;
+ case SQLSRV_SQLTYPE_BINARY: $str_type = 'binary'; break;
+ case SQLSRV_SQLTYPE_BIT: $str_type = 'bit'; break;
+ case SQLSRV_SQLTYPE_CHAR: $str_type = 'char'; break;
+ case SQLSRV_SQLTYPE_DATETIME: $str_type = 'datetime'; break;
+ case SQLSRV_SQLTYPE_DECIMAL/*($precision, $scale)*/: $str_type = 'decimal'; break;
+ case SQLSRV_SQLTYPE_FLOAT: $str_type = 'float'; break;
+ case SQLSRV_SQLTYPE_IMAGE: $str_type = 'image'; break;
+ case SQLSRV_SQLTYPE_INT: $str_type = 'int'; break;
+ case SQLSRV_SQLTYPE_MONEY: $str_type = 'money'; break;
+ case SQLSRV_SQLTYPE_NCHAR/*($charCount)*/: $str_type = 'nchar'; break;
+ case SQLSRV_SQLTYPE_NUMERIC/*($precision, $scale)*/: $str_type = 'numeric'; break;
+ case SQLSRV_SQLTYPE_NVARCHAR/*($charCount)*/: $str_type = 'nvarchar'; break;
+ case SQLSRV_SQLTYPE_NTEXT: $str_type = 'ntext'; break;
+ case SQLSRV_SQLTYPE_REAL: $str_type = 'real'; break;
+ case SQLSRV_SQLTYPE_SMALLDATETIME: $str_type = 'smalldatetime'; break;
+ case SQLSRV_SQLTYPE_SMALLINT: $str_type = 'smallint'; break;
+ case SQLSRV_SQLTYPE_SMALLMONEY: $str_type = 'smallmoney'; break;
+ case SQLSRV_SQLTYPE_TEXT: $str_type = 'text'; break;
+ case SQLSRV_SQLTYPE_TIMESTAMP: $str_type = 'timestamp'; break;
+ case SQLSRV_SQLTYPE_TINYINT: $str_type = 'tinyint'; break;
+ case SQLSRV_SQLTYPE_UNIQUEIDENTIFIER: $str_type = 'uniqueidentifier'; break;
+ case SQLSRV_SQLTYPE_UDT: $str_type = 'UDT'; break;
+ case SQLSRV_SQLTYPE_VARBINARY/*($byteCount)*/: $str_type = 'varbinary'; break;
+ case SQLSRV_SQLTYPE_VARCHAR/*($charCount)*/: $str_type = 'varchar'; break;
+ case SQLSRV_SQLTYPE_XML: $str_type = 'xml'; break;
+ default: $str_type = $int_type;
+ }
+ return $str_type;
+ }
+
+ public function free()
+ {
+ unset($this->m_rows);
+ return;
+ }
+}
+
+/**
+* @package dbal
+*/
+class dbal_mssqlnative extends dbal
+{
+ var $m_insert_id = NULL;
+ var $last_query_text = '';
+
+ /**
+ * Connect to server
+ */
+ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false)
+ {
+ # Test for driver support, to avoid suppressed fatal error
+ if (!function_exists('sqlsrv_connect'))
+ {
+ trigger_error('Native MS SQL Server driver for PHP is missing or needs to be updated. Version 1.1 or later is required to install phpBB3. You can download the driver from: http://www.microsoft.com/sqlserver/2005/en/us/PHP-Driver.aspx\n', E_USER_ERROR);
+ }
+
+ //set up connection variables
+ $this->persistency = $persistency;
+ $this->user = $sqluser;
+ $this->dbname = $database;
+ $port_delimiter = (defined('PHP_OS') && substr(PHP_OS, 0, 3) === 'WIN') ? ',' : ':';
+ $this->server = $sqlserver . (($port) ? $port_delimiter . $port : '');
+
+ //connect to database
+ error_reporting(E_ALL);
+ $this->db_connect_id = sqlsrv_connect($this->server, array(
+ 'Database' => $this->dbname,
+ 'UID' => $this->user,
+ 'PWD' => $sqlpassword
+ ));
+
+ return ($this->db_connect_id) ? $this->db_connect_id : $this->sql_error('');
+ }
+
+ /**
+ * Version information about used database
+ * @param bool $raw if true, only return the fetched sql_server_version
+ * @return string sql server version
+ */
+ function sql_server_info($raw = false)
+ {
+ global $cache;
+
+ if (empty($cache) || ($this->sql_server_version = $cache->get('mssql_version')) === false)
+ {
+ $arr_server_info = sqlsrv_server_info($this->db_connect_id);
+ $this->sql_server_version = $arr_server_info['SQLServerVersion'];
+
+ if (!empty($cache))
+ {
+ $cache->put('mssql_version', $this->sql_server_version);
+ }
+ }
+
+ if ($raw)
+ {
+ return $this->sql_server_version;
+ }
+
+ return ($this->sql_server_version) ? 'MSSQL<br />' . $this->sql_server_version : 'MSSQL';
+ }
+
+ /**
+ * SQL Transaction
+ * @access private
+ */
+ function _sql_transaction($status = 'begin')
+ {
+ switch ($status)
+ {
+ case 'begin':
+ return sqlsrv_begin_transaction($this->db_connect_id);
+ break;
+
+ case 'commit':
+ return sqlsrv_commit($this->db_connect_id);
+ break;
+
+ case 'rollback':
+ return sqlsrv_rollback($this->db_connect_id);
+ break;
+ }
+ return true;
+ }
+
+ /**
+ * Base query method
+ *
+ * @param string $query Contains the SQL query which shall be executed
+ * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache
+ * @return mixed When casted to bool the returned value returns true on success and false on failure
+ *
+ * @access public
+ */
+ function sql_query($query = '', $cache_ttl = 0)
+ {
+ if ($query != '')
+ {
+ global $cache;
+
+ // EXPLAIN only in extra debug mode
+ if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('start', $query);
+ }
+
+ $this->last_query_text = $query;
+ $this->query_result = ($cache_ttl && method_exists($cache, 'sql_load')) ? $cache->sql_load($query) : false;
+ $this->sql_add_num_queries($this->query_result);
+
+ if ($this->query_result === false)
+ {
+ if (($this->query_result = @sqlsrv_query($this->db_connect_id, $query)) === false)
+ {
+ $this->sql_error($query);
+ }
+
+ if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('stop', $query);
+ }
+
+ if ($cache_ttl && method_exists($cache, 'sql_save'))
+ {
+ $this->open_queries[(int) $this->query_result] = $this->query_result;
+ $cache->sql_save($query, $this->query_result, $cache_ttl);
+ }
+ else if (strpos($query, 'SELECT') === 0 && $this->query_result)
+ {
+ $this->open_queries[(int) $this->query_result] = $this->query_result;
+ }
+ }
+ else if (defined('DEBUG_EXTRA'))
+ {
+ $this->sql_report('fromcache', $query);
+ }
+ }
+ else
+ {
+ return false;
+ }
+ return $this->query_result;
+ }
+
+ /**
+ * Build LIMIT query
+ */
+ function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0)
+ {
+ $this->query_result = false;
+
+ if ($offset === false || $offset == 0)
+ {
+ if (strpos($query, "SELECT") === false)
+ {
+ $query = "TOP {$total} " . $query;
+ }
+ else
+ {
+ $query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP '.$total, $query);
+ }
+ }
+ else
+ {
+ $query = preg_replace('/SELECT(\s*DISTINCT)?/Dsi', 'SELECT$1 TOP(10000000) ', $query);
+ $query = 'SELECT *
+ FROM (SELECT sub2.*, ROW_NUMBER() OVER(ORDER BY sub2.line2) AS line3
+ FROM (SELECT 1 AS line2, sub1.* FROM (' . $query . ') AS sub1) as sub2) AS sub3
+ WHERE line3 BETWEEN ' . ($offset+1) . ' AND ' . ($offset + $total);
+ }
+
+ $result = $this->sql_query($query, $cache_ttl);
+
+ return $result;
+ }
+
+ /**
+ * Return number of affected rows
+ */
+ function sql_affectedrows()
+ {
+ return ($this->db_connect_id) ? @sqlsrv_rows_affected($this->db_connect_id) : false;
+ }
+
+ /**
+ * Fetch current row
+ */
+ function sql_fetchrow($query_id = false)
+ {
+ global $cache;
+
+ if ($query_id === false)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (isset($cache->sql_rowset[$query_id]))
+ {
+ return $cache->sql_fetchrow($query_id);
+ }
+
+ if ($query_id === false)
+ {
+ return false;
+ }
+
+ $row = @sqlsrv_fetch_array($query_id, SQLSRV_FETCH_ASSOC);
+
+ // I hope i am able to remove this later... hopefully only a PHP or MSSQL bug
+ if ($row)
+ {
+ foreach ($row as $key => $value)
+ {
+ $row[$key] = ($value === ' ' || $value === NULL) ? '' : $value;
+ }
+ }
+ return $row;
+ }
+
+ /**
+ * Seek to given row number
+ * rownum is zero-based
+ */
+ function sql_rowseek($rownum, &$query_id)
+ {
+ global $cache;
+
+ if (isset($cache->sql_rowset[$query_id]))
+ {
+ return $cache->sql_rowseek($rownum, $query_id);
+ }
+
+ $seek = new result_mssqlnative($query_id);
+ $row = $seek->seek($rownum);
+ return ($row = $seek->fetch()) ? $row : false;
+ }
+
+ /**
+ * Get last inserted id after insert statement
+ */
+ function sql_nextid()
+ {
+ $result_id = @sqlsrv_query($this->db_connect_id, 'SELECT @@IDENTITY');
+
+ if ($result_id !== false)
+ {
+ $row = @sqlsrv_fetch_array($result_id);
+ $id = $row[0];
+ @sqlsrv_free_stmt($result_id);
+ return $id;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Free sql result
+ */
+ function sql_freeresult($query_id = false)
+ {
+ global $cache;
+
+ if ($query_id === false)
+ {
+ $query_id = $this->query_result;
+ }
+
+ if (isset($cache->sql_rowset[$query_id]))
+ {
+ return $cache->sql_freeresult($query_id);
+ }
+
+ if (isset($this->open_queries[$query_id]))
+ {
+ unset($this->open_queries[$query_id]);
+ return @sqlsrv_free_stmt($query_id);
+ }
+ return false;
+ }
+
+ /**
+ * Escape string used in sql query
+ */
+ function sql_escape($msg)
+ {
+ return str_replace(array("'", "\0"), array("''", ''), $msg);
+ }
+
+ /**
+ * Build LIKE expression
+ * @access private
+ */
+ function _sql_like_expression($expression)
+ {
+ return $expression . " ESCAPE '\\'";
+ }
+
+ /**
+ * return sql error array
+ * @access private
+ */
+ function _sql_error()
+ {
+ $errors = @sqlsrv_errors(SQLSRV_ERR_ERRORS);
+ $error_message = '';
+
+ if ($errors != null)
+ {
+ foreach ($errors as $error)
+ {
+ $error_message .= "SQLSTATE: ".$error[ 'SQLSTATE']."\n";
+ $error_message .= "code: ".$error[ 'code']."\n";
+ $error_message .= "message: ".$error[ 'message']."\n";
+ }
+ $this->last_error_result = $error_message;
+ $error = $this->last_error_result;
+ }
+ else
+ {
+ $error = (isset($this->last_error_result) && $this->last_error_result) ? $this->last_error_result : array();
+ }
+ return $error;
+ }
+
+ /**
+ * Build db-specific query data
+ * @access private
+ */
+ function _sql_custom_build($stage, $data)
+ {
+ return $data;
+ }
+
+ /**
+ * Close sql connection
+ * @access private
+ */
+ function _sql_close()
+ {
+ return @sqlsrv_close($this->db_connect_id);
+ }
+
+ /**
+ * Build db-specific report
+ * @access private
+ */
+ function _sql_report($mode, $query = '')
+ {
+ switch ($mode)
+ {
+ case 'start':
+ $html_table = false;
+ @sqlsrv_query($this->db_connect_id, 'SET SHOWPLAN_TEXT ON;');
+ if ($result = @sqlsrv_query($this->db_connect_id, $query))
+ {
+ @sqlsrv_next_result($result);
+ while ($row = @sqlsrv_fetch_array($result))
+ {
+ $html_table = $this->sql_report('add_select_row', $query, $html_table, $row);
+ }
+ }
+ @sqlsrv_query($this->db_connect_id, 'SET SHOWPLAN_TEXT OFF;');
+ @sqlsrv_free_stmt($result);
+
+ if ($html_table)
+ {
+ $this->html_hold .= '</table>';
+ }
+ break;
+
+ case 'fromcache':
+ $endtime = explode(' ', microtime());
+ $endtime = $endtime[0] + $endtime[1];
+
+ $result = @sqlsrv_query($this->db_connect_id, $query);
+ while ($void = @sqlsrv_fetch_array($result))
+ {
+ // Take the time spent on parsing rows into account
+ }
+ @sqlsrv_free_stmt($result);
+
+ $splittime = explode(' ', microtime());
+ $splittime = $splittime[0] + $splittime[1];
+
+ $this->sql_report('record_fromcache', $query, $endtime, $splittime);
+
+ break;
+ }
+ }
+
+ /**
+ * Utility method used to retrieve number of rows
+ * Emulates mysql_num_rows
+ * Used in acp_database.php -> write_data_mssqlnative()
+ */
+ function mssqlnative_num_rows($res)
+ {
+ if ($res !== false)
+ {
+ $row = new result_mssqlnative($res);
+ $num_rows = $row->num_rows();
+ return $num_rows;
+ }
+ else
+ {
+ return false;
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 4b73aa4af9..38f910974a 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -202,7 +202,7 @@ function set_config_count($config_name, $increment, $is_dynamic = false)
function gen_rand_string($num_chars = 8)
{
$rand_str = unique_id();
- $rand_str = str_replace('0', 'Z', strtoupper(base_convert($rand_str, 16, 35)));
+ $rand_str = str_replace(array('0', 'O'), array('Z', 'Y'), strtoupper(base_convert($rand_str, 16, 34)));
return substr($rand_str, 0, $num_chars);
}
@@ -2336,6 +2336,19 @@ function redirect($url, $return = false, $disable_cd_check = false)
// Relative uri
$pathinfo = pathinfo($url);
+ if (!$disable_cd_check && !file_exists($pathinfo['dirname']))
+ {
+ $url = str_replace('../', '', $url);
+ $pathinfo = pathinfo($url);
+
+ if (!file_exists($pathinfo['dirname']))
+ {
+ // fallback to "last known user page"
+ $url = generate_board_url() . '/' . $user->page['page'];
+ break;
+ }
+ }
+
// Is the uri pointing to the current directory?
if ($pathinfo['dirname'] == '.')
{
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index c033684ae1..93244be55c 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -3042,6 +3042,7 @@ function get_database_size()
case 'mssql':
case 'mssql_odbc':
+ case 'mssqlnative':
$sql = 'SELECT ((SUM(size) * 8.0) * 1024.0) as dbsize
FROM sysfiles';
$result = $db->sql_query($sql, 7200);
diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php
index 048212bcfe..0fdae9b274 100644
--- a/phpBB/includes/functions_convert.php
+++ b/phpBB/includes/functions_convert.php
@@ -1645,6 +1645,7 @@ function mass_auth($ug_type, $forum_id, $ug_id, $acl_list, $setting = ACL_NO)
case 'mssql':
case 'sqlite':
+ case 'mssqlnative':
$sql = implode(' UNION ALL ', preg_replace('#^(.*?)$#', 'SELECT \1', $sql_subary));
break;
diff --git a/phpBB/includes/functions_install.php b/phpBB/includes/functions_install.php
index 1b9c66fc84..992e8d6bb0 100644
--- a/phpBB/includes/functions_install.php
+++ b/phpBB/includes/functions_install.php
@@ -95,6 +95,16 @@ function get_available_dbms($dbms = false, $return_unavailable = false, $only_20
'AVAILABLE' => true,
'2.0.x' => true,
),
+ 'mssqlnative' => array(
+ 'LABEL' => 'MS SQL Server 2005+ [ Native ]',
+ 'SCHEMA' => 'mssql',
+ 'MODULE' => 'sqlsrv',
+ 'DELIM' => 'GO',
+ 'COMMENTS' => 'remove_comments',
+ 'DRIVER' => 'mssqlnative',
+ 'AVAILABLE' => true,
+ '2.0.x' => false,
+ ),
'oracle' => array(
'LABEL' => 'Oracle',
'SCHEMA' => 'oracle',
@@ -220,6 +230,7 @@ function get_tables($db)
case 'mssql':
case 'mssql_odbc':
+ case 'mssqlnative':
$sql = "SELECT name
FROM sysobjects
WHERE type='U'";
@@ -313,6 +324,7 @@ function connect_check_db($error_connect, &$error, $dbms_details, $table_prefix,
case 'mssql':
case 'mssql_odbc':
+ case 'mssqlnative':
$prefix_length = 90;
break;
diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php
index 8979511d9a..50aad8588a 100644
--- a/phpBB/includes/message_parser.php
+++ b/phpBB/includes/message_parser.php
@@ -1284,6 +1284,7 @@ class parse_message extends bbcode_firstpass
{
case 'mssql':
case 'mssql_odbc':
+ case 'mssqlnative':
$sql = 'SELECT *
FROM ' . SMILIES_TABLE . '
ORDER BY LEN(code) DESC';
diff --git a/phpBB/includes/ucp/ucp_remind.php b/phpBB/includes/ucp/ucp_remind.php
index df6733d038..f9b792de20 100644
--- a/phpBB/includes/ucp/ucp_remind.php
+++ b/phpBB/includes/ucp/ucp_remind.php
@@ -77,11 +77,12 @@ class ucp_remind
$server_url = generate_board_url();
- $key_len = 54 - strlen($server_url);
- $key_len = max(6, $key_len); // we want at least 6
- $key_len = ($config['max_pass_chars']) ? min($key_len, $config['max_pass_chars']) : $key_len; // we want at most $config['max_pass_chars']
- $user_actkey = substr(gen_rand_string(10), 0, $key_len);
- $user_password = gen_rand_string(8);
+ // Make password at least 8 characters long, make it longer if admin wants to.
+ // gen_rand_string() however has a limit of 12 or 13.
+ $user_password = gen_rand_string(max(8, rand((int) $config['min_pass_chars'], (int) $config['max_pass_chars'])));
+
+ // For the activation key a random length between 6 and 10 will do.
+ $user_actkey = gen_rand_string(rand(6, 10));
$sql = 'UPDATE ' . USERS_TABLE . "
SET user_newpasswd = '" . $db->sql_escape(phpbb_hash($user_password)) . "', user_actkey = '" . $db->sql_escape($user_actkey) . "'
diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php
index e82530189c..df8aadfdb2 100644
--- a/phpBB/install/database_update.php
+++ b/phpBB/install/database_update.php
@@ -8,7 +8,7 @@
*
*/
-$updates_to_version = '3.0.7';
+$updates_to_version = '3.0.8-dev';
// Enter any version to update from to test updates. The version within the db will not be updated.
$debug_from_version = false;
@@ -1788,7 +1788,37 @@ class updater_db_tools
'VCHAR_CI' => '[varchar] (255)',
'VARBINARY' => '[varchar] (255)',
),
-
+
+ 'mssqlnative' => array(
+ 'INT:' => '[int]',
+ 'BINT' => '[float]',
+ 'UINT' => '[int]',
+ 'UINT:' => '[int]',
+ 'TINT:' => '[int]',
+ 'USINT' => '[int]',
+ 'BOOL' => '[int]',
+ 'VCHAR' => '[varchar] (255)',
+ 'VCHAR:' => '[varchar] (%d)',
+ 'CHAR:' => '[char] (%d)',
+ 'XSTEXT' => '[varchar] (1000)',
+ 'STEXT' => '[varchar] (3000)',
+ 'TEXT' => '[varchar] (8000)',
+ 'MTEXT' => '[text]',
+ 'XSTEXT_UNI'=> '[varchar] (100)',
+ 'STEXT_UNI' => '[varchar] (255)',
+ 'TEXT_UNI' => '[varchar] (4000)',
+ 'MTEXT_UNI' => '[text]',
+ 'TIMESTAMP' => '[int]',
+ 'DECIMAL' => '[float]',
+ 'DECIMAL:' => '[float]',
+ 'PDECIMAL' => '[float]',
+ 'PDECIMAL:' => '[float]',
+ 'VCHAR_UNI' => '[varchar] (255)',
+ 'VCHAR_UNI:'=> '[varchar] (%d)',
+ 'VCHAR_CI' => '[varchar] (255)',
+ 'VARBINARY' => '[varchar] (255)',
+ ),
+
'oracle' => array(
'INT:' => 'number(%d)',
'BINT' => 'number(20)',
@@ -1890,7 +1920,7 @@ class updater_db_tools
* A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules.
* @var array
*/
- var $supported_dbms = array('firebird', 'mssql', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite');
+ var $supported_dbms = array('firebird', 'mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite');
/**
* This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array).
@@ -1935,6 +1965,10 @@ class updater_db_tools
case 'mssql_odbc':
$this->sql_layer = 'mssql';
break;
+
+ case 'mssqlnative':
+ $this->sql_layer = 'mssqlnative';
+ break;
default:
$this->sql_layer = $this->db->sql_layer;
@@ -2367,6 +2401,7 @@ class updater_db_tools
// same deal with PostgreSQL, we must perform more complex operations than
// we technically could
case 'mssql':
+ case 'mssqlnative':
$sql = "SELECT c.name
FROM syscolumns c
LEFT JOIN sysobjects o ON c.id = o.id
@@ -2470,7 +2505,7 @@ class updater_db_tools
*/
function sql_index_exists($table_name, $index_name)
{
- if ($this->sql_layer == 'mssql')
+ if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative')
{
$sql = "EXEC sp_statistics '$table_name'";
$result = $this->db->sql_query($sql);
@@ -2575,7 +2610,7 @@ class updater_db_tools
*/
function sql_unique_index_exists($table_name, $index_name)
{
- if ($this->sql_layer == 'mssql')
+ if ($this->sql_layer == 'mssql' || $this->sql_layer == 'mssqlnative')
{
$sql = "EXEC sp_statistics '$table_name'";
$result = $this->db->sql_query($sql);
@@ -2814,6 +2849,7 @@ class updater_db_tools
break;
case 'mssql':
+ case 'mssqlnative':
$sql .= " {$column_type} ";
$sql_default = " {$column_type} ";
@@ -2963,6 +2999,7 @@ class updater_db_tools
break;
case 'mssql':
+ case 'mssqlnative':
// Does not support AFTER, only through temporary table
$statements[] = 'ALTER TABLE [' . $table_name . '] ADD [' . $column_name . '] ' . $column_data['column_type_sql_default'];
break;
@@ -3087,6 +3124,7 @@ class updater_db_tools
break;
case 'mssql':
+ case 'mssqlnative':
$statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']';
break;
@@ -3181,6 +3219,7 @@ class updater_db_tools
switch ($this->sql_layer)
{
case 'mssql':
+ case 'mssqlnative':
$statements[] = 'DROP INDEX ' . $table_name . '.' . $index_name;
break;
@@ -3217,6 +3256,7 @@ class updater_db_tools
break;
case 'mssql':
+ case 'mssqlnative':
$sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD ";
$sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED (";
$sql .= '[' . implode("],\n\t\t[", $column) . ']';
@@ -3310,6 +3350,7 @@ class updater_db_tools
break;
case 'mssql':
+ case 'mssqlnative':
$statements[] = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]';
break;
}
@@ -3339,6 +3380,7 @@ class updater_db_tools
break;
case 'mssql':
+ case 'mssqlnative':
$statements[] = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]';
break;
}
@@ -3371,6 +3413,7 @@ class updater_db_tools
break;
case 'mssql':
+ case 'mssqlnative':
$statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql'];
if (!empty($column_data['default']))
diff --git a/phpBB/install/install_convert.php b/phpBB/install/install_convert.php
index 7f1b9de5b6..06c3a8b4a6 100644
--- a/phpBB/install/install_convert.php
+++ b/phpBB/install/install_convert.php
@@ -1248,6 +1248,7 @@ class install_convert extends module
{
case 'mssql':
case 'mssql_odbc':
+ case 'mssqlnative':
$db->sql_query('SET IDENTITY_INSERT ' . $schema['target'] . ' ON');
break;
}
@@ -1375,6 +1376,7 @@ class install_convert extends module
{
case 'mssql':
case 'mssql_odbc':
+ case 'mssqlnative':
$db->sql_query('SET IDENTITY_INSERT ' . $schema['target'] . ' OFF');
break;
diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php
index 1cc1365752..f4989b5bd7 100644
--- a/phpBB/install/install_install.php
+++ b/phpBB/install/install_install.php
@@ -1203,6 +1203,7 @@ class install_install extends module
{
case 'mssql':
case 'mssql_odbc':
+ case 'mssqlnative':
$sql_query = preg_replace('#\# MSSQL IDENTITY (phpbb_[a-z_]+) (ON|OFF) \##s', 'SET IDENTITY_INSERT \1 \2;', $sql_query);
break;
@@ -1375,7 +1376,7 @@ class install_install extends module
$sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
SET config_value = 'phpbb_captcha_gd'
WHERE config_name = 'captcha_plugin'";
-
+
$sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config
SET config_value = '1'
WHERE config_name = 'captcha_gd'";
diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql
index 960c6eeaed..0827b14cc2 100644
--- a/phpBB/install/schemas/mssql_schema.sql
+++ b/phpBB/install/schemas/mssql_schema.sql
@@ -4,9 +4,6 @@
*/
-BEGIN TRANSACTION
-GO
-
/*
Table: 'phpbb_attachments'
*/
@@ -1733,8 +1730,3 @@ ALTER TABLE [phpbb_zebra] WITH NOCHECK ADD
) ON [PRIMARY]
GO
-
-
-COMMIT
-GO
-
diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql
index 22e8b34f3b..38088b291d 100644
--- a/phpBB/install/schemas/schema_data.sql
+++ b/phpBB/install/schemas/schema_data.sql
@@ -241,7 +241,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('topics_per_page',
INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '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 ('upload_path', 'files');
-INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.0.7');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.0.8-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');
@@ -828,4 +828,4 @@ INSERT INTO phpbb_extensions (group_id, extension) VALUES (9, 'mp3');
INSERT INTO phpbb_extensions (group_id, extension) VALUES (9, 'ogg');
INSERT INTO phpbb_extensions (group_id, extension) VALUES (9, 'ogm');
-# POSTGRES COMMIT #
+# POSTGRES COMMIT # \ No newline at end of file
diff --git a/phpBB/language/en/acp/board.php b/phpBB/language/en/acp/board.php
index 7f07237fbf..ce57b07eae 100644
--- a/phpBB/language/en/acp/board.php
+++ b/phpBB/language/en/acp/board.php
@@ -85,7 +85,7 @@ $lang = array_merge($lang, array(
'ALLOW_SMILIES' => 'Allow smilies',
'ALLOW_TOPIC_NOTIFY' => 'Allow subscribing to topics',
'BOARD_PM' => 'Private messaging',
- 'BOARD_PM_EXPLAIN' => 'Enable or disable private messaging for all users.',
+ 'BOARD_PM_EXPLAIN' => 'Enable private messaging for all users.',
));
// Avatar Settings
diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php
index 821896f32a..a3d47b5b59 100644
--- a/phpBB/language/en/common.php
+++ b/phpBB/language/en/common.php
@@ -124,7 +124,7 @@ $lang = array_merge($lang, array(
'COMMA_SEPARATOR' => ', ', // Used in pagination of ACP & prosilver, use localised comma if appropriate, eg: Ideographic or Arabic
'CONFIRM' => 'Confirm',
'CONFIRM_CODE' => 'Confirmation code',
- 'CONFIRM_CODE_EXPLAIN' => 'Enter the code exactly as it appears. All letters are case insensitive, there is no zero.',
+ 'CONFIRM_CODE_EXPLAIN' => 'Enter the code exactly as it appears. All letters are case insensitive.',
'CONFIRM_CODE_WRONG' => 'The confirmation code you entered was incorrect.',
'CONFIRM_OPERATION' => 'Are you sure you wish to carry out this operation?',
'CONGRATULATIONS' => 'Congratulations to',
diff --git a/phpBB/language/en/install.php b/phpBB/language/en/install.php
index 9543c712da..1c27e2f40d 100644
--- a/phpBB/language/en/install.php
+++ b/phpBB/language/en/install.php
@@ -147,6 +147,7 @@ $lang = array_merge($lang, array(
'DLL_MBSTRING' => 'Multi-byte character support',
'DLL_MSSQL' => 'MSSQL Server 2000+',
'DLL_MSSQL_ODBC' => 'MSSQL Server 2000+ via ODBC',
+ 'DLL_MSSQLNATIVE' => 'MSSQL Server 2005+ [ Native ]',
'DLL_MYSQL' => 'MySQL',
'DLL_MYSQLI' => 'MySQL with MySQLi Extension',
'DLL_ORACLE' => 'Oracle',
@@ -214,6 +215,7 @@ $lang = array_merge($lang, array(
<li>SQLite 2.8.2+</li>
<li>Firebird 2.1+</li>
<li>MS SQL Server 2000 or above (directly or via ODBC)</li>
+ <li>MS SQL Server 2005 or above (native)</li>
<li>Oracle</li>
</ul>
diff --git a/phpBB/styles/prosilver/template/editor.js b/phpBB/styles/prosilver/template/editor.js
index 98dab5d7c8..9c2691db8d 100644
--- a/phpBB/styles/prosilver/template/editor.js
+++ b/phpBB/styles/prosilver/template/editor.js
@@ -157,7 +157,7 @@ function insert_text(text, spaces, popup)
var sel_start = textarea.selectionStart;
var sel_end = textarea.selectionEnd;
- mozWrap(textarea, text, '')
+ mozWrap(textarea, text, '');
textarea.selectionStart = sel_start + text.length;
textarea.selectionEnd = sel_end + text.length;
}
@@ -259,7 +259,7 @@ function addquote(post_id, username)
var lines = split_lines(theSelection);
for (i = 0; i < lines.length; i++)
{
- insert_text('> ' + lines[i] + '\n')
+ insert_text('> ' + lines[i] + '\n');
}
}
}
@@ -289,7 +289,7 @@ function split_lines(text)
if (splitAt == -1)
{
splitLines[j] = line;
- j++
+ j++;
}
else
{
@@ -298,7 +298,7 @@ function split_lines(text)
j++;
}
}
- while(splitAt != -1)
+ while(splitAt != -1);
}
}
return splitLines;
@@ -319,7 +319,7 @@ function mozWrap(txtarea, open, close)
}
var s1 = (txtarea.value).substring(0,selStart);
- var s2 = (txtarea.value).substring(selStart, selEnd)
+ var s2 = (txtarea.value).substring(selStart, selEnd);
var s3 = (txtarea.value).substring(selEnd, selLength);
txtarea.value = s1 + open + s2 + close + s3;
diff --git a/phpBB/styles/subsilver2/template/editor.js b/phpBB/styles/subsilver2/template/editor.js
index 0c48c93ad3..2d157caada 100644
--- a/phpBB/styles/subsilver2/template/editor.js
+++ b/phpBB/styles/subsilver2/template/editor.js
@@ -156,7 +156,7 @@ function insert_text(text, spaces, popup)
var sel_start = textarea.selectionStart;
var sel_end = textarea.selectionEnd;
- mozWrap(textarea, text, '')
+ mozWrap(textarea, text, '');
textarea.selectionStart = sel_start + text.length;
textarea.selectionEnd = sel_end + text.length;
}
@@ -272,7 +272,7 @@ function mozWrap(txtarea, open, close)
}
var s1 = (txtarea.value).substring(0,selStart);
- var s2 = (txtarea.value).substring(selStart, selEnd)
+ var s2 = (txtarea.value).substring(selStart, selEnd);
var s3 = (txtarea.value).substring(selEnd, selLength);
txtarea.value = s1 + open + s2 + close + s3;