diff options
Diffstat (limited to 'phpBB/phpbb')
54 files changed, 1149 insertions, 95 deletions
diff --git a/phpBB/phpbb/auth/provider/base.php b/phpBB/phpbb/auth/provider/base.php index 4c49070eaf..dea27ccc25 100644 --- a/phpBB/phpbb/auth/provider/base.php +++ b/phpBB/phpbb/auth/provider/base.php @@ -61,7 +61,7 @@ abstract class base implements \phpbb\auth\provider\provider_interface /** * {@inheritdoc} */ - public function get_auth_link_data() + public function get_auth_link_data($user_id = 0) { return; } diff --git a/phpBB/phpbb/auth/provider/ldap.php b/phpBB/phpbb/auth/provider/ldap.php index c71950c698..c48b771ab0 100644 --- a/phpBB/phpbb/auth/provider/ldap.php +++ b/phpBB/phpbb/auth/provider/ldap.php @@ -289,7 +289,6 @@ class ldap extends \phpbb\auth\provider\base /** * {@inheritdoc} */ - public function acp() { // These are fields required in the config table @@ -308,7 +307,7 @@ class ldap extends \phpbb\auth\provider\base 'TEMPLATE_VARS' => array( 'AUTH_LDAP_BASE_DN' => $new_config['ldap_base_dn'], 'AUTH_LDAP_EMAIL' => $new_config['ldap_email'], - 'AUTH_LDAP_PASSORD' => $new_config['ldap_password'], + 'AUTH_LDAP_PASSORD' => $new_config['ldap_password'] !== '' ? '********' : '', 'AUTH_LDAP_PORT' => $new_config['ldap_port'], 'AUTH_LDAP_SERVER' => $new_config['ldap_server'], 'AUTH_LDAP_UID' => $new_config['ldap_uid'], diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php index c0ce3f1fba..be0fbf5831 100644 --- a/phpBB/phpbb/auth/provider/oauth/oauth.php +++ b/phpBB/phpbb/auth/provider/oauth/oauth.php @@ -553,13 +553,13 @@ class oauth extends \phpbb\auth\provider\base /** * {@inheritdoc} */ - public function get_auth_link_data() + public function get_auth_link_data($user_id = 0) { $block_vars = array(); // Get all external accounts tied to the current user $data = array( - 'user_id' => (int) $this->user->data['user_id'], + 'user_id' => ($user_id <= 0) ? (int) $this->user->data['user_id'] : (int) $user_id, ); $sql = 'SELECT oauth_provider_id, provider FROM ' . $this->auth_provider_oauth_token_account_assoc . ' WHERE ' . $this->db->sql_build_array('SELECT', $data); @@ -616,10 +616,13 @@ class oauth extends \phpbb\auth\provider\base return 'LOGIN_LINK_MISSING_DATA'; } + // Remove user specified in $link_data if possible + $user_id = isset($link_data['user_id']) ? $link_data['user_id'] : $this->user->data['user_id']; + // Remove the link $sql = 'DELETE FROM ' . $this->auth_provider_oauth_token_account_assoc . " WHERE provider = '" . $this->db->sql_escape($link_data['oauth_service']) . "' - AND user_id = " . (int) $this->user->data['user_id']; + AND user_id = " . (int) $user_id; $this->db->sql_query($sql); // Clear all tokens belonging to the user on this servce diff --git a/phpBB/phpbb/auth/provider/provider_interface.php b/phpBB/phpbb/auth/provider/provider_interface.php index 613297cefc..35e0f559a1 100644 --- a/phpBB/phpbb/auth/provider/provider_interface.php +++ b/phpBB/phpbb/auth/provider/provider_interface.php @@ -166,6 +166,10 @@ interface provider_interface /** * Returns an array of data necessary to build the ucp_auth_link page * + * @param int $user_id User ID for whom the data should be retrieved. + * defaults to 0, which is not a valid ID. The method + * should fall back to the current user's ID in this + * case. * @return array|null If this function is not implemented on an auth * provider then it returns null. If it is implemented * it will return an array of up to four elements of @@ -181,7 +185,7 @@ interface provider_interface * 'VARS' => array(...), * ) */ - public function get_auth_link_data(); + public function get_auth_link_data($user_id = 0); /** * Unlinks an external account from a phpBB account. diff --git a/phpBB/phpbb/avatar/driver/gravatar.php b/phpBB/phpbb/avatar/driver/gravatar.php index 2082e0fd02..bb4977c30c 100644 --- a/phpBB/phpbb/avatar/driver/gravatar.php +++ b/phpBB/phpbb/avatar/driver/gravatar.php @@ -172,6 +172,8 @@ class gravatar extends \phpbb\avatar\driver\driver */ protected function get_gravatar_url($row) { + global $phpbb_dispatcher; + $url = self::GRAVATAR_URL; $url .= md5(strtolower(trim($row['avatar']))); @@ -180,6 +182,17 @@ class gravatar extends \phpbb\avatar\driver\driver $url .= '?s=' . max($row['avatar_width'], $row['avatar_height']); } + /** + * Modify gravatar url + * + * @event core.get_gravatar_url_after + * @var string row User data or group data + * @var string url Gravatar URL + * @since 3.1.7-RC1 + */ + $vars = array('row', 'url'); + extract($phpbb_dispatcher->trigger_event('core.get_gravatar_url_after', compact($vars))); + return $url; } } diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index ee36243844..e44157294c 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -24,6 +24,11 @@ class upload extends \phpbb\avatar\driver\driver protected $mimetype_guesser; /** + * @var \phpbb\event\dispatcher_interface + */ + protected $dispatcher; + + /** * Construct a driver object * * @param \phpbb\config\config $config phpBB configuration @@ -31,22 +36,24 @@ class upload extends \phpbb\avatar\driver\driver * @param string $php_ext PHP file extension * @param \phpbb_path_helper $path_helper phpBB path helper * @param \phpbb\mimetype\guesser $mimetype_guesser Mimetype guesser + * @param \phpbb\event\dispatcher_interface $dispatcher phpBB Event dispatcher object * @param \phpbb\cache\driver\driver_interface $cache Cache driver */ - public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\mimetype\guesser $mimetype_guesser, \phpbb\cache\driver\driver_interface $cache = null) + public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\path_helper $path_helper, \phpbb\mimetype\guesser $mimetype_guesser, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\cache\driver\driver_interface $cache = null) { $this->config = $config; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; $this->path_helper = $path_helper; $this->mimetype_guesser = $mimetype_guesser; + $this->dispatcher = $dispatcher; $this->cache = $cache; } /** * {@inheritdoc} */ - public function get_data($row, $ignore_config = false) + public function get_data($row) { $root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $this->path_helper->get_web_root_path(); @@ -137,6 +144,15 @@ class upload extends \phpbb\avatar\driver\driver $prefix = $this->config['avatar_salt'] . '_'; $file->clean_filename('avatar', $prefix, $row['id']); + // If there was an error during upload, then abort operation + if (sizeof($file->error)) + { + $file->remove(); + $error = $file->error; + return false; + } + + // Calculate new destination $destination = $this->config['avatar_path']; // Adjust destination path (no trailing slash) @@ -151,16 +167,45 @@ class upload extends \phpbb\avatar\driver\driver $destination = ''; } - // Move file and overwrite any existing image - $file->move_file($destination, true); + /** + * Before moving new file in place (and eventually overwriting the existing avatar with the newly uploaded avatar) + * + * @event core.avatar_driver_upload_move_file_before + * @var string destination Destination directory where the file is going to be moved + * @var string prefix Prefix for the avatar filename + * @var array row Array with avatar row data + * @var array error Array of errors, if filled in by this event file will not be moved + * @since 3.1.6-RC1 + */ + $vars = array( + 'destination', + 'prefix', + 'row', + 'error', + ); + extract($this->dispatcher->trigger_event('core.avatar_driver_upload_move_file_before', compact($vars))); - if (sizeof($file->error)) + if (!sizeof($error)) + { + // Move file and overwrite any existing image + $file->move_file($destination, true); + } + + // If there was an error during move, then clean up leftovers + $error = array_merge($error, $file->error); + if (sizeof($error)) { $file->remove(); - $error = array_merge($error, $file->error); return false; } + // Delete current avatar if not overwritten + $ext = substr(strrchr($row['avatar'], '.'), 1); + if ($ext && $ext !== $file->get('extension')) + { + $this->delete($row); + } + return array( 'avatar' => $row['id'] . '_' . time() . '.' . $file->get('extension'), 'avatar_width' => $file->get('width'), @@ -185,10 +230,32 @@ class upload extends \phpbb\avatar\driver\driver */ public function delete($row) { + + $error = array(); + $destination = $this->config['avatar_path']; + $prefix = $this->config['avatar_salt'] . '_'; $ext = substr(strrchr($row['avatar'], '.'), 1); - $filename = $this->phpbb_root_path . $this->config['avatar_path'] . '/' . $this->config['avatar_salt'] . '_' . $row['id'] . '.' . $ext; + $filename = $this->phpbb_root_path . $destination . '/' . $prefix . $row['id'] . '.' . $ext; + + /** + * Before deleting an existing avatar + * + * @event core.avatar_driver_upload_delete_before + * @var string destination Destination directory where the file is going to be deleted + * @var string prefix Prefix for the avatar filename + * @var array row Array with avatar row data + * @var array error Array of errors, if filled in by this event file will not be deleted + * @since 3.1.6-RC1 + */ + $vars = array( + 'destination', + 'prefix', + 'row', + 'error', + ); + extract($this->dispatcher->trigger_event('core.avatar_driver_upload_delete_before', compact($vars))); - if (file_exists($filename)) + if (!sizeof($error) && file_exists($filename)) { @unlink($filename); } diff --git a/phpBB/phpbb/cache/driver/memcache.php b/phpBB/phpbb/cache/driver/memcache.php index 406ab11ddd..caa82fb0b1 100644 --- a/phpBB/phpbb/cache/driver/memcache.php +++ b/phpBB/phpbb/cache/driver/memcache.php @@ -50,7 +50,7 @@ class memcache extends \phpbb\cache\driver\memory parent::__construct(); $this->memcache = new \Memcache; - foreach(explode(',', PHPBB_ACM_MEMCACHE) as $u) + foreach (explode(',', PHPBB_ACM_MEMCACHE) as $u) { $parts = explode('/', $u); $this->memcache->addServer(trim($parts[0]), trim($parts[1])); diff --git a/phpBB/phpbb/captcha/plugins/qa.php b/phpBB/phpbb/captcha/plugins/qa.php index 04052b3406..2771369e57 100644 --- a/phpBB/phpbb/captcha/plugins/qa.php +++ b/phpBB/phpbb/captcha/plugins/qa.php @@ -350,7 +350,7 @@ class qa ), ); - foreach($schemas as $table => $schema) + foreach ($schemas as $table => $schema) { if (!$db_tool->sql_table_exists($table)) { diff --git a/phpBB/phpbb/config/db_text.php b/phpBB/phpbb/config/db_text.php index ddc7c9aef0..818f6bdcc9 100644 --- a/phpBB/phpbb/config/db_text.php +++ b/phpBB/phpbb/config/db_text.php @@ -100,9 +100,9 @@ class db_text $sql = 'UPDATE ' . $this->table . " SET config_value = '" . $this->db->sql_escape($value) . "' WHERE config_name = '" . $this->db->sql_escape($key) . "'"; - $result = $this->db->sql_query($sql); + $this->db->sql_query($sql); - if (!$this->db->sql_affectedrows($result)) + if (!$this->db->sql_affectedrows()) { $sql = 'INSERT INTO ' . $this->table . ' ' . $this->db->sql_build_array('INSERT', array( 'config_name' => (string) $key, diff --git a/phpBB/phpbb/console/command/cron/run.php b/phpBB/phpbb/console/command/cron/run.php index 72ad1205ef..a9648fcd41 100644 --- a/phpBB/phpbb/console/command/cron/run.php +++ b/phpBB/phpbb/console/command/cron/run.php @@ -50,6 +50,7 @@ class run extends \phpbb\console\command\command $this ->setName('cron:run') ->setDescription($this->user->lang('CLI_DESCRIPTION_CRON_RUN')) + ->setHelp($this->user->lang('CLI_HELP_CRON_RUN')) ->addArgument('name', InputArgument::OPTIONAL, $this->user->lang('CLI_DESCRIPTION_CRON_RUN_ARGUMENT_1')) ; } diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index a07a396e73..79378c2434 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -100,12 +100,14 @@ class helper * @param string $page_title The title of the page to output * @param int $status_code The status code to be sent to the page header * @param bool $display_online_list Do we display online users list + * @param int $item_id Restrict online users to item id + * @param string $item Restrict online users to a certain session item, e.g. forum for session_forum_id * * @return Response object containing rendered page */ - public function render($template_file, $page_title = '', $status_code = 200, $display_online_list = false) + public function render($template_file, $page_title = '', $status_code = 200, $display_online_list = false, $item_id = 0, $item = 'forum') { - page_header($page_title, $display_online_list); + page_header($page_title, $display_online_list, $item_id, $item); $this->template->set_filenames(array( 'body' => $template_file, diff --git a/phpBB/phpbb/cron/task/core/tidy_search.php b/phpBB/phpbb/cron/task/core/tidy_search.php index ce16b3f988..eb3970254f 100644 --- a/phpBB/phpbb/cron/task/core/tidy_search.php +++ b/phpBB/phpbb/cron/task/core/tidy_search.php @@ -20,24 +20,60 @@ namespace phpbb\cron\task\core; */ class tidy_search extends \phpbb\cron\task\base { + /** + * phpBB root path + * @var string + */ protected $phpbb_root_path; + + /** + * PHP file extension + * @var string + */ protected $php_ext; + + /** + * Auth object + * @var \phpbb\auth\auth + */ protected $auth; + + /** + * Config object + * @var \phpbb\config\config + */ protected $config; + + /** + * Database object + * @var \phpbb\db\driver\driver_interface + */ protected $db; + + /** + * User object + * @var \phpbb\user + */ protected $user; /** + * Event dispatcher object + * @var \phpbb\event\dispatcher_interface + */ + protected $phpbb_dispatcher; + + /** * Constructor. * - * @param string $phpbb_root_path The root path + * @param string $phpbb_root_path The phpBB root path * @param string $php_ext The PHP file extension - * @param \phpbb\auth\auth $auth The auth - * @param \phpbb\config\config $config The config - * @param \phpbb\db\driver\driver_interface $db The db connection - * @param \phpbb\user $user The user + * @param \phpbb\auth\auth $auth The auth object + * @param \phpbb\config\config $config The config object + * @param \phpbb\db\driver\driver_interface $db The database object + * @param \phpbb\user $user The user object + * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher The event dispatcher object */ - public function __construct($phpbb_root_path, $php_ext, \phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\user $user) + public function __construct($phpbb_root_path, $php_ext, \phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, \phpbb\event\dispatcher_interface $phpbb_dispatcher) { $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; @@ -45,6 +81,7 @@ class tidy_search extends \phpbb\cron\task\base $this->config = $config; $this->db = $db; $this->user = $user; + $this->phpbb_dispatcher = $phpbb_dispatcher; } /** @@ -58,7 +95,7 @@ class tidy_search extends \phpbb\cron\task\base // We do some additional checks in the module to ensure it can actually be utilised $error = false; - $search = new $search_type($error, $this->phpbb_root_path, $this->php_ext, $this->auth, $this->config, $this->db, $this->user); + $search = new $search_type($error, $this->phpbb_root_path, $this->php_ext, $this->auth, $this->config, $this->db, $this->user, $this->phpbb_dispatcher); if (!$error) { diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index 9fc04d47a1..1b49775b32 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -962,7 +962,7 @@ abstract class driver implements driver_interface { if (preg_match('/^(UPDATE|DELETE|REPLACE)/', $query)) { - $this->sql_report .= 'Affected rows: <b>' . $this->sql_affectedrows($this->query_result) . '</b> | '; + $this->sql_report .= 'Affected rows: <b>' . $this->sql_affectedrows() . '</b> | '; } $this->sql_report .= 'Before: ' . sprintf('%.5f', $this->curtime - $starttime) . 's | After: ' . sprintf('%.5f', $endtime - $starttime) . 's | Elapsed: <b>' . sprintf('%.5f', $endtime - $this->curtime) . 's</b>'; } diff --git a/phpBB/phpbb/db/driver/sqlite3.php b/phpBB/phpbb/db/driver/sqlite3.php index 4e3e0d3329..cc3352af34 100644 --- a/phpBB/phpbb/db/driver/sqlite3.php +++ b/phpBB/phpbb/db/driver/sqlite3.php @@ -48,6 +48,7 @@ class sqlite3 extends \phpbb\db\driver\driver try { $this->dbo = new \SQLite3($this->server, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE); + $this->dbo->busyTimeout(60000); $this->db_connect_id = true; } catch (\Exception $e) diff --git a/phpBB/phpbb/db/migration/data/v310/style_update_p1.php b/phpBB/phpbb/db/migration/data/v310/style_update_p1.php index 3b0d53d803..2c7b7edf2e 100644 --- a/phpBB/phpbb/db/migration/data/v310/style_update_p1.php +++ b/phpBB/phpbb/db/migration/data/v310/style_update_p1.php @@ -160,7 +160,7 @@ class style_update_p1 extends \phpbb\db\migration\migration FROM ' . STYLES_TABLE . " WHERE style_name = 'prosilver'"; $result = $this->sql_query($sql); - $default_style = $this->db->sql_fetchfield($result); + $default_style = $this->db->sql_fetchfield('style_id'); $this->db->sql_freeresult($result); $this->config->set('default_style', $default_style); diff --git a/phpBB/phpbb/db/migration/data/v31x/m_pm_report.php b/phpBB/phpbb/db/migration/data/v31x/m_pm_report.php new file mode 100644 index 0000000000..9b5710c639 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/m_pm_report.php @@ -0,0 +1,64 @@ +<?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\v31x; + +class m_pm_report extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v31x\v316rc1'); + } + + public function update_data() + { + return array( + array('permission.add', array('m_pm_report', true, 'm_report')), + array('custom', array( + array($this, 'update_module_auth'), + ), + ), + ); + } + + public function revert_data() + { + return array( + array('permission.remove', array('m_pm_report')), + array('custom', array( + array($this, 'revert_module_auth'), + ), + ), + ); + } + + public function update_module_auth() + { + $sql = 'UPDATE ' . MODULES_TABLE . " + SET module_auth = 'acl_m_pm_report' + WHERE module_class = 'mcp' + AND module_basename = 'mcp_pm_reports' + AND module_auth = 'aclf_m_report'"; + $this->db->sql_query($sql); + } + + public function revert_module_auth() + { + $sql = 'UPDATE ' . MODULES_TABLE . " + SET module_auth = 'aclf_m_report' + WHERE module_class = 'mcp' + AND module_basename = 'mcp_pm_reports' + AND module_auth = 'acl_m_pm_report'"; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/db/migration/data/v31x/v315.php b/phpBB/phpbb/db/migration/data/v31x/v315.php new file mode 100644 index 0000000000..778cdf717e --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/v315.php @@ -0,0 +1,31 @@ +<?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\v31x; + +class v315 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v315rc1', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.5')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v31x/v315rc1.php b/phpBB/phpbb/db/migration/data/v31x/v315rc1.php new file mode 100644 index 0000000000..4cf4472aa7 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/v315rc1.php @@ -0,0 +1,31 @@ +<?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\v31x; + +class v315rc1 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v314', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.5-RC1')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v31x/v316.php b/phpBB/phpbb/db/migration/data/v31x/v316.php new file mode 100644 index 0000000000..cec113eff2 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/v316.php @@ -0,0 +1,31 @@ +<?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\v31x; + +class v316 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v316rc1', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.6')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v31x/v316rc1.php b/phpBB/phpbb/db/migration/data/v31x/v316rc1.php new file mode 100644 index 0000000000..487cd05e5d --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/v316rc1.php @@ -0,0 +1,31 @@ +<?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\v31x; + +class v316rc1 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v315', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.6-RC1')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/tool/permission.php b/phpBB/phpbb/db/migration/tool/permission.php index 1a91127d2d..ceff6d7d5a 100644 --- a/phpBB/phpbb/db/migration/tool/permission.php +++ b/phpBB/phpbb/db/migration/tool/permission.php @@ -425,13 +425,27 @@ class permission implements \phpbb\db\migration\tool\tool_interface $role_id = (int) $this->db->sql_fetchfield('auth_role_id'); if ($role_id) { - $sql = 'SELECT role_name + $sql = 'SELECT role_name, role_type FROM ' . ACL_ROLES_TABLE . ' WHERE role_id = ' . $role_id; $this->db->sql_query($sql); - $role_name = $this->db->sql_fetchfield('role_name'); - - return $this->permission_set($role_name, $auth_option, 'role', $has_permission); + $role_data = $this->db->sql_fetchrow(); + $role_name = $role_data['role_name']; + $role_type = $role_data['role_type']; + + // Filter new auth options to match the role type: a_ | f_ | m_ | u_ + // Set new auth options to the role only if options matching the role type were found + $auth_option = array_filter($auth_option, + function ($option) use ($role_type) + { + return strpos($option, $role_type) === 0; + } + ); + + if (sizeof($auth_option)) + { + return $this->permission_set($role_name, $auth_option, 'role', $has_permission); + } } $sql = 'SELECT auth_option_id, auth_setting diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 638c13e86d..a214356ac3 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -399,7 +399,6 @@ class container_builder */ protected function get_container_filename() { - $filename = str_replace(array('/', '.'), array('slash', 'dot'), $this->phpbb_root_path); - return $this->phpbb_root_path . 'cache/container_' . $filename . '.' . $this->php_ext; + return $this->phpbb_root_path . 'cache/container_' . md5($this->phpbb_root_path) . '.' . $this->php_ext; } } diff --git a/phpBB/phpbb/feed/helper.php b/phpBB/phpbb/feed/helper.php index 198134cdcf..f2030f5ced 100644 --- a/phpBB/phpbb/feed/helper.php +++ b/phpBB/phpbb/feed/helper.php @@ -149,12 +149,10 @@ class helper { $update_count = array(); parse_attachments($forum_id, $content, $post_attachments, $update_count); - $post_attachments = implode('<br />', $post_attachments); + $content .= implode('<br />', $post_attachments); // Convert attachments' relative path to absolute path - $post_attachments = str_replace($this->phpbb_root_path . 'download/file.' . $this->phpEx, $this->get_board_url() . '/download/file.' . $this->phpEx, $post_attachments); - - $content .= $post_attachments; + $content = str_replace($this->phpbb_root_path . 'download/file.' . $this->phpEx, $this->get_board_url() . '/download/file.' . $this->phpEx, $content); } // Remove Comments from inline attachments [ia] diff --git a/phpBB/phpbb/log/log.php b/phpBB/phpbb/log/log.php index f4ba76ff0c..3d995b4e4a 100644 --- a/phpBB/phpbb/log/log.php +++ b/phpBB/phpbb/log/log.php @@ -535,7 +535,7 @@ class log implements \phpbb\log\log_interface 'ORDER_BY' => $sort_by, ); - if($log_time) + if ($log_time) { $get_logs_sql_ary['WHERE'] = 'l.log_time >= ' . (int) $log_time . ' AND ' . $get_logs_sql_ary['WHERE']; diff --git a/phpBB/phpbb/notification/method/messenger_base.php b/phpBB/phpbb/notification/method/messenger_base.php index bde4573117..c3aee088f9 100644 --- a/phpBB/phpbb/notification/method/messenger_base.php +++ b/phpBB/phpbb/notification/method/messenger_base.php @@ -69,7 +69,7 @@ abstract class messenger_base extends \phpbb\notification\method\base $user = $this->user_loader->get_user($notification->user_id); - if ($user['user_type'] == USER_IGNORE || in_array($notification->user_id, $banned_users)) + if ($user['user_type'] == USER_IGNORE || ($user['user_type'] == USER_INACTIVE && $user['user_inactive_reason'] == INACTIVE_MANUAL) || in_array($notification->user_id, $banned_users)) { continue; } diff --git a/phpBB/phpbb/notification/type/admin_activate_user.php b/phpBB/phpbb/notification/type/admin_activate_user.php index dfc0157558..7c5c18aa47 100644 --- a/phpBB/phpbb/notification/type/admin_activate_user.php +++ b/phpBB/phpbb/notification/type/admin_activate_user.php @@ -104,7 +104,7 @@ class admin_activate_user extends \phpbb\notification\type\base */ public function get_avatar() { - return $this->user_loader->get_avatar($this->item_id); + return $this->user_loader->get_avatar($this->item_id, false, true); } /** diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php index a9e635b41a..5760c12166 100644 --- a/phpBB/phpbb/notification/type/approve_post.php +++ b/phpBB/phpbb/notification/type/approve_post.php @@ -82,7 +82,7 @@ class approve_post extends \phpbb\notification\type\post $users[$post['poster_id']] = array(''); return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array( - 'item_type' => self::$notification_option['id'], + 'item_type' => static::$notification_option['id'], ))); } diff --git a/phpBB/phpbb/notification/type/approve_topic.php b/phpBB/phpbb/notification/type/approve_topic.php index 2f4678359c..26e51bf9cd 100644 --- a/phpBB/phpbb/notification/type/approve_topic.php +++ b/phpBB/phpbb/notification/type/approve_topic.php @@ -82,7 +82,7 @@ class approve_topic extends \phpbb\notification\type\topic $users[$post['poster_id']] = array(''); return $this->get_authorised_recipients(array_keys($users), $post['forum_id'], array_merge($options, array( - 'item_type' => self::$notification_option['id'], + 'item_type' => static::$notification_option['id'], ))); } diff --git a/phpBB/phpbb/notification/type/bookmark.php b/phpBB/phpbb/notification/type/bookmark.php index 4f2d34cb60..1626add22c 100644 --- a/phpBB/phpbb/notification/type/bookmark.php +++ b/phpBB/phpbb/notification/type/bookmark.php @@ -95,7 +95,7 @@ class bookmark extends \phpbb\notification\type\post $sql = 'SELECT n.* FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt WHERE n.notification_type_id = ' . (int) $this->notification_type_id . ' - AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . ' + AND n.item_parent_id = ' . (int) static::get_item_parent_id($post) . ' AND n.notification_read = 0 AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1'; diff --git a/phpBB/phpbb/notification/type/group_request.php b/phpBB/phpbb/notification/type/group_request.php index 4baf516fed..96bfc86322 100644 --- a/phpBB/phpbb/notification/type/group_request.php +++ b/phpBB/phpbb/notification/type/group_request.php @@ -96,7 +96,7 @@ class group_request extends \phpbb\notification\type\base */ public function get_avatar() { - return $this->user_loader->get_avatar($this->item_id); + return $this->user_loader->get_avatar($this->item_id, false, true); } /** diff --git a/phpBB/phpbb/notification/type/pm.php b/phpBB/phpbb/notification/type/pm.php index 330a70c85a..d2f34f95d0 100644 --- a/phpBB/phpbb/notification/type/pm.php +++ b/phpBB/phpbb/notification/type/pm.php @@ -100,7 +100,7 @@ class pm extends \phpbb\notification\type\base */ public function get_avatar() { - return $this->user_loader->get_avatar($this->get_data('from_user_id')); + return $this->user_loader->get_avatar($this->get_data('from_user_id'), false, true); } /** diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index 421eff6372..2969da550d 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -135,7 +135,7 @@ class post extends \phpbb\notification\type\base $sql = 'SELECT n.* FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt WHERE n.notification_type_id = ' . (int) $this->notification_type_id . ' - AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . ' + AND n.item_parent_id = ' . (int) static::get_item_parent_id($post) . ' AND n.notification_read = 0 AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1'; @@ -165,7 +165,7 @@ class post extends \phpbb\notification\type\base */ public function get_avatar() { - return $this->user_loader->get_avatar($this->get_data('poster_id')); + return $this->user_loader->get_avatar($this->get_data('poster_id'), false, true); } /** diff --git a/phpBB/phpbb/notification/type/post_in_queue.php b/phpBB/phpbb/notification/type/post_in_queue.php index 315b8b0243..5832c99cd2 100644 --- a/phpBB/phpbb/notification/type/post_in_queue.php +++ b/phpBB/phpbb/notification/type/post_in_queue.php @@ -108,7 +108,7 @@ class post_in_queue extends \phpbb\notification\type\post } return $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], array_merge($options, array( - 'item_type' => self::$notification_option['id'], + 'item_type' => static::$notification_option['id'], ))); } diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php index 508ca92fa0..2732cb84e4 100644 --- a/phpBB/phpbb/notification/type/quote.php +++ b/phpBB/phpbb/notification/type/quote.php @@ -78,7 +78,7 @@ class quote extends \phpbb\notification\type\post ), $options); $usernames = false; - preg_match_all(self::$regular_expression_match, $post['post_text'], $usernames); + preg_match_all(static::$regular_expression_match, $post['post_text'], $usernames); if (empty($usernames[1])) { @@ -116,7 +116,7 @@ class quote extends \phpbb\notification\type\post $sql = 'SELECT n.user_id FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt WHERE n.notification_type_id = ' . (int) $this->notification_type_id . ' - AND n.item_id = ' . self::get_item_id($post) . ' + AND n.item_id = ' . static::get_item_id($post) . ' AND nt.notification_type_id = n.notification_type_id AND nt.notification_type_enabled = 1'; $result = $this->db->sql_query($sql); @@ -147,7 +147,7 @@ class quote extends \phpbb\notification\type\post { $sql = 'DELETE FROM ' . $this->notifications_table . ' WHERE notification_type_id = ' . (int) $this->notification_type_id . ' - AND item_id = ' . self::get_item_id($post) . ' + AND item_id = ' . static::get_item_id($post) . ' AND ' . $this->db->sql_in_set('user_id', $remove_notifications); $this->db->sql_query($sql); } diff --git a/phpBB/phpbb/notification/type/report_pm.php b/phpBB/phpbb/notification/type/report_pm.php index d39143f4b7..785e5f243d 100644 --- a/phpBB/phpbb/notification/type/report_pm.php +++ b/phpBB/phpbb/notification/type/report_pm.php @@ -120,7 +120,7 @@ class report_pm extends \phpbb\notification\type\pm } return $this->check_user_notification_options($auth_approve[$post['forum_id']][$this->permission], array_merge($options, array( - 'item_type' => self::$notification_option['id'], + 'item_type' => static::$notification_option['id'], ))); } @@ -223,7 +223,7 @@ class report_pm extends \phpbb\notification\type\pm */ public function get_avatar() { - return $this->user_loader->get_avatar($this->get_data('reporter_id')); + return $this->user_loader->get_avatar($this->get_data('reporter_id'), false, true); } /** diff --git a/phpBB/phpbb/notification/type/report_pm_closed.php b/phpBB/phpbb/notification/type/report_pm_closed.php index 9f301ee2cc..1c99db60c3 100644 --- a/phpBB/phpbb/notification/type/report_pm_closed.php +++ b/phpBB/phpbb/notification/type/report_pm_closed.php @@ -130,7 +130,7 @@ class report_pm_closed extends \phpbb\notification\type\pm */ public function get_avatar() { - return $this->user_loader->get_avatar($this->get_data('closer_id')); + return $this->user_loader->get_avatar($this->get_data('closer_id'), false, true); } /** diff --git a/phpBB/phpbb/notification/type/report_post.php b/phpBB/phpbb/notification/type/report_post.php index 027cca716b..aed31e8642 100644 --- a/phpBB/phpbb/notification/type/report_post.php +++ b/phpBB/phpbb/notification/type/report_post.php @@ -196,7 +196,7 @@ class report_post extends \phpbb\notification\type\post_in_queue */ public function get_avatar() { - return $this->user_loader->get_avatar($this->get_data('reporter_id')); + return $this->user_loader->get_avatar($this->get_data('reporter_id'), false, true); } /** diff --git a/phpBB/phpbb/notification/type/report_post_closed.php b/phpBB/phpbb/notification/type/report_post_closed.php index a0bb187a0d..3f4378628b 100644 --- a/phpBB/phpbb/notification/type/report_post_closed.php +++ b/phpBB/phpbb/notification/type/report_post_closed.php @@ -137,7 +137,7 @@ class report_post_closed extends \phpbb\notification\type\post */ public function get_avatar() { - return $this->user_loader->get_avatar($this->get_data('closer_id')); + return $this->user_loader->get_avatar($this->get_data('closer_id'), false, true); } /** diff --git a/phpBB/phpbb/notification/type/topic.php b/phpBB/phpbb/notification/type/topic.php index 5f57087b73..fb08a9eee1 100644 --- a/phpBB/phpbb/notification/type/topic.php +++ b/phpBB/phpbb/notification/type/topic.php @@ -119,7 +119,7 @@ class topic extends \phpbb\notification\type\base */ public function get_avatar() { - return $this->user_loader->get_avatar($this->get_data('poster_id')); + return $this->user_loader->get_avatar($this->get_data('poster_id'), false, true); } /** diff --git a/phpBB/phpbb/notification/type/topic_in_queue.php b/phpBB/phpbb/notification/type/topic_in_queue.php index 4c60c6b858..6e57b9ac0c 100644 --- a/phpBB/phpbb/notification/type/topic_in_queue.php +++ b/phpBB/phpbb/notification/type/topic_in_queue.php @@ -108,7 +108,7 @@ class topic_in_queue extends \phpbb\notification\type\topic } return $this->check_user_notification_options($auth_read[$topic['forum_id']]['f_read'], array_merge($options, array( - 'item_type' => self::$notification_option['id'], + 'item_type' => static::$notification_option['id'], ))); } diff --git a/phpBB/phpbb/passwords/driver/helper.php b/phpBB/phpbb/passwords/driver/helper.php index caa65080ac..f80c3e3df6 100644 --- a/phpBB/phpbb/passwords/driver/helper.php +++ b/phpBB/phpbb/passwords/driver/helper.php @@ -153,11 +153,23 @@ class helper */ public function string_compare($string_a, $string_b) { - $difference = strlen($string_a) != strlen($string_b); + // Return if input variables are not strings or if length does not match + if (!is_string($string_a) || !is_string($string_b) || strlen($string_a) != strlen($string_b)) + { + return false; + } + + // Use hash_equals() if it's available + if (function_exists('hash_equals')) + { + return hash_equals($string_a, $string_b); + } + + $difference = 0; for ($i = 0; $i < strlen($string_a) && $i < strlen($string_b); $i++) { - $difference |= $string_a[$i] != $string_b[$i]; + $difference |= ord($string_a[$i]) ^ ord($string_b[$i]); } return $difference === 0; diff --git a/phpBB/phpbb/permissions.php b/phpBB/phpbb/permissions.php index 82f59b5c20..e75476f59b 100644 --- a/phpBB/phpbb/permissions.php +++ b/phpBB/phpbb/permissions.php @@ -160,6 +160,28 @@ class permissions } /** + * Checks if a category has been defined + * + * @param string $category Identifier of the category + * @return bool True if the category is defined, false otherwise + */ + public function category_defined($category) + { + return isset($this->categories[$category]); + } + + /** + * Checks if a permission has been defined + * + * @param string $permission Identifier of the permission + * @return bool True if the permission is defined, false otherwise + */ + public function permission_defined($permission) + { + return isset($this->permissions[$permission]); + } + + /** * Returns the language string of a permission * * @param string $permission Identifier of the permission @@ -285,8 +307,9 @@ class permissions 'm_split' => array('lang' => 'ACL_M_SPLIT', 'cat' => 'topic_actions'), 'm_merge' => array('lang' => 'ACL_M_MERGE', 'cat' => 'topic_actions'), - 'm_warn' => array('lang' => 'ACL_M_WARN', 'cat' => 'misc'), - 'm_ban' => array('lang' => 'ACL_M_BAN', 'cat' => 'misc'), + 'm_warn' => array('lang' => 'ACL_M_WARN', 'cat' => 'misc'), + 'm_pm_report' => array('lang' => 'ACL_M_PM_REPORT', 'cat' => 'misc'), + 'm_ban' => array('lang' => 'ACL_M_BAN', 'cat' => 'misc'), // Admin Permissions 'a_board' => array('lang' => 'ACL_A_BOARD', 'cat' => 'settings'), diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php index ca78167ec0..7f6267ed32 100644 --- a/phpBB/phpbb/plupload/plupload.php +++ b/phpBB/phpbb/plupload/plupload.php @@ -125,7 +125,7 @@ class plupload // Need to modify some of the $_FILES values to reflect the new file return array( 'tmp_name' => $file_path, - 'name' => $this->request->variable('real_filename', ''), + 'name' => $this->request->variable('real_filename', '', true), 'size' => filesize($file_path), 'type' => $this->mimetype_guesser->guess($file_path, $file_name), ); diff --git a/phpBB/phpbb/profilefields/manager.php b/phpBB/phpbb/profilefields/manager.php index 4ad3214ae4..ea4b24af56 100644 --- a/phpBB/phpbb/profilefields/manager.php +++ b/phpBB/phpbb/profilefields/manager.php @@ -276,12 +276,32 @@ class manager $profile_field = $this->type_collection[$field_data['field_type']]; $tpl_fields[] = array( + 'PROFILE_FIELD_IDENT' => $field_ident, 'PROFILE_FIELD_TYPE' => $field_data['field_type'], 'PROFILE_FIELD_NAME' => $profile_field->get_field_name($field_data['lang_name']), 'PROFILE_FIELD_EXPLAIN' => $this->user->lang($field_data['lang_explain']), ); } + $profile_cache = $this->profile_cache; + + /** + * Event to modify template headlines of the generated profile fields + * + * @event core.generate_profile_fields_template_headlines + * @var string restrict_option Restrict the published fields to a certain profile field option + * @var array tpl_fields Array with template data fields + * @var array profile_cache A copy of the profile cache to make additional checks + * @since 3.1.6-RC1 + */ + $vars = array( + 'restrict_option', + 'tpl_fields', + 'profile_cache', + ); + extract($this->dispatcher->trigger_event('core.generate_profile_fields_template_headlines', compact($vars))); + unset($profile_cache); + return $tpl_fields; } diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php index 1a0aba096f..3ddbd85b36 100644 --- a/phpBB/phpbb/search/fulltext_mysql.php +++ b/phpBB/phpbb/search/fulltext_mysql.php @@ -43,6 +43,12 @@ class fulltext_mysql extends \phpbb\search\base protected $db; /** + * phpBB event dispatcher object + * @var \phpbb\event\dispatcher_interface + */ + protected $phpbb_dispatcher; + + /** * User object * @var \phpbb\user */ @@ -79,11 +85,13 @@ class fulltext_mysql extends \phpbb\search\base * @param \phpbb\config\config $config Config object * @param \phpbb\db\driver\driver_interface Database object * @param \phpbb\user $user User object + * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher object */ - public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user) + public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher) { $this->config = $config; $this->db = $db; + $this->phpbb_dispatcher = $phpbb_dispatcher; $this->user = $user; $this->word_length = array('min' => $this->config['fulltext_mysql_min_word_len'], 'max' => $this->config['fulltext_mysql_max_word_len']); @@ -371,7 +379,7 @@ class fulltext_mysql extends \phpbb\search\base } // generate a search_key from all the options to identify the results - $search_key = md5(implode('#', array( + $search_key_array = array( implode(', ', $this->split_words), $type, $fields, @@ -382,7 +390,39 @@ class fulltext_mysql extends \phpbb\search\base implode(',', $ex_fid_ary), $post_visibility, implode(',', $author_ary) - ))); + ); + + /** + * Allow changing the search_key for cached results + * + * @event core.search_mysql_by_keyword_modify_search_key + * @var array search_key_array Array with search parameters to generate the search_key + * @var string type Searching type ('posts', 'topics') + * @var string fields Searching fields ('titleonly', 'msgonly', 'firstpost', 'all') + * @var string terms Searching terms ('all', 'any') + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sort_key The sort type used from the possible sort types + * @var int topic_id Limit the search to this topic_id only + * @var array ex_fid_ary Which forums not to search on + * @var string post_visibility Post visibility data + * @var array author_ary Array of user_id containing the users to filter the results to + * @since 3.1.7-RC1 + */ + $vars = array( + 'search_key_array', + 'type', + 'fields', + 'terms', + 'sort_days', + 'sort_key', + 'topic_id', + 'ex_fid_ary', + 'post_visibility', + 'author_ary', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_mysql_by_keyword_modify_search_key', compact($vars))); + + $search_key = md5(implode('#', $search_key_array)); if ($start < 0) { @@ -447,6 +487,55 @@ class fulltext_mysql extends \phpbb\search\base break; } + $search_query = $this->search_query; + + /** + * Allow changing the query used to search for posts using fulltext_mysql + * + * @event core.search_mysql_keywords_main_query_before + * @var string search_query The parsed keywords used for this search + * @var int result_count The previous result count for the format of the query. + * Set to 0 to force a re-count + * @var bool join_topic Weather or not TOPICS_TABLE should be CROSS JOIN'ED + * @var array author_ary Array of user_id containing the users to filter the results to + * @var string author_name An extra username to search on (!empty(author_ary) must be true, to be relevant) + * @var array ex_fid_ary Which forums not to search on + * @var int topic_id Limit the search to this topic_id only + * @var string sql_sort_table Extra tables to include in the SQL query. + * Used in conjunction with sql_sort_join + * @var string sql_sort_join SQL conditions to join all the tables used together. + * Used in conjunction with sql_sort_table + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sql_match Which columns to do the search on. + * @var string sql_match_where Extra conditions to use to properly filter the matching process + * @var string sort_by_sql The possible predefined sort types + * @var string sort_key The sort type used from the possible sort types + * @var string sort_dir "a" for ASC or "d" dor DESC for the sort order used + * @var string sql_sort The result SQL when processing sort_by_sql + sort_key + sort_dir + * @var int start How many posts to skip in the search results (used for pagination) + * @since 3.1.5-RC1 + */ + $vars = array( + 'search_query', + 'result_count', + 'join_topic', + 'author_ary', + 'author_name', + 'ex_fid_ary', + 'topic_id', + 'sql_sort_table', + 'sql_sort_join', + 'sort_days', + 'sql_match', + 'sql_match_where', + 'sort_by_sql', + 'sort_key', + 'sort_dir', + 'sql_sort', + 'start', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_mysql_keywords_main_query_before', compact($vars))); + $sql_select = (!$result_count) ? 'SQL_CALC_FOUND_ROWS ' : ''; $sql_select = ($type == 'posts') ? $sql_select . 'p.post_id' : 'DISTINCT ' . $sql_select . 't.topic_id'; $sql_from = ($join_topic) ? TOPICS_TABLE . ' t, ' : ''; @@ -553,7 +642,7 @@ class fulltext_mysql extends \phpbb\search\base } // generate a search_key from all the options to identify the results - $search_key = md5(implode('#', array( + $search_key_array = array( '', $type, ($firstpost_only) ? 'firstpost' : '', @@ -566,7 +655,39 @@ class fulltext_mysql extends \phpbb\search\base $post_visibility, implode(',', $author_ary), $author_name, - ))); + ); + + /** + * Allow changing the search_key for cached results + * + * @event core.search_mysql_by_author_modify_search_key + * @var array search_key_array Array with search parameters to generate the search_key + * @var string type Searching type ('posts', 'topics') + * @var boolean firstpost_only Flag indicating if only topic starting posts are considered + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sort_key The sort type used from the possible sort types + * @var int topic_id Limit the search to this topic_id only + * @var array ex_fid_ary Which forums not to search on + * @var string post_visibility Post visibility data + * @var array author_ary Array of user_id containing the users to filter the results to + * @var string author_name The username to search on + * @since 3.1.7-RC1 + */ + $vars = array( + 'search_key_array', + 'type', + 'firstpost_only', + 'sort_days', + 'sort_key', + 'topic_id', + 'ex_fid_ary', + 'post_visibility', + 'author_ary', + 'author_name', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_mysql_by_author_modify_search_key', compact($vars))); + + $search_key = md5(implode('#', $search_key_array)); if ($start < 0) { @@ -620,6 +741,59 @@ class fulltext_mysql extends \phpbb\search\base $m_approve_fid_sql = ' AND ' . $post_visibility; + /** + * Allow changing the query used to search for posts by author in fulltext_mysql + * + * @event core.search_mysql_author_query_before + * @var int result_count The previous result count for the format of the query. + * Set to 0 to force a re-count + * @var string sql_sort_table CROSS JOIN'ed table to allow doing the sort chosen + * @var string sql_sort_join Condition to define how to join the CROSS JOIN'ed table specifyed in sql_sort_table + * @var string type Either "posts" or "topics" specifying the type of search being made + * @var array author_ary Array of user_id containing the users to filter the results to + * @var string author_name An extra username to search on + * @var string sql_author SQL WHERE condition for the post author ids + * @var int topic_id Limit the search to this topic_id only + * @var string sql_topic_id SQL of topic_id + * @var string sort_by_sql The possible predefined sort types + * @var string sort_key The sort type used from the possible sort types + * @var string sort_dir "a" for ASC or "d" dor DESC for the sort order used + * @var string sql_sort The result SQL when processing sort_by_sql + sort_key + sort_dir + * @var string sort_days Time, in days, that the oldest post showing can have + * @var string sql_time The SQL to search on the time specifyed by sort_days + * @var bool firstpost_only Wether or not to search only on the first post of the topics + * @var string sql_firstpost The SQL with the conditions to join the tables when using firstpost_only + * @var array ex_fid_ary Forum ids that must not be searched on + * @var array sql_fora SQL query for ex_fid_ary + * @var string m_approve_fid_sql WHERE clause condition on post_visibility restrictions + * @var int start How many posts to skip in the search results (used for pagination) + * @since 3.1.5-RC1 + */ + $vars = array( + 'result_count', + 'sql_sort_table', + 'sql_sort_join', + 'type', + 'author_ary', + 'author_name', + 'sql_author', + 'topic_id', + 'sql_topic_id', + 'sort_by_sql', + 'sort_key', + 'sort_dir', + 'sql_sort', + 'sort_days', + 'sql_time', + 'firstpost_only', + 'sql_firstpost', + 'ex_fid_ary', + 'sql_fora', + 'm_approve_fid_sql', + 'start', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_mysql_author_query_before', compact($vars))); + // If the cache was completely empty count the results $calc_results = ($result_count) ? '' : 'SQL_CALC_FOUND_ROWS '; diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index 4d02dd1cbf..a02f889415 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -57,7 +57,7 @@ class fulltext_native extends \phpbb\search\base protected $must_not_contain_ids = array(); /** - * Post ids of posts containing atleast one word that needs to be excluded + * Post ids of posts containing at least one word that needs to be excluded * @var array */ protected $must_exclude_one_ids = array(); @@ -87,6 +87,12 @@ class fulltext_native extends \phpbb\search\base protected $db; /** + * phpBB event dispatcher object + * @var \phpbb\event\dispatcher_interface + */ + protected $phpbb_dispatcher; + + /** * User object * @var \phpbb\user */ @@ -96,13 +102,15 @@ class fulltext_native extends \phpbb\search\base * Initialises the fulltext_native search backend with min/max word length and makes sure the UTF-8 normalizer is loaded * * @param boolean|string &$error is passed by reference and should either be set to false on success or an error message on failure + * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher object */ - public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user) + public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher) { $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $phpEx; $this->config = $config; $this->db = $db; + $this->phpbb_dispatcher = $phpbb_dispatcher; $this->user = $user; $this->word_length = array('min' => $this->config['fulltext_native_min_chars'], 'max' => $this->config['fulltext_native_max_chars']); @@ -522,7 +530,7 @@ class fulltext_native extends \phpbb\search\base sort($must_exclude_one_ids); // generate a search_key from all the options to identify the results - $search_key = md5(implode('#', array( + $search_key_array = array( serialize($must_contain_ids), serialize($must_not_contain_ids), serialize($must_exclude_one_ids), @@ -536,7 +544,45 @@ class fulltext_native extends \phpbb\search\base $post_visibility, implode(',', $author_ary), $author_name, - ))); + ); + + /** + * Allow changing the search_key for cached results + * + * @event core.search_native_by_keyword_modify_search_key + * @var array search_key_array Array with search parameters to generate the search_key + * @var array must_contain_ids Array with post ids of posts containing words that are to be included + * @var array must_not_contain_ids Array with post ids of posts containing words that should not be included + * @var array must_exclude_one_ids Array with post ids of posts containing at least one word that needs to be excluded + * @var string type Searching type ('posts', 'topics') + * @var string fields Searching fields ('titleonly', 'msgonly', 'firstpost', 'all') + * @var string terms Searching terms ('all', 'any') + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sort_key The sort type used from the possible sort types + * @var int topic_id Limit the search to this topic_id only + * @var array ex_fid_ary Which forums not to search on + * @var string post_visibility Post visibility data + * @var array author_ary Array of user_id containing the users to filter the results to + * @since 3.1.7-RC1 + */ + $vars = array( + 'search_key_array', + 'must_contain_ids', + 'must_not_contain_ids', + 'must_exclude_one_ids', + 'type', + 'fields', + 'terms', + 'sort_days', + 'sort_key', + 'topic_id', + 'ex_fid_ary', + 'post_visibility', + 'author_ary', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_native_by_keyword_modify_search_key', compact($vars))); + + $search_key = md5(implode('#', $search_key_array)); // try reading the results from cache $total_results = 0; @@ -712,6 +758,70 @@ class fulltext_native extends \phpbb\search\base $sql_where[] = $post_visibility; + $search_query = $this->search_query; + $must_exclude_one_ids = $this->must_exclude_one_ids; + $must_not_contain_ids = $this->must_not_contain_ids; + $must_contain_ids = $this->must_contain_ids; + + /** + * Allow changing the query used for counting for posts using fulltext_native + * + * @event core.search_native_keywords_count_query_before + * @var string search_query The parsed keywords used for this search + * @var array must_not_contain_ids Ids that cannot be taken into account for the results + * @var array must_exclude_one_ids Ids that cannot be on the results + * @var array must_contain_ids Ids that must be on the results + * @var int total_results The previous result count for the format of the query + * Set to 0 to force a re-count + * @var array sql_array The data on how to search in the DB at this point + * @var bool left_join_topics Whether or not TOPICS_TABLE should be CROSS JOIN'ED + * @var array author_ary Array of user_id containing the users to filter the results to + * @var string author_name An extra username to search on (!empty(author_ary) must be true, to be relevant) + * @var array ex_fid_ary Which forums not to search on + * @var int topic_id Limit the search to this topic_id only + * @var string sql_sort_table Extra tables to include in the SQL query. + * Used in conjunction with sql_sort_join + * @var string sql_sort_join SQL conditions to join all the tables used together. + * Used in conjunction with sql_sort_table + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sql_where An array of the current WHERE clause conditions + * @var string sql_match Which columns to do the search on + * @var string sql_match_where Extra conditions to use to properly filter the matching process + * @var bool group_by Whether or not the SQL query requires a GROUP BY for the elements in the SELECT clause + * @var string sort_by_sql The possible predefined sort types + * @var string sort_key The sort type used from the possible sort types + * @var string sort_dir "a" for ASC or "d" dor DESC for the sort order used + * @var string sql_sort The result SQL when processing sort_by_sql + sort_key + sort_dir + * @var int start How many posts to skip in the search results (used for pagination) + * @since 3.1.5-RC1 + */ + $vars = array( + 'search_query', + 'must_not_contain_ids', + 'must_exclude_one_ids', + 'must_contain_ids', + 'total_results', + 'sql_array', + 'left_join_topics', + 'author_ary', + 'author_name', + 'ex_fid_ary', + 'topic_id', + 'sql_sort_table', + 'sql_sort_join', + 'sort_days', + 'sql_where', + 'sql_match', + 'sql_match_where', + 'group_by', + 'sort_by_sql', + 'sort_key', + 'sort_dir', + 'sql_sort', + 'start', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_native_keywords_count_query_before', compact($vars))); + if ($topic_id) { $sql_where[] = 'p.topic_id = ' . $topic_id; @@ -908,7 +1018,7 @@ class fulltext_native extends \phpbb\search\base } // generate a search_key from all the options to identify the results - $search_key = md5(implode('#', array( + $search_key_array = array( '', $type, ($firstpost_only) ? 'firstpost' : '', @@ -921,7 +1031,39 @@ class fulltext_native extends \phpbb\search\base $post_visibility, implode(',', $author_ary), $author_name, - ))); + ); + + /** + * Allow changing the search_key for cached results + * + * @event core.search_native_by_author_modify_search_key + * @var array search_key_array Array with search parameters to generate the search_key + * @var string type Searching type ('posts', 'topics') + * @var boolean firstpost_only Flag indicating if only topic starting posts are considered + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sort_key The sort type used from the possible sort types + * @var int topic_id Limit the search to this topic_id only + * @var array ex_fid_ary Which forums not to search on + * @var string post_visibility Post visibility data + * @var array author_ary Array of user_id containing the users to filter the results to + * @var string author_name The username to search on + * @since 3.1.7-RC1 + */ + $vars = array( + 'search_key_array', + 'type', + 'firstpost_only', + 'sort_days', + 'sort_key', + 'topic_id', + 'ex_fid_ary', + 'post_visibility', + 'author_ary', + 'author_name', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_native_by_author_modify_search_key', compact($vars))); + + $search_key = md5(implode('#', $search_key_array)); // try reading the results from cache $total_results = 0; @@ -972,6 +1114,53 @@ class fulltext_native extends \phpbb\search\base $select = ($type == 'posts') ? 'p.post_id' : 't.topic_id'; $is_mysql = false; + /** + * Allow changing the query used to search for posts by author in fulltext_native + * + * @event core.search_native_author_count_query_before + * @var int total_results The previous result count for the format of the query. + * Set to 0 to force a re-count + * @var string type The type of search being made + * @var string select SQL SELECT clause for what to get + * @var string sql_sort_table CROSS JOIN'ed table to allow doing the sort chosen + * @var string sql_sort_join Condition to define how to join the CROSS JOIN'ed table specifyed in sql_sort_table + * @var array sql_author SQL WHERE condition for the post author ids + * @var int topic_id Limit the search to this topic_id only + * @var string sort_by_sql The possible predefined sort types + * @var string sort_key The sort type used from the possible sort types + * @var string sort_dir "a" for ASC or "d" dor DESC for the sort order used + * @var string sql_sort The result SQL when processing sort_by_sql + sort_key + sort_dir + * @var string sort_days Time, in days, that the oldest post showing can have + * @var string sql_time The SQL to search on the time specifyed by sort_days + * @var bool firstpost_only Wether or not to search only on the first post of the topics + * @var string sql_firstpost The SQL used in the WHERE claused to filter by firstpost. + * @var array ex_fid_ary Forum ids that must not be searched on + * @var array sql_fora SQL query for ex_fid_ary + * @var int start How many posts to skip in the search results (used for pagination) + * @since 3.1.5-RC1 + */ + $vars = array( + 'total_results', + 'type', + 'select', + 'sql_sort_table', + 'sql_sort_join', + 'sql_author', + 'topic_id', + 'sort_by_sql', + 'sort_key', + 'sort_dir', + 'sql_sort', + 'sort_days', + 'sql_time', + 'firstpost_only', + 'sql_firstpost', + 'ex_fid_ary', + 'sql_fora', + 'start', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_native_author_count_query_before', compact($vars))); + // If the cache was completely empty count the results if (!$total_results) { @@ -1075,7 +1264,7 @@ class fulltext_native extends \phpbb\search\base // Count rows for the executed queries. Replace $select within $sql with SQL_CALC_FOUND_ROWS, and run it. $sql_calc = str_replace('SELECT ' . $select, 'SELECT DISTINCT SQL_CALC_FOUND_ROWS p.post_id', $sql); - $this->db->sql_query($sql_calc); + $result = $this->db->sql_query($sql_calc); $this->db->sql_freeresult($result); $sql_count = 'SELECT FOUND_ROWS() as total_results'; diff --git a/phpBB/phpbb/search/fulltext_postgres.php b/phpBB/phpbb/search/fulltext_postgres.php index b6af371d13..c2186b0df3 100644 --- a/phpBB/phpbb/search/fulltext_postgres.php +++ b/phpBB/phpbb/search/fulltext_postgres.php @@ -56,6 +56,12 @@ class fulltext_postgres extends \phpbb\search\base protected $db; /** + * phpBB event dispatcher object + * @var \phpbb\event\dispatcher_interface + */ + protected $phpbb_dispatcher; + + /** * User object * @var \phpbb\user */ @@ -92,11 +98,13 @@ class fulltext_postgres extends \phpbb\search\base * @param \phpbb\config\config $config Config object * @param \phpbb\db\driver\driver_interface Database object * @param \phpbb\user $user User object + * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher object */ - public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user) + public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher) { $this->config = $config; $this->db = $db; + $this->phpbb_dispatcher = $phpbb_dispatcher; $this->user = $user; $this->word_length = array('min' => $this->config['fulltext_postgres_min_word_len'], 'max' => $this->config['fulltext_postgres_max_word_len']); @@ -333,7 +341,7 @@ class fulltext_postgres extends \phpbb\search\base } // generate a search_key from all the options to identify the results - $search_key = md5(implode('#', array( + $search_key_array = array( implode(', ', $this->split_words), $type, $fields, @@ -344,7 +352,39 @@ class fulltext_postgres extends \phpbb\search\base implode(',', $ex_fid_ary), $post_visibility, implode(',', $author_ary) - ))); + ); + + /** + * Allow changing the search_key for cached results + * + * @event core.search_postgres_by_keyword_modify_search_key + * @var array search_key_array Array with search parameters to generate the search_key + * @var string type Searching type ('posts', 'topics') + * @var string fields Searching fields ('titleonly', 'msgonly', 'firstpost', 'all') + * @var string terms Searching terms ('all', 'any') + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sort_key The sort type used from the possible sort types + * @var int topic_id Limit the search to this topic_id only + * @var array ex_fid_ary Which forums not to search on + * @var string post_visibility Post visibility data + * @var array author_ary Array of user_id containing the users to filter the results to + * @since 3.1.7-RC1 + */ + $vars = array( + 'search_key_array', + 'type', + 'fields', + 'terms', + 'sort_days', + 'sort_key', + 'topic_id', + 'ex_fid_ary', + 'post_visibility', + 'author_ary', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_postgres_by_keyword_modify_search_key', compact($vars))); + + $search_key = md5(implode('#', $search_key_array)); if ($start < 0) { @@ -409,6 +449,55 @@ class fulltext_postgres extends \phpbb\search\base break; } + $tsearch_query = $this->tsearch_query; + + /** + * Allow changing the query used to search for posts using fulltext_postgres + * + * @event core.search_postgres_keywords_main_query_before + * @var string tsearch_query The parsed keywords used for this search + * @var int result_count The previous result count for the format of the query. + * Set to 0 to force a re-count + * @var bool join_topic Weather or not TOPICS_TABLE should be CROSS JOIN'ED + * @var array author_ary Array of user_id containing the users to filter the results to + * @var string author_name An extra username to search on (!empty(author_ary) must be true, to be relevant) + * @var array ex_fid_ary Which forums not to search on + * @var int topic_id Limit the search to this topic_id only + * @var string sql_sort_table Extra tables to include in the SQL query. + * Used in conjunction with sql_sort_join + * @var string sql_sort_join SQL conditions to join all the tables used together. + * Used in conjunction with sql_sort_table + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sql_match Which columns to do the search on. + * @var string sql_match_where Extra conditions to use to properly filter the matching process + * @var string sort_by_sql The possible predefined sort types + * @var string sort_key The sort type used from the possible sort types + * @var string sort_dir "a" for ASC or "d" dor DESC for the sort order used + * @var string sql_sort The result SQL when processing sort_by_sql + sort_key + sort_dir + * @var int start How many posts to skip in the search results (used for pagination) + * @since 3.1.5-RC1 + */ + $vars = array( + 'tsearch_query', + 'result_count', + 'join_topic', + 'author_ary', + 'author_name', + 'ex_fid_ary', + 'topic_id', + 'sql_sort_table', + 'sql_sort_join', + 'sort_days', + 'sql_match', + 'sql_match_where', + 'sort_by_sql', + 'sort_key', + 'sort_dir', + 'sql_sort', + 'start', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_postgres_keywords_main_query_before', compact($vars))); + $sql_select = ($type == 'posts') ? 'p.post_id' : 'DISTINCT t.topic_id'; $sql_from = ($join_topic) ? TOPICS_TABLE . ' t, ' : ''; $field = ($type == 'posts') ? 'post_id' : 'topic_id'; @@ -528,7 +617,7 @@ class fulltext_postgres extends \phpbb\search\base } // generate a search_key from all the options to identify the results - $search_key = md5(implode('#', array( + $search_key_array = array( '', $type, ($firstpost_only) ? 'firstpost' : '', @@ -541,7 +630,39 @@ class fulltext_postgres extends \phpbb\search\base $post_visibility, implode(',', $author_ary), $author_name, - ))); + ); + + /** + * Allow changing the search_key for cached results + * + * @event core.search_postgres_by_author_modify_search_key + * @var array search_key_array Array with search parameters to generate the search_key + * @var string type Searching type ('posts', 'topics') + * @var boolean firstpost_only Flag indicating if only topic starting posts are considered + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sort_key The sort type used from the possible sort types + * @var int topic_id Limit the search to this topic_id only + * @var array ex_fid_ary Which forums not to search on + * @var string post_visibility Post visibility data + * @var array author_ary Array of user_id containing the users to filter the results to + * @var string author_name The username to search on + * @since 3.1.7-RC1 + */ + $vars = array( + 'search_key_array', + 'type', + 'firstpost_only', + 'sort_days', + 'sort_key', + 'topic_id', + 'ex_fid_ary', + 'post_visibility', + 'author_ary', + 'author_name', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_postgres_by_author_modify_search_key', compact($vars))); + + $search_key = md5(implode('#', $search_key_array)); if ($start < 0) { @@ -595,6 +716,55 @@ class fulltext_postgres extends \phpbb\search\base $m_approve_fid_sql = ' AND ' . $post_visibility; + /** + * Allow changing the query used to search for posts by author in fulltext_postgres + * + * @event core.search_postgres_author_count_query_before + * @var int result_count The previous result count for the format of the query. + * Set to 0 to force a re-count + * @var string sql_sort_table CROSS JOIN'ed table to allow doing the sort chosen + * @var string sql_sort_join Condition to define how to join the CROSS JOIN'ed table specifyed in sql_sort_table + * @var array author_ary Array of user_id containing the users to filter the results to + * @var string author_name An extra username to search on + * @var string sql_author SQL WHERE condition for the post author ids + * @var int topic_id Limit the search to this topic_id only + * @var string sql_topic_id SQL of topic_id + * @var string sort_by_sql The possible predefined sort types + * @var string sort_key The sort type used from the possible sort types + * @var string sort_dir "a" for ASC or "d" dor DESC for the sort order used + * @var string sql_sort The result SQL when processing sort_by_sql + sort_key + sort_dir + * @var string sort_days Time, in days, that the oldest post showing can have + * @var string sql_time The SQL to search on the time specifyed by sort_days + * @var bool firstpost_only Wether or not to search only on the first post of the topics + * @var array ex_fid_ary Forum ids that must not be searched on + * @var array sql_fora SQL query for ex_fid_ary + * @var string m_approve_fid_sql WHERE clause condition on post_visibility restrictions + * @var int start How many posts to skip in the search results (used for pagination) + * @since 3.1.5-RC1 + */ + $vars = array( + 'result_count', + 'sql_sort_table', + 'sql_sort_join', + 'author_ary', + 'author_name', + 'sql_author', + 'topic_id', + 'sql_topic_id', + 'sort_by_sql', + 'sort_key', + 'sort_dir', + 'sql_sort', + 'sort_days', + 'sql_time', + 'firstpost_only', + 'ex_fid_ary', + 'sql_fora', + 'm_approve_fid_sql', + 'start', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_postgres_author_count_query_before', compact($vars))); + // Build the query for really selecting the post_ids if ($type == 'posts') { diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php index eb53ca6d40..612ef8f1f3 100644 --- a/phpBB/phpbb/search/fulltext_sphinx.php +++ b/phpBB/phpbb/search/fulltext_sphinx.php @@ -96,6 +96,12 @@ class fulltext_sphinx protected $dbtype; /** + * phpBB event dispatcher object + * @var \phpbb\event\dispatcher_interface + */ + protected $phpbb_dispatcher; + + /** * User object * @var \phpbb\user */ @@ -125,12 +131,14 @@ class fulltext_sphinx * @param \phpbb\config\config $config Config object * @param \phpbb\db\driver\driver_interface Database object * @param \phpbb\user $user User object + * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher object */ - public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user) + public function __construct(&$error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher) { $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $phpEx; $this->config = $config; + $this->phpbb_dispatcher = $phpbb_dispatcher; $this->user = $user; $this->db = $db; $this->auth = $auth; @@ -138,7 +146,7 @@ class fulltext_sphinx // Initialize \phpbb\db\tools object $this->db_tools = new \phpbb\db\tools($this->db); - if(!$this->config['fulltext_sphinx_id']) + if (!$this->config['fulltext_sphinx_id']) { set_config('fulltext_sphinx_id', unique_id()); } @@ -350,6 +358,23 @@ class fulltext_sphinx $non_unique = array('sql_query_pre' => true, 'sql_attr_uint' => true, 'sql_attr_timestamp' => true, 'sql_attr_str2ordinal' => true, 'sql_attr_bool' => true); $delete = array('sql_group_column' => true, 'sql_date_column' => true, 'sql_str2ordinal_column' => true); + + /** + * Allow adding/changing the Sphinx configuration data + * + * @event core.search_sphinx_modify_config_data + * @var array config_data Array with the Sphinx configuration data + * @var array non_unique Array with the Sphinx non-unique variables to delete + * @var array delete Array with the Sphinx variables to delete + * @since 3.1.7-RC1 + */ + $vars = array( + 'config_data', + 'non_unique', + 'delete', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_sphinx_modify_config_data', compact($vars))); + foreach ($config_data as $section_name => $section_data) { $section = $config_object->get_section_by_name($section_name); @@ -523,6 +548,41 @@ class fulltext_sphinx $this->sphinx->SetFilter('topic_id', array($topic_id)); } + /** + * Allow modifying the Sphinx search options + * + * @event core.search_sphinx_keywords_modify_options + * @var string type Searching type ('posts', 'topics') + * @var string fields Searching fields ('titleonly', 'msgonly', 'firstpost', 'all') + * @var string terms Searching terms ('all', 'any') + * @var int sort_days Time, in days, of the oldest possible post to list + * @var string sort_key The sort type used from the possible sort types + * @var int topic_id Limit the search to this topic_id only + * @var array ex_fid_ary Which forums not to search on + * @var string post_visibility Post visibility data + * @var array author_ary Array of user_id containing the users to filter the results to + * @var string author_name The username to search on + * @var object sphinx The Sphinx searchd client object + * @since 3.1.7-RC1 + */ + $sphinx = $this->sphinx; + $vars = array( + 'type', + 'fields', + 'terms', + 'sort_days', + 'sort_key', + 'topic_id', + 'ex_fid_ary', + 'post_visibility', + 'author_ary', + 'author_name', + 'sphinx', + ); + extract($this->phpbb_dispatcher->trigger_event('core.search_sphinx_keywords_modify_options', compact($vars))); + $this->sphinx = $sphinx; + unset($sphinx); + $search_query_prefix = ''; switch ($fields) diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index bedd581725..a5c8f264e0 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -519,7 +519,7 @@ class session */ function session_create($user_id = false, $set_admin = false, $persist_login = false, $viewonline = true) { - global $SID, $_SID, $db, $config, $cache, $phpbb_root_path, $phpEx, $phpbb_container; + global $SID, $_SID, $db, $config, $cache, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher; $this->data = array(); @@ -893,6 +893,19 @@ class session $_SID = ''; } + $session_data = $sql_ary; + /** + * Event to send new session data to extension + * Read-only event + * + * @event core.session_create_after + * @var array session_data Associative array of session keys to be updated + * @since 3.1.6-RC1 + */ + $vars = array('session_data'); + extract($phpbb_dispatcher->trigger_event('core.session_create_after', compact($vars))); + unset($session_data); + return true; } @@ -906,13 +919,30 @@ class session */ function session_kill($new_session = true) { - global $SID, $_SID, $db, $config, $phpbb_root_path, $phpEx, $phpbb_container; + global $SID, $_SID, $db, $config, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher; $sql = 'DELETE FROM ' . SESSIONS_TABLE . " WHERE session_id = '" . $db->sql_escape($this->session_id) . "' AND session_user_id = " . (int) $this->data['user_id']; $db->sql_query($sql); + $user_id = (int) $this->data['user_id']; + $session_id = $this->session_id; + /** + * Event to send session kill information to extension + * Read-only event + * + * @event core.session_kill_after + * @var int user_id user_id of the session user. + * @var string session_id current user's session_id + * @var bool new_session should we create new session for user + * @since 3.1.6-RC1 + */ + $vars = array('user_id', 'session_id', 'new_session'); + extract($phpbb_dispatcher->trigger_event('core.session_kill_after', compact($vars))); + unset($user_id); + unset($session_id); + // Allow connecting logout with external auth method logout $provider_collection = $phpbb_container->get('auth.provider_collection'); $provider = $provider_collection->get_provider(); @@ -980,7 +1010,7 @@ class session */ function session_gc() { - global $db, $config, $phpbb_root_path, $phpEx, $phpbb_container; + global $db, $config, $phpbb_root_path, $phpEx, $phpbb_container, $phpbb_dispatcher; $batch_size = 10; @@ -1048,6 +1078,14 @@ class session $db->sql_query($sql); } + /** + * Event to trigger extension on session_gc + * + * @event core.session_gc_after + * @since 3.1.6-RC1 + */ + $phpbb_dispatcher->dispatch('core.session_gc_after'); + return; } @@ -1541,12 +1579,24 @@ class session */ public function update_session($session_data, $session_id = null) { - global $db; + global $db, $phpbb_dispatcher; $session_id = ($session_id) ? $session_id : $this->session_id; $sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $session_data) . " WHERE session_id = '" . $db->sql_escape($session_id) . "'"; $db->sql_query($sql); + + /** + * Event to send update session information to extension + * Read-only event + * + * @event core.update_session_after + * @var array session_data Associative array of session keys to be updated + * @var string session_id current user's session_id + * @since 3.1.6-RC1 + */ + $vars = array('session_data', 'session_id'); + extract($phpbb_dispatcher->trigger_event('core.update_session_after', compact($vars))); } } diff --git a/phpBB/phpbb/template/asset.php b/phpBB/phpbb/template/asset.php index 67dbd7b357..ff9366af4a 100644 --- a/phpBB/phpbb/template/asset.php +++ b/phpBB/phpbb/template/asset.php @@ -152,6 +152,24 @@ class asset */ public function set_path($path, $urlencode = false) { + // Since 1.7.0 Twig returns the real path of the file. We need it to be relative to the working directory. + $real_root_path = realpath($this->path_helper->get_phpbb_root_path()) . DIRECTORY_SEPARATOR; + + // If the asset is under the phpBB root path we need to remove its path and then prepend $phpbb_root_path + if (substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path) + { + $path = $this->path_helper->get_phpbb_root_path() . str_replace('\\', '/', substr($path, strlen($real_root_path))); + } + else + { + // Else we make the path relative to the current working directory + $real_root_path = realpath('.') . DIRECTORY_SEPARATOR; + if ($real_root_path && substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path) + { + $path = str_replace('\\', '/', substr($path, strlen($real_root_path))); + } + } + if ($urlencode) { $paths = explode('/', $path); @@ -161,6 +179,7 @@ class asset } $path = implode('/', $paths); } + $this->components['path'] = $path; } diff --git a/phpBB/phpbb/template/twig/node/includecss.php b/phpBB/phpbb/template/twig/node/includecss.php index 2ce63402aa..2dac154036 100644 --- a/phpBB/phpbb/template/twig/node/includecss.php +++ b/phpBB/phpbb/template/twig/node/includecss.php @@ -31,7 +31,7 @@ class includecss extends \phpbb\template\twig\node\includeasset $compiler ->raw("<link href=\"' . ") ->raw("\$asset_file . '\"") - ->raw(' rel="stylesheet" type="text/css" media="screen, projection" />') + ->raw(' rel="stylesheet" type="text/css" media="screen" />') ; } } diff --git a/phpBB/phpbb/tree/nestedset.php b/phpBB/phpbb/tree/nestedset.php index 57d109652e..8490c7c299 100644 --- a/phpBB/phpbb/tree/nestedset.php +++ b/phpBB/phpbb/tree/nestedset.php @@ -837,7 +837,10 @@ abstract class nestedset implements \phpbb\tree\tree_interface ' . $this->get_sql_where('AND') . ' ORDER BY ' . $this->column_left_id . ', ' . $this->column_item_id . ' ASC'; $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) + $rows = $this->db->sql_fetchrowset($result); + $this->db->sql_freeresult($result); + + foreach ($rows as $row) { // First we update the left_id for this module if ($row[$this->column_left_id] != $new_id) @@ -862,7 +865,6 @@ abstract class nestedset implements \phpbb\tree\tree_interface } $new_id++; } - $this->db->sql_freeresult($result); if ($acquired_new_lock) { diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php index 882e9cef26..f5ad5096bb 100644 --- a/phpBB/phpbb/user.php +++ b/phpBB/phpbb/user.php @@ -301,6 +301,14 @@ class user extends \phpbb\session // After calling it we continue script execution... phpbb_user_session_handler(); + /** + * Execute code at the end of user setup + * + * @event core.user_setup_after + * @since 3.1.6-RC1 + */ + $phpbb_dispatcher->dispatch('core.user_setup_after'); + // If this function got called from the error handler we are finished here. if (defined('IN_ERROR_HANDLER')) { @@ -637,7 +645,7 @@ class user extends \phpbb\session $lang_path = $this->lang_path; } - if (strpos($phpbb_root_path . $filename, $lang_path . $this->lang_name . '/') === 0) + if (strpos($phpbb_root_path . $filename, $lang_path) === 0) { $language_filename = $phpbb_root_path . $filename; } diff --git a/phpBB/phpbb/user_loader.php b/phpBB/phpbb/user_loader.php index 24e663b150..5ce8ca2d4d 100644 --- a/phpBB/phpbb/user_loader.php +++ b/phpBB/phpbb/user_loader.php @@ -179,9 +179,10 @@ class user_loader * @param bool $query Should we query the database if this user has not yet been loaded? * Typically this should be left as false and you should make sure * you load users ahead of time with load_users() + * @param bool @lazy If true, will be lazy loaded (requires JS) * @return string */ - public function get_avatar($user_id, $query = false) + public function get_avatar($user_id, $query = false, $lazy = false) { if (!($user = $this->get_user($user_id, $query))) { @@ -193,7 +194,7 @@ class user_loader include($this->phpbb_root_path . 'includes/functions_display.' . $this->php_ext); } - return get_user_avatar($user['user_avatar'], $user['user_avatar_type'], $user['user_avatar_width'], $user['user_avatar_height']); + return get_user_avatar($user['user_avatar'], $user['user_avatar_type'], $user['user_avatar_width'], $user['user_avatar_height'], 'USER_AVATAR', false, $lazy); } /** |