aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/phpbb
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/phpbb')
-rw-r--r--phpBB/phpbb/avatar/driver/upload.php1
-rw-r--r--phpBB/phpbb/content_visibility.php69
-rw-r--r--phpBB/phpbb/db/driver/driver.php11
-rw-r--r--phpBB/phpbb/db/driver/driver_interface.php10
-rw-r--r--phpBB/phpbb/db/driver/factory.php8
-rw-r--r--phpBB/phpbb/db/driver/mssql.php9
-rw-r--r--phpBB/phpbb/db/driver/mssql_base.php9
-rw-r--r--phpBB/phpbb/db/driver/mysql_base.php9
-rw-r--r--phpBB/phpbb/db/driver/oracle.php9
-rw-r--r--phpBB/phpbb/db/driver/postgres.php9
-rw-r--r--phpBB/phpbb/db/driver/sqlite.php19
-rw-r--r--phpBB/phpbb/db/driver/sqlite3.php21
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_facebook.php3
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_googleplus.php3
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_skype.php3
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_twitter.php3
-rw-r--r--phpBB/phpbb/db/migration/data/v310/profilefield_youtube.php3
-rw-r--r--phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php2
-rw-r--r--phpBB/phpbb/db/migration/data/v310/topic_sort_username.php44
-rw-r--r--phpBB/phpbb/db/tools.php251
-rw-r--r--phpBB/phpbb/mimetype/content_guesser.php2
-rw-r--r--phpBB/phpbb/notification/type/approve_post.php9
-rw-r--r--phpBB/phpbb/notification/type/approve_topic.php9
-rw-r--r--phpBB/phpbb/notification/type/base.php33
-rw-r--r--phpBB/phpbb/notification/type/bookmark.php12
-rw-r--r--phpBB/phpbb/notification/type/post.php14
-rw-r--r--phpBB/phpbb/notification/type/quote.php17
-rw-r--r--phpBB/phpbb/notification/type/topic.php14
-rw-r--r--phpBB/phpbb/profilefields/type/type_googleplus.php2
-rw-r--r--phpBB/phpbb/user.php11
30 files changed, 427 insertions, 192 deletions
diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php
index edc5941602..f5ba50451a 100644
--- a/phpBB/phpbb/avatar/driver/upload.php
+++ b/phpBB/phpbb/avatar/driver/upload.php
@@ -27,7 +27,6 @@ class upload extends \phpbb\avatar\driver\driver
* Construct a driver object
*
* @param \phpbb\config\config $config phpBB configuration
- * @param \phpbb\request\request $request Request object
* @param string $phpbb_root_path Path to the phpBB root
* @param string $php_ext PHP file extension
* @param \phpbb_path_helper $path_helper phpBB path helper
diff --git a/phpBB/phpbb/content_visibility.php b/phpBB/phpbb/content_visibility.php
index da4405d676..8bd537586e 100644
--- a/phpBB/phpbb/content_visibility.php
+++ b/phpBB/phpbb/content_visibility.php
@@ -570,7 +570,7 @@ class content_visibility
* Add post to topic and forum statistics
*
* @param $data array Contains information from the topics table about given topic
- * @param $sql_data array Populated with the SQL changes, may be empty at call time
+ * @param &$sql_data array Populated with the SQL changes, may be empty at call time
* @return null
*/
public function add_post_to_statistic($data, &$sql_data)
@@ -591,7 +591,7 @@ class content_visibility
* Remove post from topic and forum statistics
*
* @param $data array Contains information from the topics table about given topic
- * @param $sql_data array Populated with the SQL changes, may be empty at call time
+ * @param &$sql_data array Populated with the SQL changes, may be empty at call time
* @return null
*/
public function remove_post_from_statistic($data, &$sql_data)
@@ -623,64 +623,29 @@ class content_visibility
/**
* Remove topic from forum statistics
*
- * @param $topic_id int The topic to act on
- * @param $forum_id int Forum where the topic is found
- * @param $topic_row array Contains information from the topic, may be empty at call time
- * @param $sql_data array Populated with the SQL changes, may be empty at call time
+ * @param $data array Post and topic data
+ * @param &$sql_data array Populated with the SQL changes, may be empty at call time
* @return null
*/
- public function remove_topic_from_statistic($topic_id, $forum_id, &$topic_row, &$sql_data)
+ public function remove_topic_from_statistic($data, &$sql_data)
{
- // Do we need to grab some topic informations?
- if (!sizeof($topic_row))
+ if ($data['topic_visibility'] == ITEM_APPROVED)
{
- $sql = 'SELECT topic_type, topic_posts_approved, topic_posts_unapproved, topic_posts_softdeleted, topic_visibility
- FROM ' . $this->topics_table . '
- WHERE topic_id = ' . (int) $topic_id;
- $result = $this->db->sql_query($sql);
- $topic_row = $this->db->sql_fetchrow($result);
- $this->db->sql_freeresult($result);
- }
-
- // If this is an edited topic or the first post the topic gets completely disapproved later on...
- $sql_data[$this->forums_table] = (($sql_data[$this->forums_table]) ? $sql_data[$this->forums_table] . ', ' : '') . 'forum_topics_approved = forum_topics_approved - 1';
- $sql_data[$this->forums_table] .= ', forum_posts_approved = forum_posts_approved - ' . $topic_row['topic_posts_approved'];
- $sql_data[$this->forums_table] .= ', forum_posts_unapproved = forum_posts_unapproved - ' . $topic_row['topic_posts_unapproved'];
- $sql_data[$this->forums_table] .= ', forum_posts_softdeleted = forum_posts_softdeleted - ' . $topic_row['topic_posts_softdeleted'];
+ $sql_data[FORUMS_TABLE] .= 'forum_posts_approved = forum_posts_approved - 1, forum_topics_approved = forum_topics_approved - 1';
- $this->config->increment('num_topics', -1, false);
- $this->config->increment('num_posts', $topic_row['topic_posts_approved'] * (-1), false);
-
- // Get user post count information
- $sql = 'SELECT poster_id, COUNT(post_id) AS num_posts
- FROM ' . $this->posts_table . '
- WHERE topic_id = ' . (int) $topic_id . '
- AND post_postcount = 1
- AND post_visibility = ' . ITEM_APPROVED . '
- GROUP BY poster_id';
- $result = $this->db->sql_query($sql);
-
- $postcounts = array();
- while ($row = $this->db->sql_fetchrow($result))
+ if ($data['post_postcount'])
+ {
+ $sql_data[$this->users_table] = ((!empty($sql_data[$this->users_table])) ? $sql_data[$this->users_table] . ', ' : '') . 'user_posts = user_posts - 1';
+ }
+ }
+ else if ($data['topic_visibility'] == ITEM_UNAPPROVED || $data['post_visibility'] == ITEM_REAPPROVE)
{
- $postcounts[(int) $row['num_posts']][] = (int) $row['poster_id'];
+ $sql_data[FORUMS_TABLE] .= 'forum_posts_unapproved = forum_posts_unapproved - 1, forum_topics_unapproved = forum_topics_unapproved - 1';
}
- $this->db->sql_freeresult($result);
-
- // Decrement users post count
- foreach ($postcounts as $num_posts => $poster_ids)
+ else if ($data['topic_visibility'] == ITEM_DELETED)
{
- $sql = 'UPDATE ' . $this->users_table . '
- SET user_posts = 0
- WHERE user_posts < ' . $num_posts . '
- AND ' . $this->db->sql_in_set('user_id', $poster_ids);
- $this->db->sql_query($sql);
-
- $sql = 'UPDATE ' . $this->users_table . '
- SET user_posts = user_posts - ' . $num_posts . '
- WHERE user_posts >= ' . $num_posts . '
- AND ' . $this->db->sql_in_set('user_id', $poster_ids);
- $this->db->sql_query($sql);
+ $sql_data[FORUMS_TABLE] .= 'forum_posts_softdeleted = forum_posts_softdeleted - 1, forum_topics_softdeleted = forum_topics_softdeleted - 1';
}
+
}
}
diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php
index 3e9110d8bc..9fc04d47a1 100644
--- a/phpBB/phpbb/db/driver/driver.php
+++ b/phpBB/phpbb/db/driver/driver.php
@@ -372,6 +372,17 @@ abstract class driver implements driver_interface
/**
* {@inheritDoc}
*/
+ function sql_not_like_expression($expression)
+ {
+ $expression = utf8_str_replace(array('_', '%'), array("\_", "\%"), $expression);
+ $expression = utf8_str_replace(array(chr(0) . "\_", chr(0) . "\%"), array('_', '%'), $expression);
+
+ return $this->_sql_not_like_expression('NOT LIKE \'' . $this->sql_escape($expression) . '\'');
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public function sql_case($condition, $action_true, $action_false = false)
{
$sql_case = 'CASE WHEN ' . $condition;
diff --git a/phpBB/phpbb/db/driver/driver_interface.php b/phpBB/phpbb/db/driver/driver_interface.php
index 6722d059a5..8b487c5d42 100644
--- a/phpBB/phpbb/db/driver/driver_interface.php
+++ b/phpBB/phpbb/db/driver/driver_interface.php
@@ -419,6 +419,16 @@ interface driver_interface
public function sql_like_expression($expression);
/**
+ * Correctly adjust NOT LIKE expression for special characters
+ * Some DBMS are handling them in a different way
+ *
+ * @param string $expression The expression to use. Every wildcard is
+ * escaped, except $this->any_char and $this->one_char
+ * @return string A SQL statement like: "NOT LIKE 'bertie_%'"
+ */
+ public function sql_not_like_expression($expression);
+
+ /**
* Explain queries
*
* @param string $mode Available modes: display, start, stop,
diff --git a/phpBB/phpbb/db/driver/factory.php b/phpBB/phpbb/db/driver/factory.php
index f0fa18051b..fb3a826254 100644
--- a/phpBB/phpbb/db/driver/factory.php
+++ b/phpBB/phpbb/db/driver/factory.php
@@ -420,6 +420,14 @@ class factory implements driver_interface
/**
* {@inheritdoc}
*/
+ public function sql_not_like_expression($expression)
+ {
+ return $this->get_driver()->sql_not_like_expression($expression);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
public function sql_report($mode, $query = '')
{
return $this->get_driver()->sql_report($mode, $query);
diff --git a/phpBB/phpbb/db/driver/mssql.php b/phpBB/phpbb/db/driver/mssql.php
index 268463a151..f9ea884ce2 100644
--- a/phpBB/phpbb/db/driver/mssql.php
+++ b/phpBB/phpbb/db/driver/mssql.php
@@ -351,6 +351,15 @@ class mssql extends \phpbb\db\driver\driver
}
/**
+ * Build NOT LIKE expression
+ * @access private
+ */
+ function _sql_not_like_expression($expression)
+ {
+ return $expression . " ESCAPE '\\'";
+ }
+
+ /**
* return sql error array
* @access private
*/
diff --git a/phpBB/phpbb/db/driver/mssql_base.php b/phpBB/phpbb/db/driver/mssql_base.php
index e7101903b8..514df9eaca 100644
--- a/phpBB/phpbb/db/driver/mssql_base.php
+++ b/phpBB/phpbb/db/driver/mssql_base.php
@@ -52,6 +52,15 @@ abstract class mssql_base extends \phpbb\db\driver\driver
}
/**
+ * Build NOT LIKE expression
+ * @access private
+ */
+ function _sql_not_like_expression($expression)
+ {
+ return $expression . " ESCAPE '\\'";
+ }
+
+ /**
* Build db-specific query data
* @access private
*/
diff --git a/phpBB/phpbb/db/driver/mysql_base.php b/phpBB/phpbb/db/driver/mysql_base.php
index e7c9b63f20..5e0b359134 100644
--- a/phpBB/phpbb/db/driver/mysql_base.php
+++ b/phpBB/phpbb/db/driver/mysql_base.php
@@ -112,6 +112,15 @@ abstract class mysql_base extends \phpbb\db\driver\driver
}
/**
+ * Build NOT LIKE expression
+ * @access private
+ */
+ function _sql_not_like_expression($expression)
+ {
+ return $expression;
+ }
+
+ /**
* Build db-specific query data
* @access private
*/
diff --git a/phpBB/phpbb/db/driver/oracle.php b/phpBB/phpbb/db/driver/oracle.php
index d1a186f1ba..6dcab5dd7d 100644
--- a/phpBB/phpbb/db/driver/oracle.php
+++ b/phpBB/phpbb/db/driver/oracle.php
@@ -645,6 +645,15 @@ class oracle extends \phpbb\db\driver\driver
return $expression . " ESCAPE '\\'";
}
+ /**
+ * Build NOT LIKE expression
+ * @access private
+ */
+ function _sql_not_like_expression($expression)
+ {
+ return $expression . " ESCAPE '\\'";
+ }
+
function _sql_custom_build($stage, $data)
{
return $data;
diff --git a/phpBB/phpbb/db/driver/postgres.php b/phpBB/phpbb/db/driver/postgres.php
index 83e9fa51f6..a3b9aa4c6b 100644
--- a/phpBB/phpbb/db/driver/postgres.php
+++ b/phpBB/phpbb/db/driver/postgres.php
@@ -371,6 +371,15 @@ class postgres extends \phpbb\db\driver\driver
}
/**
+ * Build NOT LIKE expression
+ * @access private
+ */
+ function _sql_not_like_expression($expression)
+ {
+ return $expression;
+ }
+
+ /**
* {@inheritDoc}
*/
function cast_expr_to_bigint($expression)
diff --git a/phpBB/phpbb/db/driver/sqlite.php b/phpBB/phpbb/db/driver/sqlite.php
index 2112e5ba2f..d5da0e2438 100644
--- a/phpBB/phpbb/db/driver/sqlite.php
+++ b/phpBB/phpbb/db/driver/sqlite.php
@@ -277,7 +277,7 @@ class sqlite extends \phpbb\db\driver\driver
*/
function sql_like_expression($expression)
{
- // Unlike LIKE, GLOB is case sensitive (unfortunatly). SQLite users need to live with it!
+ // Unlike LIKE, GLOB is unfortunately case sensitive.
// We only catch * and ? here, not the character map possible on file globbing.
$expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression);
@@ -288,6 +288,23 @@ class sqlite extends \phpbb\db\driver\driver
}
/**
+ * {@inheritDoc}
+ *
+ * For SQLite an underscore is a not-known character...
+ */
+ function sql_not_like_expression($expression)
+ {
+ // Unlike NOT LIKE, NOT GLOB is unfortunately case sensitive.
+ // We only catch * and ? here, not the character map possible on file globbing.
+ $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression);
+
+ $expression = str_replace(array('?', '*'), array("\?", "\*"), $expression);
+ $expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression);
+
+ return 'NOT GLOB \'' . $this->sql_escape($expression) . '\'';
+ }
+
+ /**
* return sql error array
* @access private
*/
diff --git a/phpBB/phpbb/db/driver/sqlite3.php b/phpBB/phpbb/db/driver/sqlite3.php
index 0922229e0a..4e3e0d3329 100644
--- a/phpBB/phpbb/db/driver/sqlite3.php
+++ b/phpBB/phpbb/db/driver/sqlite3.php
@@ -260,11 +260,11 @@ class sqlite3 extends \phpbb\db\driver\driver
/**
* {@inheritDoc}
*
- * For SQLite an underscore is a not-known character...
+ * For SQLite an underscore is an unknown character.
*/
public function sql_like_expression($expression)
{
- // Unlike LIKE, GLOB is case sensitive (unfortunatly). SQLite users need to live with it!
+ // Unlike LIKE, GLOB is unfortunately case sensitive.
// We only catch * and ? here, not the character map possible on file globbing.
$expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression);
@@ -275,6 +275,23 @@ class sqlite3 extends \phpbb\db\driver\driver
}
/**
+ * {@inheritDoc}
+ *
+ * For SQLite an underscore is an unknown character.
+ */
+ public function sql_not_like_expression($expression)
+ {
+ // Unlike NOT LIKE, NOT GLOB is unfortunately case sensitive
+ // We only catch * and ? here, not the character map possible on file globbing.
+ $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression);
+
+ $expression = str_replace(array('?', '*'), array("\?", "\*"), $expression);
+ $expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression);
+
+ return 'NOT GLOB \'' . $this->sql_escape($expression) . '\'';
+ }
+
+ /**
* return sql error array
*
* @return array
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_facebook.php b/phpBB/phpbb/db/migration/data/v310/profilefield_facebook.php
index 5964e7a997..7324b893cc 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_facebook.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_facebook.php
@@ -18,8 +18,9 @@ class profilefield_facebook extends \phpbb\db\migration\profilefield_base_migrat
static public function depends_on()
{
return array(
- '\phpbb\db\migration\data\v310\profilefield_types',
+ '\phpbb\db\migration\data\v310\profilefield_contact_field',
'\phpbb\db\migration\data\v310\profilefield_show_novalue',
+ '\phpbb\db\migration\data\v310\profilefield_types',
);
}
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_googleplus.php b/phpBB/phpbb/db/migration/data/v310/profilefield_googleplus.php
index 9bef0a4c0b..3b0963fc19 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_googleplus.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_googleplus.php
@@ -18,8 +18,9 @@ class profilefield_googleplus extends \phpbb\db\migration\profilefield_base_migr
static public function depends_on()
{
return array(
- '\phpbb\db\migration\data\v310\profilefield_types',
+ '\phpbb\db\migration\data\v310\profilefield_contact_field',
'\phpbb\db\migration\data\v310\profilefield_show_novalue',
+ '\phpbb\db\migration\data\v310\profilefield_types',
);
}
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_skype.php b/phpBB/phpbb/db/migration/data/v310/profilefield_skype.php
index 9a5de9d0eb..0dbe9041bb 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_skype.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_skype.php
@@ -18,8 +18,9 @@ class profilefield_skype extends \phpbb\db\migration\profilefield_base_migration
static public function depends_on()
{
return array(
- '\phpbb\db\migration\data\v310\profilefield_types',
+ '\phpbb\db\migration\data\v310\profilefield_contact_field',
'\phpbb\db\migration\data\v310\profilefield_show_novalue',
+ '\phpbb\db\migration\data\v310\profilefield_types',
);
}
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_twitter.php b/phpBB/phpbb/db/migration/data/v310/profilefield_twitter.php
index 68d038f609..850e096439 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_twitter.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_twitter.php
@@ -18,8 +18,9 @@ class profilefield_twitter extends \phpbb\db\migration\profilefield_base_migrati
static public function depends_on()
{
return array(
- '\phpbb\db\migration\data\v310\profilefield_types',
+ '\phpbb\db\migration\data\v310\profilefield_contact_field',
'\phpbb\db\migration\data\v310\profilefield_show_novalue',
+ '\phpbb\db\migration\data\v310\profilefield_types',
);
}
diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_youtube.php b/phpBB/phpbb/db/migration/data/v310/profilefield_youtube.php
index bb90c0aa5c..40a569d2a2 100644
--- a/phpBB/phpbb/db/migration/data/v310/profilefield_youtube.php
+++ b/phpBB/phpbb/db/migration/data/v310/profilefield_youtube.php
@@ -18,8 +18,9 @@ class profilefield_youtube extends \phpbb\db\migration\profilefield_base_migrati
static public function depends_on()
{
return array(
- '\phpbb\db\migration\data\v310\profilefield_types',
+ '\phpbb\db\migration\data\v310\profilefield_contact_field',
'\phpbb\db\migration\data\v310\profilefield_show_novalue',
+ '\phpbb\db\migration\data\v310\profilefield_types',
);
}
diff --git a/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php
index 6335c75398..58845b88ec 100644
--- a/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php
+++ b/phpBB/phpbb/db/migration/data/v310/soft_delete_mod_convert.php
@@ -121,7 +121,7 @@ class soft_delete_mod_convert extends \phpbb\db\migration\migration
new \phpbb\auth\auth(),
$this->config,
$this->db,
- new \phpbb\user(),
+ new \phpbb\user('\phpbb\datetime'),
$this->phpbb_root_path,
$this->php_ext,
$this->table_prefix . 'forums',
diff --git a/phpBB/phpbb/db/migration/data/v310/topic_sort_username.php b/phpBB/phpbb/db/migration/data/v310/topic_sort_username.php
new file mode 100644
index 0000000000..527da20590
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v310/topic_sort_username.php
@@ -0,0 +1,44 @@
+<?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.
+*
+*/
+
+namespace phpbb\db\migration\data\v310;
+
+class topic_sort_username extends \phpbb\db\migration\migration
+{
+ static public function depends_on()
+ {
+ return array('\phpbb\db\migration\data\v310\dev');
+ }
+
+ public function update_schema()
+ {
+ return array(
+ 'change_columns' => array(
+ $this->table_prefix . 'topics' => array(
+ 'topic_first_poster_name' => array('VCHAR_UNI:255', '', 'true_sort'),
+ ),
+ ),
+ );
+ }
+
+ public function revert_schema()
+ {
+ return array(
+ 'change_columns' => array(
+ $this->table_prefix . 'topics' => array(
+ 'topic_first_poster_name' => array('VCHAR_UNI:255', ''),
+ ),
+ ),
+ );
+ }
+}
diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php
index 5d93eb8246..3567570137 100644
--- a/phpBB/phpbb/db/tools.php
+++ b/phpBB/phpbb/db/tools.php
@@ -1816,7 +1816,8 @@ class tools
$old_return_statements = $this->return_statements;
$this->return_statements = true;
- $indexes = $this->mssql_get_existing_indexes($table_name, $column_name);
+ $indexes = $this->get_existing_indexes($table_name, $column_name);
+ $indexes = array_merge($indexes, $this->get_existing_indexes($table_name, $column_name, true));
// Drop any indexes
$recreate_indexes = array();
@@ -2038,7 +2039,7 @@ class tools
break;
case 'oracle':
- $statements[] = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')';
+ $statements[] = 'ALTER TABLE ' . $table_name . ' add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')';
break;
case 'sqlite':
@@ -2274,10 +2275,23 @@ class tools
}
/**
+ * Removes table_name from the index_name if it is at the beginning
+ *
+ * @param $table_name
+ * @param $index_name
+ * @return string
+ */
+ protected function strip_table_name_from_index_name($table_name, $index_name)
+ {
+ return (strpos(strtoupper($index_name), strtoupper($table_name)) === 0) ? substr($index_name, strlen($table_name) + 1) : $index_name;
+ }
+
+ /**
* Change column type (not name!)
*/
function sql_column_change($table_name, $column_name, $column_data, $inline = false)
{
+ $original_column_data = $column_data;
$column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data);
$statements = array();
@@ -2289,12 +2303,14 @@ class tools
$old_return_statements = $this->return_statements;
$this->return_statements = true;
- $indexes = $this->mssql_get_existing_indexes($table_name, $column_name);
+ $indexes = $this->get_existing_indexes($table_name, $column_name);
+ $unique_indexes = $this->get_existing_indexes($table_name, $column_name, true);
// Drop any indexes
- if (!empty($indexes))
+ if (!empty($indexes) || !empty($unique_indexes))
{
- foreach ($indexes as $index_name => $index_data)
+ $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes));
+ foreach ($drop_indexes as $index_name)
{
$result = $this->sql_index_drop($table_name, $index_name);
$statements = array_merge($statements, $result);
@@ -2324,6 +2340,16 @@ class tools
}
}
+ if (!empty($unique_indexes))
+ {
+ // Recreate unique indexes after we changed the column
+ foreach ($unique_indexes as $index_name => $index_data)
+ {
+ $result = $this->sql_create_unique_index($table_name, $index_name, $index_data);
+ $statements = array_merge($statements, $result);
+ }
+ }
+
$this->return_statements = $old_return_statements;
break;
@@ -2333,7 +2359,69 @@ class tools
break;
case 'oracle':
- $statements[] = 'ALTER TABLE ' . $table_name . ' MODIFY ' . $column_name . ' ' . $column_data['column_type_sql'];
+ // We need the data here
+ $old_return_statements = $this->return_statements;
+ $this->return_statements = true;
+
+ // Get list of existing indexes
+ $indexes = $this->get_existing_indexes($table_name, $column_name);
+ $unique_indexes = $this->get_existing_indexes($table_name, $column_name, true);
+
+ // Drop any indexes
+ if (!empty($indexes) || !empty($unique_indexes))
+ {
+ $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes));
+ foreach ($drop_indexes as $index_name)
+ {
+ $result = $this->sql_index_drop($table_name, $this->strip_table_name_from_index_name($table_name, $index_name));
+ $statements = array_merge($statements, $result);
+ }
+ }
+
+ $temp_column_name = 'temp_' . substr(md5($column_name), 0, 25);
+ // Add a temporary table with the new type
+ $result = $this->sql_column_add($table_name, $temp_column_name, $original_column_data);
+ $statements = array_merge($statements, $result);
+
+ // Copy the data to the new column
+ $statements[] = 'UPDATE ' . $table_name . ' SET ' . $temp_column_name . ' = ' . $column_name;
+
+ // Drop the original column
+ $result = $this->sql_column_remove($table_name, $column_name);
+ $statements = array_merge($statements, $result);
+
+ // Recreate the original column with the new type
+ $result = $this->sql_column_add($table_name, $column_name, $original_column_data);
+ $statements = array_merge($statements, $result);
+
+ if (!empty($indexes))
+ {
+ // Recreate indexes after we changed the column
+ foreach ($indexes as $index_name => $index_data)
+ {
+ $result = $this->sql_create_index($table_name, $this->strip_table_name_from_index_name($table_name, $index_name), $index_data);
+ $statements = array_merge($statements, $result);
+ }
+ }
+
+ if (!empty($unique_indexes))
+ {
+ // Recreate unique indexes after we changed the column
+ foreach ($unique_indexes as $index_name => $index_data)
+ {
+ $result = $this->sql_create_unique_index($table_name, $this->strip_table_name_from_index_name($table_name, $index_name), $index_data);
+ $statements = array_merge($statements, $result);
+ }
+ }
+
+ // Copy the data to the original column
+ $statements[] = 'UPDATE ' . $table_name . ' SET ' . $column_name . ' = ' . $temp_column_name;
+
+ // Drop the temporary column again
+ $result = $this->sql_column_remove($table_name, $temp_column_name);
+ $statements = array_merge($statements, $result);
+
+ $this->return_statements = $old_return_statements;
break;
case 'postgres':
@@ -2517,45 +2605,78 @@ class tools
*
* @param string $table_name
* @param string $column_name
+ * @param bool $unique Should we get unique indexes or normal ones
* @return array Array with Index name => columns
*/
- protected function mssql_get_existing_indexes($table_name, $column_name)
+ public function get_existing_indexes($table_name, $column_name, $unique = false)
{
- $existing_indexes = array();
- if ($this->mssql_is_sql_server_2000())
+ switch ($this->sql_layer)
{
- // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx
- // Deprecated in SQL Server 2005
- $sql = "SELECT DISTINCT ix.name AS phpbb_index_name
- FROM sysindexes ix
- INNER JOIN sysindexkeys ixc
- ON ixc.id = ix.id
- AND ixc.indid = ix.indid
- INNER JOIN syscolumns cols
- ON cols.colid = ixc.colid
- AND cols.id = ix.id
- WHERE ix.id = object_id('{$table_name}')
- AND cols.name = '{$column_name}'";
+ case 'mysql_40':
+ case 'mysql_41':
+ case 'postgres':
+ case 'sqlite':
+ case 'sqlite3':
+ // Not supported
+ throw new \Exception('DBMS is not supported');
+ break;
}
- else
+
+ $sql = '';
+ $existing_indexes = array();
+
+ switch ($this->sql_layer)
{
- $sql = "SELECT DISTINCT ix.name AS phpbb_index_name
- FROM sys.indexes ix
- INNER JOIN sys.index_columns ixc
- ON ixc.object_id = ix.object_id
- AND ixc.index_id = ix.index_id
- INNER JOIN sys.columns cols
- ON cols.column_id = ixc.column_id
- AND cols.object_id = ix.object_id
- WHERE ix.object_id = object_id('{$table_name}')
- AND cols.name = '{$column_name}'";
+ case 'mssql':
+ case 'mssqlnative':
+ if ($this->mssql_is_sql_server_2000())
+ {
+ // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx
+ // Deprecated in SQL Server 2005
+ $sql = "SELECT DISTINCT ix.name AS phpbb_index_name
+ FROM sysindexes ix
+ INNER JOIN sysindexkeys ixc
+ ON ixc.id = ix.id
+ AND ixc.indid = ix.indid
+ INNER JOIN syscolumns cols
+ ON cols.colid = ixc.colid
+ AND cols.id = ix.id
+ WHERE ix.id = object_id('{$table_name}')
+ AND cols.name = '{$column_name}'
+ AND INDEXPROPERTY(ix.id, ix.name, 'IsUnique') = " . ($unique) ? '1' : '0';
+ }
+ else
+ {
+ $sql = "SELECT DISTINCT ix.name AS phpbb_index_name
+ FROM sys.indexes ix
+ INNER JOIN sys.index_columns ixc
+ ON ixc.object_id = ix.object_id
+ AND ixc.index_id = ix.index_id
+ INNER JOIN sys.columns cols
+ ON cols.column_id = ixc.column_id
+ AND cols.object_id = ix.object_id
+ WHERE ix.object_id = object_id('{$table_name}')
+ AND cols.name = '{$column_name}'
+ AND ix.is_unique = " . ($unique) ? '1' : '0';
+ }
+ break;
+
+ case 'oracle':
+ $sql = "SELECT ix.index_name AS phpbb_index_name, ix.uniqueness AS is_unique
+ FROM all_ind_columns ixc, all_indexes ix
+ WHERE ix.index_name = ixc.index_name
+ AND ixc.table_name = '" . strtoupper($table_name) . "'
+ AND ixc.column_name = '" . strtoupper($column_name) . "'";
+ break;
}
$result = $this->db->sql_query($sql);
- $existing_indexes = array();
while ($row = $this->db->sql_fetchrow($result))
{
- $existing_indexes[$row['phpbb_index_name']] = array();
+ if (!isset($row['is_unique']) || ($unique && $row['is_unique'] == 'UNIQUE') || (!$unique && $row['is_unique'] == 'NONUNIQUE'))
+ {
+ $existing_indexes[$row['phpbb_index_name']] = array();
+ }
}
$this->db->sql_freeresult($result);
@@ -2564,35 +2685,47 @@ class tools
return array();
}
- if ($this->mssql_is_sql_server_2000())
- {
- $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name
- FROM sysindexes ix
- INNER JOIN sysindexkeys ixc
- ON ixc.id = ix.id
- AND ixc.indid = ix.indid
- INNER JOIN syscolumns cols
- ON cols.colid = ixc.colid
- AND cols.id = ix.id
- WHERE ix.id = object_id('{$table_name}')
- AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes));
- }
- else
+ switch ($this->sql_layer)
{
- $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name
- FROM sys.indexes ix
- INNER JOIN sys.index_columns ixc
- ON ixc.object_id = ix.object_id
- AND ixc.index_id = ix.index_id
- INNER JOIN sys.columns cols
- ON cols.column_id = ixc.column_id
- AND cols.object_id = ix.object_id
- WHERE ix.object_id = object_id('{$table_name}')
- AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes));
+ case 'mssql':
+ case 'mssqlnative':
+ if ($this->mssql_is_sql_server_2000())
+ {
+ $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name
+ FROM sysindexes ix
+ INNER JOIN sysindexkeys ixc
+ ON ixc.id = ix.id
+ AND ixc.indid = ix.indid
+ INNER JOIN syscolumns cols
+ ON cols.colid = ixc.colid
+ AND cols.id = ix.id
+ WHERE ix.id = object_id('{$table_name}')
+ AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes));
+ }
+ else
+ {
+ $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name
+ FROM sys.indexes ix
+ INNER JOIN sys.index_columns ixc
+ ON ixc.object_id = ix.object_id
+ AND ixc.index_id = ix.index_id
+ INNER JOIN sys.columns cols
+ ON cols.column_id = ixc.column_id
+ AND cols.object_id = ix.object_id
+ WHERE ix.object_id = object_id('{$table_name}')
+ AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes));
+ }
+ break;
+
+ case 'oracle':
+ $sql = "SELECT index_name AS phpbb_index_name, column_name AS phpbb_column_name
+ FROM all_ind_columns
+ WHERE table_name = '" . strtoupper($table_name) . "'
+ AND " . $this->db->sql_in_set('index_name', array_keys($existing_indexes));
+ break;
}
$result = $this->db->sql_query($sql);
-
while ($row = $this->db->sql_fetchrow($result))
{
$existing_indexes[$row['phpbb_index_name']][] = $row['phpbb_column_name'];
diff --git a/phpBB/phpbb/mimetype/content_guesser.php b/phpBB/phpbb/mimetype/content_guesser.php
index 9c83e8dd73..f3ad7f5f41 100644
--- a/phpBB/phpbb/mimetype/content_guesser.php
+++ b/phpBB/phpbb/mimetype/content_guesser.php
@@ -20,7 +20,7 @@ class content_guesser extends guesser_base
*/
public function is_supported()
{
- return function_exists('mime_content_type');
+ return function_exists('mime_content_type') && is_callable('mime_content_type');
}
/**
diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php
index 0aad19d6bf..22c9076adc 100644
--- a/phpBB/phpbb/notification/type/approve_post.php
+++ b/phpBB/phpbb/notification/type/approve_post.php
@@ -81,14 +81,7 @@ class approve_post extends \phpbb\notification\type\post
$users = array();
$users[$post['poster_id']] = array('');
- $auth_read = $this->auth->acl_get_list(array_keys($users), 'f_read', $post['forum_id']);
-
- if (empty($auth_read))
- {
- return array();
- }
-
- return $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], array_merge($options, array(
+ return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array(
'item_type' => self::$notification_option['id'],
)));
}
diff --git a/phpBB/phpbb/notification/type/approve_topic.php b/phpBB/phpbb/notification/type/approve_topic.php
index e649f3920e..77e53a0064 100644
--- a/phpBB/phpbb/notification/type/approve_topic.php
+++ b/phpBB/phpbb/notification/type/approve_topic.php
@@ -81,14 +81,7 @@ class approve_topic extends \phpbb\notification\type\topic
$users = array();
$users[$post['poster_id']] = array('');
- $auth_read = $this->auth->acl_get_list(array_keys($users), 'f_read', $post['forum_id']);
-
- if (empty($auth_read))
- {
- return array();
- }
-
- return $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], array_merge($options, array(
+ return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array(
'item_type' => self::$notification_option['id'],
)));
}
diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php
index a11ad76db9..4ead06071e 100644
--- a/phpBB/phpbb/notification/type/base.php
+++ b/phpBB/phpbb/notification/type/base.php
@@ -533,4 +533,37 @@ abstract class base implements \phpbb\notification\type\type_interface
WHERE ' . $where;
$this->db->sql_query($sql);
}
+
+ /**
+ * Get a list of users that are authorised to receive notifications
+ *
+ * @param array $users Array of users that have subscribed to a notification
+ * @param int $forum_id Forum ID of the forum
+ * @param array $options Array of notification options
+ * @param bool $sort Whether the users array should be sorted. Default: false
+ * @return array Array of users that are authorised recipients
+ */
+ protected function get_authorised_recipients($users, $forum_id, $options, $sort = false)
+ {
+ if (empty($users))
+ {
+ return array();
+ }
+
+ $users = array_unique($users);
+
+ if ($sort)
+ {
+ sort($users);
+ }
+
+ $auth_read = $this->auth->acl_get_list($users, 'f_read', $forum_id);
+
+ if (empty($auth_read))
+ {
+ return array();
+ }
+
+ return $this->check_user_notification_options($auth_read[$forum_id]['f_read'], $options);
+ }
}
diff --git a/phpBB/phpbb/notification/type/bookmark.php b/phpBB/phpbb/notification/type/bookmark.php
index c83288cfb8..21180b3b53 100644
--- a/phpBB/phpbb/notification/type/bookmark.php
+++ b/phpBB/phpbb/notification/type/bookmark.php
@@ -83,21 +83,13 @@ class bookmark extends \phpbb\notification\type\post
}
$this->db->sql_freeresult($result);
- if (empty($users))
- {
- return array();
- }
- sort($users);
+ $notify_users = $this->get_authorised_recipients($users, $post['forum_id'], $options, true);
- $auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']);
-
- if (empty($auth_read))
+ if (empty($notify_users))
{
return array();
}
- $notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options);
-
// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
$update_notifications = array();
$sql = 'SELECT n.*
diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php
index 357176ec35..1eba4a6a88 100644
--- a/phpBB/phpbb/notification/type/post.php
+++ b/phpBB/phpbb/notification/type/post.php
@@ -123,23 +123,13 @@ class post extends \phpbb\notification\type\base
}
$this->db->sql_freeresult($result);
- if (empty($users))
- {
- return array();
- }
+ $notify_users = $this->get_authorised_recipients($users, $post['forum_id'], $options, true);
- $users = array_unique($users);
- sort($users);
-
- $auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']);
-
- if (empty($auth_read))
+ if (empty($notify_users))
{
return array();
}
- $notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options);
-
// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
$update_notifications = array();
$sql = 'SELECT n.*
diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php
index 6e672e6fbd..5c3c822ec2 100644
--- a/phpBB/phpbb/notification/type/quote.php
+++ b/phpBB/phpbb/notification/type/quote.php
@@ -102,22 +102,7 @@ class quote extends \phpbb\notification\type\post
}
$this->db->sql_freeresult($result);
- if (empty($users))
- {
- return array();
- }
- sort($users);
-
- $auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']);
-
- if (empty($auth_read))
- {
- return array();
- }
-
- $notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options);
-
- return $notify_users;
+ return $this->get_authorised_recipients($users, $post['forum_id'], $options, true);
}
/**
diff --git a/phpBB/phpbb/notification/type/topic.php b/phpBB/phpbb/notification/type/topic.php
index 289e45bedb..af199fb765 100644
--- a/phpBB/phpbb/notification/type/topic.php
+++ b/phpBB/phpbb/notification/type/topic.php
@@ -111,19 +111,7 @@ class topic extends \phpbb\notification\type\base
}
$this->db->sql_freeresult($result);
- if (empty($users))
- {
- return array();
- }
-
- $auth_read = $this->auth->acl_get_list($users, 'f_read', $topic['forum_id']);
-
- if (empty($auth_read))
- {
- return array();
- }
-
- return $this->check_user_notification_options($auth_read[$topic['forum_id']]['f_read'], $options);
+ return $this->get_authorised_recipients($users, $topic['forum_id'], $options);
}
/**
diff --git a/phpBB/phpbb/profilefields/type/type_googleplus.php b/phpBB/phpbb/profilefields/type/type_googleplus.php
index 887baa3de1..e6729b1935 100644
--- a/phpBB/phpbb/profilefields/type/type_googleplus.php
+++ b/phpBB/phpbb/profilefields/type/type_googleplus.php
@@ -40,7 +40,7 @@ class type_googleplus extends type_string
'field_length' => 20,
'field_minlen' => 3,
'field_maxlen' => 255,
- 'field_validation' => '[\w]+',
+ 'field_validation' => '(?:(?!\.{2,})([^<>=+]))+',
'field_novalue' => '',
'field_default_value' => '',
);
diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php
index 4e90044395..ea98034434 100644
--- a/phpBB/phpbb/user.php
+++ b/phpBB/phpbb/user.php
@@ -31,6 +31,11 @@ class user extends \phpbb\session
*/
public $timezone;
+ /**
+ * @var string Class name of datetime object
+ */
+ protected $datetime;
+
var $lang_name = false;
var $lang_id = false;
var $lang_path;
@@ -42,12 +47,14 @@ class user extends \phpbb\session
/**
* Constructor to set the lang path
+ * @param string $datetime_class Class name of datetime class
*/
- function __construct()
+ function __construct($datetime_class)
{
global $phpbb_root_path;
$this->lang_path = $phpbb_root_path . 'language/';
+ $this->datetime = $datetime_class;
}
/**
@@ -727,7 +734,7 @@ class user extends \phpbb\session
public function create_datetime($time = 'now', \DateTimeZone $timezone = null)
{
$timezone = $timezone ?: $this->timezone;
- return new \phpbb\datetime($this, $time, $timezone);
+ return new $this->datetime($this, $time, $timezone);
}
/**