From 2f53761eaf8fd6991a7af4e31c8ecefe30013cab Mon Sep 17 00:00:00 2001 From: rxu Date: Sun, 3 Jul 2016 01:26:42 +0700 Subject: [ticket/14703] Fix parent module selection for custom extension modules PHPBB3-14703 --- phpBB/phpbb/db/migration/tool/module.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 035625b095..d01b659a0e 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -210,12 +210,15 @@ class module implements \phpbb\db\migration\tool\tool_interface } // The "manual" way + // More than 1 module with the same module_basename may exist + // Thus use empty module_basename to select a category as a parent if (!is_numeric($parent)) { $sql = 'SELECT module_id FROM ' . $this->modules_table . " WHERE module_langname = '" . $this->db->sql_escape($parent) . "' - AND module_class = '" . $this->db->sql_escape($class) . "'"; + AND module_class = '" . $this->db->sql_escape($class) . "' + AND module_basename = ''"; $result = $this->db->sql_query($sql); $module_id = $this->db->sql_fetchfield('module_id'); $this->db->sql_freeresult($result); -- cgit v1.2.1 From a3c10f575ba09b63de044edce835fbdd423fec63 Mon Sep 17 00:00:00 2001 From: rxu Date: Sun, 3 Jul 2016 02:23:34 +0700 Subject: [ticket/14703] Fix parent module selection for custom modules removal PHPBB3-14703 --- phpBB/phpbb/db/migration/tool/module.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index d01b659a0e..64c37fe894 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -95,7 +95,8 @@ class module implements \phpbb\db\migration\tool\tool_interface $sql = 'SELECT module_id FROM ' . $this->modules_table . " WHERE module_langname = '" . $this->db->sql_escape($parent) . "' - AND module_class = '" . $this->db->sql_escape($class) . "'"; + AND module_class = '" . $this->db->sql_escape($class) . "' + AND module_basename = ''"; $result = $this->db->sql_query($sql); $module_id = $this->db->sql_fetchfield('module_id'); $this->db->sql_freeresult($result); @@ -384,7 +385,8 @@ class module implements \phpbb\db\migration\tool\tool_interface $sql = 'SELECT module_id FROM ' . $this->modules_table . " WHERE module_langname = '" . $this->db->sql_escape($parent) . "' - AND module_class = '" . $this->db->sql_escape($class) . "'"; + AND module_class = '" . $this->db->sql_escape($class) . "' + AND module_basename = ''"; $result = $this->db->sql_query($sql); $module_id = $this->db->sql_fetchfield('module_id'); $this->db->sql_freeresult($result); -- cgit v1.2.1 From 652e3da28d11157fe281c1252c74575798cf852f Mon Sep 17 00:00:00 2001 From: rxu Date: Sun, 3 Jul 2016 17:29:15 +0700 Subject: [ticket/14703] Refine the parent module selection for custom extension modules PHPBB3-14703 --- phpBB/language/en/migrator.php | 2 + phpBB/phpbb/db/migration/tool/module.php | 150 ++++++++++++++++--------------- 2 files changed, 81 insertions(+), 71 deletions(-) diff --git a/phpBB/language/en/migrator.php b/phpBB/language/en/migrator.php index 244a5faadf..f3f19f63c0 100644 --- a/phpBB/language/en/migrator.php +++ b/phpBB/language/en/migrator.php @@ -60,6 +60,8 @@ $lang = array_merge($lang, array( 'MIGRATION_INVALID_DATA_UNDEFINED_METHOD' => 'A migration is invalid. An undefined migration tool method was encountered.', 'MODULE_ERROR' => 'An error occurred while creating a module: %s', + 'MODULE_EXISTS' => 'A module already exists: %s', + 'MODULE_EXIST_MULTIPLE' => 'Several modules with the given parent module langname already exist: %s. Try using before/after keys to clarify the module placement.', 'MODULE_INFO_FILE_NOT_EXIST' => 'A required module info file is missing: %2$s', 'MODULE_NOT_EXIST' => 'A required module does not exist: %s', diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 64c37fe894..ed8162b81e 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -36,6 +36,9 @@ class module implements \phpbb\db\migration\tool\tool_interface /** @var string */ protected $modules_table; + /** @var array */ + protected $module_categories = array(); + /** * Constructor * @@ -87,31 +90,8 @@ class module implements \phpbb\db\migration\tool\tool_interface $parent_sql = ''; if ($parent !== false) { - // Allows '' to be sent as 0 - $parent = $parent ?: 0; - - if (!is_numeric($parent)) - { - $sql = 'SELECT module_id - FROM ' . $this->modules_table . " - WHERE module_langname = '" . $this->db->sql_escape($parent) . "' - AND module_class = '" . $this->db->sql_escape($class) . "' - AND module_basename = ''"; - $result = $this->db->sql_query($sql); - $module_id = $this->db->sql_fetchfield('module_id'); - $this->db->sql_freeresult($result); - - if (!$module_id) - { - return false; - } - - $parent_sql = 'AND parent_id = ' . (int) $module_id; - } - else - { - $parent_sql = 'AND parent_id = ' . (int) $parent; - } + $parent = $this->get_parent_module_id($parent); + $parent_sql = 'AND parent_id = ' . (int) $parent; } $sql = 'SELECT module_id @@ -172,15 +152,14 @@ class module implements \phpbb\db\migration\tool\tool_interface */ public function add($class, $parent = 0, $data = array()) { - // Allows '' to be sent as 0 - $parent = $parent ?: 0; - // allow sending the name as a string in $data to create a category if (!is_array($data)) { $data = array('module_langname' => $data); } + $parent = $data['parent_id'] = $this->get_parent_module_id($parent); + if (!isset($data['module_langname'])) { // The "automatic" way @@ -211,34 +190,14 @@ class module implements \phpbb\db\migration\tool\tool_interface } // The "manual" way - // More than 1 module with the same module_basename may exist - // Thus use empty module_basename to select a category as a parent - if (!is_numeric($parent)) - { - $sql = 'SELECT module_id - FROM ' . $this->modules_table . " - WHERE module_langname = '" . $this->db->sql_escape($parent) . "' - AND module_class = '" . $this->db->sql_escape($class) . "' - AND module_basename = ''"; - $result = $this->db->sql_query($sql); - $module_id = $this->db->sql_fetchfield('module_id'); - $this->db->sql_freeresult($result); - - if (!$module_id) - { - throw new \phpbb\db\migration\exception('MODULE_NOT_EXIST', $parent); - } - - $parent = $data['parent_id'] = $module_id; - } - else if (!$this->exists($class, false, $parent)) + if (!$this->exists($class, false, $parent)) { throw new \phpbb\db\migration\exception('MODULE_NOT_EXIST', $parent); } if ($this->exists($class, $parent, $data['module_langname'])) { - return; + throw new \phpbb\db\migration\exception('MODULE_EXISTS', $module_id); } if (!class_exists('acp_modules')) @@ -377,27 +336,8 @@ class module implements \phpbb\db\migration\tool\tool_interface $parent_sql = ''; if ($parent !== false) { - // Allows '' to be sent as 0 - $parent = ($parent) ?: 0; - - if (!is_numeric($parent)) - { - $sql = 'SELECT module_id - FROM ' . $this->modules_table . " - WHERE module_langname = '" . $this->db->sql_escape($parent) . "' - AND module_class = '" . $this->db->sql_escape($class) . "' - AND module_basename = ''"; - $result = $this->db->sql_query($sql); - $module_id = $this->db->sql_fetchfield('module_id'); - $this->db->sql_freeresult($result); - - // we know it exists from the module_exists check - $parent_sql = 'AND parent_id = ' . (int) $module_id; - } - else - { - $parent_sql = 'AND parent_id = ' . (int) $parent; - } + $parent = $this->get_parent_module_id($parent); + $parent_sql = 'AND parent_id = ' . (int) $parent; } $module_ids = array(); @@ -492,4 +432,72 @@ class module implements \phpbb\db\migration\tool\tool_interface return array_pop($module); } + + /** + * Get the list of installed module categories + * key - module_langname + * value - module_id + * + * @return null + */ + protected function get_categories_list() + { + // Select the top level categories + // and 2nd level [sub]categories which exist for ACP only + $sql = 'SELECT m2.module_id, m2.module_langname + FROM ' . $this->modules_table . ' m1, ' . $this->modules_table . " m2 + WHERE m1.parent_id = 0 + AND (m1.module_id = m2.module_id + OR m2.module_class = 'acp' AND m2.parent_id = m1.module_id) + ORDER BY m1.module_id, m2.module_id ASC"; + + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $this->module_categories[(int) $row['module_id']] = $row['module_langname']; + } + $this->db->sql_freeresult($result); + } + + /** + * Get parent module id + * + * @param string|int $parent_id The parent module_id|module_langname + * @return int The parent module_id + * @throws \phpbb\db\migration\exception + */ + public function get_parent_module_id($parent_id) + { + // Allow '' to be sent as 0 + $parent_id = $parent_id ?: 0; + + if (!is_numeric($parent_id)) + { + // Refresh the $module_categories array + $this->get_categories_list(); + + // Search for the parent module_langname + $ids = array_keys($this->module_categories, $parent_id); + + switch (sizeof($ids)) + { + // No parent with the given module_langname exist + case 0: + throw new \phpbb\db\migration\exception('MODULE_NOT_EXIST', $parent_id); + break; + + // Return the module id + case 1: + $parent_id = (int) $ids[0]; + break; + + // Several modules with the given module_langname were found + default: + throw new \phpbb\db\migration\exception('MODULE_EXIST_MULTIPLE', $parent_id); + break; + } + } + + return $parent_id; + } } -- cgit v1.2.1 From eaafb758ce5be55dd762c039fd7a746aa6c64b58 Mon Sep 17 00:00:00 2001 From: rxu Date: Sat, 23 Jul 2016 20:54:16 +0700 Subject: [ticket/14703] Select the parent module id from the several found PHPBB3-14703 --- phpBB/language/en/migrator.php | 1 + phpBB/phpbb/db/migration/tool/module.php | 25 ++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/phpBB/language/en/migrator.php b/phpBB/language/en/migrator.php index f3f19f63c0..4b6a0241e5 100644 --- a/phpBB/language/en/migrator.php +++ b/phpBB/language/en/migrator.php @@ -65,6 +65,7 @@ $lang = array_merge($lang, array( 'MODULE_INFO_FILE_NOT_EXIST' => 'A required module info file is missing: %2$s', 'MODULE_NOT_EXIST' => 'A required module does not exist: %s', + 'PARENT_MODULE_FIND_ERROR' => 'Unable to determine the parent module identifier: %s', 'PERMISSION_NOT_EXIST' => 'The permission setting "%s" unexpectedly does not exist.', 'ROLE_NOT_EXIST' => 'The permission role "%s" unexpectedly does not exist.', diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index ed8162b81e..0869ce37d3 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -158,7 +158,7 @@ class module implements \phpbb\db\migration\tool\tool_interface $data = array('module_langname' => $data); } - $parent = $data['parent_id'] = $this->get_parent_module_id($parent); + $parent = $data['parent_id'] = $this->get_parent_module_id($parent, $data); if (!isset($data['module_langname'])) { @@ -463,10 +463,11 @@ class module implements \phpbb\db\migration\tool\tool_interface * Get parent module id * * @param string|int $parent_id The parent module_id|module_langname + * @param array $data The module data array * @return int The parent module_id * @throws \phpbb\db\migration\exception */ - public function get_parent_module_id($parent_id) + public function get_parent_module_id($parent_id, $data = array()) { // Allow '' to be sent as 0 $parent_id = $parent_id ?: 0; @@ -492,8 +493,26 @@ class module implements \phpbb\db\migration\tool\tool_interface break; // Several modules with the given module_langname were found + // Try to determine the parent_id by the neighbour module parent default: - throw new \phpbb\db\migration\exception('MODULE_EXIST_MULTIPLE', $parent_id); + if (!empty($data) && (isset($data['before']) || isset($data['after']))) + { + $neighbour_module_langname = isset($data['before']) ? $data['before'] : $data['after']; + $sql = 'SELECT parent_id + FROM ' . MODULES_TABLE . ' + WHERE module_langname ' . $this->db->sql_escape($neighbour_module_langname) . ' + AND ' . $this->db->sql_in_set('parent_id', $ids); + $result = $this->db->sql_query($sql); + $parent_id = (int) $this->db->sql_fetchfield('parent_id'); + if (!$parent_id) + { + throw new \phpbb\db\migration\exception('PARENT_MODULE_FIND_ERROR', $data['parent_id']); + } + } + else + { + throw new \phpbb\db\migration\exception('MODULE_EXIST_MULTIPLE', $parent_id); + } break; } } -- cgit v1.2.1 From 8cf2790d5577f7e2398d5017216d3c5540cb0eb0 Mon Sep 17 00:00:00 2001 From: rxu Date: Sun, 24 Jul 2016 00:24:32 +0700 Subject: [ticket/14703] Add test for the case multiple parent module_langname found PHPBB3-14703 --- phpBB/phpbb/db/migration/tool/module.php | 12 ++++--- tests/dbal/fixtures/migrator_module.xml | 54 +++++++++++++++++++++++++++++++- tests/dbal/migrator_tool_module_test.php | 34 ++++++++++++++++++++ 3 files changed, 94 insertions(+), 6 deletions(-) diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 0869ce37d3..67daea5482 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -495,13 +495,13 @@ class module implements \phpbb\db\migration\tool\tool_interface // Several modules with the given module_langname were found // Try to determine the parent_id by the neighbour module parent default: - if (!empty($data) && (isset($data['before']) || isset($data['after']))) + if (isset($data['before']) || isset($data['after'])) { $neighbour_module_langname = isset($data['before']) ? $data['before'] : $data['after']; $sql = 'SELECT parent_id - FROM ' . MODULES_TABLE . ' - WHERE module_langname ' . $this->db->sql_escape($neighbour_module_langname) . ' - AND ' . $this->db->sql_in_set('parent_id', $ids); + FROM ' . MODULES_TABLE . " + WHERE module_langname = '" . $this->db->sql_escape($neighbour_module_langname) . "' + AND " . $this->db->sql_in_set('parent_id', $ids); $result = $this->db->sql_query($sql); $parent_id = (int) $this->db->sql_fetchfield('parent_id'); if (!$parent_id) @@ -509,8 +509,10 @@ class module implements \phpbb\db\migration\tool\tool_interface throw new \phpbb\db\migration\exception('PARENT_MODULE_FIND_ERROR', $data['parent_id']); } } - else + else if (!empty($data)) { + // Only throw exception whhile adding module when the $data is not empty + // Otherwise it's just removing or existance checking and no need for exception throw new \phpbb\db\migration\exception('MODULE_EXIST_MULTIPLE', $parent_id); } break; diff --git a/tests/dbal/fixtures/migrator_module.xml b/tests/dbal/fixtures/migrator_module.xml index 32afe7e6f3..e172d7a145 100644 --- a/tests/dbal/fixtures/migrator_module.xml +++ b/tests/dbal/fixtures/migrator_module.xml @@ -20,7 +20,7 @@ acp 0 1 - 4 + 6 ACP_CAT @@ -38,5 +38,57 @@ test + + 3 + 1 + 1 + + acp + 1 + 4 + 5 + ACP_FORUM_BASED_PERMISSIONS + + + + + 4 + 1 + 1 + + acp + 0 + 7 + 12 + ACP_CAT_FORUMS + + + + + 5 + 1 + 1 + + acp + 4 + 8 + 11 + ACP_FORUM_BASED_PERMISSIONS + + + + + 6 + 1 + 1 + + acp + 5 + 9 + 10 + ACP_FORUM_BASED_PERMISSIONS_CHILD_1 + + + diff --git a/tests/dbal/migrator_tool_module_test.php b/tests/dbal/migrator_tool_module_test.php index 08c3e979b8..bf4ae0b1ee 100644 --- a/tests/dbal/migrator_tool_module_test.php +++ b/tests/dbal/migrator_tool_module_test.php @@ -118,6 +118,40 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case $this->fail($e); } $this->assertEquals(true, $this->tool->exists('acp', 'ACP_NEW_CAT', 'ACP_NEW_MODULE')); + + // Test adding module when plural parent module_langname exists + // PHPBB3-14703 + // Adding fail + try + { + $this->tool->add('acp', 'ACP_FORUM_BASED_PERMISSIONS', array( + 'module_basename' => 'acp_new_permissions_module', + 'module_langname' => 'ACP_NEW_PERMISSIONS_MODULE', + 'module_mode' => 'test', + 'module_auth' => '', + )); + $this->fail('Exception not thrown'); + } + catch (Exception $e) {} + + // Test adding module when plural parent module_langname exists + // PHPBB3-14703 + // Adding success + try + { + $this->tool->add('acp', 'ACP_FORUM_BASED_PERMISSIONS', array( + 'module_basename' => 'acp_new_permissions_module', + 'module_langname' => 'ACP_NEW_PERMISSIONS_MODULE', + 'module_mode' => 'test', + 'module_auth' => '', + 'after' => 'ACP_FORUM_BASED_PERMISSIONS_CHILD_1', + )); + } + catch (Exception $e) + { + $this->fail($e); + } + $this->assertEquals(true, $this->tool->exists('acp', 'ACP_FORUM_BASED_PERMISSIONS', 'ACP_NEW_PERMISSIONS_MODULE')); } public function test_remove() -- cgit v1.2.1 From 5eb493fa86249d865eefe4886b187cf271ffd989 Mon Sep 17 00:00:00 2001 From: rxu Date: Sun, 24 Jul 2016 12:40:55 +0700 Subject: [ticket/14703] Fix existance checking if multiple parent module_langname found PHPBB3-14703 --- phpBB/phpbb/db/migration/tool/module.php | 35 ++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 67daea5482..112c05e968 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -90,7 +90,7 @@ class module implements \phpbb\db\migration\tool\tool_interface $parent_sql = ''; if ($parent !== false) { - $parent = $this->get_parent_module_id($parent); + $parent = $this->get_parent_module_id($parent, $module); $parent_sql = 'AND parent_id = ' . (int) $parent; } @@ -336,7 +336,7 @@ class module implements \phpbb\db\migration\tool\tool_interface $parent_sql = ''; if ($parent !== false) { - $parent = $this->get_parent_module_id($parent); + $parent = $this->get_parent_module_id($parent, $module); $parent_sql = 'AND parent_id = ' . (int) $parent; } @@ -463,15 +463,21 @@ class module implements \phpbb\db\migration\tool\tool_interface * Get parent module id * * @param string|int $parent_id The parent module_id|module_langname - * @param array $data The module data array + * @param int|string|array $data The module_id, module_langname for existance checking or module data array for adding * @return int The parent module_id * @throws \phpbb\db\migration\exception */ - public function get_parent_module_id($parent_id, $data = array()) + public function get_parent_module_id($parent_id, $data = '') { // Allow '' to be sent as 0 $parent_id = $parent_id ?: 0; + // If automatic adding is in action, convert array back to string to simplify things + if (is_array($data) && sizeof($data) == 1) + { + $data = $data['module_langname']; + } + if (!is_numeric($parent_id)) { // Refresh the $module_categories array @@ -495,11 +501,11 @@ class module implements \phpbb\db\migration\tool\tool_interface // Several modules with the given module_langname were found // Try to determine the parent_id by the neighbour module parent default: - if (isset($data['before']) || isset($data['after'])) + if (is_array($data) && (isset($data['before']) || isset($data['after']))) { $neighbour_module_langname = isset($data['before']) ? $data['before'] : $data['after']; $sql = 'SELECT parent_id - FROM ' . MODULES_TABLE . " + FROM ' . $this->modules_table . " WHERE module_langname = '" . $this->db->sql_escape($neighbour_module_langname) . "' AND " . $this->db->sql_in_set('parent_id', $ids); $result = $this->db->sql_query($sql); @@ -509,10 +515,21 @@ class module implements \phpbb\db\migration\tool\tool_interface throw new \phpbb\db\migration\exception('PARENT_MODULE_FIND_ERROR', $data['parent_id']); } } - else if (!empty($data)) + else if (!empty($data) && !is_array($data)) + { + // The module_langname is set, checking for the module existance + // As more than 1 parents were found already, there's no way for null parent_id here + $sql = 'SELECT m2.module_id as module_parent_id + FROM ' . $this->modules_table . ' m1, ' . $this->modules_table . " m2 + WHERE " . ((is_numeric($data)) ? 'm1.module_id = ' . (int) $data : "m1.module_langname = '" . $this->db->sql_escape($data)) . "' + AND m2.module_id = m1.parent_id + AND " . $this->db->sql_in_set('m2.module_id', $ids); + $result = $this->db->sql_query($sql); + $parent_id = (int) $this->db->sql_fetchfield('module_parent_id'); + } + else { - // Only throw exception whhile adding module when the $data is not empty - // Otherwise it's just removing or existance checking and no need for exception + //Unable to get the parent module id, throwing an exception throw new \phpbb\db\migration\exception('MODULE_EXIST_MULTIPLE', $parent_id); } break; -- cgit v1.2.1 From 8e8e25cc1f4f443f6ff945336f534217a5e4339e Mon Sep 17 00:00:00 2001 From: rxu Date: Sun, 24 Jul 2016 23:34:38 +0700 Subject: [ticket/14703] Fix the docblock PHPBB3-14703 --- phpBB/phpbb/db/migration/tool/module.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/phpbb/db/migration/tool/module.php b/phpBB/phpbb/db/migration/tool/module.php index 112c05e968..ff9a18836f 100644 --- a/phpBB/phpbb/db/migration/tool/module.php +++ b/phpBB/phpbb/db/migration/tool/module.php @@ -435,8 +435,8 @@ class module implements \phpbb\db\migration\tool\tool_interface /** * Get the list of installed module categories - * key - module_langname - * value - module_id + * key - module_id + * value - module_langname * * @return null */ -- cgit v1.2.1 From 557f85e7fc3dc299859e846a8f406f0e19aaf465 Mon Sep 17 00:00:00 2001 From: rxu Date: Sun, 28 Aug 2016 21:36:49 +0700 Subject: [ticket/14703] Improve exception testing PHPBB3-14703 --- tests/dbal/migrator_tool_module_test.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/dbal/migrator_tool_module_test.php b/tests/dbal/migrator_tool_module_test.php index bf4ae0b1ee..49dff8b929 100644 --- a/tests/dbal/migrator_tool_module_test.php +++ b/tests/dbal/migrator_tool_module_test.php @@ -132,7 +132,11 @@ class phpbb_dbal_migrator_tool_module_test extends phpbb_database_test_case )); $this->fail('Exception not thrown'); } - catch (Exception $e) {} + catch (Exception $e) + { + $this->assertEquals('phpbb\db\migration\exception', get_class($e)); + $this->assertEquals('MODULE_EXIST_MULTIPLE', $e->getMessage()); + } // Test adding module when plural parent module_langname exists // PHPBB3-14703 -- cgit v1.2.1