diff options
Diffstat (limited to 'phpBB/phpbb')
161 files changed, 3542 insertions, 818 deletions
diff --git a/phpBB/phpbb/auth/provider/apache.php b/phpBB/phpbb/auth/provider/apache.php index 23cdc89829..6374f29d67 100644 --- a/phpBB/phpbb/auth/provider/apache.php +++ b/phpBB/phpbb/auth/provider/apache.php @@ -26,7 +26,7 @@ class apache extends \phpbb\auth\provider\base /** * Apache Authentication Constructor * - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\config\config $config * @param \phpbb\passwords\manager $passwords_manager * @param \phpbb\request\request $request @@ -34,7 +34,7 @@ class apache extends \phpbb\auth\provider\base * @param string $phpbb_root_path * @param string $php_ext */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, $phpbb_root_path, $php_ext) { $this->db = $db; $this->config = $config; diff --git a/phpBB/phpbb/auth/provider/db.php b/phpBB/phpbb/auth/provider/db.php index 6bbbc0be16..5adbf84d9f 100644 --- a/phpBB/phpbb/auth/provider/db.php +++ b/phpBB/phpbb/auth/provider/db.php @@ -28,7 +28,7 @@ class db extends \phpbb\auth\provider\base /** * Database Authentication Constructor * - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\config\config $config * @param \phpbb\passwords\manager $passwords_manager * @param \phpbb\request\request $request @@ -36,7 +36,7 @@ class db extends \phpbb\auth\provider\base * @param string $phpbb_root_path * @param string $php_ext */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, $phpbb_root_path, $php_ext) { $this->db = $db; $this->config = $config; diff --git a/phpBB/phpbb/auth/provider/ldap.php b/phpBB/phpbb/auth/provider/ldap.php index e92a227e16..3d3f1990eb 100644 --- a/phpBB/phpbb/auth/provider/ldap.php +++ b/phpBB/phpbb/auth/provider/ldap.php @@ -28,12 +28,12 @@ class ldap extends \phpbb\auth\provider\base /** * LDAP Authentication Constructor * - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\config\config $config * @param \phpbb\passwords\manager $passwords_manager * @param \phpbb\user $user */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\user $user) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\user $user) { $this->db = $db; $this->config = $config; diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php index 0128c89248..10d5cda5e3 100644 --- a/phpBB/phpbb/auth/provider/oauth/oauth.php +++ b/phpBB/phpbb/auth/provider/oauth/oauth.php @@ -22,7 +22,7 @@ class oauth extends \phpbb\auth\provider\base /** * Database driver * - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -106,7 +106,7 @@ class oauth extends \phpbb\auth\provider\base /** * OAuth Authentication Constructor * - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\config\config $config * @param \phpbb\passwords\manager $passwords_manager * @param \phpbb\request\request_interface $request @@ -118,7 +118,7 @@ class oauth extends \phpbb\auth\provider\base * @param string $phpbb_root_path * @param string $php_ext */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request_interface $request, \phpbb\user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_token_account_assoc, \phpbb\di\service_collection $service_providers, $users_table, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request_interface $request, \phpbb\user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_token_account_assoc, \phpbb\di\service_collection $service_providers, $users_table, $phpbb_root_path, $php_ext) { $this->db = $db; $this->config = $config; diff --git a/phpBB/phpbb/auth/provider/oauth/token_storage.php b/phpBB/phpbb/auth/provider/oauth/token_storage.php index 43574288dc..d32a03be0a 100644 --- a/phpBB/phpbb/auth/provider/oauth/token_storage.php +++ b/phpBB/phpbb/auth/provider/oauth/token_storage.php @@ -26,7 +26,7 @@ class token_storage implements TokenStorageInterface /** * Cache driver. * - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -52,11 +52,11 @@ class token_storage implements TokenStorageInterface /** * Creates token storage for phpBB. * - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\user $user * @param string $auth_provider_oauth_table */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\user $user, $auth_provider_oauth_table) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, $auth_provider_oauth_table) { $this->db = $db; $this->user = $user; diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php index 1e50e135e4..f77ef1332b 100644 --- a/phpBB/phpbb/avatar/driver/upload.php +++ b/phpBB/phpbb/avatar/driver/upload.php @@ -147,7 +147,7 @@ class upload extends \phpbb\avatar\driver\driver return array( 'allow_avatar_remote_upload'=> array('lang' => 'ALLOW_REMOTE_UPLOAD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true), 'avatar_filesize' => array('lang' => 'MAX_FILESIZE', 'validate' => 'int:0', 'type' => 'number:0', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']), - 'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rwpath', 'type' => 'text:20:255', 'explain' => true), + 'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true), ); } diff --git a/phpBB/phpbb/cache/driver/driver_interface.php b/phpBB/phpbb/cache/driver/driver_interface.php index 8444028115..8929647411 100644 --- a/phpBB/phpbb/cache/driver/driver_interface.php +++ b/phpBB/phpbb/cache/driver/driver_interface.php @@ -106,7 +106,7 @@ interface driver_interface * result to persistent storage. In other words, there is no need * to call save() afterwards. * - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param string $query SQL query, should be used for generating storage key * @param mixed $query_result The result from \dbal::sql_query, to be passed to * \dbal::sql_fetchrow to get all rows and store them @@ -117,7 +117,7 @@ interface driver_interface * representing the query should be returned. Otherwise * the original $query_result should be returned. */ - public function sql_save(\phpbb\db\driver\driver $db, $query, $query_result, $ttl); + public function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl); /** * Check if result for a given SQL query exists in cache. diff --git a/phpBB/phpbb/cache/driver/file.php b/phpBB/phpbb/cache/driver/file.php index a57a805193..286ba328c3 100644 --- a/phpBB/phpbb/cache/driver/file.php +++ b/phpBB/phpbb/cache/driver/file.php @@ -407,7 +407,7 @@ class file extends \phpbb\cache\driver\base /** * {@inheritDoc} */ - function sql_save(\phpbb\db\driver\driver $db, $query, $query_result, $ttl) + function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl) { // Remove extra spaces and tabs $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); diff --git a/phpBB/phpbb/cache/driver/memory.php b/phpBB/phpbb/cache/driver/memory.php index b618b0f3e6..d5404455d1 100644 --- a/phpBB/phpbb/cache/driver/memory.php +++ b/phpBB/phpbb/cache/driver/memory.php @@ -279,7 +279,7 @@ abstract class memory extends \phpbb\cache\driver\base /** * {@inheritDoc} */ - function sql_save(\phpbb\db\driver\driver $db, $query, $query_result, $ttl) + function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl) { // Remove extra spaces and tabs $query = preg_replace('/[\n\r\s\t]+/', ' ', $query); diff --git a/phpBB/phpbb/cache/driver/null.php b/phpBB/phpbb/cache/driver/null.php index 8af63eb725..99cfe454e0 100644 --- a/phpBB/phpbb/cache/driver/null.php +++ b/phpBB/phpbb/cache/driver/null.php @@ -101,7 +101,7 @@ class null extends \phpbb\cache\driver\base /** * {@inheritDoc} */ - function sql_save(\phpbb\db\driver\driver $db, $query, $query_result, $ttl) + function sql_save(\phpbb\db\driver\driver_interface $db, $query, $query_result, $ttl) { return $query_result; } diff --git a/phpBB/phpbb/cache/service.php b/phpBB/phpbb/cache/service.php index ebbcfb8cdb..f9b6324b05 100644 --- a/phpBB/phpbb/cache/service.php +++ b/phpBB/phpbb/cache/service.php @@ -32,7 +32,7 @@ class service /** * Database connection. * - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -55,11 +55,11 @@ class service * * @param \phpbb\cache\driver\driver_interface $driver The cache driver * @param \phpbb\config\config $config The config - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param string $phpbb_root_path Root path * @param string $php_ext PHP extension */ - public function __construct(\phpbb\cache\driver\driver_interface $driver, \phpbb\config\config $config, \phpbb\db\driver\driver $db, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\cache\driver\driver_interface $driver, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, $phpbb_root_path, $php_ext) { $this->set_driver($driver); $this->config = $config; diff --git a/phpBB/phpbb/config/db.php b/phpBB/phpbb/config/db.php index c1a3630a14..ea84a9f873 100644 --- a/phpBB/phpbb/config/db.php +++ b/phpBB/phpbb/config/db.php @@ -23,7 +23,7 @@ class db extends \phpbb\config\config /** * Database connection - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -36,11 +36,11 @@ class db extends \phpbb\config\config /** * Creates a configuration container with a default set of values * - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param \phpbb\cache\driver\driver_interface $cache Cache instance * @param string $table Configuration table name */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\cache\driver\driver_interface $cache, $table) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, $table) { $this->db = $db; $this->cache = $cache; diff --git a/phpBB/phpbb/config/db_text.php b/phpBB/phpbb/config/db_text.php index b1ea112b53..250a2ec7de 100644 --- a/phpBB/phpbb/config/db_text.php +++ b/phpBB/phpbb/config/db_text.php @@ -20,7 +20,7 @@ class db_text { /** * Database connection - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -31,10 +31,10 @@ class db_text protected $table; /** - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param string $table Table name */ - public function __construct(\phpbb\db\driver\driver $db, $table) + public function __construct(\phpbb\db\driver\driver_interface $db, $table) { $this->db = $db; $this->table = $this->db->sql_escape($table); diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php new file mode 100644 index 0000000000..16a09af6fc --- /dev/null +++ b/phpBB/phpbb/console/command/db/migrate.php @@ -0,0 +1,128 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ +namespace phpbb\console\command\db; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class migrate extends \phpbb\console\command\command +{ + /** @var \phpbb\db\migrator */ + protected $migrator; + + /** @var \phpbb\extension\manager */ + protected $extension_manager; + + /** @var \phpbb\config\config */ + protected $config; + + /** @var \phpbb\cache\service */ + protected $cache; + + /** @var \phpbb\log\log */ + protected $log; + + /** @var \phpbb\user */ + protected $user; + + function __construct(\phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, \phpbb\user $user) + { + $this->migrator = $migrator; + $this->extension_manager = $extension_manager; + $this->config = $config; + $this->cache = $cache; + $this->log = $log; + $this->user = $user; + $this->user->add_lang(array('common', 'acp/common', 'install', 'migrator')); + parent::__construct(); + } + + protected function configure() + { + $this + ->setName('db:migrate') + ->setDescription('Updates the database by applying migrations.') + ; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->load_migrations(); + $orig_version = $this->config['version']; + while (!$this->migrator->finished()) + { + $migration_start_time = microtime(true); + + try + { + $this->migrator->update(); + } + catch (\phpbb\db\migration\exception $e) + { + $output->writeln('<error>' . $e->getLocalisedMessage($this->user) . '</error>'); + $this->finalise_update(); + return 1; + } + + $migration_stop_time = microtime(true) - $migration_start_time; + + $state = array_merge( + array( + 'migration_schema_done' => false, + 'migration_data_done' => false, + ), + $this->migrator->last_run_migration['state'] + ); + + if (!empty($this->migrator->last_run_migration['effectively_installed'])) + { + $msg = $this->user->lang('MIGRATION_EFFECTIVELY_INSTALLED', $this->migrator->last_run_migration['name']); + $output->writeln("<comment>$msg</comment>"); + } + else if ($this->migrator->last_run_migration['task'] == 'process_data_step' && $state['migration_data_done']) + { + $msg = $this->user->lang('MIGRATION_DATA_DONE', $this->migrator->last_run_migration['name'], $migration_stop_time); + $output->writeln("<info>$msg</info>"); + } + else if ($this->migrator->last_run_migration['task'] == 'process_data_step') + { + $output->writeln($this->user->lang('MIGRATION_DATA_IN_PROGRESS', $this->migrator->last_run_migration['name'], $migration_stop_time)); + } + else if ($state['migration_schema_done']) + { + $msg = $this->user->lang('MIGRATION_SCHEMA_DONE', $this->migrator->last_run_migration['name'], $migration_stop_time); + $output->writeln("<info>$msg</info>"); + } + } + + if ($orig_version != $this->config['version']) + { + $this->log->add('admin', 'LOG_UPDATE_DATABASE', $orig_version, $this->config['version']); + } + + $this->finalise_update(); + $output->writeln($this->user->lang['DATABASE_UPDATE_COMPLETE']); + } + + protected function load_migrations() + { + $migrations = $this->extension_manager + ->get_finder() + ->core_path('phpbb/db/migration/data/') + ->extension_directory('/migrations') + ->get_classes(); + $this->migrator->set_migrations($migrations); + } + + protected function finalise_update() + { + $this->cache->purge(); + $this->config->increment('assets_version', 1); + } +} diff --git a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php index 04db880091..8c520673d9 100644 --- a/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php +++ b/phpBB/phpbb/console/command/fixup/recalculate_email_hash.php @@ -13,10 +13,10 @@ use Symfony\Component\Console\Output\OutputInterface; class recalculate_email_hash extends \phpbb\console\command\command { - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; - function __construct(\phpbb\db\driver\driver $db) + function __construct(\phpbb\db\driver\driver_interface $db) { $this->db = $db; diff --git a/phpBB/phpbb/content_visibility.php b/phpBB/phpbb/content_visibility.php index f18ee0fd73..881a8f2c54 100644 --- a/phpBB/phpbb/content_visibility.php +++ b/phpBB/phpbb/content_visibility.php @@ -18,7 +18,7 @@ class content_visibility { /** * Database object - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -50,13 +50,13 @@ class content_visibility * Constructor * * @param \phpbb\auth\auth $auth Auth object - * @param \phpbb\db\driver\driver $db Database object + * @param \phpbb\db\driver\driver_interface $db Database object * @param \phpbb\user $user User object * @param string $phpbb_root_path Root path * @param string $php_ext PHP Extension * @return null */ - public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver $db, \phpbb\user $user, $phpbb_root_path, $php_ext, $forums_table, $posts_table, $topics_table, $users_table) + public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, $phpbb_root_path, $php_ext, $forums_table, $posts_table, $topics_table, $users_table) { $this->auth = $auth; $this->db = $db; @@ -215,23 +215,23 @@ class content_visibility /** * Change visibility status of one post or all posts of a topic * - * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED} + * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE} * @param $post_id mixed Post ID or array of post IDs to act on, * if it is empty, all posts of topic_id will be modified * @param $topic_id int Topic where $post_id is found * @param $forum_id int Forum where $topic_id is found * @param $user_id int User performing the action * @param $time int Timestamp when the action is performed - * @param $reason string Reason why the visibilty was changed. + * @param $reason string Reason why the visibility was changed. * @param $is_starter bool Is this the first post of the topic changed? * @param $is_latest bool Is this the last post of the topic changed? * @param $limit_visibility mixed Limit updating per topic_id to a certain visibility * @param $limit_delete_time mixed Limit updating per topic_id to a certain deletion time - * @return array Changed post data, empty array if an error occured. + * @return array Changed post data, empty array if an error occurred. */ public function set_post_visibility($visibility, $post_id, $topic_id, $forum_id, $user_id, $time, $reason, $is_starter, $is_latest, $limit_visibility = false, $limit_delete_time = false) { - if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED))) + if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE))) { return array(); } @@ -326,7 +326,7 @@ class content_visibility // Update users postcounts foreach ($postcounts as $num_posts => $poster_ids) { - if ($visibility == ITEM_DELETED) + if (in_array($visibility, array(ITEM_REAPPROVE, ITEM_DELETED))) { $sql = 'UPDATE ' . $this->users_table . ' SET user_posts = 0 @@ -387,54 +387,36 @@ class content_visibility // Update the topic's reply count and the forum's post count if ($update_topic_postcount) { - $cur_posts = $cur_unapproved_posts = $cur_softdeleted_posts = 0; + $field_alias = array( + ITEM_APPROVED => 'posts_approved', + ITEM_UNAPPROVED => 'posts_unapproved', + ITEM_DELETED => 'posts_softdeleted', + ITEM_REAPPROVE => 'posts_unapproved', + ); + $cur_posts = array_fill_keys($field_alias, 0); + foreach ($postcount_visibility as $post_visibility => $visibility_posts) { - // We need to substract the posts from the counters ... - if ($post_visibility == ITEM_APPROVED) - { - $cur_posts += $visibility_posts; - } - else if ($post_visibility == ITEM_UNAPPROVED) - { - $cur_unapproved_posts += $visibility_posts; - } - else if ($post_visibility == ITEM_DELETED) - { - $cur_softdeleted_posts += $visibility_posts; - } + $cur_posts[$field_alias[(int) $post_visibility]] += $visibility_posts; } $sql_ary = array(); - if ($visibility == ITEM_DELETED) + $recipient_field = $field_alias[$visibility]; + + foreach ($cur_posts as $field => $count) { - if ($cur_posts) - { - $sql_ary['posts_approved'] = ' - ' . $cur_posts; - } - if ($cur_unapproved_posts) + // Decrease the count for the old statuses. + if ($count && $field != $recipient_field) { - $sql_ary['posts_unapproved'] = ' - ' . $cur_unapproved_posts; - } - if ($cur_posts + $cur_unapproved_posts) - { - $sql_ary['posts_softdeleted'] = ' + ' . ($cur_posts + $cur_unapproved_posts); + $sql_ary[$field] = " - $count"; } } - else + // Add up the count from all statuses excluding the recipient status. + $count_increase = array_sum(array_diff($cur_posts, array($recipient_field))); + + if ($count_increase) { - if ($cur_unapproved_posts) - { - $sql_ary['posts_unapproved'] = ' - ' . $cur_unapproved_posts; - } - if ($cur_softdeleted_posts) - { - $sql_ary['posts_softdeleted'] = ' - ' . $cur_softdeleted_posts; - } - if ($cur_softdeleted_posts + $cur_unapproved_posts) - { - $sql_ary['posts_approved'] = ' + ' . ($cur_softdeleted_posts + $cur_unapproved_posts); - } + $sql_ary[$recipient_field] = " + $count_increase"; } if (sizeof($sql_ary)) @@ -475,7 +457,7 @@ class content_visibility * as soft deleted. * If you want to update all posts, use the force option. * - * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED} + * @param $visibility int Element of {ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE} * @param $topic_id mixed Topic ID to act on * @param $forum_id int Forum where $topic_id is found * @param $user_id int User performing the action @@ -486,7 +468,7 @@ class content_visibility */ public function set_topic_visibility($visibility, $topic_id, $forum_id, $user_id, $time, $reason, $force_update_all = false) { - if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED))) + if (!in_array($visibility, array(ITEM_APPROVED, ITEM_DELETED, ITEM_REAPPROVE))) { return array(); } @@ -532,7 +514,7 @@ class content_visibility } else if (!$force_update_all && $original_topic_data['topic_visibility'] == ITEM_APPROVED && $visibility == ITEM_DELETED) { - // If we're soft deleting a topic we only approved posts are soft deleted. + // If we're soft deleting a topic we only mark approved posts as soft deleted. $this->set_post_visibility($visibility, false, $topic_id, $forum_id, $user_id, $time, '', true, true, $original_topic_data['topic_visibility']); } else diff --git a/phpBB/phpbb/cron/task/core/prune_all_forums.php b/phpBB/phpbb/cron/task/core/prune_all_forums.php index 90b9a5914b..36a551394a 100644 --- a/phpBB/phpbb/cron/task/core/prune_all_forums.php +++ b/phpBB/phpbb/cron/task/core/prune_all_forums.php @@ -31,9 +31,9 @@ class prune_all_forums extends \phpbb\cron\task\base * @param string $phpbb_root_path The root path * @param string $php_ext The PHP extension * @param \phpbb\config\config $config The config - * @param \phpbb\db\driver\driver $db The db connection + * @param \phpbb\db\driver\driver_interface $db The db connection */ - public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver $db) + public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db) { $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; diff --git a/phpBB/phpbb/cron/task/core/prune_forum.php b/phpBB/phpbb/cron/task/core/prune_forum.php index e0d8b067c5..542d75e5b9 100644 --- a/phpBB/phpbb/cron/task/core/prune_forum.php +++ b/phpBB/phpbb/cron/task/core/prune_forum.php @@ -41,9 +41,9 @@ class prune_forum extends \phpbb\cron\task\base implements \phpbb\cron\task\para * @param string $phpbb_root_path The root path * @param string $php_ext The PHP extension * @param \phpbb\config\config $config The config - * @param \phpbb\db\driver\driver $db The db connection + * @param \phpbb\db\driver\driver_interface $db The db connection */ - public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver $db) + public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db) { $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; diff --git a/phpBB/phpbb/cron/task/core/prune_shadow_topics.php b/phpBB/phpbb/cron/task/core/prune_shadow_topics.php new file mode 100644 index 0000000000..b30e665a87 --- /dev/null +++ b/phpBB/phpbb/cron/task/core/prune_shadow_topics.php @@ -0,0 +1,191 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\cron\task\core; + +/** +* Prune one forum of its shadow topics cron task. +* +* It is intended to be used when cron is invoked via web. +* This task can decide whether it should be run using data obtained by viewforum +* code, without making additional database queries. +* +* @package phpBB3 +*/ +class prune_shadow_topics extends \phpbb\cron\task\base implements \phpbb\cron\task\parametrized +{ + protected $phpbb_root_path; + protected $php_ext; + protected $config; + protected $db; + protected $log; + + /** + * If $forum_data is given, it is assumed to contain necessary information + * about a single forum that is to be pruned. + * + * If $forum_data is not given, forum id will be retrieved via request_var + * and a database query will be performed to load the necessary information + * about the forum. + */ + protected $forum_data; + + /** + * Constructor. + * + * @param string $phpbb_root_path The root path + * @param string $php_ext The PHP extension + * @param \phpbb\config\config $config The config + * @param \phpbb\db\driver\driver $db The db connection + * @param \phpbb\log\log $log The phpBB log system + */ + public function __construct($phpbb_root_path, $php_ext, \phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\log\log $log) + { + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + $this->config = $config; + $this->db = $db; + $this->log = $log; + } + + /** + * Manually set forum data. + * + * @param array $forum_data Information about a forum to be pruned. + */ + public function set_forum_data($forum_data) + { + $this->forum_data = $forum_data; + } + + /** + * Runs this cron task. + * + * @return null + */ + public function run() + { + if (!function_exists('auto_prune')) + { + include($this->phpbb_root_path . 'includes/functions_admin.' . $this->php_ext); + } + + if ($this->forum_data['prune_shadow_days']) + { + $this->auto_prune_shadow_topics($this->forum_data['forum_id'], 'shadow', $this->forum_data['forum_flags'], $this->forum_data['prune_shadow_days'], $this->forum_data['prune_shadow_freq']); + } + } + + /** + * Returns whether this cron task can run, given current board configuration. + * + * This cron task will not run when system cron is utilised, as in + * such cases prune_all_forums task would run instead. + * + * Additionally, this task must be given the forum data, either via + * the constructor or parse_parameters method. + * + * @return bool + */ + public function is_runnable() + { + return !$this->config['use_system_cron'] && $this->forum_data; + } + + /** + * Returns whether this cron task should run now, because enough time + * has passed since it was last run. + * + * Forum pruning interval is specified in the forum data. + * + * @return bool + */ + public function should_run() + { + return $this->forum_data['enable_shadow_prune'] && $this->forum_data['prune_shadow_next'] < time(); + } + + /** + * Returns parameters of this cron task as an array. + * The array has one key, f, whose value is id of the forum to be pruned. + * + * @return array + */ + public function get_parameters() + { + return array('f' => $this->forum_data['forum_id']); + } + + /** + * Parses parameters found in $request, which is an instance of + * \phpbb\request\request_interface. + * + * It is expected to have a key f whose value is id of the forum to be pruned. + * + * @param \phpbb\request\request_interface $request Request object. + * + * @return null + */ + public function parse_parameters(\phpbb\request\request_interface $request) + { + $this->forum_data = null; + if ($request->is_set('f')) + { + $forum_id = $request->variable('f', 0); + + $sql = 'SELECT forum_id, prune_shadow_next, enable_shadow_prune, prune_shadow_days, forum_flags, prune_shadow_freq + FROM ' . FORUMS_TABLE . " + WHERE forum_id = $forum_id"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row) + { + $this->forum_data = $row; + } + } + } + + /** + * Automatically prune shadow topics + * Based on fuunction auto_prune() + * @param int $forum_id Forum ID of forum that should be pruned + * @param string $prune_mode Prune mode + * @param int $prune_flags Prune flags + * @param int $prune_freq Prune frequency + * @return null + */ + protected function auto_prune_shadow_topics($forum_id, $prune_mode, $prune_flags, $prune_days, $prune_freq) + { + $sql = 'SELECT forum_name + FROM ' . FORUMS_TABLE . " + WHERE forum_id = $forum_id"; + $result = $this->db->sql_query($sql, 3600); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if ($row) + { + $prune_date = time() - ($prune_days * 86400); + $next_prune = time() + ($prune_freq * 86400); + + prune($forum_id, $prune_mode, $prune_date, $prune_flags, true); + + $sql = 'UPDATE ' . FORUMS_TABLE . " + SET prune_shadow_next = $next_prune + WHERE forum_id = $forum_id"; + $this->db->sql_query($sql); + + $this->log->add('admin', 'LOG_PRUNE_SHADOW', $row['forum_name']); + } + + return; + } +} diff --git a/phpBB/phpbb/cron/task/core/tidy_search.php b/phpBB/phpbb/cron/task/core/tidy_search.php index 42f7df308f..eac6aa0a36 100644 --- a/phpBB/phpbb/cron/task/core/tidy_search.php +++ b/phpBB/phpbb/cron/task/core/tidy_search.php @@ -32,10 +32,10 @@ class tidy_search extends \phpbb\cron\task\base * @param string $php_ext The PHP extension * @param \phpbb\auth\auth $auth The auth * @param \phpbb\config\config $config The config - * @param \phpbb\db\driver\driver $db The db connection + * @param \phpbb\db\driver\driver_interface $db The db connection * @param \phpbb\user $user The user */ - public function __construct($phpbb_root_path, $php_ext, \phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\db\driver\driver $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) { $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; diff --git a/phpBB/phpbb/db/driver/driver.php b/phpBB/phpbb/db/driver/driver.php index b61800006f..85d160c80e 100644 --- a/phpBB/phpbb/db/driver/driver.php +++ b/phpBB/phpbb/db/driver/driver.php @@ -13,7 +13,7 @@ namespace phpbb\db\driver; * Database Abstraction Layer * @package dbal */ -class driver +abstract class driver implements driver_interface { var $db_connect_id; var $query_result; @@ -84,7 +84,7 @@ class driver } /** - * return on error or display error message + * {@inheritDoc} */ function sql_return_on_error($fail = false) { @@ -95,7 +95,7 @@ class driver } /** - * Return number of sql queries and cached sql queries used + * {@inheritDoc} */ function sql_num_queries($cached = false) { @@ -103,7 +103,7 @@ class driver } /** - * Add to query count + * {@inheritDoc} */ function sql_add_num_queries($cached = false) { @@ -113,7 +113,7 @@ class driver } /** - * DBAL garbage collection, close sql connection + * {@inheritDoc} */ function sql_close() { @@ -146,8 +146,7 @@ class driver } /** - * Build LIMIT query - * Doing some validation here. + * {@inheritDoc} */ function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) { @@ -164,7 +163,7 @@ class driver } /** - * Fetch all rows + * {@inheritDoc} */ function sql_fetchrowset($query_id = false) { @@ -188,8 +187,7 @@ class driver } /** - * Seek to given row number - * rownum is zero-based + * {@inheritDoc} */ function sql_rowseek($rownum, &$query_id) { @@ -231,8 +229,7 @@ class driver } /** - * Fetch field - * if rownum is false, the current row is used, else it is pointing to the row (zero-based) + * {@inheritDoc} */ function sql_fetchfield($field, $rownum = false, $query_id = false) { @@ -263,11 +260,7 @@ class driver } /** - * Correctly adjust LIKE expression for special characters - * Some DBMS are handling them in a different way - * - * @param string $expression The expression to use. Every wildcard is escaped, except $this->any_char and $this->one_char - * @return string LIKE expression including the keyword! + * {@inheritDoc} */ function sql_like_expression($expression) { @@ -278,14 +271,7 @@ class driver } /** - * Build a case expression - * - * Note: The two statements action_true and action_false must have the same data type (int, vchar, ...) in the database! - * - * @param string $condition The condition which must be true, to use action_true rather then action_else - * @param string $action_true SQL expression that is used, if the condition is true - * @param string $action_else SQL expression that is used, if the condition is false, optional - * @return string CASE expression including the condition and statements + * {@inheritDoc} */ public function sql_case($condition, $action_true, $action_false = false) { @@ -297,11 +283,7 @@ class driver } /** - * Build a concatenated expression - * - * @param string $expr1 Base SQL expression where we append the second one - * @param string $expr2 SQL expression that is appended to the first expression - * @return string Concatenated string + * {@inheritDoc} */ public function sql_concatenate($expr1, $expr2) { @@ -309,9 +291,7 @@ class driver } /** - * Returns whether results of a query need to be buffered to run a transaction while iterating over them. - * - * @return bool Whether buffering is required. + * {@inheritDoc} */ function sql_buffer_nested_transactions() { @@ -319,15 +299,14 @@ class driver } /** - * SQL Transaction - * @access private + * {@inheritDoc} */ function sql_transaction($status = 'begin') { switch ($status) { case 'begin': - // If we are within a transaction we will not open another one, but enclose the current one to not loose data (prevening auto commit) + // If we are within a transaction we will not open another one, but enclose the current one to not loose data (preventing auto commit) if ($this->transaction) { $this->transactions++; @@ -345,14 +324,16 @@ class driver break; case 'commit': - // If there was a previously opened transaction we do not commit yet... but count back the number of inner transactions + // If there was a previously opened transaction we do not commit yet... + // but count back the number of inner transactions if ($this->transaction && $this->transactions) { $this->transactions--; return true; } - // Check if there is a transaction (no transaction can happen if there was an error, with a combined rollback and error returning enabled) + // Check if there is a transaction (no transaction can happen if + // there was an error, with a combined rollback and error returning enabled) // This implies we have transaction always set for autocommit db's if (!$this->transaction) { @@ -385,11 +366,7 @@ class driver } /** - * Build sql statement from array for insert/update/select statements - * - * Idea for this from Ikonboard - * Possible query values: INSERT, INSERT_SELECT, UPDATE, SELECT, DELETE - * + * {@inheritDoc} */ function sql_build_array($query, $assoc_ary = false) { @@ -437,14 +414,7 @@ class driver } /** - * Build IN or NOT IN sql comparison string, uses <> or = on single element - * arrays to improve comparison speed - * - * @access public - * @param string $field name of the sql column that shall be compared - * @param array $array array of values that are allowed (IN) or not allowed (NOT IN) - * @param bool $negate true for NOT IN (), false for IN () (default) - * @param bool $allow_empty_set If true, allow $array to be empty, this function will return 1=1 or 1=0 then. Default to false. + * {@inheritDoc} */ function sql_in_set($field, $array, $negate = false, $allow_empty_set = false) { @@ -489,12 +459,7 @@ class driver } /** - * Run binary AND operator on DB column. - * Results in sql statement: "{$column_name} & (1 << {$bit}) {$compare}" - * - * @param string $column_name The column name to use - * @param int $bit The value to use for the AND operator, will be converted to (1 << $bit). Is used by options, using the number schema... 0, 1, 2...29 - * @param string $compare Any custom SQL code after the check (for example "= 0") + * {@inheritDoc} */ function sql_bit_and($column_name, $bit, $compare = '') { @@ -507,12 +472,7 @@ class driver } /** - * Run binary OR operator on DB column. - * Results in sql statement: "{$column_name} | (1 << {$bit}) {$compare}" - * - * @param string $column_name The column name to use - * @param int $bit The value to use for the OR operator, will be converted to (1 << $bit). Is used by options, using the number schema... 0, 1, 2...29 - * @param string $compare Any custom SQL code after the check (for example "= 0") + * {@inheritDoc} */ function sql_bit_or($column_name, $bit, $compare = '') { @@ -525,10 +485,7 @@ class driver } /** - * Returns SQL string to cast a string expression to an int. - * - * @param string $expression An expression evaluating to string - * @return string Expression returning an int + * {@inheritDoc} */ function cast_expr_to_bigint($expression) { @@ -536,10 +493,7 @@ class driver } /** - * Returns SQL string to cast an integer expression to a string. - * - * @param string $expression An expression evaluating to int - * @return string Expression returning a string + * {@inheritDoc} */ function cast_expr_to_string($expression) { @@ -547,11 +501,7 @@ class driver } /** - * Run LOWER() on DB column of type text (i.e. neither varchar nor char). - * - * @param string $column_name The column name to use - * - * @return string A SQL statement like "LOWER($column_name)" + * {@inheritDoc} */ function sql_lower_text($column_name) { @@ -559,13 +509,7 @@ class 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. - * - * @return bool false if no statements were executed. - * @access public + * {@inheritDoc} */ function sql_multi_insert($table, $sql_ary) { @@ -637,9 +581,7 @@ class driver } /** - * Build sql statement from array for select and select distinct statements - * - * Possible query values: SELECT, SELECT_DISTINCT + * {@inheritDoc} */ function sql_build_query($query, $array) { @@ -742,7 +684,7 @@ class driver } /** - * display sql error page + * {@inheritDoc} */ function sql_error($sql = '') { @@ -812,7 +754,7 @@ class driver } /** - * Explain queries + * {@inheritDoc} */ function sql_report($mode, $query = '') { @@ -1002,14 +944,7 @@ class driver } /** - * Gets the estimated number of rows in a specified table. - * - * @param string $table_name Table name - * - * @return string Number of rows in $table_name. - * Prefixed with ~ if estimated (otherwise exact). - * - * @access public + * {@inheritDoc} */ function get_estimated_row_count($table_name) { @@ -1017,13 +952,7 @@ class driver } /** - * Gets the exact number of rows in a specified table. - * - * @param string $table_name Table name - * - * @return string Exact number of rows in $table_name. - * - * @access public + * {@inheritDoc} */ function get_row_count($table_name) { diff --git a/phpBB/phpbb/db/driver/driver_interface.php b/phpBB/phpbb/db/driver/driver_interface.php new file mode 100644 index 0000000000..a9051616c9 --- /dev/null +++ b/phpBB/phpbb/db/driver/driver_interface.php @@ -0,0 +1,355 @@ +<?php +/** +* +* @package dbal +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\driver; + +interface driver_interface +{ + /** + * Gets the exact number of rows in a specified table. + * + * @param string $table_name Table name + * @return string Exact number of rows in $table_name. + */ + public function get_row_count($table_name); + + /** + * Gets the estimated number of rows in a specified table. + * + * @param string $table_name Table name + * @return string Number of rows in $table_name. + * Prefixed with ~ if estimated (otherwise exact). + */ + public function get_estimated_row_count($table_name); + + /** + * Run LOWER() on DB column of type text (i.e. neither varchar nor char). + * + * @param string $column_name The column name to use + * @return string A SQL statement like "LOWER($column_name)" + */ + public function sql_lower_text($column_name); + + /** + * Display sql error page + * + * @param string $sql The SQL query causing the error + * @return mixed Returns the full error message, if $this->return_on_error + * is set, null otherwise + */ + public function sql_error($sql = ''); + + /** + * Returns whether results of a query need to be buffered to run a + * transaction while iterating over them. + * + * @return bool Whether buffering is required. + */ + public function sql_buffer_nested_transactions(); + + /** + * Run binary OR operator on DB column. + * + * @param string $column_name The column name to use + * @param int $bit The value to use for the OR operator, + * will be converted to (1 << $bit). Is used by options, + * using the number schema... 0, 1, 2...29 + * @param string $compare Any custom SQL code after the check (e.g. "= 0") + * @return string A SQL statement like "$column | (1 << $bit) {$compare}" + */ + public function sql_bit_or($column_name, $bit, $compare = ''); + + /** + * Version information about used database + * + * @param bool $raw Only return the fetched sql_server_version + * @param bool $use_cache Is it safe to retrieve the value from the cache + * @return string sql server version + */ + public function sql_server_info($raw = false, $use_cache = true); + + /** + * Return on error or display error message + * + * @param bool $fail Should we return on errors, or stop + * @return null + */ + public function sql_return_on_error($fail = false); + + /** + * Build sql statement from an array + * + * @param string $query Should be on of the following strings: + * INSERT, INSERT_SELECT, UPDATE, SELECT, DELETE + * @param array $assoc_ary Array with "column => value" pairs + * @return string A SQL statement like "c1 = 'a' AND c2 = 'b'" + */ + public function sql_build_array($query, $assoc_ary = array()); + + /** + * Fetch all rows + * + * @param mixed $query_id Already executed query to get the rows from, + * if false, the last query will be used. + * @return mixed Nested array if the query had rows, false otherwise + */ + public function sql_fetchrowset($query_id = false); + + /** + * SQL Transaction + * + * @param string $status Should be one of the following strings: + * begin, commit, rollback + * @return mixed Buffered, seekable result handle, false on error + */ + public function sql_transaction($status = 'begin'); + + /** + * Build a concatenated expression + * + * @param string $expr1 Base SQL expression where we append the second one + * @param string $expr2 SQL expression that is appended to the first expression + * @return string Concatenated string + */ + public function sql_concatenate($expr1, $expr2); + + /** + * Build a case expression + * + * Note: The two statements action_true and action_false must have the same + * data type (int, vchar, ...) in the database! + * + * @param string $condition The condition which must be true, + * to use action_true rather then action_else + * @param string $action_true SQL expression that is used, if the condition is true + * @param mixed $action_false SQL expression that is used, if the condition is false + * @return string CASE expression including the condition and statements + */ + public function sql_case($condition, $action_true, $action_false = false); + + /** + * Build sql statement from array for select and select distinct statements + * + * Possible query values: SELECT, SELECT_DISTINCT + * + * @param string $query Should be one of: SELECT, SELECT_DISTINCT + * @param array $array Array with the query data: + * SELECT A comma imploded list of columns to select + * FROM Array with "table => alias" pairs, + * (alias can also be an array) + * Optional: LEFT_JOIN Array of join entries: + * FROM Table that should be joined + * ON Condition for the join + * Optional: WHERE Where SQL statement + * Optional: GROUP_BY Group by SQL statement + * Optional: ORDER_BY Order by SQL statement + * @return string A SQL statement ready for execution + */ + public function sql_build_query($query, $array); + + /** + * Fetch field + * if rownum is false, the current row is used, else it is pointing to the row (zero-based) + * + * @param string $field Name of the column + * @param mixed $rownum Row number, if false the current row will be used + * and the row curser will point to the next row + * Note: $rownum is 0 based + * @param mixed $query_id Already executed query to get the rows from, + * if false, the last query will be used. + * @return mixed String value of the field in the selected row, + * false, if the row does not exist + */ + public function sql_fetchfield($field, $rownum = false, $query_id = false); + + /** + * Fetch current row + * + * @param mixed $query_id Already executed query to get the rows from, + * if false, the last query will be used. + * @return mixed Array with the current row, + * false, if the row does not exist + */ + public function sql_fetchrow($query_id = false); + + /** + * Returns SQL string to cast a string expression to an int. + * + * @param string $expression An expression evaluating to string + * @return string Expression returning an int + */ + public function cast_expr_to_bigint($expression); + + /** + * Get last inserted id after insert statement + * + * @return string Autoincrement value of the last inserted row + */ + public function sql_nextid(); + + /** + * Add to query count + * + * @param bool $cached Is this query cached? + * @return null + */ + public function sql_add_num_queries($cached = false); + + /** + * Build LIMIT query + * + * @param string $query The SQL query to execute + * @param int $total The number of rows to select + * @param int $offset + * @param int $cache_ttl Either 0 to avoid caching or + * the time in seconds which the result shall be kept in cache + * @return mixed Buffered, seekable result handle, false on error + */ + public function sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0); + + /** + * Base query method + * + * @param string $query The SQL query to execute + * @param int $cache_ttl Either 0 to avoid caching or + * the time in seconds which the result shall be kept in cache + * @return mixed Buffered, seekable result handle, false on error + */ + public function sql_query($query = '', $cache_ttl = 0); + + /** + * Returns SQL string to cast an integer expression to a string. + * + * @param string $expression An expression evaluating to int + * @return string Expression returning a string + */ + public function cast_expr_to_string($expression); + + /** + * Connect to server + * + * @param string $sqlserver Address of the database server + * @param string $sqluser User name of the SQL user + * @param string $sqlpassword Password of the SQL user + * @param string $database Name of the database + * @param mixed $port Port of the database server + * @param bool $persistency + * @param bool $new_link Should a new connection be established + * @return mixed Connection ID on success, string error message otherwise + */ + public function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false); + + /** + * Run binary AND operator on DB column. + * Results in sql statement: "{$column_name} & (1 << {$bit}) {$compare}" + * + * @param string $column_name The column name to use + * @param int $bit The value to use for the AND operator, + * will be converted to (1 << $bit). Is used by + * options, using the number schema: 0, 1, 2...29 + * @param string $compare Any custom SQL code after the check (for example "= 0") + * @return string A SQL statement like: "{$column} & (1 << {$bit}) {$compare}" + */ + public function sql_bit_and($column_name, $bit, $compare = ''); + + /** + * Free sql result + * + * @param mixed $query_id Already executed query result, + * if false, the last query will be used. + * @return null + */ + public function sql_freeresult($query_id = false); + + /** + * Return number of sql queries and cached sql queries used + * + * @param bool $cached Should we return the number of cached or normal queries? + * @return int Number of queries that have been executed + */ + public function sql_num_queries($cached = false); + + /** + * 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 + * @return bool false if no statements were executed. + */ + public function sql_multi_insert($table, $sql_ary); + + /** + * Return number of affected rows + * + * @return mixed Number of the affected rows by the last query + * false if no query has been run before + */ + public function sql_affectedrows(); + + /** + * DBAL garbage collection, close SQL connection + * + * @return mixed False if no connection was opened before, + * Server response otherwise + */ + public function sql_close(); + + /** + * Seek to given row number + * + * @param mixed $rownum Row number the curser should point to + * Note: $rownum is 0 based + * @param mixed $query_id ID of the query to set the row cursor on + * if false, the last query will be used. + * $query_id will then be set correctly + * @return bool False if something went wrong + */ + public function sql_rowseek($rownum, &$query_id); + + /** + * Escape string used in sql query + * + * @param string $msg String to be escaped + * @return string Escaped version of $msg + */ + public function sql_escape($msg); + + /** + * Correctly adjust LIKE expression for special characters + * Some DBMS are handling them in a different way + * + * @param string $expression The expression to use. Every wildcard is + * escaped, except $this->any_char and $this->one_char + * @return string A SQL statement like: "LIKE 'bertie_%'" + */ + public function sql_like_expression($expression); + + /** + * Explain queries + * + * @param string $mode Available modes: display, start, stop, + * add_select_row, fromcache, record_fromcache + * @param string $query The Query that should be explained + * @return mixed Either a full HTML page, boolean or null + */ + public function sql_report($mode, $query = ''); + + /** + * Build IN or NOT IN sql comparison string, uses <> or = on single element + * arrays to improve comparison speed + * + * @param string $field Name of the sql column that shall be compared + * @param array $array Array of values that are (not) allowed + * @param bool $negate true for NOT IN (), false for IN () + * @param bool $allow_empty_set If true, allow $array to be empty, + * this function will return 1=1 or 1=0 then. + * @return string A SQL statement like: "IN (1, 2, 3, 4)" or "= 1" + */ + public function sql_in_set($field, $array, $negate = false, $allow_empty_set = false); +} diff --git a/phpBB/phpbb/db/driver/firebird.php b/phpBB/phpbb/db/driver/firebird.php index ed56a5d154..a4967c7ffe 100644 --- a/phpBB/phpbb/db/driver/firebird.php +++ b/phpBB/phpbb/db/driver/firebird.php @@ -22,7 +22,7 @@ class firebird extends \phpbb\db\driver\driver var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -79,10 +79,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache forced to false for Interbase - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -127,13 +124,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -297,7 +288,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -313,7 +304,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -351,7 +342,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -379,7 +370,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -405,7 +396,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * Escape string used in sql query + * {@inheritDoc} */ function sql_escape($msg) { @@ -441,7 +432,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * @inheritdoc + * {@inheritDoc} */ function cast_expr_to_bigint($expression) { @@ -450,7 +441,7 @@ class firebird extends \phpbb\db\driver\driver } /** - * @inheritdoc + * {@inheritDoc} */ function cast_expr_to_string($expression) { diff --git a/phpBB/phpbb/db/driver/mssql.php b/phpBB/phpbb/db/driver/mssql.php index 6ebc891673..588cd7a7e8 100644 --- a/phpBB/phpbb/db/driver/mssql.php +++ b/phpBB/phpbb/db/driver/mssql.php @@ -19,7 +19,7 @@ class mssql extends \phpbb\db\driver\driver var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -55,10 +55,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache If true, it is safe to retrieve the value from the cache - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -124,13 +121,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -215,7 +206,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -223,7 +214,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -259,8 +250,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Seek to given row number - * rownum is zero-based + * {@inheritDoc} */ function sql_rowseek($rownum, &$query_id) { @@ -280,7 +270,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -299,7 +289,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -325,7 +315,7 @@ class mssql extends \phpbb\db\driver\driver } /** - * Escape string used in sql query + * {@inheritDoc} */ function sql_escape($msg) { diff --git a/phpBB/phpbb/db/driver/mssql_base.php b/phpBB/phpbb/db/driver/mssql_base.php index 113f1c6902..1e3fb8235a 100644 --- a/phpBB/phpbb/db/driver/mssql_base.php +++ b/phpBB/phpbb/db/driver/mssql_base.php @@ -24,7 +24,7 @@ abstract class mssql_base extends \phpbb\db\driver\driver } /** - * Escape string used in sql query + * {@inheritDoc} */ function sql_escape($msg) { diff --git a/phpBB/phpbb/db/driver/mssql_odbc.php b/phpBB/phpbb/db/driver/mssql_odbc.php index f8c70f1cd7..34b913dc8a 100644 --- a/phpBB/phpbb/db/driver/mssql_odbc.php +++ b/phpBB/phpbb/db/driver/mssql_odbc.php @@ -26,7 +26,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -83,10 +83,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache If true, it is safe to retrieve the value from the cache - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -144,13 +141,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -236,7 +227,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -244,8 +235,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base } /** - * Fetch current row - * @note number of bytes returned depends on odbc.defaultlrl php.ini setting. If it is limited to 4K for example only 4K of data is returned max. + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -265,7 +255,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -286,7 +276,7 @@ class mssql_odbc extends \phpbb\db\driver\mssql_base } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { diff --git a/phpBB/phpbb/db/driver/mssqlnative.php b/phpBB/phpbb/db/driver/mssqlnative.php index 125db9c8d4..b449de2ae4 100644 --- a/phpBB/phpbb/db/driver/mssqlnative.php +++ b/phpBB/phpbb/db/driver/mssqlnative.php @@ -24,7 +24,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -53,10 +53,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache If true, it is safe to retrieve the value from the cache - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -113,13 +110,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -215,7 +206,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -223,7 +214,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -263,7 +254,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -283,7 +274,7 @@ class mssqlnative extends \phpbb\db\driver\mssql_base } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { diff --git a/phpBB/phpbb/db/driver/mysql.php b/phpBB/phpbb/db/driver/mysql.php index e311f0dd74..1a4fd364df 100644 --- a/phpBB/phpbb/db/driver/mysql.php +++ b/phpBB/phpbb/db/driver/mysql.php @@ -24,8 +24,7 @@ class mysql extends \phpbb\db\driver\mysql_base var $connect_error = ''; /** - * Connect to server - * @access public + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -103,10 +102,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache If true, it is safe to retrieve the value from the cache - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -154,13 +150,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -213,7 +203,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -221,7 +211,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -241,8 +231,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Seek to given row number - * rownum is zero-based + * {@inheritDoc} */ function sql_rowseek($rownum, &$query_id) { @@ -262,7 +251,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -270,7 +259,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -296,7 +285,7 @@ class mysql extends \phpbb\db\driver\mysql_base } /** - * Escape string used in sql query + * {@inheritDoc} */ function sql_escape($msg) { diff --git a/phpBB/phpbb/db/driver/mysql_base.php b/phpBB/phpbb/db/driver/mysql_base.php index 87b6d153a9..d0f6a9e8fa 100644 --- a/phpBB/phpbb/db/driver/mysql_base.php +++ b/phpBB/phpbb/db/driver/mysql_base.php @@ -43,14 +43,7 @@ abstract class mysql_base extends \phpbb\db\driver\driver } /** - * Gets the estimated number of rows in a specified table. - * - * @param string $table_name Table name - * - * @return string Number of rows in $table_name. - * Prefixed with ~ if estimated (otherwise exact). - * - * @access public + * {@inheritDoc} */ function get_estimated_row_count($table_name) { @@ -72,13 +65,7 @@ abstract class mysql_base extends \phpbb\db\driver\driver } /** - * Gets the exact number of rows in a specified table. - * - * @param string $table_name Table name - * - * @return string Exact number of rows in $table_name. - * - * @access public + * {@inheritDoc} */ function get_row_count($table_name) { diff --git a/phpBB/phpbb/db/driver/mysqli.php b/phpBB/phpbb/db/driver/mysqli.php index adc8f96302..6814599b24 100644 --- a/phpBB/phpbb/db/driver/mysqli.php +++ b/phpBB/phpbb/db/driver/mysqli.php @@ -21,7 +21,7 @@ class mysqli extends \phpbb\db\driver\mysql_base var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -96,10 +96,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache If true, it is safe to retrieve the value from the cache - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -151,13 +148,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -205,7 +196,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -213,7 +204,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -239,8 +230,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Seek to given row number - * rownum is zero-based + * {@inheritDoc} */ function sql_rowseek($rownum, &$query_id) { @@ -260,7 +250,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -268,7 +258,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -288,7 +278,7 @@ class mysqli extends \phpbb\db\driver\mysql_base } /** - * Escape string used in sql query + * {@inheritDoc} */ function sql_escape($msg) { diff --git a/phpBB/phpbb/db/driver/oracle.php b/phpBB/phpbb/db/driver/oracle.php index 36ed43d4a7..8a304b5042 100644 --- a/phpBB/phpbb/db/driver/oracle.php +++ b/phpBB/phpbb/db/driver/oracle.php @@ -19,7 +19,7 @@ class oracle extends \phpbb\db\driver\driver var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -72,10 +72,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache forced to false for Oracle - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -240,13 +237,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -473,7 +464,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -481,7 +472,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -532,8 +523,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Seek to given row number - * rownum is zero-based + * {@inheritDoc} */ function sql_rowseek($rownum, &$query_id) { @@ -570,7 +560,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -602,7 +592,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -628,7 +618,7 @@ class oracle extends \phpbb\db\driver\driver } /** - * Escape string used in sql query + * {@inheritDoc} */ function sql_escape($msg) { diff --git a/phpBB/phpbb/db/driver/postgres.php b/phpBB/phpbb/db/driver/postgres.php index 5dbd1ca74f..9e091f0a5d 100644 --- a/phpBB/phpbb/db/driver/postgres.php +++ b/phpBB/phpbb/db/driver/postgres.php @@ -20,7 +20,7 @@ class postgres extends \phpbb\db\driver\driver var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -115,10 +115,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache If true, it is safe to retrieve the value from the cache - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -166,13 +163,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -253,7 +244,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -261,7 +252,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -281,8 +272,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Seek to given row number - * rownum is zero-based + * {@inheritDoc} */ function sql_rowseek($rownum, &$query_id) { @@ -302,7 +292,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -331,7 +321,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -357,8 +347,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * Escape string used in sql query - * Note: Do not use for bytea values if we may use them at a later stage + * {@inheritDoc} */ function sql_escape($msg) { @@ -375,7 +364,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * @inheritdoc + * {@inheritDoc} */ function cast_expr_to_bigint($expression) { @@ -383,7 +372,7 @@ class postgres extends \phpbb\db\driver\driver } /** - * @inheritdoc + * {@inheritDoc} */ function cast_expr_to_string($expression) { diff --git a/phpBB/phpbb/db/driver/sqlite.php b/phpBB/phpbb/db/driver/sqlite.php index 59ec895c0f..86a585f4eb 100644 --- a/phpBB/phpbb/db/driver/sqlite.php +++ b/phpBB/phpbb/db/driver/sqlite.php @@ -19,7 +19,7 @@ class sqlite extends \phpbb\db\driver\driver var $connect_error = ''; /** - * Connect to server + * {@inheritDoc} */ function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) { @@ -58,10 +58,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Version information about used database - * @param bool $raw if true, only return the fetched sql_server_version - * @param bool $use_cache if true, it is safe to retrieve the stored value from the cache - * @return string sql server version + * {@inheritDoc} */ function sql_server_info($raw = false, $use_cache = true) { @@ -108,13 +105,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Base query method - * - * @param string $query Contains the SQL query which shall be executed - * @param int $cache_ttl Either 0 to avoid caching or the time in seconds which the result shall be kept in cache - * @return mixed When casted to bool the returned value returns true on success and false on failure - * - * @access public + * {@inheritDoc} */ function sql_query($query = '', $cache_ttl = 0) { @@ -185,7 +176,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Return number of affected rows + * {@inheritDoc} */ function sql_affectedrows() { @@ -193,7 +184,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Fetch current row + * {@inheritDoc} */ function sql_fetchrow($query_id = false) { @@ -213,8 +204,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Seek to given row number - * rownum is zero-based + * {@inheritDoc} */ function sql_rowseek($rownum, &$query_id) { @@ -234,7 +224,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Get last inserted id after insert statement + * {@inheritDoc} */ function sql_nextid() { @@ -242,7 +232,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Free sql result + * {@inheritDoc} */ function sql_freeresult($query_id = false) { @@ -262,7 +252,7 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Escape string used in sql query + * {@inheritDoc} */ function sql_escape($msg) { @@ -270,7 +260,8 @@ class sqlite extends \phpbb\db\driver\driver } /** - * Correctly adjust LIKE expression for special characters + * {@inheritDoc} + * * For SQLite an underscore is a not-known character... this may change with SQLite3 */ function sql_like_expression($expression) diff --git a/phpBB/phpbb/db/driver/sqlite3.php b/phpBB/phpbb/db/driver/sqlite3.php new file mode 100644 index 0000000000..971b3e55d3 --- /dev/null +++ b/phpBB/phpbb/db/driver/sqlite3.php @@ -0,0 +1,375 @@ +<?php +/** +* +* @package dbal +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\driver; + +/** +* SQLite3 Database Abstraction Layer +* Minimum Requirement: 3.6.15+ +* @package dbal +*/ +class sqlite3 extends \phpbb\db\driver\driver +{ + /** + * @var string Stores errors during connection setup in case the driver is not available + */ + protected $connect_error = ''; + + /** + * @var \SQLite3 The SQLite3 database object to operate against + */ + protected $dbo = null; + + /** + * {@inheritDoc} + */ + public function sql_connect($sqlserver, $sqluser, $sqlpassword, $database, $port = false, $persistency = false, $new_link = false) + { + $this->persistency = false; + $this->user = $sqluser; + $this->server = $sqlserver . (($port) ? ':' . $port : ''); + $this->dbname = $database; + + if (!class_exists('SQLite3', false)) + { + $this->connect_error = 'SQLite3 not found, is the extension installed?'; + return $this->sql_error(''); + } + + try + { + $this->dbo = new \SQLite3($this->server, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE); + $this->db_connect_id = true; + } + catch (Exception $e) + { + return array('message' => $e->getMessage()); + } + + return true; + } + + /** + * {@inheritDoc} + */ + public function sql_server_info($raw = false, $use_cache = true) + { + global $cache; + + if (!$use_cache || empty($cache) || ($this->sql_server_version = $cache->get('sqlite_version')) === false) + { + $version = \SQLite3::version(); + + $this->sql_server_version = $version['versionString']; + + if (!empty($cache) && $use_cache) + { + $cache->put('sqlite_version', $this->sql_server_version); + } + } + + return ($raw) ? $this->sql_server_version : 'SQLite ' . $this->sql_server_version; + } + + /** + * SQL Transaction + * + * @param string $status Should be one of the following strings: + * begin, commit, rollback + * @return bool Success/failure of the transaction query + */ + protected function _sql_transaction($status = 'begin') + { + switch ($status) + { + case 'begin': + return $this->dbo->exec('BEGIN IMMEDIATE'); + break; + + case 'commit': + return $this->dbo->exec('COMMIT'); + break; + + case 'rollback': + return $this->dbo->exec('ROLLBACK'); + break; + } + + return true; + } + + /** + * {@inheritDoc} + */ + public function sql_query($query = '', $cache_ttl = 0) + { + if ($query != '') + { + global $cache; + + // EXPLAIN only in extra debug mode + if (defined('DEBUG')) + { + $this->sql_report('start', $query); + } + + $this->last_query_text = $query; + $this->query_result = ($cache && $cache_ttl) ? $cache->sql_load($query) : false; + $this->sql_add_num_queries($this->query_result); + + if ($this->query_result === false) + { + if (($this->query_result = @$this->dbo->query($query)) === false) + { + $this->sql_error($query); + } + + if (defined('DEBUG')) + { + $this->sql_report('stop', $query); + } + + if ($cache && $cache_ttl) + { + $this->query_result = $cache->sql_save($this, $query, $this->query_result, $cache_ttl); + } + } + else if (defined('DEBUG')) + { + $this->sql_report('fromcache', $query); + } + } + else + { + return false; + } + + return $this->query_result; + } + + /** + * Build LIMIT query + * + * @param string $query The SQL query to execute + * @param int $total The number of rows to select + * @param int $offset + * @param int $cache_ttl Either 0 to avoid caching or + * the time in seconds which the result shall be kept in cache + * @return mixed Buffered, seekable result handle, false on error + */ + protected function _sql_query_limit($query, $total, $offset = 0, $cache_ttl = 0) + { + $this->query_result = false; + + // if $total is set to 0 we do not want to limit the number of rows + if ($total == 0) + { + $total = -1; + } + + $query .= "\n LIMIT " . ((!empty($offset)) ? $offset . ', ' . $total : $total); + + return $this->sql_query($query, $cache_ttl); + } + + /** + * {@inheritDoc} + */ + public function sql_affectedrows() + { + return ($this->db_connect_id) ? $this->dbo->changes() : false; + } + + /** + * {@inheritDoc} + */ + public function sql_fetchrow($query_id = false) + { + global $cache; + + if ($query_id === false) + { + $query_id = $this->query_result; + } + + if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) + { + return $cache->sql_fetchrow($query_id); + } + + return is_object($query_id) ? $query_id->fetchArray(SQLITE3_ASSOC) : false; + } + + /** + * {@inheritDoc} + */ + public function sql_nextid() + { + return ($this->db_connect_id) ? $this->dbo->lastInsertRowID() : false; + } + + /** + * {@inheritDoc} + */ + public function sql_freeresult($query_id = false) + { + global $cache; + + if ($query_id === false) + { + $query_id = $this->query_result; + } + + if ($cache && !is_object($query_id) && $cache->sql_exists($query_id)) + { + return $cache->sql_freeresult($query_id); + } + + if ($query_id) + { + return @$query_id->finalize(); + } + } + + /** + * {@inheritDoc} + */ + public function sql_escape($msg) + { + return \SQLite3::escapeString($msg); + } + + /** + * {@inheritDoc} + * + * For SQLite an underscore is a not-known character... + */ + public function sql_like_expression($expression) + { + // Unlike LIKE, GLOB is case sensitive (unfortunatly). SQLite users need to live with it! + // We only catch * and ? here, not the character map possible on file globbing. + $expression = str_replace(array(chr(0) . '_', chr(0) . '%'), array(chr(0) . '?', chr(0) . '*'), $expression); + + $expression = str_replace(array('?', '*'), array("\?", "\*"), $expression); + $expression = str_replace(array(chr(0) . "\?", chr(0) . "\*"), array('?', '*'), $expression); + + return 'GLOB \'' . $this->sql_escape($expression) . '\''; + } + + /** + * return sql error array + * + * @return array + */ + protected function _sql_error() + { + if (class_exists('SQLite3', false)) + { + $error = array( + 'message' => $this->dbo->lastErrorMsg(), + 'code' => $this->dbo->lastErrorCode(), + ); + } + else + { + $error = array( + 'message' => $this->connect_error, + 'code' => '', + ); + } + + return $error; + } + + /** + * Build db-specific query data + * + * @param string $stage Available stages: FROM, WHERE + * @param mixed $data A string containing the CROSS JOIN query or an array of WHERE clauses + * + * @return string The db-specific query fragment + */ + protected function _sql_custom_build($stage, $data) + { + return $data; + } + + /** + * Close sql connection + * + * @return bool False if failure + */ + protected function _sql_close() + { + return $this->dbo->close(); + } + + /** + * Build db-specific report + * + * @param string $mode Available modes: display, start, stop, + * add_select_row, fromcache, record_fromcache + * @param string $query The Query that should be explained + * @return mixed Either a full HTML page, boolean or null + */ + protected function _sql_report($mode, $query = '') + { + switch ($mode) + { + case 'start': + + $explain_query = $query; + if (preg_match('/UPDATE ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m)) + { + $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2]; + } + else if (preg_match('/DELETE FROM ([a-z0-9_]+).*?WHERE(.*)/s', $query, $m)) + { + $explain_query = 'SELECT * FROM ' . $m[1] . ' WHERE ' . $m[2]; + } + + if (preg_match('/^SELECT/', $explain_query)) + { + $html_table = false; + + if ($result = $this->dbo->query("EXPLAIN QUERY PLAN $explain_query")) + { + while ($row = $result->fetchArray(SQLITE3_ASSOC)) + { + $html_table = $this->sql_report('add_select_row', $query, $html_table, $row); + } + } + + if ($html_table) + { + $this->html_hold .= '</table>'; + } + } + + break; + + case 'fromcache': + $endtime = explode(' ', microtime()); + $endtime = $endtime[0] + $endtime[1]; + + $result = $this->dbo->query($query); + while ($void = $result->fetchArray(SQLITE3_ASSOC)) + { + // Take the time spent on parsing rows into account + } + + $splittime = explode(' ', microtime()); + $splittime = $splittime[0] + $splittime[1]; + + $this->sql_report('record_fromcache', $query, $endtime, $splittime); + + break; + } + } +} diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_1.php index aed0f2784b..2b65bb0185 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10.php index 305309c3bd..d6f3029f7e 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc1.php index fb50d67fb5..0ee2a46a00 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc2.php index 63ba1e8fc2..e676571a15 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc3.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc3.php index 7055063032..d2656397a2 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc3.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_10_rc3.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11.php index 1246597efb..6b7c9735fa 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc1.php index 7e284235e1..91ffae2f05 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc2.php index 017038855d..55290dcbcf 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_11_rc2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12.php index 5a2d569724..c4bf3a30ef 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php index 35a3015959..ab8463cc73 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc2.php index 3edb578fc8..f41f20954a 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc3.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc3.php index 510693a5b7..9171ceb26f 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc3.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc3.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_1_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_1_rc1.php index c8273c0801..724a61ecce 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_1_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_1_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2.php index 7e2a08590e..53792d4ce1 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc1.php index 7a856383e2..691ad44406 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc2.php index 61562575eb..26fa4f015b 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_2_rc2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_3.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_3.php index b2adbeaa43..5374e8786a 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_3.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_3.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_3_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_3_rc1.php index 57bd59bba3..367bf2c806 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_3_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_3_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4.php index 5d6140393b..94bba00079 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php index a8af4dd76c..98aafc6d43 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_4_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5.php index 7bbe7ffed9..92555adf78 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php index ffe2c6a44d..c6b77bc379 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1part2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1part2.php index 04b14b5189..b56721bd80 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1part2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1part2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6.php index 85ea2e9d20..fb0957fc45 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc1.php index 87d5e490f8..12b0122237 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc2.php index 7a0ef28601..351079e96c 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc3.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc3.php index 73a1fe9e6a..1ccfa1cb37 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc3.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc3.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc4.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc4.php index b6e5be2c2f..6451f4fe02 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc4.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_6_rc4.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7.php index 2b0da30bc6..70cb1293e6 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_pl1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_pl1.php index 3547ee77e1..db2175a99a 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_pl1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_pl1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc1.php index de4d772808..3bdedf8c57 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc2.php index 800803a753..65ad905aa7 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_7_rc2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8.php index 6c8b1df6fc..c1e49f1dde 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php index 1a14e5c961..e3c232f9e4 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9.php index 9af2fce971..34e85f010a 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php index 3fb790bc0d..79ef839005 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc2.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc2.php index cd79d24ade..1eb7837faf 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc2.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc3.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc3.php index 7e59b8f9e8..bbeb76509f 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc3.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc3.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc4.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc4.php index e71d9defa6..bc75891f4d 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc4.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_9_rc4.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php b/phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php index ab5b1a535b..aa44222cd8 100644 --- a/phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php +++ b/phpBB/phpbb/db/migration/data/v310/acp_prune_users_module.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2014 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/allow_cdn.php b/phpBB/phpbb/db/migration/data/v310/allow_cdn.php index aa471df6e7..2cb9e58767 100644 --- a/phpBB/phpbb/db/migration/data/v310/allow_cdn.php +++ b/phpBB/phpbb/db/migration/data/v310/allow_cdn.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/alpha1.php b/phpBB/phpbb/db/migration/data/v310/alpha1.php index 403e301e64..704f5a7a29 100644 --- a/phpBB/phpbb/db/migration/data/v310/alpha1.php +++ b/phpBB/phpbb/db/migration/data/v310/alpha1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth.php b/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth.php index 971a7e8504..daca99c255 100644 --- a/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth.php +++ b/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth2.php b/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth2.php new file mode 100644 index 0000000000..692647dcde --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/auth_provider_oauth2.php @@ -0,0 +1,40 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class auth_provider_oauth2 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\auth_provider_oauth', + ); + } + + public function update_data() + { + return array( + array('custom', array( + array($this, 'update_auth_link_module_auth'), + )), + ); + } + + public function update_auth_link_module_auth() + { + $sql = 'UPDATE ' . MODULES_TABLE . " + SET module_auth = 'authmethod_oauth' + WHERE module_class = 'ucp' + AND module_basename = 'ucp_auth_link' + AND module_mode = 'auth_link' + AND module_auth = ''"; + $this->db->sql_query($sql); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/avatar_types.php b/phpBB/phpbb/db/migration/data/v310/avatar_types.php index bdbdccf0c5..17bb1f26ca 100644 --- a/phpBB/phpbb/db/migration/data/v310/avatar_types.php +++ b/phpBB/phpbb/db/migration/data/v310/avatar_types.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/avatars.php b/phpBB/phpbb/db/migration/data/v310/avatars.php index 80ce606f29..b6cd914dd9 100644 --- a/phpBB/phpbb/db/migration/data/v310/avatars.php +++ b/phpBB/phpbb/db/migration/data/v310/avatars.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/board_contact_name.php b/phpBB/phpbb/db/migration/data/v310/board_contact_name.php new file mode 100644 index 0000000000..37b4d50545 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/board_contact_name.php @@ -0,0 +1,30 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class board_contact_name extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + return isset($this->config['board_contact_name']); + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\beta2'); + } + + public function update_data() + { + return array( + array('config.add', array('board_contact_name', '')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/boardindex.php b/phpBB/phpbb/db/migration/data/v310/boardindex.php index 27492f2d0d..17040a60b8 100644 --- a/phpBB/phpbb/db/migration/data/v310/boardindex.php +++ b/phpBB/phpbb/db/migration/data/v310/boardindex.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/config_db_text.php b/phpBB/phpbb/db/migration/data/v310/config_db_text.php index 1a7ee7a9a6..49f30d289f 100644 --- a/phpBB/phpbb/db/migration/data/v310/config_db_text.php +++ b/phpBB/phpbb/db/migration/data/v310/config_db_text.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/dev.php b/phpBB/phpbb/db/migration/data/v310/dev.php index 83611d3731..da78db7b89 100644 --- a/phpBB/phpbb/db/migration/data/v310/dev.php +++ b/phpBB/phpbb/db/migration/data/v310/dev.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/extensions.php b/phpBB/phpbb/db/migration/data/v310/extensions.php index d8b38dbc9e..a0d57087d4 100644 --- a/phpBB/phpbb/db/migration/data/v310/extensions.php +++ b/phpBB/phpbb/db/migration/data/v310/extensions.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/forgot_password.php b/phpBB/phpbb/db/migration/data/v310/forgot_password.php index 814093caa9..523f4e2c0a 100644 --- a/phpBB/phpbb/db/migration/data/v310/forgot_password.php +++ b/phpBB/phpbb/db/migration/data/v310/forgot_password.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/jquery_update.php b/phpBB/phpbb/db/migration/data/v310/jquery_update.php index bd2de2b4d4..187d6b876a 100644 --- a/phpBB/phpbb/db/migration/data/v310/jquery_update.php +++ b/phpBB/phpbb/db/migration/data/v310/jquery_update.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/mod_rewrite.php b/phpBB/phpbb/db/migration/data/v310/mod_rewrite.php index ffb790b135..e7d71f63e3 100644 --- a/phpBB/phpbb/db/migration/data/v310/mod_rewrite.php +++ b/phpBB/phpbb/db/migration/data/v310/mod_rewrite.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/namespaces.php b/phpBB/phpbb/db/migration/data/v310/namespaces.php index f74ecbd874..aa0b2bbfac 100644 --- a/phpBB/phpbb/db/migration/data/v310/namespaces.php +++ b/phpBB/phpbb/db/migration/data/v310/namespaces.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/notifications.php b/phpBB/phpbb/db/migration/data/v310/notifications.php index 61be25bb5f..cf26436ccb 100644 --- a/phpBB/phpbb/db/migration/data/v310/notifications.php +++ b/phpBB/phpbb/db/migration/data/v310/notifications.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/notifications_schema_fix.php b/phpBB/phpbb/db/migration/data/v310/notifications_schema_fix.php index eb2eb361ee..a9d11d384c 100644 --- a/phpBB/phpbb/db/migration/data/v310/notifications_schema_fix.php +++ b/phpBB/phpbb/db/migration/data/v310/notifications_schema_fix.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/passwords.php b/phpBB/phpbb/db/migration/data/v310/passwords.php index 3422f75917..2bba9b7a70 100644 --- a/phpBB/phpbb/db/migration/data/v310/passwords.php +++ b/phpBB/phpbb/db/migration/data/v310/passwords.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/passwords_p2.php b/phpBB/phpbb/db/migration/data/v310/passwords_p2.php index 553e79403d..2768c8975d 100644 --- a/phpBB/phpbb/db/migration/data/v310/passwords_p2.php +++ b/phpBB/phpbb/db/migration/data/v310/passwords_p2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2014 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_cleanup.php b/phpBB/phpbb/db/migration/data/v310/profilefield_cleanup.php index 9e7ba68327..625e74fba1 100644 --- a/phpBB/phpbb/db/migration/data/v310/profilefield_cleanup.php +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_cleanup.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2014 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_interests.php b/phpBB/phpbb/db/migration/data/v310/profilefield_interests.php index 2b943c5e53..53fae2ea1a 100644 --- a/phpBB/phpbb/db/migration/data/v310/profilefield_interests.php +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_interests.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2014 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_location.php b/phpBB/phpbb/db/migration/data/v310/profilefield_location.php index 4e62eab2d7..f4db79ca5e 100644 --- a/phpBB/phpbb/db/migration/data/v310/profilefield_location.php +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_location.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2014 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_occupation.php b/phpBB/phpbb/db/migration/data/v310/profilefield_occupation.php index b0ea961c08..9a710fbcbc 100644 --- a/phpBB/phpbb/db/migration/data/v310/profilefield_occupation.php +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_occupation.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2014 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_on_memberlist.php b/phpBB/phpbb/db/migration/data/v310/profilefield_on_memberlist.php index ce51944c3e..4733b7713d 100644 --- a/phpBB/phpbb/db/migration/data/v310/profilefield_on_memberlist.php +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_on_memberlist.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2014 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_types.php b/phpBB/phpbb/db/migration/data/v310/profilefield_types.php index 2152aaee20..9b54d87c9a 100644 --- a/phpBB/phpbb/db/migration/data/v310/profilefield_types.php +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_types.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2014 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/prune_shadow_topics.php b/phpBB/phpbb/db/migration/data/v310/prune_shadow_topics.php new file mode 100644 index 0000000000..83f5f903e8 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/prune_shadow_topics.php @@ -0,0 +1,46 @@ +<?php +/** +* +* @package migration +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\db\migration\data\v310; + +class prune_shadow_topics extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\dev'); + } + + public function update_schema() + { + return array( + 'add_columns' => array( + $this->table_prefix . 'forums' => array( + 'enable_shadow_prune' => array('BOOL', 0), + 'prune_shadow_days' => array('UINT', 7), + 'prune_shadow_freq' => array('UINT', 1), + 'prune_shadow_next' => array('INT:11', 0), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'drop_columns' => array( + $this->table_prefix . 'forums' => array( + 'enable_shadow_prune', + 'prune_shadow_days', + 'prune_shadow_freq', + 'prune_shadow_next', + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/reported_posts_display.php b/phpBB/phpbb/db/migration/data/v310/reported_posts_display.php index 56b7a0916c..c6618cf467 100644 --- a/phpBB/phpbb/db/migration/data/v310/reported_posts_display.php +++ b/phpBB/phpbb/db/migration/data/v310/reported_posts_display.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/softdelete_mcp_modules.php b/phpBB/phpbb/db/migration/data/v310/softdelete_mcp_modules.php index d1a31815b2..18c225d19f 100644 --- a/phpBB/phpbb/db/migration/data/v310/softdelete_mcp_modules.php +++ b/phpBB/phpbb/db/migration/data/v310/softdelete_mcp_modules.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php b/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php index f080c78c50..10243dc77f 100644 --- a/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php +++ b/phpBB/phpbb/db/migration/data/v310/softdelete_p1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -149,6 +149,15 @@ class softdelete_p1 extends \phpbb\db\migration\migration $limit = 10; $converted_forums = 0; + if (!$start) + { + // Preserve the forum_posts value for link forums as it represents redirects. + $sql = 'UPDATE ' . $this->table_prefix . 'forums + SET forum_posts_approved = forum_posts + WHERE forum_type = ' . FORUM_LINK; + $this->db->sql_query($sql); + } + $sql = 'SELECT forum_id, topic_visibility, COUNT(topic_id) AS sum_topics, SUM(topic_posts_approved) AS sum_posts_approved, SUM(topic_posts_unapproved) AS sum_posts_unapproved FROM ' . $this->table_prefix . 'topics GROUP BY forum_id, topic_visibility diff --git a/phpBB/phpbb/db/migration/data/v310/softdelete_p2.php b/phpBB/phpbb/db/migration/data/v310/softdelete_p2.php index 38b190c766..6b84a1b980 100644 --- a/phpBB/phpbb/db/migration/data/v310/softdelete_p2.php +++ b/phpBB/phpbb/db/migration/data/v310/softdelete_p2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ 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 26f1046287..fcba1d73ed 100644 --- a/phpBB/phpbb/db/migration/data/v310/style_update_p1.php +++ b/phpBB/phpbb/db/migration/data/v310/style_update_p1.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/style_update_p2.php b/phpBB/phpbb/db/migration/data/v310/style_update_p2.php index 40d6a4dbbd..316741e11d 100644 --- a/phpBB/phpbb/db/migration/data/v310/style_update_p2.php +++ b/phpBB/phpbb/db/migration/data/v310/style_update_p2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/teampage.php b/phpBB/phpbb/db/migration/data/v310/teampage.php index 172435c672..f03c09e04f 100644 --- a/phpBB/phpbb/db/migration/data/v310/teampage.php +++ b/phpBB/phpbb/db/migration/data/v310/teampage.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/data/v310/timezone.php b/phpBB/phpbb/db/migration/data/v310/timezone.php index dd0c6a2093..2efedd4514 100644 --- a/phpBB/phpbb/db/migration/data/v310/timezone.php +++ b/phpBB/phpbb/db/migration/data/v310/timezone.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -39,23 +39,48 @@ class timezone extends \phpbb\db\migration\migration ); } - public function update_timezones() + public function update_timezones($start) { - // Update user timezones - $sql = 'SELECT user_dst, user_timezone - FROM ' . $this->table_prefix . 'users - GROUP BY user_timezone, user_dst'; - $result = $this->db->sql_query($sql); + $start = (int) $start; + $limit = 500; + $converted = 0; + + $update_blocks = array(); + $sql = 'SELECT user_id, user_timezone, user_dst + FROM ' . $this->table_prefix . 'users + ORDER BY user_id ASC'; + $result = $this->db->sql_query_limit($sql, $limit, $start); while ($row = $this->db->sql_fetchrow($result)) { + $converted++; + + // In case this is somehow run twice on a row. + // Otherwise it would just end up as UTC on the second run + if (is_numeric($row['user_timezone'])) + { + $update_blocks[$row['user_timezone'] . ':' . $row['user_dst']][] = (int) $row['user_id']; + } + } + $this->db->sql_freeresult($result); + + // Update blocks of users who share the same timezone/dst + foreach ($update_blocks as $timezone => $user_ids) + { + $timezone = explode(':', $timezone); + $converted_timezone = $this->convert_phpbb30_timezone($timezone[0], $timezone[1]); + $sql = 'UPDATE ' . $this->table_prefix . "users - SET user_timezone = '" . $this->db->sql_escape($this->convert_phpbb30_timezone($row['user_timezone'], $row['user_dst'])) . "' - WHERE user_timezone = '" . $this->db->sql_escape($row['user_timezone']) . "' - AND user_dst = " . (int) $row['user_dst']; + SET user_timezone = '" . $this->db->sql_escape($converted_timezone) . "' + WHERE " . $this->db->sql_in_set('user_id', $user_ids); $this->sql_query($sql); } - $this->db->sql_freeresult($result); + + if ($converted == $limit) + { + // There are still more to convert + return $start + $limit; + } // Update board default timezone $sql = 'UPDATE ' . $this->table_prefix . "config diff --git a/phpBB/phpbb/db/migration/data/v310/timezone_p2.php b/phpBB/phpbb/db/migration/data/v310/timezone_p2.php index 1066ab8571..891d8622a0 100644 --- a/phpBB/phpbb/db/migration/data/v310/timezone_p2.php +++ b/phpBB/phpbb/db/migration/data/v310/timezone_p2.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/exception.php b/phpBB/phpbb/db/migration/exception.php index cfe546d1ab..c6c1a45947 100644 --- a/phpBB/phpbb/db/migration/exception.php +++ b/phpBB/phpbb/db/migration/exception.php @@ -3,7 +3,7 @@ * * @package db * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/helper.php b/phpBB/phpbb/db/migration/helper.php index 009ad1da9f..238b2dbe53 100644 --- a/phpBB/phpbb/db/migration/helper.php +++ b/phpBB/phpbb/db/migration/helper.php @@ -3,7 +3,7 @@ * * @package db * @copyright (c) 2014 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/migration.php b/phpBB/phpbb/db/migration/migration.php index b32de00871..85c5fc5d08 100644 --- a/phpBB/phpbb/db/migration/migration.php +++ b/phpBB/phpbb/db/migration/migration.php @@ -3,7 +3,7 @@ * * @package db * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -23,7 +23,7 @@ abstract class migration /** @var \phpbb\config\config */ protected $config; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\db\tools */ @@ -48,13 +48,13 @@ abstract class migration * Constructor * * @param \phpbb\config\config $config - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\db\tools $db_tools * @param string $phpbb_root_path * @param string $php_ext * @param string $table_prefix */ - public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\db\tools $db_tools, $phpbb_root_path, $php_ext, $table_prefix) + public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools $db_tools, $phpbb_root_path, $php_ext, $table_prefix) { $this->config = $config; $this->db = $db; diff --git a/phpBB/phpbb/db/migration/profilefield_base_migration.php b/phpBB/phpbb/db/migration/profilefield_base_migration.php index dec7a4c2bb..3797d670f7 100644 --- a/phpBB/phpbb/db/migration/profilefield_base_migration.php +++ b/phpBB/phpbb/db/migration/profilefield_base_migration.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2014 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/schema_generator.php b/phpBB/phpbb/db/migration/schema_generator.php index a7e2fa8f06..5d40b0b26f 100644 --- a/phpBB/phpbb/db/migration/schema_generator.php +++ b/phpBB/phpbb/db/migration/schema_generator.php @@ -19,7 +19,7 @@ class schema_generator /** @var \phpbb\config\config */ protected $config; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\db\tools */ @@ -40,10 +40,13 @@ class schema_generator /** @var array */ protected $tables; + /** @var array */ + protected $dependencies = array(); + /** * Constructor */ - public function __construct(array $class_names, \phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\db\tools $db_tools, $phpbb_root_path, $php_ext, $table_prefix) + public function __construct(array $class_names, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools $db_tools, $phpbb_root_path, $php_ext, $table_prefix) { $this->config = $config; $this->db = $db; @@ -69,11 +72,13 @@ class schema_generator $migrations = $this->class_names; $tree = array(); + $check_dependencies = true; while (!empty($migrations)) { foreach ($migrations as $migration_class) { $open_dependencies = array_diff($migration_class::depends_on(), $tree); + if (empty($open_dependencies)) { $migration = new $migration_class($this->config, $this->db, $this->db_tools, $this->phpbb_root_path, $this->php_ext, $this->table_prefix); @@ -170,10 +175,41 @@ class schema_generator } unset($migrations[$migration_key]); } + else if ($check_dependencies) + { + $this->dependencies = array_merge($this->dependencies, $open_dependencies); + } + } + + // Only run this check after the first run + if ($check_dependencies) + { + $this->check_dependencies(); + $check_dependencies = false; } } ksort($this->tables); return $this->tables; } + + /** + * Check if one of the migrations files' dependencies can't be resolved + * by the supplied list of migrations + * + * @throws UnexpectedValueException If a dependency can't be resolved + */ + protected function check_dependencies() + { + // Strip duplicate values from array + $this->dependencies = array_unique($this->dependencies); + + foreach ($this->dependencies as $dependency) + { + if (!in_array($dependency, $this->class_names)) + { + throw new \UnexpectedValueException("Unable to resolve the dependency '$dependency'"); + } + } + } } diff --git a/phpBB/phpbb/db/migration/tool/config.php b/phpBB/phpbb/db/migration/tool/config.php index 36a1931f4e..96d358f647 100644 --- a/phpBB/phpbb/db/migration/tool/config.php +++ b/phpBB/phpbb/db/migration/tool/config.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index ebbcbae301..96cc6b54a5 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -19,7 +19,7 @@ class module implements \phpbb\db\migration\tool\tool_interface /** @var \phpbb\cache\service */ protected $cache; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\user */ @@ -37,14 +37,14 @@ class module implements \phpbb\db\migration\tool\tool_interface /** * Constructor * - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\cache\service $cache * @param \phpbb\user $user * @param string $phpbb_root_path * @param string $php_ext * @param string $modules_table */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\cache\service $cache, \phpbb\user $user, $phpbb_root_path, $php_ext, $modules_table) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, \phpbb\user $user, $phpbb_root_path, $php_ext, $modules_table) { $this->db = $db; $this->cache = $cache; diff --git a/phpBB/phpbb/db/migration/tool/permission.php b/phpBB/phpbb/db/migration/tool/permission.php index 38fcbd2952..6cb3f213f1 100644 --- a/phpBB/phpbb/db/migration/tool/permission.php +++ b/phpBB/phpbb/db/migration/tool/permission.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -22,7 +22,7 @@ class permission implements \phpbb\db\migration\tool\tool_interface /** @var \phpbb\cache\service */ protected $cache; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var string */ @@ -34,13 +34,13 @@ class permission implements \phpbb\db\migration\tool\tool_interface /** * Constructor * - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\cache\service $cache * @param \phpbb\auth\auth $auth * @param string $phpbb_root_path * @param string $php_ext */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\cache\service $cache, \phpbb\auth\auth $auth, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, \phpbb\auth\auth $auth, $phpbb_root_path, $php_ext) { $this->db = $db; $this->cache = $cache; diff --git a/phpBB/phpbb/db/migration/tool/tool_interface.php b/phpBB/phpbb/db/migration/tool/tool_interface.php index e7b89d8858..5eb1a2f521 100644 --- a/phpBB/phpbb/db/migration/tool/tool_interface.php +++ b/phpBB/phpbb/db/migration/tool/tool_interface.php @@ -3,7 +3,7 @@ * * @package migration * @copyright (c) 2012 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index 4fb3f1a241..5ad8563e5c 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -3,7 +3,7 @@ * * @package db * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ @@ -19,7 +19,7 @@ class migrator /** @var \phpbb\config\config */ protected $config; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\db\tools */ @@ -68,7 +68,7 @@ class migrator /** * Constructor of the database migrator */ - public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\db\tools $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools, \phpbb\db\migration\helper $helper) + public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools, \phpbb\db\migration\helper $helper) { $this->config = $config; $this->db = $db; @@ -509,10 +509,17 @@ class migrator throw new \phpbb\db\migration\exception('MIGRATION_INVALID_DATA_CUSTOM_NOT_CALLABLE', $step); } - return array( - $parameters[0], - array($last_result), - ); + if ($reverse) + { + return false; + } + else + { + return array( + $parameters[0], + array($last_result), + ); + } break; default: diff --git a/phpBB/phpbb/db/sql_insert_buffer.php b/phpBB/phpbb/db/sql_insert_buffer.php index 41026ad425..0236a55b82 100644 --- a/phpBB/phpbb/db/sql_insert_buffer.php +++ b/phpBB/phpbb/db/sql_insert_buffer.php @@ -49,7 +49,7 @@ namespace phpbb\db; */ class sql_insert_buffer { - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var string */ @@ -62,11 +62,11 @@ class sql_insert_buffer protected $buffer = array(); /** - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param string $table_name * @param int $max_buffered_rows */ - public function __construct(\phpbb\db\driver\driver $db, $table_name, $max_buffered_rows = 500) + public function __construct(\phpbb\db\driver\driver_interface $db, $table_name, $max_buffered_rows = 500) { $this->db = $db; $this->table_name = $table_name; diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 25c495b80b..a983ed91b5 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -34,6 +34,12 @@ class tools var $dbms_type_map = array(); /** + * Is the used MS SQL Server a SQL Server 2000? + * @var bool + */ + protected $is_sql_server_2000; + + /** * Get the column types for every database we support * * @return array @@ -251,6 +257,36 @@ class tools 'VARBINARY' => 'blob', ), + 'sqlite3' => array( + 'INT:' => 'INT(%d)', + 'BINT' => 'BIGINT(20)', + 'UINT' => 'INTEGER UNSIGNED', + 'UINT:' => 'INTEGER UNSIGNED', + 'TINT:' => 'TINYINT(%d)', + 'USINT' => 'INTEGER UNSIGNED', + 'BOOL' => 'INTEGER UNSIGNED', + 'VCHAR' => 'VARCHAR(255)', + 'VCHAR:' => 'VARCHAR(%d)', + 'CHAR:' => 'CHAR(%d)', + 'XSTEXT' => 'TEXT(65535)', + 'STEXT' => 'TEXT(65535)', + 'TEXT' => 'TEXT(65535)', + 'MTEXT' => 'MEDIUMTEXT(16777215)', + 'XSTEXT_UNI'=> 'TEXT(65535)', + 'STEXT_UNI' => 'TEXT(65535)', + 'TEXT_UNI' => 'TEXT(65535)', + 'MTEXT_UNI' => 'MEDIUMTEXT(16777215)', + 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED', + 'DECIMAL' => 'DECIMAL(5,2)', + 'DECIMAL:' => 'DECIMAL(%d,2)', + 'PDECIMAL' => 'DECIMAL(6,3)', + 'PDECIMAL:' => 'DECIMAL(%d,3)', + 'VCHAR_UNI' => 'VARCHAR(255)', + 'VCHAR_UNI:'=> 'VARCHAR(%d)', + 'VCHAR_CI' => 'VARCHAR(255)', + 'VARBINARY' => 'BLOB', + ), + 'postgres' => array( 'INT:' => 'INT4', 'BINT' => 'INT8', @@ -293,7 +329,7 @@ class tools * A list of supported DBMS. We change this class to support more DBMS, the DBMS itself only need to follow some rules. * @var array */ - var $supported_dbms = array('firebird', 'mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite'); + var $supported_dbms = array('firebird', 'mssql', 'mssqlnative', 'mysql_40', 'mysql_41', 'oracle', 'postgres', 'sqlite', 'sqlite3'); /** * This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array). @@ -304,10 +340,10 @@ class tools /** * Constructor. Set DB Object and set {@link $return_statements return_statements}. * - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param bool $return_statements True if only statements should be returned and no SQL being executed */ - public function __construct(\phpbb\db\driver\driver $db, $return_statements = false) + public function __construct(\phpbb\db\driver\driver_interface $db, $return_statements = false) { $this->db = $db; $this->return_statements = $return_statements; @@ -383,6 +419,13 @@ class tools WHERE type = "table"'; break; + case 'sqlite3': + $sql = 'SELECT name + FROM sqlite_master + WHERE type = "table" + AND name <> "sqlite_sequence"'; + break; + case 'mssql': case 'mssql_odbc': case 'mssqlnative': @@ -561,6 +604,7 @@ class tools case 'mysql_41': case 'postgres': case 'sqlite': + case 'sqlite3': $table_sql .= ",\n\t PRIMARY KEY (" . implode(', ', $table_data['PRIMARY_KEY']) . ')'; break; @@ -598,6 +642,7 @@ class tools case 'mysql_40': case 'sqlite': + case 'sqlite3': $table_sql .= "\n);"; $statements[] = $table_sql; break; @@ -716,7 +761,7 @@ class tools $sqlite = false; // For SQLite we need to perform the schema changes in a much more different way - if ($this->db->sql_layer == 'sqlite' && $this->return_statements) + if (($this->db->sql_layer == 'sqlite' || $this->db->sql_layer == 'sqlite3') && $this->return_statements) { $sqlite_data = array(); $sqlite = true; @@ -892,7 +937,7 @@ class tools } } - // Add unqiue indexes? + // Add unique indexes? if (!empty($schema_changes['add_unique_index'])) { foreach ($schema_changes['add_unique_index'] as $table => $index_array) @@ -1134,6 +1179,7 @@ class tools break; case 'sqlite': + case 'sqlite3': $sql = "SELECT sql FROM sqlite_master WHERE type = 'table' @@ -1267,6 +1313,7 @@ class tools break; case 'sqlite': + case 'sqlite3': $sql = "PRAGMA index_list('" . $table_name . "');"; $col = 'name'; break; @@ -1287,6 +1334,7 @@ class tools case 'oracle': case 'postgres': case 'sqlite': + case 'sqlite3': $row[$col] = substr($row[$col], strlen($table_name) + 1); break; } @@ -1303,7 +1351,7 @@ class tools } /** - * Check if a specified index exists in table. Does not return PRIMARY KEY and UNIQUE indexes. + * Check if a specified index exists in table. Does not return PRIMARY KEY indexes. * * @param string $table_name Table to check the index at * @param string $index_name The index name to check @@ -1371,6 +1419,7 @@ class tools break; case 'sqlite': + case 'sqlite3': $sql = "PRAGMA index_list('" . $table_name . "');"; $col = 'name'; break; @@ -1384,7 +1433,7 @@ class tools continue; } - if ($this->sql_layer == 'sqlite' && !$row['unique']) + if (($this->sql_layer == 'sqlite' || $this->sql_layer == 'sqlite3') && !$row['unique']) { continue; } @@ -1412,6 +1461,7 @@ class tools case 'firebird': case 'postgres': case 'sqlite': + case 'sqlite3': $row[$col] = substr($row[$col], strlen($table_name) + 1); break; } @@ -1623,11 +1673,17 @@ class tools break; case 'sqlite': + case 'sqlite3': $return_array['primary_key_set'] = false; if (isset($column_data[2]) && $column_data[2] == 'auto_increment') { $sql .= ' INTEGER PRIMARY KEY'; $return_array['primary_key_set'] = true; + + if ($this->sql_layer === 'sqlite3') + { + $sql .= ' AUTOINCREMENT'; + } } else { @@ -1764,67 +1820,63 @@ class tools break; case 'sqlite': - if ($inline && $this->return_statements) { return $column_name . ' ' . $column_data['column_type_sql']; } - if (version_compare(sqlite_libversion(), '3.0') == -1) + $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name); + if (empty($recreate_queries)) { - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}' - ORDER BY type DESC, name;"; - $result = $this->db->sql_query($sql); - - if (!$result) - { - break; - } + break; + } - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + $statements[] = 'begin'; - $statements[] = 'begin'; + $sql_create_table = array_shift($recreate_queries); - // Create a backup table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; + // Create a backup table and populate it, destroy the existing one + $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table); + $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; + $statements[] = 'DROP TABLE ' . $table_name; - preg_match('#\((.*)\)#s', $row['sql'], $matches); + preg_match('#\((.*)\)#s', $sql_create_table, $matches); - $new_table_cols = trim($matches[1]); - $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); - $column_list = array(); + $new_table_cols = trim($matches[1]); + $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); + $column_list = array(); - foreach ($old_table_cols as $declaration) + foreach ($old_table_cols as $declaration) + { + $entities = preg_split('#\s+#', trim($declaration)); + if ($entities[0] == 'PRIMARY') { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY') - { - continue; - } - $column_list[] = $entities[0]; + continue; } + $column_list[] = $entities[0]; + } - $columns = implode(',', $column_list); + $columns = implode(',', $column_list); - $new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols; + $new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols; - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');'; - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; + // create a new table and fill it up. destroy the temp one + $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');'; + $statements = array_merge($statements, $recreate_queries); - $statements[] = 'commit'; - } - else + $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; + $statements[] = 'DROP TABLE ' . $table_name . '_temp'; + + $statements[] = 'commit'; + break; + + case 'sqlite3': + if ($inline && $this->return_statements) { - $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' [' . $column_data['column_type_sql'] . ']'; + return $column_name . ' ' . $column_data['column_type_sql']; } + + $statements[] = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql']; break; } @@ -1846,50 +1898,46 @@ class tools case 'mssql': case 'mssqlnative': - $sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + // We need the data here + $old_return_statements = $this->return_statements; + $this->return_statements = true; - // Remove default constraints - if ($row['mssql_version'][0] == '8') // SQL Server 2000 - { - // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx - // Deprecated in SQL Server 2005 - $statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000) - SET @drop_default_name = - (SELECT so.name FROM sysobjects so - JOIN sysconstraints sc ON so.id = sc.constid - WHERE object_name(so.parent_obj) = '{$table_name}' - AND so.xtype = 'D' - AND sc.colid = (SELECT colid FROM syscolumns - WHERE id = object_id('{$table_name}') - AND name = '{$column_name}')) - IF @drop_default_name <> '' - BEGIN - SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']' - EXEC(@cmd) - END"; - } - else - { - $sql = "SELECT dobj.name AS def_name - FROM sys.columns col - LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D') - WHERE col.object_id = object_id('{$table_name}') - AND col.name = '{$column_name}' - AND dobj.name IS NOT NULL"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + $indexes = $this->mssql_get_existing_indexes($table_name, $column_name); - if ($row) + // Drop any indexes + $recreate_indexes = array(); + if (!empty($indexes)) + { + foreach ($indexes as $index_name => $index_data) { - $statements[] = 'ALTER TABLE [' . $table_name . '] DROP CONSTRAINT [' . $row['def_name'] . ']'; + $result = $this->sql_index_drop($table_name, $index_name); + $statements = array_merge($statements, $result); + if (sizeof($index_data) > 1) + { + // Remove this column from the index and recreate it + $recreate_indexes[$index_name] = array_diff($index_data, array($column_name)); + } } } + // Drop default value constraint + $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name); + $statements = array_merge($statements, $result); + + // Remove the column $statements[] = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']'; + + if (!empty($recreate_indexes)) + { + // Recreate indexes after we removed the column + foreach ($recreate_indexes as $index_name => $index_data) + { + $result = $this->sql_create_index($table_name, $index_name, $index_data); + $statements = array_merge($statements, $result); + } + } + + $this->return_statements = $old_return_statements; break; case 'mysql_40': @@ -1906,67 +1954,61 @@ class tools break; case 'sqlite': + case 'sqlite3': if ($inline && $this->return_statements) { return $column_name; } - if (version_compare(sqlite_libversion(), '3.0') == -1) + $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name, $column_name); + if (empty($recreate_queries)) { - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}' - ORDER BY type DESC, name;"; - $result = $this->db->sql_query($sql); - - if (!$result) - { - break; - } + break; + } - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + $statements[] = 'begin'; - $statements[] = 'begin'; + $sql_create_table = array_shift($recreate_queries); - // Create a backup table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); - $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; - $statements[] = 'DROP TABLE ' . $table_name; + // Create a backup table and populate it, destroy the existing one + $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table); + $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; + $statements[] = 'DROP TABLE ' . $table_name; - preg_match('#\((.*)\)#s', $row['sql'], $matches); + preg_match('#\((.*)\)#s', $sql_create_table, $matches); - $new_table_cols = trim($matches[1]); - $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); - $column_list = array(); + $new_table_cols = trim($matches[1]); + $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); + $column_list = array(); - foreach ($old_table_cols as $declaration) + foreach ($old_table_cols as $declaration) + { + $entities = preg_split('#\s+#', trim($declaration)); + if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name) { - $entities = preg_split('#\s+#', trim($declaration)); - if ($entities[0] == 'PRIMARY' || $entities[0] === $column_name) - { - continue; - } - $column_list[] = $entities[0]; + continue; } + $column_list[] = $entities[0]; + } - $columns = implode(',', $column_list); - - $new_table_cols = preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $new_table_cols); - - // create a new table and fill it up. destroy the temp one - $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');'; - $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; - $statements[] = 'DROP TABLE ' . $table_name . '_temp'; + $columns = implode(',', $column_list); - $statements[] = 'commit'; - } - else + $new_table_cols = trim(preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $new_table_cols)); + if (substr($new_table_cols, -1) === ',') { - $statements[] = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name; + // Remove the comma from the last entry again + $new_table_cols = substr($new_table_cols, 0, -1); } + + // create a new table and fill it up. destroy the temp one + $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');'; + $statements = array_merge($statements, $recreate_queries); + + $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; + $statements[] = 'DROP TABLE ' . $table_name . '_temp'; + + $statements[] = 'commit'; break; } @@ -1996,6 +2038,7 @@ class tools case 'oracle': case 'postgres': case 'sqlite': + case 'sqlite3': $statements[] = 'DROP INDEX ' . $table_name . '_' . $index_name; break; } @@ -2102,35 +2145,29 @@ class tools break; case 'sqlite': + case 'sqlite3': if ($inline && $this->return_statements) { return $column; } - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}' - ORDER BY type DESC, name;"; - $result = $this->db->sql_query($sql); - - if (!$result) + $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name); + if (empty($recreate_queries)) { break; } - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - $statements[] = 'begin'; + $sql_create_table = array_shift($recreate_queries); + // Create a backup table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); + $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table); $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; $statements[] = 'DROP TABLE ' . $table_name; - preg_match('#\((.*)\)#s', $row['sql'], $matches); + preg_match('#\((.*)\)#s', $sql_create_table, $matches); $new_table_cols = trim($matches[1]); $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); @@ -2150,6 +2187,8 @@ class tools // create a new table and fill it up. destroy the temp one $statements[] = 'CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ', PRIMARY KEY (' . implode(', ', $column) . '));'; + $statements = array_merge($statements, $recreate_queries); + $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; $statements[] = 'DROP TABLE ' . $table_name . '_temp'; @@ -2180,6 +2219,7 @@ class tools case 'postgres': case 'oracle': case 'sqlite': + case 'sqlite3': $statements[] = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; break; @@ -2223,6 +2263,7 @@ class tools case 'postgres': case 'oracle': case 'sqlite': + case 'sqlite3': $statements[] = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')'; break; @@ -2314,6 +2355,7 @@ class tools break; case 'sqlite': + case 'sqlite3': $sql = "PRAGMA index_info('" . $table_name . "');"; $col = 'name'; break; @@ -2333,6 +2375,7 @@ class tools case 'oracle': case 'postgres': case 'sqlite': + case 'sqlite3': $row[$col] = substr($row[$col], strlen($table_name) + 1); break; } @@ -2371,53 +2414,46 @@ class tools case 'mssql': case 'mssqlnative': + // We need the data here + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + $indexes = $this->mssql_get_existing_indexes($table_name, $column_name); + + // Drop any indexes + if (!empty($indexes)) + { + foreach ($indexes as $index_name => $index_data) + { + $result = $this->sql_index_drop($table_name, $index_name); + $statements = array_merge($statements, $result); + } + } + + // Drop default value constraint + $result = $this->mssql_get_drop_default_constraints_queries($table_name, $column_name); + $statements = array_merge($statements, $result); + + // Change the column $statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql']; if (!empty($column_data['default'])) { - $sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + // Add new default value constraint + $statements[] = 'ALTER TABLE [' . $table_name . '] ADD CONSTRAINT [DF_' . $table_name . '_' . $column_name . '_1] ' . $this->db->sql_escape($column_data['default']) . ' FOR [' . $column_name . ']'; + } - // Using TRANSACT-SQL for this statement because we do not want to have colliding data if statements are executed at a later stage - if ($row['mssql_version'][0] == '8') // SQL Server 2000 - { - $statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000) - SET @drop_default_name = - (SELECT so.name FROM sysobjects so - JOIN sysconstraints sc ON so.id = sc.constid - WHERE object_name(so.parent_obj) = '{$table_name}' - AND so.xtype = 'D' - AND sc.colid = (SELECT colid FROM syscolumns - WHERE id = object_id('{$table_name}') - AND name = '{$column_name}')) - IF @drop_default_name <> '' - BEGIN - SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']' - EXEC(@cmd) - END - SET @cmd = 'ALTER TABLE [{$table_name}] ADD CONSTRAINT [DF_{$table_name}_{$column_name}_1] {$column_data['default']} FOR [{$column_name}]' - EXEC(@cmd)"; - } - else + if (!empty($indexes)) + { + // Recreate indexes after we changed the column + foreach ($indexes as $index_name => $index_data) { - $statements[] = "DECLARE @drop_default_name VARCHAR(100), @cmd VARCHAR(1000) - SET @drop_default_name = - (SELECT dobj.name FROM sys.columns col - LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D') - WHERE col.object_id = object_id('{$table_name}') - AND col.name = '{$column_name}' - AND dobj.name IS NOT NULL) - IF @drop_default_name <> '' - BEGIN - SET @cmd = 'ALTER TABLE [{$table_name}] DROP CONSTRAINT [' + @drop_default_name + ']' - EXEC(@cmd) - END - SET @cmd = 'ALTER TABLE [{$table_name}] ADD CONSTRAINT [DF_{$table_name}_{$column_name}_1] {$column_data['default']} FOR [{$column_name}]' - EXEC(@cmd)"; + $result = $this->sql_create_index($table_name, $index_name, $index_data); + $statements = array_merge($statements, $result); } } + + $this->return_statements = $old_return_statements; break; case 'mysql_40': @@ -2493,35 +2529,29 @@ class tools break; case 'sqlite': + case 'sqlite3': if ($inline && $this->return_statements) { return $column_name . ' ' . $column_data['column_type_sql']; } - $sql = "SELECT sql - FROM sqlite_master - WHERE type = 'table' - AND name = '{$table_name}' - ORDER BY type DESC, name;"; - $result = $this->db->sql_query($sql); - - if (!$result) + $recreate_queries = $this->sqlite_get_recreate_table_queries($table_name); + if (empty($recreate_queries)) { break; } - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - $statements[] = 'begin'; + $sql_create_table = array_shift($recreate_queries); + // Create a temp table and populate it, destroy the existing one - $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']); + $statements[] = preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $sql_create_table); $statements[] = 'INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name; $statements[] = 'DROP TABLE ' . $table_name; - preg_match('#\((.*)\)#s', $row['sql'], $matches); + preg_match('#\((.*)\)#s', $sql_create_table, $matches); $new_table_cols = trim($matches[1]); $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols); @@ -2539,8 +2569,10 @@ class tools $columns = implode(',', $column_list); - // create a new table and fill it up. destroy the temp one + // Create a new table and fill it up. destroy the temp one $statements[] = 'CREATE TABLE ' . $table_name . ' (' . implode(',', $old_table_cols) . ');'; + $statements = array_merge($statements, $recreate_queries); + $statements[] = 'INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'; $statements[] = 'DROP TABLE ' . $table_name . '_temp'; @@ -2551,4 +2583,230 @@ class tools return $this->_sql_run_sql($statements); } + + /** + * Get queries to drop the default constraints of a column + * + * We need to drop the default constraints of a column, + * before being able to change their type or deleting them. + * + * @param string $table_name + * @param string $column_name + * @return array Array with SQL statements + */ + protected function mssql_get_drop_default_constraints_queries($table_name, $column_name) + { + $statements = array(); + if ($this->mssql_is_sql_server_2000()) + { + // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx + // Deprecated in SQL Server 2005 + $sql = "SELECT so.name AS def_name + FROM sysobjects so + JOIN sysconstraints sc ON so.id = sc.constid + WHERE object_name(so.parent_obj) = '{$table_name}' + AND so.xtype = 'D' + AND sc.colid = (SELECT colid FROM syscolumns + WHERE id = object_id('{$table_name}') + AND name = '{$column_name}')"; + } + else + { + $sql = "SELECT dobj.name AS def_name + FROM sys.columns col + LEFT OUTER JOIN sys.objects dobj ON (dobj.object_id = col.default_object_id AND dobj.type = 'D') + WHERE col.object_id = object_id('{$table_name}') + AND col.name = '{$column_name}' + AND dobj.name IS NOT NULL"; + } + + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $statements[] = 'ALTER TABLE [' . $table_name . '] DROP CONSTRAINT [' . $row['def_name'] . ']'; + } + $this->db->sql_freeresult($result); + + return $statements; + } + + /** + * Get a list with existing indexes for the column + * + * @param string $table_name + * @param string $column_name + * @return array Array with Index name => columns + */ + protected function mssql_get_existing_indexes($table_name, $column_name) + { + $existing_indexes = array(); + if ($this->mssql_is_sql_server_2000()) + { + // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx + // Deprecated in SQL Server 2005 + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name + FROM sysindexes ix + INNER JOIN sysindexkeys ixc + ON ixc.id = ix.id + AND ixc.indid = ix.indid + INNER JOIN syscolumns cols + ON cols.colid = ixc.colid + AND cols.id = ix.id + WHERE ix.id = object_id('{$table_name}') + AND cols.name = '{$column_name}'"; + } + else + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name + FROM sys.indexes ix + INNER JOIN sys.index_columns ixc + ON ixc.object_id = ix.object_id + AND ixc.index_id = ix.index_id + INNER JOIN sys.columns cols + ON cols.column_id = ixc.column_id + AND cols.object_id = ix.object_id + WHERE ix.object_id = object_id('{$table_name}') + AND cols.name = '{$column_name}'"; + } + + $result = $this->db->sql_query($sql); + $existing_indexes = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $existing_indexes[$row['phpbb_index_name']] = array(); + } + $this->db->sql_freeresult($result); + + if (empty($existing_indexes)) + { + return array(); + } + + if ($this->mssql_is_sql_server_2000()) + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name + FROM sysindexes ix + INNER JOIN sysindexkeys ixc + ON ixc.id = ix.id + AND ixc.indid = ix.indid + INNER JOIN syscolumns cols + ON cols.colid = ixc.colid + AND cols.id = ix.id + WHERE ix.id = object_id('{$table_name}') + AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); + } + else + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name + FROM sys.indexes ix + INNER JOIN sys.index_columns ixc + ON ixc.object_id = ix.object_id + AND ixc.index_id = ix.index_id + INNER JOIN sys.columns cols + ON cols.column_id = ixc.column_id + AND cols.object_id = ix.object_id + WHERE ix.object_id = object_id('{$table_name}') + AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); + } + + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $existing_indexes[$row['phpbb_index_name']][] = $row['phpbb_column_name']; + } + $this->db->sql_freeresult($result); + + return $existing_indexes; + } + + /** + * Is the used MS SQL Server a SQL Server 2000? + * + * @return bool + */ + protected function mssql_is_sql_server_2000() + { + if ($this->is_sql_server_2000 === null) + { + $sql = "SELECT CAST(SERVERPROPERTY('productversion') AS VARCHAR(25)) AS mssql_version"; + $result = $this->db->sql_query($sql); + $properties = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + $this->is_sql_server_2000 = $properties['mssql_version'][0] == '8'; + } + + return $this->is_sql_server_2000; + } + + /** + * Returns the Queries which are required to recreate a table including indexes + * + * @param string $table_name + * @param string $remove_column When we drop a column, we remove the column + * from all indexes. If the index has no other + * column, we drop it completly. + * @return array + */ + protected function sqlite_get_recreate_table_queries($table_name, $remove_column = '') + { + $queries = array(); + + $sql = "SELECT sql + FROM sqlite_master + WHERE type = 'table' + AND name = '{$table_name}'"; + $result = $this->db->sql_query($sql); + $sql_create_table = $this->db->sql_fetchfield('sql'); + $this->db->sql_freeresult($result); + + if (!$sql_create_table) + { + return array(); + } + $queries[] = $sql_create_table; + + $sql = "SELECT sql + FROM sqlite_master + WHERE type = 'index' + AND tbl_name = '{$table_name}'"; + $result = $this->db->sql_query($sql); + while ($sql_create_index = $this->db->sql_fetchfield('sql')) + { + if ($remove_column) + { + $match = array(); + preg_match('#(?:[\w ]+)\((.*)\)#', $sql_create_index, $match); + if (!isset($match[1])) + { + continue; + } + + // Find and remove $remove_column from the index + $columns = explode(', ', $match[1]); + $found_column = array_search($remove_column, $columns); + if ($found_column !== false) + { + unset($columns[$found_column]); + + // If the column list is not empty add the index to the list + if (!empty($columns)) + { + $queries[] = str_replace($match[1], implode(', ', $columns), $sql_create_index); + } + } + else + { + $queries[] = $sql_create_index; + } + } + else + { + $queries[] = $sql_create_index; + } + } + $this->db->sql_freeresult($result); + + return $queries; + } } diff --git a/phpBB/phpbb/event/md_exporter.php b/phpBB/phpbb/event/md_exporter.php new file mode 100644 index 0000000000..af86882885 --- /dev/null +++ b/phpBB/phpbb/event/md_exporter.php @@ -0,0 +1,439 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\event; + +/** +* Class md_exporter +* Crawls through a markdown file and grabs all events +* +* @package phpbb\event +*/ +class md_exporter +{ + /** @var string Path where we look for files*/ + protected $path; + + /** @var string phpBB Root Path */ + protected $root_path; + + /** @var string */ + protected $filter; + + /** @var string */ + protected $current_event; + + /** @var array */ + protected $events; + + /** + * @param string $phpbb_root_path + * @param mixed $extension String 'vendor/ext' to filter, null for phpBB core + */ + public function __construct($phpbb_root_path, $extension = null) + { + $this->root_path = $phpbb_root_path; + $this->path = $this->root_path; + if ($extension) + { + $this->path .= 'ext/' . $extension . '/'; + } + + $this->events = array(); + $this->events_by_file = array(); + $this->filter = $this->current_event = ''; + } + + /** + * Get the list of all events + * + * @return array Array with events: name => details + */ + public function get_events() + { + return $this->events; + } + + /** + * @param string $md_file Relative from phpBB root + * @return int Number of events found + * @throws \LogicException + */ + public function crawl_phpbb_directory_adm($md_file) + { + $this->crawl_eventsmd($md_file, 'adm'); + + $file_list = $this->get_recursive_file_list($this->path . 'adm/style/'); + foreach ($file_list as $file) + { + $file_name = 'adm/style/' . $file; + $this->validate_events_from_file($file_name, $this->crawl_file_for_events($file_name)); + } + + return sizeof($this->events); + } + + /** + * @param string $md_file Relative from phpBB root + * @return int Number of events found + * @throws \LogicException + */ + public function crawl_phpbb_directory_styles($md_file) + { + $this->crawl_eventsmd($md_file, 'styles'); + + $styles = array('prosilver', 'subsilver2'); + foreach ($styles as $style) + { + $file_list = $this->get_recursive_file_list( + $this->path . 'styles/' . $style . '/template/' + ); + + foreach ($file_list as $file) + { + $file_name = 'styles/' . $style . '/template/' . $file; + $this->validate_events_from_file($file_name, $this->crawl_file_for_events($file_name)); + } + } + + return sizeof($this->events); + } + + /** + * @param string $md_file Relative from phpBB root + * @param string $filter Should be 'styles' or 'adm' + * @return int Number of events found + * @throws \LogicException + */ + public function crawl_eventsmd($md_file, $filter) + { + if (!file_exists($this->path . $md_file)) + { + throw new \LogicException("The event docs file '{$md_file}' could not be found"); + } + + $file_content = file_get_contents($this->path . $md_file); + $this->filter = $filter; + + $events = explode("\n\n", $file_content); + foreach ($events as $event) + { + // Last row of the file + if (strpos($event, "\n===\n") === false) + { + continue; + } + + list($event_name, $details) = explode("\n===\n", $event, 2); + $this->validate_event_name($event_name); + $this->current_event = $event_name; + + if (isset($this->events[$this->current_event])) + { + throw new \LogicException("The event '{$this->current_event}' is defined multiple times"); + } + + if (($this->filter == 'adm' && strpos($this->current_event, 'acp_') !== 0) + || ($this->filter == 'styles' && strpos($this->current_event, 'acp_') === 0)) + { + continue; + } + + list($file_details, $details) = explode("\n* Since: ", $details, 2); + list($since, $description) = explode("\n* Purpose: ", $details, 2); + + $files = $this->validate_file_list($file_details); + $since = $this->validate_since($since); + + $this->events[$event_name] = array( + 'event' => $this->current_event, + 'files' => $files, + 'since' => $since, + 'description' => $description, + ); + } + + return sizeof($this->events); + } + + /** + * Format the php events as a wiki table + * @return string Number of events found + */ + public function export_events_for_wiki() + { + if ($this->filter === 'adm') + { + $wiki_page = '= ACP Template Events =' . "\n"; + $wiki_page .= '{| class="zebra sortable" cellspacing="0" cellpadding="5"' . "\n"; + $wiki_page .= '! Identifier !! Placement !! Added in Release !! Explanation' . "\n"; + } + else + { + $wiki_page = '= Template Events =' . "\n"; + $wiki_page .= '{| class="zebra sortable" cellspacing="0" cellpadding="5"' . "\n"; + $wiki_page .= '! Identifier !! Prosilver Placement (If applicable) !! Subsilver Placement (If applicable) !! Added in Release !! Explanation' . "\n"; + } + + foreach ($this->events as $event_name => $event) + { + $wiki_page .= "|- id=\"{$event_name}\"\n"; + $wiki_page .= "| [[#{$event_name}|{$event_name}]] || "; + + if ($this->filter === 'adm') + { + $wiki_page .= implode(', ', $event['files']['adm']); + } + else + { + $wiki_page .= implode(', ', $event['files']['prosilver']) . ' || ' . implode(', ', $event['files']['subsilver2']); + } + + $wiki_page .= " || {$event['since']} || " . str_replace("\n", ' ', $event['description']) . "\n"; + } + $wiki_page .= '|}' . "\n"; + + return $wiki_page; + } + + /** + * Validates a template event name + * + * @param $event_name + * @return null + * @throws \LogicException + */ + public function validate_event_name($event_name) + { + if (!preg_match('#^([a-z][a-z0-9]*(?:_[a-z][a-z0-9]*)+)$#', $event_name)) + { + throw new \LogicException("Invalid event name '{$event_name}'"); + } + } + + /** + * Validate "Since" Information + * + * @param string $since + * @return string + * @throws \LogicException + */ + public function validate_since($since) + { + if (!preg_match('#^\d+\.\d+\.\d+(?:-(?:a|b|rc|pl)\d+)?$#', $since)) + { + throw new \LogicException("Invalid since information found for event '{$this->current_event}'"); + } + + return $since; + } + + /** + * Validate the files list + * + * @param string $file_details + * @return array + * @throws \LogicException + */ + public function validate_file_list($file_details) + { + $files_list = array( + 'prosilver' => array(), + 'subsilver2' => array(), + 'adm' => array(), + ); + + // Multi file list + if (strpos($file_details, "* Locations:\n + ") === 0) + { + $file_details = substr($file_details, strlen("* Locations:\n + ")); + $files = explode("\n + ", $file_details); + foreach ($files as $file) + { + if (!file_exists($this->path . $file) || substr($file, -5) !== '.html') + { + throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 1); + } + + if (($this->filter !== 'adm') && strpos($file, 'styles/prosilver/template/') === 0) + { + $files_list['prosilver'][] = substr($file, strlen('styles/prosilver/template/')); + } + else if (($this->filter !== 'adm') && strpos($file, 'styles/subsilver2/template/') === 0) + { + $files_list['subsilver2'][] = substr($file, strlen('styles/subsilver2/template/')); + } + else if (($this->filter === 'adm') && strpos($file, 'adm/style/') === 0) + { + $files_list['adm'][] = substr($file, strlen('adm/style/')); + } + else + { + throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 2); + } + + $this->events_by_file[$file][] = $this->current_event; + } + } + else if ($this->filter == 'adm') + { + $file = substr($file_details, strlen('* Location: ')); + if (!file_exists($this->path . $file) || substr($file, -5) !== '.html') + { + throw new \LogicException("Invalid file '{$file}' not found for event '{$this->current_event}'", 1); + } + + $files_list['adm'][] = substr($file, strlen('adm/style/')); + + $this->events_by_file[$file][] = $this->current_event; + } + else + { + throw new \LogicException("Invalid file list found for event '{$this->current_event}'", 2); + } + + return $files_list; + } + + /** + * Get all template events in a template file + * + * @param string $file + * @return array + * @throws \LogicException + */ + public function crawl_file_for_events($file) + { + if (!file_exists($this->path . $file)) + { + throw new \LogicException("File '{$file}' does not exist", 1); + } + + $event_list = array(); + $file_content = file_get_contents($this->path . $file); + + $events = explode('<!-- EVENT ', $file_content); + // Remove the code before the first event + array_shift($events); + foreach ($events as $event) + { + $event = explode(' -->', $event, 2); + $event_list[] = array_shift($event); + } + + return $event_list; + } + + /** + * Validates whether all events from $file are in the md file and vice-versa + * + * @param string $file + * @param array $events + * @return true + * @throws \LogicException + */ + public function validate_events_from_file($file, array $events) + { + if (empty($this->events_by_file[$file]) && empty($events)) + { + return true; + } + else if (empty($this->events_by_file[$file])) + { + $event_list = implode("', '", $events); + throw new \LogicException("File '{$file}' should not contain events, but contains: " + . "'{$event_list}'", 1); + } + else if (empty($events)) + { + $event_list = implode("', '", $this->events_by_file[$file]); + throw new \LogicException("File '{$file}' contains no events, but should contain: " + . "'{$event_list}'", 1); + } + + $missing_events_from_file = array(); + foreach ($this->events_by_file[$file] as $event) + { + if (!in_array($event, $events)) + { + $missing_events_from_file[] = $event; + } + } + + if (!empty($missing_events_from_file)) + { + $event_list = implode("', '", $missing_events_from_file); + throw new \LogicException("File '{$file}' does not contain events: '{$event_list}'", 2); + } + + $missing_events_from_md = array(); + foreach ($events as $event) + { + if (!in_array($event, $this->events_by_file[$file])) + { + $missing_events_from_md[] = $event; + } + } + + if (!empty($missing_events_from_md)) + { + $event_list = implode("', '", $missing_events_from_md); + throw new \LogicException("File '{$file}' contains additional events: '{$event_list}'", 3); + } + + return true; + } + + /** + * Returns a list of files in $dir + * + * Works recursive with any depth + * + * @param string $dir Directory to go through + * @return array List of files (including directories) + */ + public function get_recursive_file_list($dir) + { + try + { + $iterator = new \RecursiveIteratorIterator( + new \phpbb\recursive_dot_prefix_filter_iterator( + new \RecursiveDirectoryIterator( + $dir, + \FilesystemIterator::SKIP_DOTS + ) + ), + \RecursiveIteratorIterator::SELF_FIRST + ); + } + catch (\Exception $e) + { + return array(); + } + + $files = array(); + foreach ($iterator as $file_info) + { + /** @var \RecursiveDirectoryIterator $file_info */ + if ($file_info->isDir()) + { + continue; + } + + $relative_path = $iterator->getInnerIterator()->getSubPathname(); + + if (substr($relative_path, -5) == '.html') + { + $files[] = str_replace(DIRECTORY_SEPARATOR, '/', $relative_path); + } + } + + return $files; + } +} diff --git a/phpBB/phpbb/event/php_exporter.php b/phpBB/phpbb/event/php_exporter.php new file mode 100644 index 0000000000..d86ee3c045 --- /dev/null +++ b/phpBB/phpbb/event/php_exporter.php @@ -0,0 +1,608 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\event; + +/** +* Class php_exporter +* Crawls through a list of files and grabs all php-events +* +* @package phpbb\event +*/ +class php_exporter +{ + /** @var string Path where we look for files*/ + protected $path; + + /** @var string phpBB Root Path */ + protected $root_path; + + /** @var string */ + protected $current_file; + + /** @var string */ + protected $current_event; + + /** @var int */ + protected $current_event_line; + + /** @var array */ + protected $events; + + /** @var array */ + protected $file_lines; + + /** + * @param string $phpbb_root_path + * @param mixed $extension String 'vendor/ext' to filter, null for phpBB core + */ + public function __construct($phpbb_root_path, $extension = null) + { + $this->root_path = $phpbb_root_path; + $this->path = $phpbb_root_path; + $this->events = $this->file_lines = array(); + $this->current_file = $this->current_event = ''; + $this->current_event_line = 0; + + $this->path = $this->root_path; + if ($extension) + { + $this->path .= 'ext/' . $extension . '/'; + } + } + + /** + * Get the list of all events + * + * @return array Array with events: name => details + */ + public function get_events() + { + return $this->events; + } + + /** + * Set current event data + * + * @param string $name Name of the current event (used for error messages) + * @param int $line Line where the current event is placed in + * @return null + */ + public function set_current_event($name, $line) + { + $this->current_event = $name; + $this->current_event_line = $line; + } + + /** + * Set the content of this file + * + * @param array $content Array with the lines of the file + * @return null + */ + public function set_content($content) + { + $this->file_lines = $content; + } + + /** + * Crawl the phpBB/ directory for php events + * @return int The number of events found + */ + public function crawl_phpbb_directory_php() + { + $files = $this->get_recursive_file_list(); + $this->events = array(); + foreach ($files as $file) + { + $this->crawl_php_file($file); + } + ksort($this->events); + + return sizeof($this->events); + } + + /** + * Returns a list of files in $dir + * + * @return array List of files (including the path) + */ + public function get_recursive_file_list() + { + try + { + $iterator = new \RecursiveIteratorIterator( + new \phpbb\event\recursive_event_filter_iterator( + new \RecursiveDirectoryIterator( + $this->path, + \FilesystemIterator::SKIP_DOTS + ), + $this->path + ), + \RecursiveIteratorIterator::LEAVES_ONLY + ); + } + catch (\Exception $e) + { + return array(); + } + + $files = array(); + foreach ($iterator as $file_info) + { + /** @var \RecursiveDirectoryIterator $file_info */ + $relative_path = $iterator->getInnerIterator()->getSubPathname(); + $files[] = str_replace(DIRECTORY_SEPARATOR, '/', $relative_path); + } + + return $files; + } + + /** + * Format the php events as a wiki table + * @return string + */ + public function export_events_for_wiki() + { + $wiki_page = '= PHP Events (Hook Locations) =' . "\n"; + $wiki_page .= '{| class="sortable zebra" cellspacing="0" cellpadding="5"' . "\n"; + $wiki_page .= '! Identifier !! Placement !! Arguments !! Added in Release !! Explanation' . "\n"; + foreach ($this->events as $event) + { + $wiki_page .= '|- id="' . $event['event'] . '"' . "\n"; + $wiki_page .= '| [[#' . $event['event'] . '|' . $event['event'] . ']] || ' . $event['file'] . ' || ' . implode(', ', $event['arguments']) . ' || ' . $event['since'] . ' || ' . $event['description'] . "\n"; + } + $wiki_page .= '|}' . "\n"; + + return $wiki_page; + } + + /** + * @param string $file + * @return int Number of events found in this file + * @throws \LogicException + */ + public function crawl_php_file($file) + { + $this->current_file = $file; + $this->file_lines = array(); + $content = file_get_contents($this->path . $this->current_file); + $num_events_found = 0; + + if (strpos($content, "dispatcher->trigger_event('") || strpos($content, "dispatcher->dispatch('")) + { + $this->set_content(explode("\n", $content)); + for ($i = 0, $num_lines = sizeof($this->file_lines); $i < $num_lines; $i++) + { + $event_line = false; + $found_trigger_event = strpos($this->file_lines[$i], "dispatcher->trigger_event('"); + $arguments = array(); + if ($found_trigger_event !== false) + { + $event_line = $i; + $this->set_current_event($this->get_event_name($event_line, false), $event_line); + + // Find variables of the event + $arguments = $this->get_vars_from_array(); + $doc_vars = $this->get_vars_from_docblock(); + $this->validate_vars_docblock_array($arguments, $doc_vars); + } + else + { + $found_dispatch = strpos($this->file_lines[$i], "dispatcher->dispatch('"); + if ($found_dispatch !== false) + { + $event_line = $i; + $this->set_current_event($this->get_event_name($event_line, true), $event_line); + } + } + + if ($event_line) + { + // Validate @event + $event_line_num = $this->find_event(); + $this->validate_event($this->current_event, $this->file_lines[$event_line_num]); + + // Validate @since + $since_line_num = $this->find_since(); + $since = $this->validate_since($this->file_lines[$since_line_num]); + + // Find event description line + $description_line_num = $this->find_description(); + $description = substr(trim($this->file_lines[$description_line_num]), strlen('* ')); + + if (isset($this->events[$this->current_event])) + { + throw new \LogicException("The event '{$this->current_event}' from file " + . "'{$this->current_file}:{$event_line_num}' already exists in file " + . "'{$this->events[$this->current_event]['file']}'", 10); + } + + sort($arguments); + $this->events[$this->current_event] = array( + 'event' => $this->current_event, + 'file' => $this->current_file, + 'arguments' => $arguments, + 'since' => $since, + 'description' => $description, + ); + $num_events_found++; + } + } + } + + return $num_events_found; + } + + /** + * Find the name of the event inside the dispatch() line + * + * @param int $event_line + * @param bool $is_dispatch Do we look for dispatch() or trigger_event() ? + * @return string Name of the event + * @throws \LogicException + */ + public function get_event_name($event_line, $is_dispatch) + { + $event_text_line = $this->file_lines[$event_line]; + $event_text_line = ltrim($event_text_line, "\t"); + + if ($is_dispatch) + { + $regex = '#\$([a-z](?:[a-z0-9_]|->)*)'; + $regex .= '->dispatch\('; + $regex .= '\'' . $this->preg_match_event_name() . '\''; + $regex .= '\);#'; + } + else + { + $regex = '#extract\(\$([a-z](?:[a-z0-9_]|->)*)'; + $regex .= '->trigger_event\('; + $regex .= '\'' . $this->preg_match_event_name() . '\''; + $regex .= ', compact\(\$vars\)\)\);#'; + } + + $match = array(); + preg_match($regex, $event_text_line, $match); + if (!isset($match[2])) + { + throw new \LogicException("Can not find event name in line '{$event_text_line}' " + . "in file '{$this->current_file}:{$event_line}'", 1); + } + + return $match[2]; + } + + /** + * Returns a regex match for the event name + * + * @return string + */ + protected function preg_match_event_name() + { + return '([a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)+)'; + } + + /** + * Find the $vars array + * + * @return array List of variables + * @throws \LogicException + */ + public function get_vars_from_array() + { + $line = ltrim($this->file_lines[$this->current_event_line - 1], "\t"); + if ($line === ');') + { + $vars_array = $this->get_vars_from_multi_line_array(); + } + else + { + $vars_array = $this->get_vars_from_single_line_array($line); + } + + foreach ($vars_array as $var) + { + if (!preg_match('#^([a-zA-Z_][a-zA-Z0-9_]*)$#', $var)) + { + throw new \LogicException("Found invalid var '{$var}' in array for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 3); + } + } + + sort($vars_array); + return $vars_array; + } + + /** + * Find the variables in single line array + * + * @param string $line + * @param bool $throw_multiline Throw an exception when there are too + * many arguments in one line. + * @return array List of variables + * @throws \LogicException + */ + public function get_vars_from_single_line_array($line, $throw_multiline = true) + { + $match = array(); + preg_match('#^\$vars = array\(\'([a-zA-Z0-9_\' ,]+)\'\);$#', $line, $match); + + if (isset($match[1])) + { + $vars_array = explode("', '", $match[1]); + if ($throw_multiline && sizeof($vars_array) > 6) + { + throw new \LogicException('Should use multiple lines for $vars definition ' + . "for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2); + } + return $vars_array; + } + else + { + throw new \LogicException("Can not find '\$vars = array();'-line for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1); + } + } + + /** + * Find the variables in single line array + * + * @return array List of variables + * @throws \LogicException + */ + public function get_vars_from_multi_line_array() + { + $current_vars_line = 2; + $var_lines = array(); + while (ltrim($this->file_lines[$this->current_event_line - $current_vars_line], "\t") !== '$vars = array(') + { + $var_lines[] = substr(trim($this->file_lines[$this->current_event_line - $current_vars_line]), 0, -1); + + $current_vars_line++; + if ($current_vars_line > $this->current_event_line) + { + // Reached the start of the file + throw new \LogicException("Can not find end of \$vars array for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2); + } + } + + return $this->get_vars_from_single_line_array('$vars = array(' . implode(", ", $var_lines) . ');', false); + } + + /** + * Find the $vars array + * + * @return array List of variables + * @throws \LogicException + */ + public function get_vars_from_docblock() + { + $doc_vars = array(); + $current_doc_line = 1; + $found_comment_end = false; + while (ltrim($this->file_lines[$this->current_event_line - $current_doc_line], "\t") !== '/**') + { + if (ltrim($this->file_lines[$this->current_event_line - $current_doc_line], "\t") === '*/') + { + $found_comment_end = true; + } + + if ($found_comment_end) + { + $var_line = trim($this->file_lines[$this->current_event_line - $current_doc_line]); + $var_line = preg_replace('!\s+!', ' ', $var_line); + if (strpos($var_line, '* @var ') === 0) + { + $doc_line = explode(' ', $var_line, 5); + if (sizeof($doc_line) !== 5) + { + throw new \LogicException("Found invalid line '{$this->file_lines[$this->current_event_line - $current_doc_line]}' " + . "for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1); + } + $doc_vars[] = $doc_line[3]; + } + } + + $current_doc_line++; + if ($current_doc_line > $this->current_event_line) + { + // Reached the start of the file + throw new \LogicException("Can not find end of docblock for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2); + } + } + + if (empty($doc_vars)) + { + // Reached the start of the file + throw new \LogicException("Can not find @var lines for event '{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 3); + } + + foreach ($doc_vars as $var) + { + if (!preg_match('#^([a-zA-Z_][a-zA-Z0-9_]*)$#', $var)) + { + throw new \LogicException("Found invalid @var '{$var}' in docblock for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 4); + } + } + + sort($doc_vars); + return $doc_vars; + } + + /** + * Find the "@since" Information line + * + * @return int Absolute line number + * @throws \LogicException + */ + public function find_since() + { + return $this->find_tag('since', array('event', 'var')); + } + + /** + * Find the "@event" Information line + * + * @return int Absolute line number + */ + public function find_event() + { + return $this->find_tag('event', array()); + } + + /** + * Find a "@*" Information line + * + * @param string $find_tag Name of the tag we are trying to find + * @param array $disallowed_tags List of tags that must not appear between + * the tag and the actual event + * @return int Absolute line number + * @throws \LogicException + */ + public function find_tag($find_tag, $disallowed_tags) + { + $find_tag_line = 0; + $found_comment_end = false; + while (strpos(ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t"), '* @' . $find_tag . ' ') !== 0) + { + if ($found_comment_end && ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t") === '/**') + { + // Reached the start of this doc block + throw new \LogicException("Can not find '@{$find_tag}' information for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1); + } + + foreach ($disallowed_tags as $disallowed_tag) + { + if ($found_comment_end && strpos(ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t"), '* @' . $disallowed_tag) === 0) + { + // Found @var after the @since + throw new \LogicException("Found '@{$disallowed_tag}' information after '@{$find_tag}' for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 3); + } + } + + if (ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t") === '*/') + { + $found_comment_end = true; + } + + $find_tag_line++; + if ($find_tag_line >= $this->current_event_line) + { + // Reached the start of the file + throw new \LogicException("Can not find '@{$find_tag}' information for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2); + } + } + + return $this->current_event_line - $find_tag_line; + } + + /** + * Find a "@*" Information line + * + * @return int Absolute line number + * @throws \LogicException + */ + public function find_description() + { + $find_desc_line = 0; + while (ltrim($this->file_lines[$this->current_event_line - $find_desc_line], "\t") !== '/**') + { + $find_desc_line++; + if ($find_desc_line > $this->current_event_line) + { + // Reached the start of the file + throw new \LogicException("Can not find a description for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1); + } + } + + $find_desc_line = $this->current_event_line - $find_desc_line + 1; + + $desc = trim($this->file_lines[$find_desc_line]); + if (strpos($desc, '* @') === 0 || $desc[0] !== '*' || substr($desc, 1) == '') + { + // First line of the doc block is a @-line, empty or only contains "*" + throw new \LogicException("Can not find a description for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2); + } + + return $find_desc_line; + } + + /** + * Validate "@since" Information + * + * @param string $line + * @return string + * @throws \LogicException + */ + public function validate_since($line) + { + $match = array(); + preg_match('#^\* @since (\d+\.\d+\.\d+(?:-(?:a|b|rc|pl)\d+)?)$#', ltrim($line, "\t"), $match); + if (!isset($match[1])) + { + throw new \LogicException("Invalid '@since' information for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'"); + } + + return $match[1]; + } + + /** + * Validate "@event" Information + * + * @param string $event_name + * @param string $line + * @return string + * @throws \LogicException + */ + public function validate_event($event_name, $line) + { + $event = substr(ltrim($line, "\t"), strlen('* @event ')); + + if ($event !== trim($event)) + { + throw new \LogicException("Invalid '@event' information for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 1); + } + + if ($event !== $event_name) + { + throw new \LogicException("Event name does not match '@event' tag for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'", 2); + } + + return $event; + } + + /** + * Validates that two arrays contain the same strings + * + * @param array $vars_array Variables found in the array line + * @param array $vars_docblock Variables found in the doc block + * @return null + * @throws \LogicException + */ + public function validate_vars_docblock_array($vars_array, $vars_docblock) + { + $vars_array = array_unique($vars_array); + $vars_docblock = array_unique($vars_docblock); + $sizeof_vars_array = sizeof($vars_array); + + if ($sizeof_vars_array !== sizeof($vars_docblock) || $sizeof_vars_array !== sizeof(array_intersect($vars_array, $vars_docblock))) + { + throw new \LogicException("\$vars array does not match the list of '@var' tags for event " + . "'{$this->current_event}' in file '{$this->current_file}:{$this->current_event_line}'"); + } + } +} diff --git a/phpBB/phpbb/event/recursive_event_filter_iterator.php b/phpBB/phpbb/event/recursive_event_filter_iterator.php new file mode 100644 index 0000000000..ef2f2ec0ed --- /dev/null +++ b/phpBB/phpbb/event/recursive_event_filter_iterator.php @@ -0,0 +1,70 @@ +<?php +/** +* +* @package event +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\event; + +/** +* Class recursive_event_filter_iterator +* +* This filter ignores directories and files starting with a dot. +* It also skips some directories that do not contain events anyway, +* such as e.g. files/, store/ and vendor/ +* +* @package phpbb\event +*/ +class recursive_event_filter_iterator extends \RecursiveFilterIterator +{ + protected $root_path; + + /** + * Construct + * + * @param \RecursiveIterator $iterator + * @param string $root_path + */ + public function __construct(\RecursiveIterator $iterator, $root_path) + { + $this->root_path = str_replace(DIRECTORY_SEPARATOR, '/', $root_path); + parent::__construct($iterator); + } + + /** + * Return the inner iterator's children contained in a recursive_event_filter_iterator + * + * @return recursive_event_filter_iterator + */ + public function getChildren() { + return new self($this->getInnerIterator()->getChildren(), $this->root_path); + } + + /** + * {@inheritDoc} + */ + public function accept() + { + $relative_path = str_replace(DIRECTORY_SEPARATOR, '/', $this->current()); + $filename = $this->current()->getFilename(); + + return (substr($relative_path, -4) === '.php' || $this->current()->isDir()) + && $filename[0] !== '.' + && strpos($relative_path, $this->root_path . 'cache/') !== 0 + && strpos($relative_path, $this->root_path . 'develop/') !== 0 + && strpos($relative_path, $this->root_path . 'docs/') !== 0 + && strpos($relative_path, $this->root_path . 'ext/') !== 0 + && strpos($relative_path, $this->root_path . 'files/') !== 0 + && strpos($relative_path, $this->root_path . 'includes/utf/') !== 0 + && strpos($relative_path, $this->root_path . 'language/') !== 0 + && strpos($relative_path, $this->root_path . 'phpbb/db/migration/data/') !== 0 + && strpos($relative_path, $this->root_path . 'phpbb/event/') !== 0 + && strpos($relative_path, $this->root_path . 'store/') !== 0 + && strpos($relative_path, $this->root_path . 'tests/') !== 0 + && strpos($relative_path, $this->root_path . 'vendor/') !== 0 + ; + } +} diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index 993bd1b925..b22fbf07a6 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -34,7 +34,7 @@ class manager * Creates a manager and loads information from database * * @param ContainerInterface $container A container - * @param \phpbb\db\driver\driver $db A database connection + * @param \phpbb\db\driver\driver_interface $db A database connection * @param \phpbb\config\config $config \phpbb\config\config * @param \phpbb\filesystem $filesystem * @param string $extension_table The name of the table holding extensions @@ -43,7 +43,7 @@ class manager * @param \phpbb\cache\driver\driver_interface $cache A cache instance or null * @param string $cache_name The name of the cache variable, defaults to _ext */ - public function __construct(ContainerInterface $container, \phpbb\db\driver\driver $db, \phpbb\config\config $config, \phpbb\filesystem $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null, $cache_name = '_ext') + public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\driver\driver_interface $cache = null, $cache_name = '_ext') { $this->container = $container; $this->phpbb_root_path = $phpbb_root_path; diff --git a/phpBB/phpbb/feed/attachments_base.php b/phpBB/phpbb/feed/attachments_base.php new file mode 100644 index 0000000000..a9a8175928 --- /dev/null +++ b/phpBB/phpbb/feed/attachments_base.php @@ -0,0 +1,83 @@ +<?php +/** +* +* @package phpBB3 +* @copyright (c) 2014 phpBB Group +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 +* +*/ + +namespace phpbb\feed; + +/** +* Abstract class for feeds displaying attachments +* +* @package phpBB3 +*/ +abstract class attachments_base extends \phpbb\feed\base +{ + /** + * Attachments that may be displayed + */ + protected $attachments = array(); + + /** + * Retrieve the list of attachments that may be displayed + */ + protected function fetch_attachments() + { + $sql_array = array( + 'SELECT' => 'a.*', + 'FROM' => array( + ATTACHMENTS_TABLE => 'a' + ), + 'WHERE' => 'a.in_message = 0 ', + 'ORDER_BY' => 'a.filetime DESC, a.post_msg_id ASC', + ); + + if (isset($this->topic_id)) + { + $sql_array['WHERE'] .= 'AND a.topic_id = ' . (int) $this->topic_id; + } + else if (isset($this->forum_id)) + { + $sql_array['LEFT_JOIN'] = array( + array( + 'FROM' => array(TOPICS_TABLE => 't'), + 'ON' => 'a.topic_id = t.topic_id', + ) + ); + $sql_array['WHERE'] .= 'AND t.forum_id = ' . (int) $this->forum_id; + } + + $sql = $this->db->sql_build_query('SELECT', $sql_array); + $result = $this->db->sql_query($sql); + + // Set attachments in feed items + while ($row = $this->db->sql_fetchrow($result)) + { + $this->attachments[$row['post_msg_id']][] = $row; + } + $this->db->sql_freeresult($result); + } + + /** + * {@inheritDoc} + */ + public function open() + { + parent::open(); + $this->fetch_attachments(); + } + + /** + * Get attachments related to a given post + * + * @param $post_id int Post id + * @return mixed Attachments related to $post_id + */ + public function get_attachments($post_id) + { + return $this->attachments[$post_id]; + } +} diff --git a/phpBB/phpbb/feed/base.php b/phpBB/phpbb/feed/base.php index e6c1e606fa..0e3a80ebb8 100644 --- a/phpBB/phpbb/feed/base.php +++ b/phpBB/phpbb/feed/base.php @@ -25,7 +25,7 @@ abstract class base /** @var \phpbb\config\config */ protected $config; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\cache\driver\driver_interface */ @@ -70,7 +70,7 @@ abstract class base * * @param \phpbb\feed\helper $helper Feed helper * @param \phpbb\config\config $config Config object - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param \phpbb\cache\driver\driver_interface $cache Cache object * @param \phpbb\user $user User object * @param \phpbb\auth\auth $auth Auth object @@ -78,7 +78,7 @@ abstract class base * @param string $phpEx php file extension * @return null */ - function __construct(\phpbb\feed\helper $helper, \phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\cache\driver\driver_interface $cache, \phpbb\user $user, \phpbb\auth\auth $auth, \phpbb\content_visibility $content_visibility, $phpEx) + function __construct(\phpbb\feed\helper $helper, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, \phpbb\user $user, \phpbb\auth\auth $auth, \phpbb\content_visibility $content_visibility, $phpEx) { $this->config = $config; $this->helper = $helper; diff --git a/phpBB/phpbb/feed/factory.php b/phpBB/phpbb/feed/factory.php index d370160563..742b279ef4 100644 --- a/phpBB/phpbb/feed/factory.php +++ b/phpBB/phpbb/feed/factory.php @@ -24,7 +24,7 @@ class factory /** @var \phpbb\config\config */ protected $config; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @@ -32,10 +32,10 @@ class factory * * @param objec $container Container object * @param \phpbb\config\config $config Config object - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @return null */ - public function __construct($container, \phpbb\config\config $config, \phpbb\db\driver\driver $db) + public function __construct($container, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db) { $this->container = $container; $this->config = $config; diff --git a/phpBB/phpbb/feed/forum.php b/phpBB/phpbb/feed/forum.php index 85ecb60f7e..8e6490923d 100644 --- a/phpBB/phpbb/feed/forum.php +++ b/phpBB/phpbb/feed/forum.php @@ -80,6 +80,8 @@ class forum extends \phpbb\feed\post_base unset($forum_ids_passworded); } + + parent::open(); } function get_sql() diff --git a/phpBB/phpbb/feed/post_base.php b/phpBB/phpbb/feed/post_base.php index c797d6a8ca..de98f446f3 100644 --- a/phpBB/phpbb/feed/post_base.php +++ b/phpBB/phpbb/feed/post_base.php @@ -14,7 +14,7 @@ namespace phpbb\feed; * * @package phpBB3 */ -abstract class post_base extends \phpbb\feed\base +abstract class post_base extends \phpbb\feed\attachments_base { var $num_items = 'feed_limit_post'; var $attachments = array(); @@ -49,41 +49,4 @@ abstract class post_base extends \phpbb\feed\base . (($this->is_moderator_approve_forum($row['forum_id']) && $row['post_visibility'] !== ITEM_APPROVED) ? ' ' . $this->separator_stats . ' ' . $this->user->lang['POST_UNAPPROVED'] : ''); } } - - function fetch_attachments() - { - $sql_array = array( - 'SELECT' => 'a.*', - 'FROM' => array( - ATTACHMENTS_TABLE => 'a' - ), - 'WHERE' => 'a.in_message = 0 ', - 'ORDER_BY' => 'a.filetime DESC, a.post_msg_id ASC', - ); - - if (isset($this->topic_id)) - { - $sql_array['WHERE'] .= 'AND a.topic_id = ' . (int) $this->topic_id; - } - else if (isset($this->forum_id)) - { - $sql_array['LEFT_JOIN'] = array( - array( - 'FROM' => array(TOPICS_TABLE => 't'), - 'ON' => 'a.topic_id = t.topic_id', - ) - ); - $sql_array['WHERE'] .= 'AND t.forum_id = ' . (int) $this->forum_id; - } - - $sql = $this->db->sql_build_query('SELECT', $sql_array); - $result = $this->db->sql_query($sql); - - // Set attachments in feed items - while ($row = $this->db->sql_fetchrow($result)) - { - $this->attachments[$row['post_msg_id']][] = $row; - } - $this->db->sql_freeresult($result); - } } diff --git a/phpBB/phpbb/feed/topic.php b/phpBB/phpbb/feed/topic.php index a7acfb502f..fb49aa65cc 100644 --- a/phpBB/phpbb/feed/topic.php +++ b/phpBB/phpbb/feed/topic.php @@ -83,6 +83,8 @@ class topic extends \phpbb\feed\post_base unset($forum_ids_passworded); } + + parent::open(); } function get_sql() diff --git a/phpBB/phpbb/feed/topic_base.php b/phpBB/phpbb/feed/topic_base.php index 7e28e67b82..e8639a6fa6 100644 --- a/phpBB/phpbb/feed/topic_base.php +++ b/phpBB/phpbb/feed/topic_base.php @@ -14,7 +14,7 @@ namespace phpbb\feed; * * @package phpBB3 */ -abstract class topic_base extends \phpbb\feed\base +abstract class topic_base extends \phpbb\feed\attachments_base { var $num_items = 'feed_limit_topic'; diff --git a/phpBB/phpbb/groupposition/exception.php b/phpBB/phpbb/groupposition/exception.php index f43502235d..9b55669524 100644 --- a/phpBB/phpbb/groupposition/exception.php +++ b/phpBB/phpbb/groupposition/exception.php @@ -3,7 +3,7 @@ * * @package groupposition * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/groupposition/legend.php b/phpBB/phpbb/groupposition/legend.php index 47ba06c006..42af005622 100644 --- a/phpBB/phpbb/groupposition/legend.php +++ b/phpBB/phpbb/groupposition/legend.php @@ -26,7 +26,7 @@ class legend implements \phpbb\groupposition\groupposition_interface /** * Database object - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -39,10 +39,10 @@ class legend implements \phpbb\groupposition\groupposition_interface /** * Constructor * - * @param \phpbb\db\driver\driver $db Database object + * @param \phpbb\db\driver\driver_interface $db Database object * @param \phpbb\user $user User object */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\user $user) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user) { $this->db = $db; $this->user = $user; diff --git a/phpBB/phpbb/groupposition/teampage.php b/phpBB/phpbb/groupposition/teampage.php index d934571ebc..4f1b102720 100644 --- a/phpBB/phpbb/groupposition/teampage.php +++ b/phpBB/phpbb/groupposition/teampage.php @@ -30,7 +30,7 @@ class teampage implements \phpbb\groupposition\groupposition_interface /** * Database object - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -49,11 +49,11 @@ class teampage implements \phpbb\groupposition\groupposition_interface /** * Constructor * - * @param \phpbb\db\driver\driver $db Database object + * @param \phpbb\db\driver\driver_interface $db Database object * @param \phpbb\user $user User object * @param \phpbb\cache\driver\driver_interface $cache Cache object */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\user $user, \phpbb\cache\driver\driver_interface $cache) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, \phpbb\cache\driver\driver_interface $cache) { $this->db = $db; $this->user = $user; diff --git a/phpBB/phpbb/json_response.php b/phpBB/phpbb/json_response.php index 45c2f6cac4..e17525519a 100644 --- a/phpBB/phpbb/json_response.php +++ b/phpBB/phpbb/json_response.php @@ -3,7 +3,7 @@ * * @package phpBB3 * @copyright (c) 2011 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/lock/db.php b/phpBB/phpbb/lock/db.php index 461adda045..2b437ef899 100644 --- a/phpBB/phpbb/lock/db.php +++ b/phpBB/phpbb/lock/db.php @@ -42,7 +42,7 @@ class db /** * A database connection - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ private $db; @@ -53,9 +53,9 @@ class db * * @param string $config_name A config variable to be used for locking * @param array $config The phpBB configuration - * @param \phpbb\db\driver\driver $db A database connection + * @param \phpbb\db\driver\driver_interface $db A database connection */ - public function __construct($config_name, \phpbb\config\config $config, \phpbb\db\driver\driver $db) + public function __construct($config_name, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db) { $this->config_name = $config_name; $this->config = $config; diff --git a/phpBB/phpbb/log/log.php b/phpBB/phpbb/log/log.php index 68b023e244..e4c5ce47d9 100644 --- a/phpBB/phpbb/log/log.php +++ b/phpBB/phpbb/log/log.php @@ -93,10 +93,10 @@ class log implements \phpbb\log\log_interface /** * Constructor * - * @param \phpbb\db\driver\driver $db Database object + * @param \phpbb\db\driver\driver_interface $db Database object * @param \phpbb\user $user User object * @param \phpbb\auth\auth $auth Auth object - * @param phpbb_dispatcher $phpbb_dispatcher Event dispatcher + * @param \phpbb\event\dispatcher $phpbb_dispatcher Event dispatcher * @param string $phpbb_root_path Root path * @param string $relative_admin_path Relative admin root path * @param string $php_ext PHP Extension @@ -305,9 +305,17 @@ class log implements \phpbb\log\log_interface * @var array sql_ary Array with log data we insert into the * database. If sql_ary[log_type] is not set, * we won't add the entry to the database. - * @since 3.1-A1 + * @since 3.1.0-a1 */ - $vars = array('mode', 'user_id', 'log_ip', 'log_operation', 'log_time', 'additional_data', 'sql_ary'); + $vars = array( + 'mode', + 'user_id', + 'log_ip', + 'log_operation', + 'log_time', + 'additional_data', + 'sql_ary', + ); extract($this->dispatcher->trigger_event('core.add_log', compact($vars))); // We didn't find a log_type, so we don't save it in the database. @@ -403,9 +411,23 @@ class log implements \phpbb\log\log_interface * is false, no entries will be returned. * @var string sql_additional Additional conditions for the entries, * e.g.: 'AND l.forum_id = 1' - * @since 3.1-A1 + * @since 3.1.0-a1 */ - $vars = array('mode', 'count_logs', 'limit', 'offset', 'forum_id', 'topic_id', 'user_id', 'log_time', 'sort_by', 'keywords', 'profile_url', 'log_type', 'sql_additional'); + $vars = array( + 'mode', + 'count_logs', + 'limit', + 'offset', + 'forum_id', + 'topic_id', + 'user_id', + 'log_time', + 'sort_by', + 'keywords', + 'profile_url', + 'log_type', + 'sql_additional', + ); extract($this->dispatcher->trigger_event('core.get_logs_modify_type', compact($vars))); if ($log_type === false) @@ -490,7 +512,7 @@ class log implements \phpbb\log\log_interface 'topic_id' => (int) $row['topic_id'], 'viewforum' => ($row['forum_id'] && $this->auth->acl_get('f_read', $row['forum_id'])) ? append_sid("{$this->phpbb_root_path}viewforum.{$this->php_ext}", 'f=' . $row['forum_id']) : false, - 'action' => (isset($this->user->lang[$row['log_operation']])) ? $this->user->lang[$row['log_operation']] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}', + 'action' => (isset($this->user->lang[$row['log_operation']])) ? $row['log_operation'] : '{' . ucfirst(str_replace('_', ' ', $row['log_operation'])) . '}', ); /** @@ -499,7 +521,7 @@ class log implements \phpbb\log\log_interface * @event core.get_logs_modify_entry_data * @var array row Entry data from the database * @var array log_entry_data Entry's data which is returned - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('row', 'log_entry_data'); extract($this->dispatcher->trigger_event('core.get_logs_modify_entry_data', compact($vars))); @@ -517,12 +539,26 @@ class log implements \phpbb\log\log_interface // arguments, if there are we fill out the arguments // array. It doesn't matter if we add more arguments than // placeholders. - if ((substr_count($log[$i]['action'], '%') - sizeof($log_data_ary)) > 0) + $num_args = 0; + if (!is_array($this->user->lang[$row['log_operation']])) + { + $num_args = substr_count($this->user->lang[$row['log_operation']], '%'); + } + else + { + foreach ($this->user->lang[$row['log_operation']] as $case => $plural_string) + { + $num_args = max($num_args, substr_count($plural_string, '%')); + } + } + + if (($num_args - sizeof($log_data_ary)) > 0) { - $log_data_ary = array_merge($log_data_ary, array_fill(0, substr_count($log[$i]['action'], '%') - sizeof($log_data_ary), '')); + $log_data_ary = array_merge($log_data_ary, array_fill(0, $num_args - sizeof($log_data_ary), '')); } - $log[$i]['action'] = vsprintf($log[$i]['action'], $log_data_ary); + $lang_arguments = array_merge(array($log[$i]['action']), $log_data_ary); + $log[$i]['action'] = call_user_func_array(array($this->user, 'lang'), $lang_arguments); // If within the admin panel we do not censor text out if ($this->get_is_admin()) @@ -544,6 +580,10 @@ class log implements \phpbb\log\log_interface $log[$i]['action'] = make_clickable($log[$i]['action']); */ } + else + { + $log[$i]['action'] = $this->user->lang($log[$i]['action']); + } $i++; } @@ -558,7 +598,7 @@ class log implements \phpbb\log\log_interface * get the permission data * @var array reportee_id_list Array of additional user IDs we * get the username strings for - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('log', 'topic_id_list', 'reportee_id_list'); extract($this->dispatcher->trigger_event('core.get_logs_get_additional_data', compact($vars))); @@ -625,9 +665,23 @@ class log implements \phpbb\log\log_interface $operations = array(); foreach ($this->user->lang as $key => $value) { - if (substr($key, 0, 4) == 'LOG_' && preg_match($keywords_pattern, $value)) + if (substr($key, 0, 4) == 'LOG_') { - $operations[] = $key; + if (is_array($value)) + { + foreach ($value as $plural_value) + { + if (preg_match($keywords_pattern, $plural_value)) + { + $operations[] = $key; + break; + } + } + } + else if (preg_match($keywords_pattern, $value)) + { + $operations[] = $key; + } } } diff --git a/phpBB/phpbb/notification/exception.php b/phpBB/phpbb/notification/exception.php index 6bdded3fd8..1b4cc89fc9 100644 --- a/phpBB/phpbb/notification/exception.php +++ b/phpBB/phpbb/notification/exception.php @@ -3,7 +3,7 @@ * * @package notifications * @copyright (c) 2013 phpBB Group -* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2 +* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2 * */ diff --git a/phpBB/phpbb/notification/manager.php b/phpBB/phpbb/notification/manager.php index 2e8652771b..09d9677ccd 100644 --- a/phpBB/phpbb/notification/manager.php +++ b/phpBB/phpbb/notification/manager.php @@ -30,7 +30,7 @@ class manager /** @var \phpbb\config\config */ protected $config; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\cache\service */ @@ -62,7 +62,7 @@ class manager * @param ContainerBuilder $phpbb_container * @param \phpbb\user_loader $user_loader * @param \phpbb\config\config $config - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\user $user * @param string $phpbb_root_path * @param string $php_ext @@ -71,7 +71,7 @@ class manager * @param string $user_notifications_table * @return \phpbb\notification\manager */ - public function __construct($notification_types, $notification_methods, $phpbb_container, \phpbb\user_loader $user_loader, \phpbb\config\config $config, \phpbb\db\driver\driver $db, \phpbb\cache\service $cache, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) + public function __construct($notification_types, $notification_methods, $phpbb_container, \phpbb\user_loader $user_loader, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\cache\service $cache, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) { $this->notification_types = $notification_types; $this->notification_methods = $notification_methods; diff --git a/phpBB/phpbb/notification/method/base.php b/phpBB/phpbb/notification/method/base.php index 4ce42de830..2e6507d30f 100644 --- a/phpBB/phpbb/notification/method/base.php +++ b/phpBB/phpbb/notification/method/base.php @@ -21,7 +21,7 @@ abstract class base implements \phpbb\notification\method\method_interface /** @var \phpbb\user_loader */ protected $user_loader; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\cache\driver\driver_interface */ @@ -59,7 +59,7 @@ abstract class base implements \phpbb\notification\method\method_interface * Notification Method Base Constructor * * @param \phpbb\user_loader $user_loader - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\cache\driver\driver_interface $cache * @param \phpbb\user $user * @param \phpbb\auth\auth $auth @@ -68,7 +68,7 @@ abstract class base implements \phpbb\notification\method\method_interface * @param string $php_ext * @return \phpbb\notification\method\base */ - public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver $db, \phpbb\cache\driver\driver_interface $cache, $user, \phpbb\auth\auth $auth, \phpbb\config\config $config, $phpbb_root_path, $php_ext) + public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, $user, \phpbb\auth\auth $auth, \phpbb\config\config $config, $phpbb_root_path, $php_ext) { $this->user_loader = $user_loader; $this->db = $db; diff --git a/phpBB/phpbb/notification/type/approve_post.php b/phpBB/phpbb/notification/type/approve_post.php index e51ff12b3e..5912ad62b4 100644 --- a/phpBB/phpbb/notification/type/approve_post.php +++ b/phpBB/phpbb/notification/type/approve_post.php @@ -138,4 +138,12 @@ class approve_post extends \phpbb\notification\type\post { return 'post_approved'; } + + /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return $this->get_url(); + } } diff --git a/phpBB/phpbb/notification/type/base.php b/phpBB/phpbb/notification/type/base.php index 10c876b286..7d08521d40 100644 --- a/phpBB/phpbb/notification/type/base.php +++ b/phpBB/phpbb/notification/type/base.php @@ -21,7 +21,7 @@ abstract class base implements \phpbb\notification\type\type_interface /** @var \phpbb\user_loader */ protected $user_loader; - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\cache\driver\driver_interface */ @@ -89,7 +89,7 @@ abstract class base implements \phpbb\notification\type\type_interface * Notification Type Base Constructor * * @param \phpbb\user_loader $user_loader - * @param \phpbb\db\driver\driver $db + * @param \phpbb\db\driver\driver_interface $db * @param \phpbb\cache\driver\driver_interface $cache * @param \phpbb\user $user * @param \phpbb\auth\auth $auth @@ -101,7 +101,7 @@ abstract class base implements \phpbb\notification\type\type_interface * @param string $user_notifications_table * @return \phpbb\notification\type\base */ - public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver $db, \phpbb\cache\driver\driver_interface $cache, $user, \phpbb\auth\auth $auth, \phpbb\config\config $config, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) + public function __construct(\phpbb\user_loader $user_loader, \phpbb\db\driver\driver_interface $db, \phpbb\cache\driver\driver_interface $cache, $user, \phpbb\auth\auth $auth, \phpbb\config\config $config, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table) { $this->user_loader = $user_loader; $this->db = $db; @@ -276,6 +276,14 @@ abstract class base implements \phpbb\notification\type\type_interface } /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return $this->get_url(); + } + + /** * Prepare to output the notification to the template * * @return array Template variables diff --git a/phpBB/phpbb/notification/type/bookmark.php b/phpBB/phpbb/notification/type/bookmark.php index 003998677d..c981695f74 100644 --- a/phpBB/phpbb/notification/type/bookmark.php +++ b/phpBB/phpbb/notification/type/bookmark.php @@ -110,10 +110,14 @@ class bookmark extends \phpbb\notification\type\post unset($notify_users[$row['user_id']]); $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row); - $sql = 'UPDATE ' . $this->notifications_table . ' - SET ' . $this->db->sql_build_array('UPDATE', $notification->add_responders($post)) . ' - WHERE notification_id = ' . $row['notification_id']; - $this->db->sql_query($sql); + $update_responders = $notification->add_responders($post); + if (!empty($update_responders)) + { + $sql = 'UPDATE ' . $this->notifications_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $update_responders) . ' + WHERE notification_id = ' . $row['notification_id']; + $this->db->sql_query($sql); + } } $this->db->sql_freeresult($result); diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index f973becc3b..93fbcbde22 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -152,10 +152,14 @@ class post extends \phpbb\notification\type\base unset($notify_users[$row['user_id']]); $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row); - $sql = 'UPDATE ' . $this->notifications_table . ' - SET ' . $this->db->sql_build_array('UPDATE', $notification->add_responders($post)) . ' - WHERE notification_id = ' . $row['notification_id']; - $this->db->sql_query($sql); + $update_responders = $notification->add_responders($post); + if (!empty($update_responders)) + { + $sql = 'UPDATE ' . $this->notifications_table . ' + SET ' . $this->db->sql_build_array('UPDATE', $update_responders) . ' + WHERE notification_id = ' . $row['notification_id']; + $this->db->sql_query($sql); + } } $this->db->sql_freeresult($result); @@ -206,7 +210,11 @@ class post extends \phpbb\notification\type\base } } - if ($trimmed_responders_cnt) + if ($trimmed_responders_cnt > 20) + { + $usernames[] = $this->user->lang('NOTIFICATION_MANY_OTHERS'); + } + else if ($trimmed_responders_cnt) { $usernames[] = $this->user->lang('NOTIFICATION_X_OTHERS', $trimmed_responders_cnt); } @@ -270,6 +278,14 @@ class post extends \phpbb\notification\type\base } /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return append_sid($this->phpbb_root_path . 'viewtopic.' . $this->php_ext, "t={$this->item_parent_id}&view=unread#unread"); + } + + /** * Users needed to query before this notification can be displayed * * @return array Array of user_ids @@ -384,19 +400,27 @@ class post extends \phpbb\notification\type\base // Do not add them as a responder if they were the original poster that created the notification if ($this->get_data('poster_id') == $post['poster_id']) { - return array('notification_data' => serialize($this->get_data(false))); + return array(); } $responders = $this->get_data('responders'); $responders = ($responders === null) ? array() : $responders; + // Do not add more than 25 responders, + // we trim the username list to "a, b, c and x others" anyway + // so there is no use to add all of them anyway. + if (sizeof($responders) > 25) + { + return array(); + } + foreach ($responders as $responder) { // Do not add them as a responder multiple times if ($responder['poster_id'] == $post['poster_id']) { - return array('notification_data' => serialize($this->get_data(false))); + return array(); } } @@ -407,6 +431,15 @@ class post extends \phpbb\notification\type\base $this->set_data('responders', $responders); - return array('notification_data' => serialize($this->get_data(false))); + $serialized_data = serialize($this->get_data(false)); + + // If the data is longer then 4000 characters, it would cause a SQL error. + // We don't add the username to the list if this is the case. + if (utf8_strlen($serialized_data) >= 4000) + { + return array(); + } + + return array('notification_data' => $serialized_data); } } diff --git a/phpBB/phpbb/notification/type/post_in_queue.php b/phpBB/phpbb/notification/type/post_in_queue.php index db16763583..56dfcce588 100644 --- a/phpBB/phpbb/notification/type/post_in_queue.php +++ b/phpBB/phpbb/notification/type/post_in_queue.php @@ -119,6 +119,14 @@ class post_in_queue extends \phpbb\notification\type\post } /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return parent::get_url(); + } + + /** * Function for preparing the data for insertion in an SQL query * (The service handles insertion) * diff --git a/phpBB/phpbb/notification/type/quote.php b/phpBB/phpbb/notification/type/quote.php index 745430e114..f4b4d763eb 100644 --- a/phpBB/phpbb/notification/type/quote.php +++ b/phpBB/phpbb/notification/type/quote.php @@ -113,29 +113,6 @@ class quote extends \phpbb\notification\type\post $notify_users = $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], $options); - // Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications - $update_notifications = array(); - $sql = 'SELECT n.* - 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.notification_read = 0 - AND nt.notification_type_id = n.notification_type_id - AND nt.notification_type_enabled = 1'; - $result = $this->db->sql_query($sql); - while ($row = $this->db->sql_fetchrow($result)) - { - // Do not create a new notification - unset($notify_users[$row['user_id']]); - - $notification = $this->notification_manager->get_item_type_class($this->get_type(), $row); - $sql = 'UPDATE ' . $this->notifications_table . ' - SET ' . $this->db->sql_build_array('UPDATE', $notification->add_responders($post)) . ' - WHERE notification_id = ' . $row['notification_id']; - $this->db->sql_query($sql); - } - $this->db->sql_freeresult($result); - return $notify_users; } @@ -191,6 +168,14 @@ class quote extends \phpbb\notification\type\post } /** + * {inheritDoc} + */ + public function get_redirect_url() + { + return $this->get_url(); + } + + /** * Get email template * * @return string|bool diff --git a/phpBB/phpbb/notification/type/type_interface.php b/phpBB/phpbb/notification/type/type_interface.php index e3e6898172..2f465aae2b 100644 --- a/phpBB/phpbb/notification/type/type_interface.php +++ b/phpBB/phpbb/notification/type/type_interface.php @@ -99,6 +99,13 @@ interface type_interface public function get_url(); /** + * Get the url to redirect after the item has been marked as read + * + * @return string URL + */ + public function get_redirect_url(); + + /** * URL to unsubscribe to this notification * * @param string|bool $method Method name to unsubscribe from (email|jabber|etc), False to unsubscribe from all notifications for this item diff --git a/phpBB/phpbb/path_helper.php b/phpBB/phpbb/path_helper.php index a8e12c4063..f92c2b72b2 100644 --- a/phpBB/phpbb/path_helper.php +++ b/phpBB/phpbb/path_helper.php @@ -149,6 +149,16 @@ class path_helper $script_name = $this->symfony_request->getScriptName(); /* + * If the path info is empty but we're using app.php, then we + * might be using an empty route like app.php/ which is + * supported by symfony's routing + */ + if ($path_info === '/' && preg_match('/app\.' . $this->php_ext . '\/$/', $request_uri)) + { + return $this->web_root_path = $this->phpbb_root_path . '../'; + } + + /* * If the path info is empty (single /), then we're not using * a route like app.php/foo/bar */ @@ -206,4 +216,120 @@ class path_helper return $scheme . $this->filesystem->clean_path($path); } + + /** + * Glue URL parameters together + * + * @param array $params URL parameters in the form of array(name => value) + * @return string Returns the glued string, e.g. name1=value1&name2=value2 + */ + public function glue_url_params($params) + { + $_params = array(); + + foreach ($params as $key => $value) + { + $_params[] = $key . '=' . $value; + } + return implode('&', $_params); + } + + /** + * Get the base and parameters of a URL + * + * @param string $url URL to break apart + * @param bool $is_amp Is the parameter separator &. Defaults to true. + * @return array Returns the base and parameters in the form of array('base' => string, 'params' => array(name => value)) + */ + public function get_url_parts($url, $is_amp = true) + { + $separator = ($is_amp) ? '&' : '&'; + $params = array(); + + if (strpos($url, '?') !== false) + { + $base = substr($url, 0, strpos($url, '?')); + $args = substr($url, strlen($base) + 1); + $args = ($args) ? explode($separator, $args) : array(); + + foreach ($args as $argument) + { + if (empty($argument)) + { + continue; + } + list($key, $value) = explode('=', $argument, 2); + + if ($key === '') + { + continue; + } + + $params[$key] = $value; + } + } + else + { + $base = $url; + } + + return array( + 'base' => $base, + 'params' => $params, + ); + } + + /** + * Strip parameters from an already built URL. + * + * @param string $url URL to strip parameters from + * @param array|string $strip Parameters to strip. + * @param bool $is_amp Is the parameter separator &. Defaults to true. + * @return string Returns the new URL. + */ + public function strip_url_params($url, $strip, $is_amp = true) + { + $url_parts = $this->get_url_parts($url, $is_amp); + $params = $url_parts['params']; + + if (!is_array($strip)) + { + $strip = array($strip); + } + + if (!empty($params)) + { + // Strip the parameters off + foreach ($strip as $param) + { + unset($params[$param]); + } + } + + return $url_parts['base'] . (($params) ? '?' . $this->glue_url_params($params) : ''); + } + + /** + * Append parameters to an already built URL. + * + * @param string $url URL to append parameters to + * @param array $new_params Parameters to add in the form of array(name => value) + * @param string $is_amp Is the parameter separator &. Defaults to true. + * @return string Returns the new URL. + */ + public function append_url_params($url, $new_params, $is_amp = true) + { + $url_parts = $this->get_url_parts($url, $is_amp); + $params = array_merge($url_parts['params'], $new_params); + + // Move the sid to the end if it's set + if (isset($params['sid'])) + { + $sid = $params['sid']; + unset($params['sid']); + $params['sid'] = $sid; + } + + return $url_parts['base'] . (($params) ? '?' . $this->glue_url_params($params) : ''); + } } diff --git a/phpBB/phpbb/permissions.php b/phpBB/phpbb/permissions.php index a3fddb0b9e..3cf39b5126 100644 --- a/phpBB/phpbb/permissions.php +++ b/phpBB/phpbb/permissions.php @@ -57,7 +57,7 @@ class permissions * 'lang' => 'ACL_U_VIEWPROFILE', * 'cat' => 'profile', * ), - * @since 3.1-A1 + * @since 3.1.0-a1 */ $vars = array('types', 'categories', 'permissions'); extract($phpbb_dispatcher->trigger_event('core.permissions', compact($vars))); diff --git a/phpBB/phpbb/plupload/plupload.php b/phpBB/phpbb/plupload/plupload.php index 6bff2b8a7e..b988ce7ce0 100644 --- a/phpBB/phpbb/plupload/plupload.php +++ b/phpBB/phpbb/plupload/plupload.php @@ -146,10 +146,11 @@ class plupload * @param \phpbb\template\template $template * @param string $s_action The URL to submit the POST data to * @param int $forum_id The ID of the forum + * @param int $max_files Maximum number of files allowed. 0 for unlimited. * * @return null */ - public function configure(\phpbb\cache\service $cache, \phpbb\template\template $template, $s_action, $forum_id) + public function configure(\phpbb\cache\service $cache, \phpbb\template\template $template, $s_action, $forum_id, $max_files) { $filters = $this->generate_filter_string($cache, $forum_id); $chunk_size = $this->get_chunk_size(); @@ -161,6 +162,9 @@ class plupload 'FILTERS' => $filters, 'CHUNK_SIZE' => $chunk_size, 'S_PLUPLOAD_URL' => htmlspecialchars_decode($s_action), + 'MAX_ATTACHMENTS' => $max_files, + 'ATTACH_ORDER' => ($this->config['display_order']) ? 'asc' : 'desc', + 'L_TOO_MANY_ATTACHMENTS' => $this->user->lang('TOO_MANY_ATTACHMENTS', $max_files), )); $this->user->add_lang('plupload'); diff --git a/phpBB/phpbb/profilefields/lang_helper.php b/phpBB/phpbb/profilefields/lang_helper.php index 7bae1bdc18..7ad4722230 100644 --- a/phpBB/phpbb/profilefields/lang_helper.php +++ b/phpBB/phpbb/profilefields/lang_helper.php @@ -23,7 +23,7 @@ class lang_helper /** * Database object - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -36,7 +36,7 @@ class lang_helper /** * Construct * - * @param \phpbb\db\driver\driver $db Database object + * @param \phpbb\db\driver\driver_interface $db Database object * @param string $language_table Table where the language strings are stored */ public function __construct($db, $language_table) diff --git a/phpBB/phpbb/profilefields/manager.php b/phpBB/phpbb/profilefields/manager.php index a4626bc5de..37449c67c4 100644 --- a/phpBB/phpbb/profilefields/manager.php +++ b/phpBB/phpbb/profilefields/manager.php @@ -23,7 +23,7 @@ class manager /** * Database object - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -63,7 +63,7 @@ class manager * Construct * * @param \phpbb\auth\auth $auth Auth object - * @param \phpbb\db\driver\driver $db Database object + * @param \phpbb\db\driver\driver_interface $db Database object * @param \phpbb\request\request $request Request object * @param \phpbb\template\template $template Template object * @param \phpbb\di\service_collection $type_collection @@ -72,7 +72,7 @@ class manager * @param string $fields_language_table * @param string $fields_data_table */ - public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver $db, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\di\service_collection $type_collection, \phpbb\user $user, $fields_table, $fields_language_table, $fields_data_table) + public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\di\service_collection $type_collection, \phpbb\user $user, $fields_table, $fields_language_table, $fields_data_table) { $this->auth = $auth; $this->db = $db; @@ -231,6 +231,7 @@ class manager if (!$this->db->sql_affectedrows()) { + $cp_data = $this->build_insert_sql_array($cp_data); $cp_data['user_id'] = (int) $user_id; $this->db->sql_return_on_error(true); diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php index 509b73e26e..e5b0c89cb6 100644 --- a/phpBB/phpbb/search/fulltext_mysql.php +++ b/phpBB/phpbb/search/fulltext_mysql.php @@ -36,7 +36,7 @@ class fulltext_mysql extends \phpbb\search\base /** * Database connection - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index 60180f1728..f3b229cc7c 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -80,7 +80,7 @@ class fulltext_native extends \phpbb\search\base /** * Database connection - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -768,6 +768,7 @@ class fulltext_native extends \phpbb\search\base break; case 'sqlite': + case 'sqlite3': $sql_array_count['SELECT'] = ($type == 'posts') ? 'DISTINCT p.post_id' : 'DISTINCT p.topic_id'; $sql = 'SELECT COUNT(' . (($type == 'posts') ? 'post_id' : 'topic_id') . ') as total_results FROM (' . $this->db->sql_build_query('SELECT', $sql_array_count) . ')'; @@ -997,7 +998,7 @@ class fulltext_native extends \phpbb\search\base } else { - if ($this->db->sql_layer == 'sqlite') + if ($this->db->sql_layer == 'sqlite' || $this->db->sql_layer == 'sqlite3') { $sql = 'SELECT COUNT(topic_id) as total_results FROM (SELECT DISTINCT t.topic_id'; @@ -1014,7 +1015,7 @@ class fulltext_native extends \phpbb\search\base $post_visibility $sql_fora AND t.topic_id = p.topic_id - $sql_time" . (($this->db->sql_layer == 'sqlite') ? ')' : ''); + $sql_time" . (($this->db->sql_layer == 'sqlite' || $this->db->sql_layer == 'sqlite3') ? ')' : ''); } $result = $this->db->sql_query($sql); @@ -1481,6 +1482,7 @@ class fulltext_native extends \phpbb\search\base switch ($this->db->sql_layer) { case 'sqlite': + case 'sqlite3': case 'firebird': $this->db->sql_query('DELETE FROM ' . SEARCH_WORDLIST_TABLE); $this->db->sql_query('DELETE FROM ' . SEARCH_WORDMATCH_TABLE); diff --git a/phpBB/phpbb/search/fulltext_postgres.php b/phpBB/phpbb/search/fulltext_postgres.php index 63caeffcc5..864a53e642 100644 --- a/phpBB/phpbb/search/fulltext_postgres.php +++ b/phpBB/phpbb/search/fulltext_postgres.php @@ -61,7 +61,7 @@ class fulltext_postgres extends \phpbb\search\base /** * Database connection - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php index d86a394326..1501dcdc31 100644 --- a/phpBB/phpbb/search/fulltext_sphinx.php +++ b/phpBB/phpbb/search/fulltext_sphinx.php @@ -77,7 +77,7 @@ class fulltext_sphinx /** * Database connection - * @var \phpbb\db\driver\driver + * @var \phpbb\db\driver\driver_interface */ protected $db; diff --git a/phpBB/phpbb/tree/nestedset.php b/phpBB/phpbb/tree/nestedset.php index 2bfb65732d..9aaee9e468 100644 --- a/phpBB/phpbb/tree/nestedset.php +++ b/phpBB/phpbb/tree/nestedset.php @@ -11,7 +11,7 @@ namespace phpbb\tree; abstract class nestedset implements \phpbb\tree\tree_interface { - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db; /** @var \phpbb\lock\db */ @@ -52,7 +52,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface /** * Construct * - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param \phpbb\lock\db $lock Lock class used to lock the table when moving forums around * @param string $table_name Table name * @param string $message_prefix Prefix for the messages thrown by exceptions @@ -60,7 +60,7 @@ abstract class nestedset implements \phpbb\tree\tree_interface * @param array $item_basic_data Array with basic item data that is stored in item_parents * @param array $columns Array with column names to overwrite */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\lock\db $lock, $table_name, $message_prefix = '', $sql_where = '', $item_basic_data = array(), $columns = array()) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\lock\db $lock, $table_name, $message_prefix = '', $sql_where = '', $item_basic_data = array(), $columns = array()) { $this->db = $db; $this->lock = $lock; diff --git a/phpBB/phpbb/tree/nestedset_forum.php b/phpBB/phpbb/tree/nestedset_forum.php index ef6023546b..5973b0b6d9 100644 --- a/phpBB/phpbb/tree/nestedset_forum.php +++ b/phpBB/phpbb/tree/nestedset_forum.php @@ -14,11 +14,11 @@ class nestedset_forum extends \phpbb\tree\nestedset /** * Construct * - * @param \phpbb\db\driver\driver $db Database connection + * @param \phpbb\db\driver\driver_interface $db Database connection * @param \phpbb\lock\db $lock Lock class used to lock the table when moving forums around * @param string $table_name Table name */ - public function __construct(\phpbb\db\driver\driver $db, \phpbb\lock\db $lock, $table_name) + public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\lock\db $lock, $table_name) { parent::__construct( $db, diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php index c2dcc9db7a..2f186593ec 100644 --- a/phpBB/phpbb/user.php +++ b/phpBB/phpbb/user.php @@ -153,9 +153,17 @@ class user extends \phpbb\session * that are absolutely needed globally using this * event. Use local events otherwise. * @var mixed style_id Style we are going to display - * @since 3.1-A1 + * @since 3.1.0-a1 */ - $vars = array('user_data', 'user_lang_name', 'user_date_format', 'user_timezone', 'lang_set', 'lang_set_ext', 'style_id'); + $vars = array( + 'user_data', + 'user_lang_name', + 'user_date_format', + 'user_timezone', + 'lang_set', + 'lang_set_ext', + 'style_id', + ); extract($phpbb_dispatcher->trigger_event('core.user_setup', compact($vars))); $this->data = $user_data; diff --git a/phpBB/phpbb/user_loader.php b/phpBB/phpbb/user_loader.php index c1d69802f8..9179572277 100644 --- a/phpBB/phpbb/user_loader.php +++ b/phpBB/phpbb/user_loader.php @@ -19,7 +19,7 @@ namespace phpbb; */ class user_loader { - /** @var \phpbb\db\driver\driver */ + /** @var \phpbb\db\driver\driver_interface */ protected $db = null; /** @var string */ @@ -41,12 +41,12 @@ class user_loader /** * User loader constructor * - * @param \phpbb\db\driver\driver $db A database connection + * @param \phpbb\db\driver\driver_interface $db A database connection * @param string $phpbb_root_path Path to the phpbb includes directory. * @param string $php_ext php file extension * @param string $users_table The name of the database table (phpbb_users) */ - public function __construct(\phpbb\db\driver\driver $db, $phpbb_root_path, $php_ext, $users_table) + public function __construct(\phpbb\db\driver\driver_interface $db, $phpbb_root_path, $php_ext, $users_table) { $this->db = $db; |