diff --git a/phpBB/includes/auth.php b/phpBB/includes/auth.php index ef8245d58c..98aae0236b 100644 --- a/phpBB/includes/auth.php +++ b/phpBB/includes/auth.php @@ -84,7 +84,7 @@ class auth /** * Look up an option - * if the option is prefixed with !, then the result becomes nagated + * if the option is prefixed with !, then the result becomes negated */ function acl_get($opt, $f = 0) { @@ -136,7 +136,7 @@ class auth * Get forums with the specified permission setting * if the option is prefixed with !, then the result becomes nagated * - * @param clean true|false set to true if only values needs to be returned which are set/unset + * @param bool $clean set to true if only values needs to be returned which are set/unset */ function acl_getf($opt, $clean = false) { @@ -240,38 +240,6 @@ class auth return $auth_ary; } - /** - * Get raw group based permission settings - function acl_group_raw_data($group_id = false, $opts = false, $forum_id = false) - { - global $db; - - $sql_group = ($group_id !== false) ? ((!is_array($group_id)) ? "group_id = $group_id" : 'group_id IN (' . implode(', ', $group_id) . ')') : ''; - $sql_forum = ($forum_id !== false) ? ((!is_array($forum_id)) ? "AND a.forum_id = $forum_id" : 'AND a.forum_id IN (' . implode(', ', $forum_id) . ')') : ''; - $sql_opts = ($opts !== false) ? ((!is_array($opts)) ? "AND ao.auth_option = '$opts'" : 'AND ao.auth_option IN (' . implode(', ', preg_replace('#^\s*(.*)\s*$#e', "\"'\" . \$db->sql_escape('\\1') . \"'\"", $opts)) . ')') : ''; - - $hold_ary = array(); - - // Grab group settings... - $sql = 'SELECT a.group_id, ao.auth_option, a.forum_id, a.auth_setting - FROM ' . ACL_OPTIONS_TABLE . ' ao, ' . ACL_GROUPS_TABLE . ' a - WHERE ao.auth_option_id = a.auth_option_id - ' . (($sql_group) ? 'AND a.' . $sql_group : '') . " - $sql_forum - $sql_opts - ORDER BY a.forum_id, ao.auth_option"; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $hold_ary[$row['group_id']][$row['forum_id']][$row['auth_option']] = $row['auth_setting']; - } - $db->sql_freeresult($result); - - return $hold_ary; - } -*/ - /** * Cache data to user_permissions row */ @@ -390,7 +358,20 @@ class auth $sql_user = ($user_id !== false) ? ((!is_array($user_id)) ? "user_id = $user_id" : 'user_id IN (' . implode(', ', $user_id) . ')') : ''; $sql_forum = ($forum_id !== false) ? ((!is_array($forum_id)) ? "AND a.forum_id = $forum_id" : 'AND a.forum_id IN (' . implode(', ', $forum_id) . ')') : ''; - $sql_opts = ($opts !== false) ? ((!is_array($opts)) ? "AND ao.auth_option = '$opts'" : 'AND ao.auth_option IN (' . implode(', ', preg_replace('#^\s*(.*)\s*$#e', "\"'\" . \$db->sql_escape('\\1') . \"'\"", $opts)) . ')') : ''; + + $sql_opts = ''; + + if ($opts !== false) + { + if (!is_array($opts)) + { + $sql_opts = (strpos($opts, '%') !== false) ? "AND ao.auth_option LIKE '" . $db->sql_escape($opts) . "'" : "AND ao.auth_option = '" . $db->sql_escape($opts) . "'"; + } + else + { + $sql_opts = 'AND ao.auth_option IN (' . implode(', ', preg_replace('#^\s*(.*)\s*$#e', "\"'\" . \$db->sql_escape('\\1') . \"'\"", $opts)) . ')'; + } + } $hold_ary = array(); @@ -434,6 +415,49 @@ class auth return $hold_ary; } + /** + * Get raw group based permission settings + */ + function acl_group_raw_data($group_id = false, $opts = false, $forum_id = false) + { + global $db; + + $sql_group = ($group_id !== false) ? ((!is_array($group_id)) ? "group_id = $group_id" : 'group_id IN (' . implode(', ', $group_id) . ')') : ''; + $sql_forum = ($forum_id !== false) ? ((!is_array($forum_id)) ? "AND a.forum_id = $forum_id" : 'AND a.forum_id IN (' . implode(', ', $forum_id) . ')') : ''; + + if ($opts !== false) + { + if (!is_array($opts)) + { + $sql_opts = (strpos($opts, '%') !== false) ? "AND ao.auth_option LIKE '" . $db->sql_escape($opts) . "'" : "AND ao.auth_option = '" . $db->sql_escape($opts) . "'"; + } + else + { + $sql_opts = 'AND ao.auth_option IN (' . implode(', ', preg_replace('#^\s*(.*)\s*$#e', "\"'\" . \$db->sql_escape('\\1') . \"'\"", $opts)) . ')'; + } + } + + $hold_ary = array(); + + // Grab group settings... + $sql = 'SELECT a.group_id, ao.auth_option, a.forum_id, a.auth_setting + FROM ' . ACL_OPTIONS_TABLE . ' ao, ' . ACL_GROUPS_TABLE . ' a + WHERE ao.auth_option_id = a.auth_option_id + ' . (($sql_group) ? 'AND a.' . $sql_group : '') . " + $sql_forum + $sql_opts + ORDER BY a.forum_id, ao.auth_option"; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $hold_ary[$row['group_id']][$row['forum_id']][$row['auth_option']] = $row['auth_setting']; + } + $db->sql_freeresult($result); + + return $hold_ary; + } + /** * Authentication plug-ins is largely down to Sergey Kanareykin, our thanks to him. * @todo replace this with a new system @@ -470,4 +494,325 @@ class auth } } +/** +* @package phpBB3 +*/ +class auth_admin extends auth +{ + /** + * Init auth settings + */ + function auth_admin() + { + global $db, $cache; + + if (($this->acl_options = $cache->get('acl_options')) === false) + { + $sql = 'SELECT auth_option, is_global, is_local + FROM ' . ACL_OPTIONS_TABLE . ' + ORDER BY auth_option_id'; + $result = $db->sql_query($sql); + + $global = $local = 0; + while ($row = $db->sql_fetchrow($result)) + { + if ($row['is_global']) + { + $this->acl_options['global'][$row['auth_option']] = $global++; + } + + if ($row['is_local']) + { + $this->acl_options['local'][$row['auth_option']] = $local++; + } + } + $db->sql_freeresult($result); + + $cache->put('acl_options', $this->acl_options); + } + } + + /** + * Get permission mask + * This function only supports getting permissions of one type (for example a_%) + * + * @param user|forum|admin|mod_global|mod_local|custom $mode defining the permission mask to get (custom uses $auth_option and $scope) + * @param mixed $user_id user ids to search for (a user_id or a group_id has to be specified at least) + * @param mixed $group_id group ids to search for, return group related settings (a user_id or a group_id has to be specified at least) + * @param mixed $forum_id forum_ids to search for. Defining a forum id also means getting local settings (required for the modes forum and mod_local) + * @param string $auth_option if mode is 'custom' the auth_option defines the permission setting to look after + * @param local|global $scope if mode is 'custom' the scope defines the permission scope. If local, a forum_id is additionally required + */ + function get_mask($mode, $user_id = false, $group_id = false, $forum_id = false, $auth_option = false, $scope = false) + { + global $db; + + $hold_ary = array(); + $auth_option = ''; + + switch ($mode) + { + // Custom (not known) permissions + case 'custom': + + if ($auth_option === false || $scope === false) + { + return array(); + } + + if ($forum_id !== false) + { + $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, $auth_option . '%', $forum_id) : $this->acl_raw_data($user_id, $auth_option . '%', $forum_id); + } + else + { + $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, $auth_option . '%') : $this->acl_raw_data($user_id, $auth_option . '%'); + } + + break; + + // User Permission Mask + case 'user': + + if ($group_id === false && $user_id === false) + { + return array(); + } + + $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, 'u_%') : $this->acl_raw_data($user_id, 'u_%'); + + $auth_option = 'u_'; + $scope = 'global'; + + break; + + // Forum Permission Mask (User/Group based) + case 'forum': + + if ($forum_id === false && ($group_id === false || $user_id === false)) + { + return array(); + } + + $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, 'f_%', $forum_id) : $this->acl_raw_data($user_id, 'f_%', $forum_id); + + $auth_option = 'f_'; + $scope = 'local'; + + break; + + // Admin Permission Mask + case 'admin': + + if ($group_id === false && $user_id === false) + { + return array(); + } + + $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, 'a_%') : $this->acl_raw_data($user_id, 'a_%'); + + $auth_option = 'a_'; + $scope = 'global'; + + break; + + case 'mod_global': + + if ($group_id === false && $user_id === false) + { + return array(); + } + + $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, 'm_%') : $this->acl_raw_data($user_id, 'm_%'); + + $auth_option = 'm_'; + $scope = 'global'; + + break; + + case 'mod_local': + + if ($forum_id === false && ($group_id === false || $user_id === false)) + { + return array(); + } + + $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, 'm_%', $forum_id) : $this->acl_raw_data($user_id, 'm_%', $forum_id); + + $auth_option = 'm_'; + $scope = 'local'; + + break; + } + + // Make sure hold_ary is filled with every setting (prevents missing forums/users/groups) + $ug_id = ($group_id !== false) ? ((!is_array($group_id)) ? array($group_id) : $group_id) : ((!is_array($user_id)) ? array($user_id) : $user_id); + $forum_ids = ($forum_id !== false) ? ((!is_array($forum_id)) ? array($forum_id) : $forum_id) : array(0); + + foreach ($ug_id as $_id) + { + if (!isset($hold_ary[$_id])) + { + $hold_ary[$_id] = array(); + } + + foreach ($forum_ids as $f_id) + { + if (!isset($hold_ary[$_id][$f_id])) + { + $hold_ary[$_id][$f_id] = array(); + } + } + } + + // Now, we need to fill the gaps with ACL_NO. ;) + + // Only those options we need + $compare_options = array_diff(preg_replace('/^((?!' . $auth_option . ').+)|(' . $auth_option . ')$/', '', array_keys($this->acl_options[$scope])), array('')); + + // Now switch back to keys + if (sizeof($compare_options)) + { + $compare_options = array_combine($compare_options, array_fill(1, sizeof($compare_options), 0)); + } + + // Actually fill the gaps + if (sizeof($hold_ary)) + { + foreach ($hold_ary as $ug_id => $row) + { + foreach ($row as $id => $options) + { + // Not a "fine" solution, but at all it's a 1-dimensional + // array_diff_key function filling the resulting array values with zeros + // The differences get merged into $hold_ary (all permissions having ACL_NO set) + $hold_ary[$ug_id][$id] = array_merge($options, + + array_map(create_function('$value', 'return 0;'), + array_flip( + array_diff( + array_keys($compare_options), array_keys($options) + ) + ) + ) + ); + } + } + } + else + { + $hold_ary[($group_id !== false) ? $group_id : $user_id][(int) $forum_id] = $compare_options; + } + + return $hold_ary; + } + + /** + * NOTE: this function is not in use atm + * Add a new option to the list ... $options is a hash of form -> + * $options = array( + * 'local' => array('option1', 'option2', ...), + * 'global' => array('optionA', 'optionB', ...) + * ); + */ + function acl_add_option($options) + { + global $db, $cache; + + if (!is_array($options)) + { + return false; + } + + $cur_options = array(); + + $sql = 'SELECT auth_option, is_global, is_local + FROM ' . ACL_OPTIONS_TABLE . ' + ORDER BY auth_option_id'; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + if ($row['is_global']) + { + $cur_options['global'][] = $row['auth_option']; + } + + if ($row['is_local']) + { + $cur_options['local'][] = $row['auth_option']; + } + } + $db->sql_freeresult($result); + + // Here we need to insert new options ... this requires discovering whether + // an options is global, local or both and whether we need to add an permission + // set flag (x_) + $new_options = array('local' => array(), 'global' => array()); + + foreach ($options as $type => $option_ary) + { + $option_ary = array_unique($option_ary); + + foreach ($option_ary as $option_value) + { + if (!in_array($option_value, $cur_options[$type])) + { + $new_options[$type][] = $option_value; + } + + $flag = substr($option_value, 0, strpos($option_value, '_') + 1); + + if (!in_array($flag, $cur_options[$type]) && !in_array($flag, $new_options[$type])) + { + $new_options[$type][] = $flag; + } + } + } + unset($options); + + $options = array(); + $options['local'] = array_diff($new_options['local'], $new_options['global']); + $options['global'] = array_diff($new_options['global'], $new_options['local']); + $options['local_global'] = array_intersect($new_options['local'], $new_options['global']); + + $sql_ary = array(); + + foreach ($options as $type => $option_ary) + { + foreach ($option_ary as $option) + { + $sql_ary[] = array( + 'auth_option' => $option, + 'is_global' => ($type == 'global' || $type == 'local_global') ? 1 : 0, + 'is_local' => ($type == 'local' || $type == 'local_global') ? 1 : 0 + ); + } + } + + if (sizeof($sql_ary)) + { + switch (SQL_LAYER) + { + case 'mysql': + case 'mysql4': + case 'mysqli': + $db->sql_query('INSERT INTO ' . ACL_OPTIONS_TABLE . ' ' . $db->sql_build_array('MULTI_INSERT', $sql_ary)); + break; + + default: + foreach ($sql_ary as $ary) + { + $db->sql_query('INSERT INTO ' . ACL_OPTIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $ary)); + } + break; + } + } + + $cache->destroy('acl_options'); + + return true; + } +} + ?> \ No newline at end of file diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php index e38255d7d5..f58dfe95fa 100644 --- a/phpBB/includes/functions_admin.php +++ b/phpBB/includes/functions_admin.php @@ -2059,175 +2059,6 @@ function view_warned_users(&$users, &$user_count, $limit = 0, $offset = 0, $limi return; } -/* -if (class_exists('auth')) -{ - class auth_admin extends auth - { - // Set a user or group ACL record - function acl_set($ug_type, &$forum_id, &$ug_id, &$auth) - { - global $db; - - // One or more forums - if (!is_array($forum_id)) - { - $forum_id = array($forum_id); - } - - // Set any flags as required - foreach ($auth as $auth_option => $setting) - { - $flag = substr($auth_option, 0, strpos($auth_option, '_') + 1); - if (empty($auth[$flag])) - { - $auth[$flag] = $setting; - } - } - - $sql = 'SELECT auth_option_id, auth_option - FROM ' . ACL_OPTIONS_TABLE; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $option_ids[$row['auth_option']] = $row['auth_option_id']; - } - $db->sql_freeresult($result); - - $sql_forum = 'AND a.forum_id IN (' . implode(', ', array_map('intval', $forum_id)) . ')'; - - $sql = ($ug_type == 'user') ? 'SELECT o.auth_option_id, o.auth_option, a.forum_id, a.auth_setting FROM ' . ACL_USERS_TABLE . ' a, ' . ACL_OPTIONS_TABLE . " o WHERE a.auth_option_id = o.auth_option_id $sql_forum AND a.user_id = $ug_id" : 'SELECT o.auth_option_id, o.auth_option, a.forum_id, a.auth_setting FROM ' . ACL_GROUPS_TABLE . ' a, ' . ACL_OPTIONS_TABLE . " o WHERE a.auth_option_id = o.auth_option_id $sql_forum AND a.group_id = $ug_id"; - $result = $db->sql_query($sql); - - $cur_auth = array(); - while ($row = $db->sql_fetchrow($result)) - { - $cur_auth[$row['forum_id']][$row['auth_option_id']] = $row['auth_setting']; - } - $db->sql_freeresult($result); - - $table = ($ug_type == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE; - $id_field = $ug_type . '_id'; - - $sql_ary = array(); - foreach ($forum_id as $forum) - { - foreach ($auth as $auth_option => $setting) - { - $auth_option_id = $option_ids[$auth_option]; - - switch ($setting) - { - case ACL_UNSET: - if (isset($cur_auth[$forum][$auth_option_id])) - { - $sql_ary['delete'][] = "DELETE FROM $table - WHERE forum_id = $forum - AND auth_option_id = $auth_option_id - AND $id_field = $ug_id"; - } - break; - - default: - if (!isset($cur_auth[$forum][$auth_option_id])) - { - $sql_ary['insert'][] = "$ug_id, $forum, $auth_option_id, $setting"; - } - else if ($cur_auth[$forum][$auth_option_id] != $setting) - { - $sql_ary['update'][] = "UPDATE " . $table . " - SET auth_setting = $setting - WHERE $id_field = $ug_id - AND forum_id = $forum - AND auth_option_id = $auth_option_id"; - } - } - } - } - unset($cur_auth); - - $sql = ''; - foreach ($sql_ary as $sql_type => $sql_subary) - { - switch ($sql_type) - { - case 'insert': - switch (SQL_LAYER) - { - case 'mysql': - $sql = 'VALUES ' . implode(', ', preg_replace('#^(.*?)$#', '(\1)', $sql_subary)); - break; - - case 'mysql4': - case 'mysqli': - case 'mssql': - case 'mssql_odbc': - case 'sqlite': - $sql = implode(' UNION ALL ', preg_replace('#^(.*?)$#', 'SELECT \1', $sql_subary)); - break; - - default: - foreach ($sql_subary as $sql) - { - $sql = "INSERT INTO $table ($id_field, forum_id, auth_option_id, auth_setting) VALUES ($sql)"; - $db->sql_query($sql); - $sql = ''; - } - } - - if ($sql != '') - { - $sql = "INSERT INTO $table ($id_field, forum_id, auth_option_id, auth_setting) $sql"; - $db->sql_query($sql); - } - break; - - case 'update': - case 'delete': - foreach ($sql_subary as $sql) - { - $result = $db->sql_query($sql); - $sql = ''; - } - break; - } - unset($sql_ary[$sql_type]); - } - unset($sql_ary); - - $this->acl_clear_prefetch(); - } - - function acl_delete($mode, &$forum_id, &$ug_id, $auth_ids = false) - { - global $db; - - // One or more forums - if (!is_array($forum_id)) - { - $forum_id = array($forum_id); - } - - $auth_sql = ($auth_ids) ? ' AND auth_option_id IN (' . implode(', ', array_map('intval', $auth_ids)) . ')' : ''; - - $table = ($mode == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE; - $id_field = $mode . '_id'; - - foreach ($forum_id as $forum) - { - $sql = "DELETE FROM $table - WHERE $id_field = $ug_id - AND forum_id = $forum - $auth_sql"; - $db->sql_query($sql); - } - - $this->acl_clear_prefetch(); - } -} -*/ - /** * Update Post Informations (First/Last Post in topic/forum) * Should be used instead of sync() if only the last post informations are out of sync... faster diff --git a/phpBB/includes/message_parser.php b/phpBB/includes/message_parser.php index cb7b898d12..e8d2a93444 100644 --- a/phpBB/includes/message_parser.php +++ b/phpBB/includes/message_parser.php @@ -312,7 +312,7 @@ class bbcode_firstpass extends bbcode } // Because highlight_string is specialcharing the text (but we already did this before), we have to reverse this in order to get correct results - $code = strtr($code, array_flip(get_html_translation_table(HTML_ENTITIES))); + $code = html_entity_decode($code); ob_start(); highlight_string($code); diff --git a/phpBB/memberlist.php b/phpBB/memberlist.php index 1c5e78b5de..f23543ea89 100644 --- a/phpBB/memberlist.php +++ b/phpBB/memberlist.php @@ -671,7 +671,7 @@ switch ($mode) 'FROM_USERNAME' => stripslashes($user->data['username']), 'TO_USERNAME' => ($topic_id) ? stripslashes($name) : stripslashes($row['username']), 'MESSAGE' => $message, - 'TOPIC_NAME' => ($topic_id) ? strtr($row['topic_title'], array_flip(get_html_translation_table(HTML_ENTITIES))) : '', + 'TOPIC_NAME' => ($topic_id) ? html_entity_decode($row['topic_title']) : '', 'U_TOPIC' => ($topic_id) ? generate_board_url() . "/viewtopic.$phpEx?f=" . $row['forum_id'] . "&t=$topic_id" : '') ); diff --git a/phpBB/posting.php b/phpBB/posting.php index 36e4ff1dd0..276db4355d 100644 --- a/phpBB/posting.php +++ b/phpBB/posting.php @@ -250,7 +250,7 @@ if ($sql) { $sql = 'SELECT draft_id FROM ' . DRAFTS_TABLE . ' - WHERE (forum_id = ' . $forum_id . (($topic_id) ? " OR topic_id = $topic_id" : '') . ') + WHERE (forum_id IN (' . $forum_id . ', 0)' . (($topic_id) ? " OR topic_id = $topic_id" : '') . ') AND user_id = ' . $user->data['user_id'] . (($draft_id) ? " AND draft_id <> $draft_id" : ''); $result = $db->sql_query_limit($sql, 1); @@ -486,8 +486,8 @@ if ($draft_id && $user->data['is_registered'] && $auth->acl_get('u_savedrafts')) if ($row = $db->sql_fetchrow($result)) { - $_REQUEST['subject'] = strtr($row['draft_subject'], array_flip(get_html_translation_table(HTML_ENTITIES))); - $_POST['message'] = strtr($row['draft_message'], array_flip(get_html_translation_table(HTML_ENTITIES))); + $_REQUEST['subject'] = html_entity_decode($row['draft_subject']); + $_REQUEST['message'] = html_entity_decode($row['draft_message']); $refresh = true; $template->assign_var('S_DRAFT_LOADED', true); }