diff options
Diffstat (limited to 'phpBB/includes')
-rw-r--r-- | phpBB/includes/db/driver/driver.php | 4 | ||||
-rw-r--r-- | phpBB/includes/db/sql_insert_buffer.php | 150 | ||||
-rw-r--r-- | phpBB/includes/notification/manager.php | 11 | ||||
-rw-r--r-- | phpBB/includes/notification/method/email.php | 78 | ||||
-rw-r--r-- | phpBB/includes/notification/method/jabber.php | 18 | ||||
-rw-r--r-- | phpBB/includes/notification/method/messenger_base.php | 100 | ||||
-rw-r--r-- | phpBB/includes/search/fulltext_sphinx.php | 6 | ||||
-rw-r--r-- | phpBB/includes/search/sphinx/config_variable.php | 2 | ||||
-rw-r--r-- | phpBB/includes/ucp/ucp_pm_viewmessage.php | 3 | ||||
-rw-r--r-- | phpBB/includes/user_loader.php | 4 |
10 files changed, 268 insertions, 108 deletions
diff --git a/phpBB/includes/db/driver/driver.php b/phpBB/includes/db/driver/driver.php index 8dda94bc2c..b915ee081b 100644 --- a/phpBB/includes/db/driver/driver.php +++ b/phpBB/includes/db/driver/driver.php @@ -568,12 +568,12 @@ class phpbb_db_driver * Run more than one insert statement. * * @param string $table table name to run the statements on - * @param array &$sql_ary multi-dimensional array holding the statement data. + * @param array $sql_ary multi-dimensional array holding the statement data. * * @return bool false if no statements were executed. * @access public */ - function sql_multi_insert($table, &$sql_ary) + function sql_multi_insert($table, $sql_ary) { if (!sizeof($sql_ary)) { diff --git a/phpBB/includes/db/sql_insert_buffer.php b/phpBB/includes/db/sql_insert_buffer.php new file mode 100644 index 0000000000..c18f908429 --- /dev/null +++ b/phpBB/includes/db/sql_insert_buffer.php @@ -0,0 +1,150 @@ +<?php +/** +* +* @package dbal +* @copyright (c) 2013 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* Collects rows for insert into a database until the buffer size is reached. +* Then flushes the buffer to the database and starts over again. +* +* Benefits over collecting a (possibly huge) insert array and then using +* $db->sql_multi_insert() include: +* +* - Going over max packet size of the database connection is usually prevented +* because the data is submitted in batches. +* +* - Reaching database connection timeout is usually prevented because +* submission of batches talks to the database every now and then. +* +* - Usage of less PHP memory because data no longer needed is discarded on +* buffer flush. +* +* Attention: +* Please note that users of this class have to call flush() to flush the +* remaining rows to the database after their batch insert operation is +* finished. +* +* Usage: +* <code> +* $buffer = new phpbb_db_sql_insert_buffer($db, 'test_table', 1234); +* +* while (do_stuff()) +* { +* $buffer->insert(array( +* 'column1' => 'value1', +* 'column2' => 'value2', +* )); +* } +* +* $buffer->flush(); +* </code> +* +* @package dbal +*/ +class phpbb_db_sql_insert_buffer +{ + /** @var phpbb_db_driver */ + protected $db; + + /** @var string */ + protected $table_name; + + /** @var int */ + protected $max_buffered_rows; + + /** @var array */ + protected $buffer = array(); + + /** + * @param phpbb_db_driver $db + * @param string $table_name + * @param int $max_buffered_rows + */ + public function __construct(phpbb_db_driver $db, $table_name, $max_buffered_rows = 500) + { + $this->db = $db; + $this->table_name = $table_name; + $this->max_buffered_rows = $max_buffered_rows; + } + + /** + * Inserts a single row into the buffer if multi insert is supported by the + * database (otherwise an insert query is sent immediately). Then flushes + * the buffer if the number of rows in the buffer is now greater than or + * equal to $max_buffered_rows. + * + * @param array $row + * + * @return bool True when some data was flushed to the database. + * False otherwise. + */ + public function insert(array $row) + { + $this->buffer[] = $row; + + // Flush buffer if it is full or when DB does not support multi inserts. + // In the later case, the buffer will always only contain one row. + if (!$this->db->multi_insert || sizeof($this->buffer) >= $this->max_buffered_rows) + { + return $this->flush(); + } + + return false; + } + + /** + * Inserts a row set, i.e. an array of rows, by calling insert(). + * + * Please note that it is in most cases better to use insert() instead of + * first building a huge rowset. Or at least sizeof($rows) should be kept + * small. + * + * @param array $rows + * + * @return bool True when some data was flushed to the database. + * False otherwise. + */ + public function insert_all(array $rows) + { + // Using bitwise |= because PHP does not have logical ||= + $result = 0; + + foreach ($rows as $row) + { + $result |= (int) $this->insert($row); + } + + return (bool) $result; + } + + /** + * Flushes the buffer content to the DB and clears the buffer. + * + * @return bool True when some data was flushed to the database. + * False otherwise. + */ + public function flush() + { + if (!empty($this->buffer)) + { + $this->db->sql_multi_insert($this->table_name, $this->buffer); + $this->buffer = array(); + + return true; + } + + return false; + } +} diff --git a/phpBB/includes/notification/manager.php b/phpBB/includes/notification/manager.php index ff83d4bb37..9eceeb753a 100644 --- a/phpBB/includes/notification/manager.php +++ b/phpBB/includes/notification/manager.php @@ -256,6 +256,7 @@ class phpbb_notification_manager SET notification_read = 1 WHERE notification_time <= " . (int) $time . (($item_type !== false) ? ' AND ' . (is_array($item_type) ? $this->db->sql_in_set('item_type', $item_type) : " item_type = '" . $this->db->sql_escape($item_type) . "'") : '') . + (($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '') . (($item_id !== false) ? ' AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id) : ''); $this->db->sql_query($sql); } @@ -389,7 +390,6 @@ class phpbb_notification_manager $user_ids = array(); $notification_objects = $notification_methods = array(); - $new_rows = array(); // Never send notifications to the anonymous user! unset($notify_users[ANONYMOUS]); @@ -419,6 +419,8 @@ class phpbb_notification_manager $pre_create_data = $notification->pre_create_insert_array($data, $notify_users); unset($notification); + $insert_buffer = new phpbb_db_sql_insert_buffer($this->db, $this->notifications_table); + // Go through each user so we can insert a row in the DB and then notify them by their desired means foreach ($notify_users as $user => $methods) { @@ -426,8 +428,8 @@ class phpbb_notification_manager $notification->user_id = (int) $user; - // Store the creation array in our new rows that will be inserted later - $new_rows[] = $notification->create_insert_array($data, $pre_create_data); + // Insert notification row using buffer. + $insert_buffer->insert($notification->create_insert_array($data, $pre_create_data)); // Users are needed to send notifications $user_ids = array_merge($user_ids, $notification->users_to_query()); @@ -447,8 +449,7 @@ class phpbb_notification_manager } } - // insert into the db - $this->db->sql_multi_insert($this->notifications_table, $new_rows); + $insert_buffer->flush(); // We need to load all of the users to send notifications $this->user_loader->load_users($user_ids); diff --git a/phpBB/includes/notification/method/email.php b/phpBB/includes/notification/method/email.php index 4a7fea6df3..dc505c0d41 100644 --- a/phpBB/includes/notification/method/email.php +++ b/phpBB/includes/notification/method/email.php @@ -34,20 +34,6 @@ class phpbb_notification_method_email extends phpbb_notification_method_base } /** - * Notify method (since jabber gets sent through the same messenger, we let the jabber class inherit from this to reduce code duplication) - * - * @var mixed - */ - protected $notify_method = NOTIFY_EMAIL; - - /** - * Base directory to prepend to the email template name - * - * @var string - */ - protected $email_template_base_dir = ''; - - /** * Is this method available for the user? * This is checked on the notifications options */ @@ -61,68 +47,6 @@ class phpbb_notification_method_email extends phpbb_notification_method_base */ public function notify() { - if (!sizeof($this->queue)) - { - return; - } - - // Load all users we want to notify (we need their email address) - $user_ids = $users = array(); - foreach ($this->queue as $notification) - { - $user_ids[] = $notification->user_id; - } - - // We do not send emails to banned users - if (!function_exists('phpbb_get_banned_user_ids')) - { - include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); - } - $banned_users = phpbb_get_banned_user_ids($user_ids); - - // Load all the users we need - $this->user_loader->load_users($user_ids); - - // Load the messenger - if (!class_exists('messenger')) - { - include($this->phpbb_root_path . 'includes/functions_messenger.' . $this->php_ext); - } - $messenger = new messenger(); - $board_url = generate_board_url(); - - // Time to go through the queue and send emails - foreach ($this->queue as $notification) - { - if ($notification->get_email_template() === false) - { - continue; - } - - $user = $this->user_loader->get_user($notification->user_id); - - if ($user['user_type'] == USER_IGNORE || in_array($notification->user_id, $banned_users)) - { - continue; - } - - $messenger->template($this->email_template_base_dir . $notification->get_email_template(), $user['user_lang']); - - $messenger->to($user['user_email'], $user['username']); - - $messenger->assign_vars(array_merge(array( - 'USERNAME' => $user['username'], - - 'U_NOTIFICATION_SETTINGS' => generate_board_url() . '/ucp.' . $this->php_ext . '?i=ucp_notifications', - ), $notification->get_email_template_variables())); - - $messenger->send($this->notify_method); - } - - // Save the queue in the messenger class (has to be called or these emails could be lost?) - $messenger->save_queue(); - - // We're done, empty the queue - $this->empty_queue(); + return $this->notify_using_messenger(NOTIFY_EMAIL); } } diff --git a/phpBB/includes/notification/method/jabber.php b/phpBB/includes/notification/method/jabber.php index 863846b8a5..debffa8ce5 100644 --- a/phpBB/includes/notification/method/jabber.php +++ b/phpBB/includes/notification/method/jabber.php @@ -21,7 +21,7 @@ if (!defined('IN_PHPBB')) * * @package notifications */ -class phpbb_notification_method_jabber extends phpbb_notification_method_email +class phpbb_notification_method_jabber extends phpbb_notification_method_messenger_base { /** * Get notification method name @@ -34,20 +34,6 @@ class phpbb_notification_method_jabber extends phpbb_notification_method_email } /** - * Notify method (since jabber gets sent through the same messenger, we let the jabber class inherit from this to reduce code duplication) - * - * @var mixed - */ - protected $notify_method = NOTIFY_IM; - - /** - * Base directory to prepend to the email template name - * - * @var string - */ - protected $email_template_base_dir = 'short/'; - - /** * Is this method available for the user? * This is checked on the notifications options */ @@ -72,6 +58,6 @@ class phpbb_notification_method_jabber extends phpbb_notification_method_email return; } - return parent::notify(); + return $this->notify_using_messenger(NOTIFY_IM, 'short/'); } } diff --git a/phpBB/includes/notification/method/messenger_base.php b/phpBB/includes/notification/method/messenger_base.php new file mode 100644 index 0000000000..ce1ecc09ce --- /dev/null +++ b/phpBB/includes/notification/method/messenger_base.php @@ -0,0 +1,100 @@ +<?php +/** +* +* @package notifications +* @copyright (c) 2012 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* Abstract notification method handling email and jabber notifications +* using the phpBB messenger. +* +* @package notifications +*/ +abstract class phpbb_notification_method_messenger_base extends phpbb_notification_method_base +{ + /** + * Notify using phpBB messenger + * + * @param int $notify_method Notify method for messenger (e.g. NOTIFY_IM) + * @param string $template_dir_prefix Base directory to prepend to the email template name + * + * @return null + */ + protected function notify_using_messenger($notify_method, $template_dir_prefix = '') + { + if (empty($this->queue)) + { + return; + } + + // Load all users we want to notify (we need their email address) + $user_ids = $users = array(); + foreach ($this->queue as $notification) + { + $user_ids[] = $notification->user_id; + } + + // We do not send emails to banned users + if (!function_exists('phpbb_get_banned_user_ids')) + { + include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); + } + $banned_users = phpbb_get_banned_user_ids($user_ids); + + // Load all the users we need + $this->user_loader->load_users($user_ids); + + // Load the messenger + if (!class_exists('messenger')) + { + include($this->phpbb_root_path . 'includes/functions_messenger.' . $this->php_ext); + } + $messenger = new messenger(); + $board_url = generate_board_url(); + + // Time to go through the queue and send emails + foreach ($this->queue as $notification) + { + if ($notification->get_email_template() === false) + { + continue; + } + + $user = $this->user_loader->get_user($notification->user_id); + + if ($user['user_type'] == USER_IGNORE || in_array($notification->user_id, $banned_users)) + { + continue; + } + + $messenger->template($email_template_base_dir . $notification->get_email_template(), $user['user_lang']); + + $messenger->to($user['user_email'], $user['username']); + + $messenger->assign_vars(array_merge(array( + 'USERNAME' => $user['username'], + + 'U_NOTIFICATION_SETTINGS' => generate_board_url() . '/ucp.' . $this->php_ext . '?i=ucp_notifications', + ), $notification->get_email_template_variables())); + + $messenger->send($notify_method); + } + + // Save the queue in the messenger class (has to be called or these emails could be lost?) + $messenger->save_queue(); + + // We're done, empty the queue + $this->empty_queue(); + } +} diff --git a/phpBB/includes/search/fulltext_sphinx.php b/phpBB/includes/search/fulltext_sphinx.php index 48445d0794..28761792ec 100644 --- a/phpBB/includes/search/fulltext_sphinx.php +++ b/phpBB/includes/search/fulltext_sphinx.php @@ -258,13 +258,13 @@ class phpbb_search_fulltext_sphinx $config_object = new phpbb_search_sphinx_config($this->config_file_data); $config_data = array( 'source source_phpbb_' . $this->id . '_main' => array( - array('type', $this->dbtype), + array('type', $this->dbtype . ' # mysql or pgsql'), // This config value sql_host needs to be changed incase sphinx and sql are on different servers - array('sql_host', $dbhost), + array('sql_host', $dbhost . ' # SQL server host sphinx connects to'), array('sql_user', $dbuser), array('sql_pass', $dbpasswd), array('sql_db', $dbname), - array('sql_port', $dbport), + array('sql_port', $dbport . ' # optional, default is 3306 for mysql and 5432 for pgsql'), array('sql_query_pre', 'SET NAMES \'utf8\''), array('sql_query_pre', 'UPDATE ' . SPHINX_TABLE . ' SET max_doc_id = (SELECT MAX(post_id) FROM ' . POSTS_TABLE . ') WHERE counter_id = 1'), array('sql_query_range', 'SELECT MIN(post_id), MAX(post_id) FROM ' . POSTS_TABLE . ''), diff --git a/phpBB/includes/search/sphinx/config_variable.php b/phpBB/includes/search/sphinx/config_variable.php index 35abe281cb..2c1d35a49c 100644 --- a/phpBB/includes/search/sphinx/config_variable.php +++ b/phpBB/includes/search/sphinx/config_variable.php @@ -75,6 +75,6 @@ class phpbb_search_sphinx_config_variable */ function to_string() { - return "\t" . $this->name . ' = ' . str_replace("\n", "\\\n", $this->value) . ' ' . $this->comment . "\n"; + return "\t" . $this->name . ' = ' . str_replace("\n", " \\\n", $this->value) . ' ' . $this->comment . "\n"; } } diff --git a/phpBB/includes/ucp/ucp_pm_viewmessage.php b/phpBB/includes/ucp/ucp_pm_viewmessage.php index 712032463f..b7d2dd6821 100644 --- a/phpBB/includes/ucp/ucp_pm_viewmessage.php +++ b/phpBB/includes/ucp/ucp_pm_viewmessage.php @@ -94,8 +94,7 @@ function view_message($id, $mode, $folder_id, $msg_id, $folder, $message_row) // Editing information if ($message_row['message_edit_count'] && $config['display_last_edited']) { - $l_edit_time_total = ($message_row['message_edit_count'] == 1) ? $user->lang['EDITED_TIME_TOTAL'] : $user->lang['EDITED_TIMES_TOTAL']; - $l_edited_by = '<br /><br />' . sprintf($l_edit_time_total, (!$message_row['message_edit_user']) ? $message_row['username'] : $message_row['message_edit_user'], $user->format_date($message_row['message_edit_time'], false, true), $message_row['message_edit_count']); + $l_edited_by = '<br /><br />' . $user->lang('EDITED_TIMES_TOTAL', (int) $message_row['message_edit_count'], (!$message_row['message_edit_user']) ? $message_row['username'] : $message_row['message_edit_user'], $user->format_date($message_row['message_edit_time'], false, true)); } else { diff --git a/phpBB/includes/user_loader.php b/phpBB/includes/user_loader.php index 77128d6570..37bf9648c1 100644 --- a/phpBB/includes/user_loader.php +++ b/phpBB/includes/user_loader.php @@ -70,8 +70,8 @@ class phpbb_user_loader { $user_ids[] = ANONYMOUS; - // Load the users - $user_ids = array_unique($user_ids); + // Make user_ids unique and convert to integer. + $user_ids = array_map('intval', array_unique($user_ids)); // Do not load users we already have in $this->users $user_ids = array_diff($user_ids, array_keys($this->users)); |