diff --git a/phpBB/phpbb/db/migration/tool/permission.php b/phpBB/phpbb/db/migration/tool/permission.php index 66ca2ed0ee..a0ae3ceddf 100644 --- a/phpBB/phpbb/db/migration/tool/permission.php +++ b/phpBB/phpbb/db/migration/tool/permission.php @@ -435,15 +435,14 @@ class permission implements \phpbb\db\migration\tool\tool_interface } $this->db->sql_freeresult($result); - if (empty($new_auth)) + $type = (string) $type; // Prevent PHP bug. + if (empty($new_auth) || !in_array($type, ['role','group'])) { return; } $current_auth = array(); - $type = (string) $type; // Prevent PHP bug. - switch ($type) { case 'role': @@ -525,40 +524,32 @@ class permission implements \phpbb\db\migration\tool\tool_interface break; } - $sql_ary = array(); - switch ($type) + $sql_ary = $auth_update_list = []; + $table = $type == 'role' ? ACL_ROLES_DATA_TABLE : ACL_GROUPS_TABLE; + foreach ($new_auth as $auth_option_id) { - case 'role': - foreach ($new_auth as $auth_option_id) - { - if (!isset($current_auth[$auth_option_id])) - { - $sql_ary[] = array( - 'role_id' => $role_id, - 'auth_option_id' => $auth_option_id, - 'auth_setting' => $has_permission, - ); - } - } + if (!isset($current_auth[$auth_option_id])) + { + $sql_ary[] = [ + $type . '_id' => ${$type . '_id'}, + 'auth_option_id' => $auth_option_id, + 'auth_setting' => (int) $has_permission, + ]; + } + else + { + $auth_update_list[] = $auth_option_id; + } + } + $this->db->sql_multi_insert($table, $sql_ary); - $this->db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary); - break; - - case 'group': - foreach ($new_auth as $auth_option_id) - { - if (!isset($current_auth[$auth_option_id])) - { - $sql_ary[] = array( - 'group_id' => $group_id, - 'auth_option_id' => $auth_option_id, - 'auth_setting' => $has_permission, - ); - } - } - - $this->db->sql_multi_insert(ACL_GROUPS_TABLE, $sql_ary); - break; + if (count($auth_update_list)) + { + $sql = 'UPDATE ' . $table . ' + SET auth_setting = ' . (int) $has_permission . ' + WHERE ' . $this->db->sql_in_set('auth_option_id', $auth_update_list) . ' + AND ' . $type . '_id = ' . (int) ${$type . '_id'}; + $this->db->sql_query($sql); } $this->auth->acl_clear_prefetch(); diff --git a/tests/dbal/migrator_tool_permission_role_test.php b/tests/dbal/migrator_tool_permission_role_test.php index 55bda8c0ce..dc180dc154 100644 --- a/tests/dbal/migrator_tool_permission_role_test.php +++ b/tests/dbal/migrator_tool_permission_role_test.php @@ -28,6 +28,12 @@ class phpbb_dbal_migrator_tool_permission_role_test extends phpbb_database_test_ 'ADMINISTRATORS' => 5, ]; + public $role_ids = [ + 'ROLE_ADMIN_STANDARD' => 1, + 'ROLE_USER_FULL' => 5, + 'ROLE_MOD_FULL' => 10, + ]; + public $new_roles = [ [ 'ROLE_ADMIN_NEW', @@ -196,4 +202,32 @@ class phpbb_dbal_migrator_tool_permission_role_test extends phpbb_database_test_ $this->assertFalse($this->db->sql_fetchfield('auth_role_id')); $this->db->sql_freeresult($result); } + + public function test_copied_permission_set() + { + $sql = 'SELECT rdt.auth_setting + FROM ' . ACL_OPTIONS_TABLE. ' ot, ' . ACL_ROLES_DATA_TABLE . ' rdt + WHERE rdt.role_id = ' . $this->role_ids['ROLE_ADMIN_STANDARD'] . " + AND auth_option = 'u_copied_permission' + AND ot.auth_option_id = rdt.auth_option_id"; + + // Add new local 'u_copied_permission' copied from 'u_test' + // It should be added to the ROLE_ADMIN_STANDARD role automatically similar to 'u_test' permission + $this->tool->add('u_copied_permission', false, 'u_test'); + $this->assertEquals(true, $this->tool->exists('u_copied_permission', false)); + + // Copied permission setting should be equal to what it was copied from + $result = $this->db->sql_query($sql); + $this->assertEquals(0, $this->db->sql_fetchfield('auth_setting')); + $this->db->sql_freeresult($result); + + // Set new permission for copied auth option for the role + $this->tool->permission_set('ROLE_ADMIN_STANDARD', 'u_copied_permission', 'role', true); + + // Copied permission setting should be updated + $result = $this->db->sql_query($sql); + $this->assertEquals(1, $this->db->sql_fetchfield('auth_setting')); + $this->db->sql_freeresult($result); + } + }