phpBB
Statistics
| Revision:

root / branches / phpBB-3_0_0 / phpBB / includes / session.php

History | View | Annotate | Download (76.4 kB)

1 2661 psotfx
<?php
2 7736 acydburn
/**
3 5114 acydburn
*
4 5114 acydburn
* @package phpBB3
5 7736 acydburn
* @version $Id$
6 7736 acydburn
* @copyright (c) 2005 phpBB Group
7 7736 acydburn
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
8 5114 acydburn
*
9 5114 acydburn
*/
10 2661 psotfx
11 5114 acydburn
/**
12 8131 acydburn
* @ignore
13 8131 acydburn
*/
14 8131 acydburn
if (!defined('IN_PHPBB'))
15 8131 acydburn
{
16 8131 acydburn
        exit;
17 8131 acydburn
}
18 8131 acydburn
19 8131 acydburn
/**
20 6058 acydburn
* Session class
21 5237 acydburn
* @package phpBB3
22 5114 acydburn
*/
23 2958 psotfx
class session
24 2958 psotfx
{
25 5175 psotfx
        var $cookie_data = array();
26 6048 acydburn
        var $page = array();
27 6048 acydburn
        var $data = array();
28 2923 psotfx
        var $browser = '';
29 6740 naderman
        var $forwarded_for = '';
30 5859 acydburn
        var $host = '';
31 6048 acydburn
        var $session_id = '';
32 2962 psotfx
        var $ip = '';
33 6048 acydburn
        var $load = 0;
34 5175 psotfx
        var $time_now = 0;
35 6048 acydburn
        var $update_session_page = true;
36 2661 psotfx
37 5175 psotfx
        /**
38 5595 acydburn
        * Extract current session page
39 6048 acydburn
        *
40 6048 acydburn
        * @param string $root_path current root path (phpbb_root_path)
41 5595 acydburn
        */
42 5595 acydburn
        function extract_current_page($root_path)
43 5595 acydburn
        {
44 5595 acydburn
                $page_array = array();
45 5595 acydburn
46 5595 acydburn
                // First of all, get the request uri...
47 5595 acydburn
                $script_name = (!empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : getenv('PHP_SELF');
48 5595 acydburn
                $args = (!empty($_SERVER['QUERY_STRING'])) ? explode('&', $_SERVER['QUERY_STRING']) : explode('&', getenv('QUERY_STRING'));
49 5595 acydburn
50 5595 acydburn
                // If we are unable to get the script name we use REQUEST_URI as a failover and note it within the page array for easier support...
51 5595 acydburn
                if (!$script_name)
52 5595 acydburn
                {
53 5595 acydburn
                        $script_name = (!empty($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : getenv('REQUEST_URI');
54 7910 davidmj
                        $script_name = (($pos = strpos($script_name, '?')) !== false) ? substr($script_name, 0, $pos) : $script_name;
55 6048 acydburn
                        $page_array['failover'] = 1;
56 5595 acydburn
                }
57 5595 acydburn
58 5595 acydburn
                // Replace backslashes and doubled slashes (could happen on some proxy setups)
59 5595 acydburn
                $script_name = str_replace(array('\\', '//'), '/', $script_name);
60 5595 acydburn
61 5595 acydburn
                // Now, remove the sid and let us get a clean query string...
62 8098 acydburn
                $use_args = array();
63 8098 acydburn
64 8098 acydburn
                // Since some browser do not encode correctly we need to do this with some "special" characters...
65 8098 acydburn
                // " -> %22, ' => %27, < -> %3C, > -> %3E
66 8098 acydburn
                $find = array('"', "'", '<', '>');
67 8098 acydburn
                $replace = array('%22', '%27', '%3C', '%3E');
68 8098 acydburn
69 5595 acydburn
                foreach ($args as $key => $argument)
70 5595 acydburn
                {
71 8544 acydburn
                        if (strpos($argument, 'sid=') === 0)
72 5595 acydburn
                        {
73 8098 acydburn
                                continue;
74 5595 acydburn
                        }
75 8098 acydburn
76 8824 toonarmy
                        $use_args[] = str_replace($find, $replace, $argument);
77 5595 acydburn
                }
78 8098 acydburn
                unset($args);
79 5595 acydburn
80 5995 acydburn
                // The following examples given are for an request uri of {path to the phpbb directory}/adm/index.php?i=10&b=2
81 5995 acydburn
82 5595 acydburn
                // The current query string
83 8098 acydburn
                $query_string = trim(implode('&', $use_args));
84 5595 acydburn
85 5595 acydburn
                // basenamed page name (for example: index.php)
86 10574 git-gate
                $page_name = (substr($script_name, -1, 1) == '/') ? '' : basename($script_name);
87 6487 acydburn
                $page_name = urlencode(htmlspecialchars($page_name));
88 5595 acydburn
89 5595 acydburn
                // current directory within the phpBB root (for example: adm)
90 6122 acydburn
                $root_dirs = explode('/', str_replace('\\', '/', phpbb_realpath($root_path)));
91 6122 acydburn
                $page_dirs = explode('/', str_replace('\\', '/', phpbb_realpath('./')));
92 5995 acydburn
                $intersection = array_intersect_assoc($root_dirs, $page_dirs);
93 5595 acydburn
94 5995 acydburn
                $root_dirs = array_diff_assoc($root_dirs, $intersection);
95 5995 acydburn
                $page_dirs = array_diff_assoc($page_dirs, $intersection);
96 5995 acydburn
97 5995 acydburn
                $page_dir = str_repeat('../', sizeof($root_dirs)) . implode('/', $page_dirs);
98 5995 acydburn
99 6015 acydburn
                if ($page_dir && substr($page_dir, -1, 1) == '/')
100 5995 acydburn
                {
101 5995 acydburn
                        $page_dir = substr($page_dir, 0, -1);
102 5995 acydburn
                }
103 5995 acydburn
104 5995 acydburn
                // Current page from phpBB root (for example: adm/index.php?i=10&b=2)
105 6114 acydburn
                $page = (($page_dir) ? $page_dir . '/' : '') . $page_name . (($query_string) ? "?$query_string" : '');
106 5595 acydburn
107 7456 acydburn
                // The script path from the webroot to the current directory (for example: /phpBB3/adm/) : always prefixed with / and ends in /
108 5595 acydburn
                $script_path = trim(str_replace('\\', '/', dirname($script_name)));
109 5595 acydburn
110 7456 acydburn
                // The script path from the webroot to the phpBB root (for example: /phpBB3/)
111 5995 acydburn
                $script_dirs = explode('/', $script_path);
112 5995 acydburn
                array_splice($script_dirs, -sizeof($page_dirs));
113 6930 acydburn
                $root_script_path = implode('/', $script_dirs) . (sizeof($root_dirs) ? '/' . implode('/', $root_dirs) : '');
114 5595 acydburn
115 5595 acydburn
                // We are on the base level (phpBB root == webroot), lets adjust the variables a bit...
116 5595 acydburn
                if (!$root_script_path)
117 5595 acydburn
                {
118 5977 acydburn
                        $root_script_path = ($page_dir) ? str_replace($page_dir, '', $script_path) : $script_path;
119 5595 acydburn
                }
120 5595 acydburn
121 6015 acydburn
                $script_path .= (substr($script_path, -1, 1) == '/') ? '' : '/';
122 6015 acydburn
                $root_script_path .= (substr($root_script_path, -1, 1) == '/') ? '' : '/';
123 6015 acydburn
124 5595 acydburn
                $page_array += array(
125 6114 acydburn
                        'page_name'                        => $page_name,
126 6114 acydburn
                        'page_dir'                        => $page_dir,
127 5595 acydburn
128 5595 acydburn
                        'query_string'                => $query_string,
129 6114 acydburn
                        'script_path'                => str_replace(' ', '%20', htmlspecialchars($script_path)),
130 6114 acydburn
                        'root_script_path'        => str_replace(' ', '%20', htmlspecialchars($root_script_path)),
131 5595 acydburn
132 8436 Kellanved
                        'page'                                => $page,
133 8438 acydburn
                        'forum'                                => (isset($_REQUEST['f']) && $_REQUEST['f'] > 0) ? (int) $_REQUEST['f'] : 0,
134 5595 acydburn
                );
135 5595 acydburn
136 5595 acydburn
                return $page_array;
137 5595 acydburn
        }
138 5595 acydburn
139 5595 acydburn
        /**
140 8846 acydburn
        * Get valid hostname/port. HTTP_HOST is used, SERVER_NAME if HTTP_HOST not present.
141 8846 acydburn
        */
142 8846 acydburn
        function extract_current_hostname()
143 8846 acydburn
        {
144 8846 acydburn
                global $config;
145 8846 acydburn
146 8846 acydburn
                // Get hostname
147 8846 acydburn
                $host = (!empty($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : ((!empty($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : getenv('SERVER_NAME'));
148 8846 acydburn
149 8846 acydburn
                // Should be a string and lowered
150 8846 acydburn
                $host = (string) strtolower($host);
151 8846 acydburn
152 8846 acydburn
                // If host is equal the cookie domain or the server name (if config is set), then we assume it is valid
153 8846 acydburn
                if ((isset($config['cookie_domain']) && $host === $config['cookie_domain']) || (isset($config['server_name']) && $host === $config['server_name']))
154 8846 acydburn
                {
155 8846 acydburn
                        return $host;
156 8846 acydburn
                }
157 8846 acydburn
158 8846 acydburn
                // Is the host actually a IP? If so, we use the IP... (IPv4)
159 8846 acydburn
                if (long2ip(ip2long($host)) === $host)
160 8846 acydburn
                {
161 8846 acydburn
                        return $host;
162 8846 acydburn
                }
163 8846 acydburn
164 8846 acydburn
                // Now return the hostname (this also removes any port definition). The http:// is prepended to construct a valid URL, hosts never have a scheme assigned
165 8846 acydburn
                $host = @parse_url('http://' . $host);
166 8846 acydburn
                $host = (!empty($host['host'])) ? $host['host'] : '';
167 8846 acydburn
168 8846 acydburn
                // Remove any portions not removed by parse_url (#)
169 8846 acydburn
                $host = str_replace('#', '', $host);
170 8846 acydburn
171 8846 acydburn
                // If, by any means, the host is now empty, we will use a "best approach" way to guess one
172 8846 acydburn
                if (empty($host))
173 8846 acydburn
                {
174 8846 acydburn
                        if (!empty($config['server_name']))
175 8846 acydburn
                        {
176 8846 acydburn
                                $host = $config['server_name'];
177 8846 acydburn
                        }
178 8846 acydburn
                        else if (!empty($config['cookie_domain']))
179 8846 acydburn
                        {
180 8848 acydburn
                                $host = (strpos($config['cookie_domain'], '.') === 0) ? substr($config['cookie_domain'], 1) : $config['cookie_domain'];
181 8846 acydburn
                        }
182 8846 acydburn
                        else
183 8846 acydburn
                        {
184 8846 acydburn
                                // Set to OS hostname or localhost
185 10178 acydburn
                                $host = (function_exists('php_uname')) ? php_uname('n') : 'localhost';
186 8846 acydburn
                        }
187 8846 acydburn
                }
188 8846 acydburn
189 8846 acydburn
                // It may be still no valid host, but for sure only a hostname (we may further expand on the cookie domain... if set)
190 8846 acydburn
                return $host;
191 8846 acydburn
        }
192 8846 acydburn
193 8846 acydburn
        /**
194 5175 psotfx
        * Start session management
195 5175 psotfx
        *
196 5175 psotfx
        * This is where all session activity begins. We gather various pieces of
197 5175 psotfx
        * information from the client and server. We test to see if a session already
198 7890 naderman
        * exists. If it does, fine and dandy. If it doesn't we'll go on to create a
199 5175 psotfx
        * new one ... pretty logical heh? We also examine the system load (if we're
200 5175 psotfx
        * running on a system which makes such information readily available) and
201 5175 psotfx
        * halt if it's above an admin definable limit.
202 5175 psotfx
        *
203 6048 acydburn
        * @param bool $update_session_page if true the session page gets updated.
204 6048 acydburn
        *                        This can be set to circumvent certain scripts to update the users last visited page.
205 5175 psotfx
        */
206 6271 acydburn
        function session_begin($update_session_page = true)
207 2661 psotfx
        {
208 7860 acydburn
                global $phpEx, $SID, $_SID, $_EXTRA_URL, $db, $config, $phpbb_root_path;
209 2661 psotfx
210 6650 acydburn
                // Give us some basic information
211 6048 acydburn
                $this->time_now                                = time();
212 6048 acydburn
                $this->cookie_data                        = array('u' => 0, 'k' => '');
213 6048 acydburn
                $this->update_session_page        = $update_session_page;
214 7135 acydburn
                $this->browser                                = (!empty($_SERVER['HTTP_USER_AGENT'])) ? htmlspecialchars((string) $_SERVER['HTTP_USER_AGENT']) : '';
215 8554 Kellanved
                $this->referer                                = (!empty($_SERVER['HTTP_REFERER'])) ? htmlspecialchars((string) $_SERVER['HTTP_REFERER']) : '';
216 10019 acydburn
                $this->forwarded_for                = (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) ? htmlspecialchars((string) $_SERVER['HTTP_X_FORWARDED_FOR']) : '';
217 8636 acydburn
218 8846 acydburn
                $this->host                                        = $this->extract_current_hostname();
219 6048 acydburn
                $this->page                                        = $this->extract_current_page($phpbb_root_path);
220 5237 acydburn
221 6740 naderman
                // if the forwarded for header shall be checked we have to validate its contents
222 6740 naderman
                if ($config['forwarded_for_check'])
223 6740 naderman
                {
224 11202 git-gate
                        $this->forwarded_for = preg_replace('# {2,}#', ' ', str_replace(',', ' ', $this->forwarded_for));
225 6740 naderman
226 6740 naderman
                        // split the list of IPs
227 10019 acydburn
                        $ips = explode(' ', $this->forwarded_for);
228 6740 naderman
                        foreach ($ips as $ip)
229 6740 naderman
                        {
230 6740 naderman
                                // check IPv4 first, the IPv6 is hopefully only going to be used very seldomly
231 8094 acydburn
                                if (!empty($ip) && !preg_match(get_preg_expression('ipv4'), $ip) && !preg_match(get_preg_expression('ipv6'), $ip))
232 6740 naderman
                                {
233 7076 naderman
                                        // contains invalid data, don't use the forwarded for header
234 7076 naderman
                                        $this->forwarded_for = '';
235 7076 naderman
                                        break;
236 6740 naderman
                                }
237 6740 naderman
                        }
238 6740 naderman
                }
239 8375 Kellanved
                else
240 8375 Kellanved
                {
241 8375 Kellanved
                        $this->forwarded_for = '';
242 8375 Kellanved
                }
243 6740 naderman
244 5179 psotfx
                if (isset($_COOKIE[$config['cookie_name'] . '_sid']) || isset($_COOKIE[$config['cookie_name'] . '_u']))
245 2661 psotfx
                {
246 6423 grahamje
                        $this->cookie_data['u'] = request_var($config['cookie_name'] . '_u', 0, false, true);
247 6423 grahamje
                        $this->cookie_data['k'] = request_var($config['cookie_name'] . '_k', '', false, true);
248 6423 grahamje
                        $this->session_id                 = request_var($config['cookie_name'] . '_sid', '', false, true);
249 6015 acydburn
250 3338 ludovic_arnaud
                        $SID = (defined('NEED_SID')) ? '?sid=' . $this->session_id : '?sid=';
251 6015 acydburn
                        $_SID = (defined('NEED_SID')) ? $this->session_id : '';
252 6248 acydburn
253 6248 acydburn
                        if (empty($this->session_id))
254 6248 acydburn
                        {
255 6248 acydburn
                                $this->session_id = $_SID = request_var('sid', '');
256 6248 acydburn
                                $SID = '?sid=' . $this->session_id;
257 6248 acydburn
                                $this->cookie_data = array('u' => 0, 'k' => '');
258 6248 acydburn
                        }
259 2661 psotfx
                }
260 2661 psotfx
                else
261 2661 psotfx
                {
262 6015 acydburn
                        $this->session_id = $_SID = request_var('sid', '');
263 2828 psotfx
                        $SID = '?sid=' . $this->session_id;
264 2661 psotfx
                }
265 6048 acydburn
266 7860 acydburn
                $_EXTRA_URL = array();
267 7860 acydburn
268 5182 psotfx
                // Why no forwarded_for et al? Well, too easily spoofed. With the results of my recent requests
269 5182 psotfx
                // it's pretty clear that in the majority of cases you'll at least be left with a proxy/cache ip.
270 11202 git-gate
                $this->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? (string) $_SERVER['REMOTE_ADDR'] : '';
271 11202 git-gate
                $this->ip = preg_replace('# {2,}#', ' ', str_replace(',', ' ', $this->ip));
272 10020 acydburn
273 10020 acydburn
                // split the list of IPs
274 11202 git-gate
                $ips = explode(' ', trim($this->ip));
275 10020 acydburn
276 10020 acydburn
                // Default IP if REMOTE_ADDR is invalid
277 10020 acydburn
                $this->ip = '127.0.0.1';
278 10020 acydburn
279 10020 acydburn
                foreach ($ips as $ip)
280 10020 acydburn
                {
281 11202 git-gate
                        if (preg_match(get_preg_expression('ipv4'), $ip))
282 10020 acydburn
                        {
283 11202 git-gate
                                $this->ip = $ip;
284 10020 acydburn
                        }
285 11202 git-gate
                        else if (preg_match(get_preg_expression('ipv6'), $ip))
286 10795 git-gate
                        {
287 11202 git-gate
                                // Quick check for IPv4-mapped address in IPv6
288 11202 git-gate
                                if (stripos($ip, '::ffff:') === 0)
289 11202 git-gate
                                {
290 11202 git-gate
                                        $ipv4 = substr($ip, 7);
291 10795 git-gate
292 11202 git-gate
                                        if (preg_match(get_preg_expression('ipv4'), $ipv4))
293 11202 git-gate
                                        {
294 11202 git-gate
                                                $ip = $ipv4;
295 11202 git-gate
                                        }
296 10795 git-gate
                                }
297 11202 git-gate
298 11202 git-gate
                                $this->ip = $ip;
299 10795 git-gate
                        }
300 11202 git-gate
                        else
301 11202 git-gate
                        {
302 11202 git-gate
                                // We want to use the last valid address in the chain
303 11202 git-gate
                                // Leave foreach loop when address is invalid
304 11202 git-gate
                                break;
305 11202 git-gate
                        }
306 10020 acydburn
                }
307 10020 acydburn
308 5902 acydburn
                $this->load = false;
309 5902 acydburn
310 2661 psotfx
                // Load limit check (if applicable)
311 7451 acydburn
                if ($config['limit_load'] || $config['limit_search_load'])
312 2661 psotfx
                {
313 8509 davidmj
                        if ((function_exists('sys_getloadavg') && $load = sys_getloadavg()) || ($load = explode(' ', @file_get_contents('/proc/loadavg'))))
314 2661 psotfx
                        {
315 8509 davidmj
                                $this->load = array_slice($load, 0, 1);
316 6228 acydburn
                                $this->load = floatval($this->load[0]);
317 2661 psotfx
                        }
318 5858 acydburn
                        else
319 5858 acydburn
                        {
320 5858 acydburn
                                set_config('limit_load', '0');
321 7451 acydburn
                                set_config('limit_search_load', '0');
322 5858 acydburn
                        }
323 2661 psotfx
                }
324 5815 naderman
325 5175 psotfx
                // Is session_id is set or session_id is set and matches the url param if required
326 5197 acydburn
                if (!empty($this->session_id) && (!defined('NEED_SID') || (isset($_GET['sid']) && $this->session_id === $_GET['sid'])))
327 2661 psotfx
                {
328 5064 acydburn
                        $sql = 'SELECT u.*, s.*
329 5064 acydburn
                                FROM ' . SESSIONS_TABLE . ' s, ' . USERS_TABLE . " u
330 4429 psotfx
                                WHERE s.session_id = '" . $db->sql_escape($this->session_id) . "'
331 5064 acydburn
                                        AND u.user_id = s.session_user_id";
332 2661 psotfx
                        $result = $db->sql_query($sql);
333 2958 psotfx
                        $this->data = $db->sql_fetchrow($result);
334 2828 psotfx
                        $db->sql_freeresult($result);
335 2661 psotfx
336 2661 psotfx
                        // Did the session exist in the DB?
337 2997 psotfx
                        if (isset($this->data['user_id']))
338 2661 psotfx
                        {
339 5175 psotfx
                                // Validate IP length according to admin ... enforces an IP
340 5175 psotfx
                                // check on bots if admin requires this
341 5237 acydburn
//                                $quadcheck = ($config['ip_check_bot'] && $this->data['user_type'] & USER_BOT) ? 4 : $config['ip_check'];
342 2661 psotfx
343 7559 naderman
                                if (strpos($this->ip, ':') !== false && strpos($this->data['session_ip'], ':') !== false)
344 7559 naderman
                                {
345 7559 naderman
                                        $s_ip = short_ipv6($this->data['session_ip'], $config['ip_check']);
346 7559 naderman
                                        $u_ip = short_ipv6($this->ip, $config['ip_check']);
347 7559 naderman
                                }
348 7559 naderman
                                else
349 7559 naderman
                                {
350 7559 naderman
                                        $s_ip = implode('.', array_slice(explode('.', $this->data['session_ip']), 0, $config['ip_check']));
351 7559 naderman
                                        $u_ip = implode('.', array_slice(explode('.', $this->ip), 0, $config['ip_check']));
352 7559 naderman
                                }
353 7559 naderman
354 8343 acydburn
                                $s_browser = ($config['browser_check']) ? trim(strtolower(substr($this->data['session_browser'], 0, 149))) : '';
355 8343 acydburn
                                $u_browser = ($config['browser_check']) ? trim(strtolower(substr($this->browser, 0, 149))) : '';
356 3710 psotfx
357 6744 naderman
                                $s_forwarded_for = ($config['forwarded_for_check']) ? substr($this->data['session_forwarded_for'], 0, 254) : '';
358 6740 naderman
                                $u_forwarded_for = ($config['forwarded_for_check']) ? substr($this->forwarded_for, 0, 254) : '';
359 8565 acydburn
360 8554 Kellanved
                                // referer checks
361 8565 acydburn
                                // The @ before $config['referer_validation'] suppresses notices present while running the updater
362 8565 acydburn
                                $check_referer_path = (@$config['referer_validation'] == REFERER_VALIDATE_PATH);
363 8554 Kellanved
                                $referer_valid = true;
364 8565 acydburn
365 8557 Kellanved
                                // we assume HEAD and TRACE to be foul play and thus only whitelist GET
366 8565 acydburn
                                if (@$config['referer_validation'] && isset($_SERVER['REQUEST_METHOD']) && strtolower($_SERVER['REQUEST_METHOD']) !== 'get')
367 8554 Kellanved
                                {
368 8554 Kellanved
                                        $referer_valid = $this->validate_referer($check_referer_path);
369 8554 Kellanved
                                }
370 6740 naderman
371 8554 Kellanved
                                if ($u_ip === $s_ip && $s_browser === $u_browser && $s_forwarded_for === $u_forwarded_for && $referer_valid)
372 2923 psotfx
                                {
373 5765 acydburn
                                        $session_expired = false;
374 5815 naderman
375 5815 naderman
                                        // Check whether the session is still valid if we have one
376 6048 acydburn
                                        $method = basename(trim($config['auth_method']));
377 6228 acydburn
                                        include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
378 5815 naderman
379 6228 acydburn
                                        $method = 'validate_session_' . $method;
380 6228 acydburn
                                        if (function_exists($method))
381 2661 psotfx
                                        {
382 6228 acydburn
                                                if (!$method($this->data))
383 5765 acydburn
                                                {
384 6228 acydburn
                                                        $session_expired = true;
385 5765 acydburn
                                                }
386 2661 psotfx
                                        }
387 5815 naderman
388 5815 naderman
                                        if (!$session_expired)
389 5765 acydburn
                                        {
390 5815 naderman
                                                // Check the session length timeframe if autologin is not enabled.
391 5815 naderman
                                                // Else check the autologin length... and also removing those having autologin enabled but no longer allowed board-wide.
392 5815 naderman
                                                if (!$this->data['session_autologin'])
393 5815 naderman
                                                {
394 5815 naderman
                                                        if ($this->data['session_time'] < $this->time_now - ($config['session_length'] + 60))
395 5815 naderman
                                                        {
396 5815 naderman
                                                                $session_expired = true;
397 5815 naderman
                                                        }
398 5815 naderman
                                                }
399 5815 naderman
                                                else if (!$config['allow_autologin'] || ($config['max_autologin_time'] && $this->data['session_time'] < $this->time_now - (86400 * (int) $config['max_autologin_time']) + 60))
400 5815 naderman
                                                {
401 5815 naderman
                                                        $session_expired = true;
402 5815 naderman
                                                }
403 5765 acydburn
                                        }
404 5765 acydburn
405 5765 acydburn
                                        if (!$session_expired)
406 5765 acydburn
                                        {
407 5765 acydburn
                                                // Only update session DB a minute or so after last update or if page changes
408 6048 acydburn
                                                if ($this->time_now - $this->data['session_time'] > 60 || ($this->update_session_page && $this->data['session_page'] != $this->page['page']))
409 5765 acydburn
                                                {
410 6048 acydburn
                                                        $sql_ary = array('session_time' => $this->time_now);
411 6048 acydburn
412 6048 acydburn
                                                        if ($this->update_session_page)
413 6048 acydburn
                                                        {
414 6048 acydburn
                                                                $sql_ary['session_page'] = substr($this->page['page'], 0, 199);
415 8436 Kellanved
                                                                $sql_ary['session_forum_id'] = $this->page['forum'];
416 6048 acydburn
                                                        }
417 6048 acydburn
418 8475 acydburn
                                                        $db->sql_return_on_error(true);
419 8475 acydburn
420 6048 acydburn
                                                        $sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
421 5765 acydburn
                                                                WHERE session_id = '" . $db->sql_escape($this->session_id) . "'";
422 8475 acydburn
                                                        $result = $db->sql_query($sql);
423 8475 acydburn
424 8475 acydburn
                                                        $db->sql_return_on_error(false);
425 8475 acydburn
426 8475 acydburn
                                                        // If the database is not yet updated, there will be an error due to the session_forum_id
427 8475 acydburn
                                                        // @todo REMOVE for 3.0.2
428 8475 acydburn
                                                        if ($result === false)
429 8475 acydburn
                                                        {
430 8475 acydburn
                                                                unset($sql_ary['session_forum_id']);
431 8475 acydburn
432 8475 acydburn
                                                                $sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
433 8475 acydburn
                                                                        WHERE session_id = '" . $db->sql_escape($this->session_id) . "'";
434 8475 acydburn
                                                                $db->sql_query($sql);
435 8475 acydburn
                                                        }
436 9636 acydburn
437 9636 acydburn
                                                        if ($this->data['user_id'] != ANONYMOUS && !empty($config['new_member_post_limit']) && $this->data['user_new'] && $config['new_member_post_limit'] <= $this->data['user_posts'])
438 9636 acydburn
                                                        {
439 9636 acydburn
                                                                $this->leave_newly_registered();
440 9636 acydburn
                                                        }
441 5765 acydburn
                                                }
442 5765 acydburn
443 5765 acydburn
                                                $this->data['is_registered'] = ($this->data['user_id'] != ANONYMOUS && ($this->data['user_type'] == USER_NORMAL || $this->data['user_type'] == USER_FOUNDER)) ? true : false;
444 5765 acydburn
                                                $this->data['is_bot'] = (!$this->data['is_registered'] && $this->data['user_id'] != ANONYMOUS) ? true : false;
445 7879 kellanved
                                                $this->data['user_lang'] = basename($this->data['user_lang']);
446 7890 naderman
447 5765 acydburn
                                                return true;
448 5765 acydburn
                                        }
449 2661 psotfx
                                }
450 5765 acydburn
                                else
451 5765 acydburn
                                {
452 5765 acydburn
                                        // Added logging temporarly to help debug bugs...
453 7946 acydburn
                                        if (defined('DEBUG_EXTRA') && $this->data['user_id'] != ANONYMOUS)
454 6436 acydburn
                                        {
455 8554 Kellanved
                                                if ($referer_valid)
456 8554 Kellanved
                                                {
457 8554 Kellanved
                                                        add_log('critical', 'LOG_IP_BROWSER_FORWARDED_CHECK', $u_ip, $s_ip, $u_browser, $s_browser, htmlspecialchars($u_forwarded_for), htmlspecialchars($s_forwarded_for));
458 8554 Kellanved
                                                }
459 8554 Kellanved
                                                else
460 8554 Kellanved
                                                {
461 8554 Kellanved
                                                        add_log('critical', 'LOG_REFERER_INVALID', $this->referer);
462 8554 Kellanved
                                                }
463 6436 acydburn
                                        }
464 5765 acydburn
                                }
465 2661 psotfx
                        }
466 2661 psotfx
                }
467 2661 psotfx
468 5175 psotfx
                // If we reach here then no (valid) session exists. So we'll create a new one
469 5175 psotfx
                return $this->session_create();
470 2661 psotfx
        }
471 7890 naderman
472 5175 psotfx
        /**
473 5175 psotfx
        * Create a new session
474 5175 psotfx
        *
475 5175 psotfx
        * If upon trying to start a session we discover there is nothing existing we
476 5175 psotfx
        * jump here. Additionally this method is called directly during login to regenerate
477 5175 psotfx
        * the session for the specific user. In this method we carry out a number of tasks;
478 5175 psotfx
        * garbage collection, (search)bot checking, banned user comparison. Basically
479 5175 psotfx
        * though this method will result in a new session for a specific user.
480 5175 psotfx
        */
481 5175 psotfx
        function session_create($user_id = false, $set_admin = false, $persist_login = false, $viewonline = true)
482 2661 psotfx
        {
483 6015 acydburn
                global $SID, $_SID, $db, $config, $cache, $phpbb_root_path, $phpEx;
484 2661 psotfx
485 5175 psotfx
                $this->data = array();
486 6048 acydburn
487 5929 acydburn
                /* Garbage collection ... remove old sessions updating user information
488 5175 psotfx
                // if necessary. It means (potentially) 11 queries but only infrequently
489 5175 psotfx
                if ($this->time_now > $config['session_last_gc'] + $config['session_gc'])
490 5175 psotfx
                {
491 5175 psotfx
                        $this->session_gc();
492 5929 acydburn
                }*/
493 6048 acydburn
494 5175 psotfx
                // Do we allow autologin on this board? No? Then override anything
495 5175 psotfx
                // that may be requested here
496 5175 psotfx
                if (!$config['allow_autologin'])
497 5175 psotfx
                {
498 5175 psotfx
                        $this->cookie_data['k'] = $persist_login = false;
499 5175 psotfx
                }
500 5175 psotfx
501 5175 psotfx
                /**
502 5175 psotfx
                * Here we do a bot check, oh er saucy! No, not that kind of bot
503 5175 psotfx
                * check. We loop through the list of bots defined by the admin and
504 5175 psotfx
                * see if we have any useragent and/or IP matches. If we do, this is a
505 5175 psotfx
                * bot, act accordingly
506 7890 naderman
                */
507 4603 psotfx
                $bot = false;
508 6572 acydburn
                $active_bots = $cache->obtain_bots();
509 5237 acydburn
510 5140 acydburn
                foreach ($active_bots as $row)
511 2954 ludovic_arnaud
                {
512 8131 acydburn
                        if ($row['bot_agent'] && preg_match('#' . str_replace('\*', '.*?', preg_quote($row['bot_agent'], '#')) . '#i', $this->browser))
513 4603 psotfx
                        {
514 4603 psotfx
                                $bot = $row['user_id'];
515 4603 psotfx
                        }
516 6048 acydburn
517 5710 acydburn
                        // If ip is supplied, we will make sure the ip is matching too...
518 5710 acydburn
                        if ($row['bot_ip'] && ($bot || !$row['bot_agent']))
519 4603 psotfx
                        {
520 5710 acydburn
                                // Set bot to false, then we only have to set it to true if it is matching
521 5710 acydburn
                                $bot = false;
522 5710 acydburn
523 4603 psotfx
                                foreach (explode(',', $row['bot_ip']) as $bot_ip)
524 4603 psotfx
                                {
525 9374 acydburn
                                        $bot_ip = trim($bot_ip);
526 9374 acydburn
527 9374 acydburn
                                        if (!$bot_ip)
528 9374 acydburn
                                        {
529 9374 acydburn
                                                continue;
530 9374 acydburn
                                        }
531 9374 acydburn
532 4603 psotfx
                                        if (strpos($this->ip, $bot_ip) === 0)
533 4603 psotfx
                                        {
534 5175 psotfx
                                                $bot = (int) $row['user_id'];
535 4603 psotfx
                                                break;
536 4603 psotfx
                                        }
537 4603 psotfx
                                }
538 4603 psotfx
                        }
539 2833 psotfx
540 4603 psotfx
                        if ($bot)
541 2954 ludovic_arnaud
                        {
542 4603 psotfx
                                break;
543 2954 ludovic_arnaud
                        }
544 2661 psotfx
                }
545 5815 naderman
546 6048 acydburn
                $method = basename(trim($config['auth_method']));
547 6228 acydburn
                include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
548 5815 naderman
549 6228 acydburn
                $method = 'autologin_' . $method;
550 6228 acydburn
                if (function_exists($method))
551 5815 naderman
                {
552 6228 acydburn
                        $this->data = $method();
553 5815 naderman
554 6228 acydburn
                        if (sizeof($this->data))
555 5815 naderman
                        {
556 6228 acydburn
                                $this->cookie_data['k'] = '';
557 6228 acydburn
                                $this->cookie_data['u'] = $this->data['user_id'];
558 5815 naderman
                        }
559 5815 naderman
                }
560 5815 naderman
561 5175 psotfx
                // If we're presented with an autologin key we'll join against it.
562 5175 psotfx
                // Else if we've been passed a user_id we'll grab data based on that
563 5815 naderman
                if (isset($this->cookie_data['k']) && $this->cookie_data['k'] && $this->cookie_data['u'] && !sizeof($this->data))
564 5175 psotfx
                {
565 7890 naderman
                        $sql = 'SELECT u.*
566 5175 psotfx
                                FROM ' . USERS_TABLE . ' u, ' . SESSIONS_KEYS_TABLE . ' k
567 5182 psotfx
                                WHERE u.user_id = ' . (int) $this->cookie_data['u'] . '
568 6436 acydburn
                                        AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ")
569 5175 psotfx
                                        AND k.user_id = u.user_id
570 5288 grahamje
                                        AND k.key_id = '" . $db->sql_escape(md5($this->cookie_data['k'])) . "'";
571 5175 psotfx
                        $result = $db->sql_query($sql);
572 5175 psotfx
                        $this->data = $db->sql_fetchrow($result);
573 5175 psotfx
                        $db->sql_freeresult($result);
574 7785 kellanved
                        $bot = false;
575 2923 psotfx
                }
576 5815 naderman
                else if ($user_id !== false && !sizeof($this->data))
577 2661 psotfx
                {
578 5175 psotfx
                        $this->cookie_data['k'] = '';
579 5175 psotfx
                        $this->cookie_data['u'] = $user_id;
580 5038 acydburn
581 5064 acydburn
                        $sql = 'SELECT *
582 5064 acydburn
                                FROM ' . USERS_TABLE . '
583 5182 psotfx
                                WHERE user_id = ' . (int) $this->cookie_data['u'] . '
584 6436 acydburn
                                        AND user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')';
585 5038 acydburn
                        $result = $db->sql_query($sql);
586 5038 acydburn
                        $this->data = $db->sql_fetchrow($result);
587 5038 acydburn
                        $db->sql_freeresult($result);
588 7785 kellanved
                        $bot = false;
589 2661 psotfx
                }
590 7890 naderman
591 10998 git-gate
                // Bot user, if they have a SID in the Request URI we need to get rid of it
592 10998 git-gate
                // otherwise they'll index this page with the SID, duplicate content oh my!
593 10998 git-gate
                if ($bot && isset($_GET['sid']))
594 10998 git-gate
                {
595 11209 git-gate
                        send_status_line(301, 'Moved Permanently');
596 10998 git-gate
                        redirect(build_url(array('sid')));
597 10998 git-gate
                }
598 10998 git-gate
599 6915 acydburn
                // If no data was returned one or more of the following occurred:
600 5175 psotfx
                // Key didn't match one in the DB
601 5175 psotfx
                // User does not exist
602 5175 psotfx
                // User is inactive
603 5175 psotfx
                // User is bot
604 5188 psotfx
                if (!sizeof($this->data) || !is_array($this->data))
605 4603 psotfx
                {
606 5175 psotfx
                        $this->cookie_data['k'] = '';
607 5175 psotfx
                        $this->cookie_data['u'] = ($bot) ? $bot : ANONYMOUS;
608 4603 psotfx
609 6364 acydburn
                        if (!$bot)
610 6364 acydburn
                        {
611 6364 acydburn
                                $sql = 'SELECT *
612 6364 acydburn
                                        FROM ' . USERS_TABLE . '
613 6364 acydburn
                                        WHERE user_id = ' . (int) $this->cookie_data['u'];
614 6364 acydburn
                        }
615 6364 acydburn
                        else
616 6364 acydburn
                        {
617 6364 acydburn
                                // We give bots always the same session if it is not yet expired.
618 6364 acydburn
                                $sql = 'SELECT u.*, s.*
619 6364 acydburn
                                        FROM ' . USERS_TABLE . ' u
620 6364 acydburn
                                        LEFT JOIN ' . SESSIONS_TABLE . ' s ON (s.session_user_id = u.user_id)
621 6364 acydburn
                                        WHERE u.user_id = ' . (int) $bot;
622 6364 acydburn
                        }
623 6364 acydburn
624 4603 psotfx
                        $result = $db->sql_query($sql);
625 5175 psotfx
                        $this->data = $db->sql_fetchrow($result);
626 4603 psotfx
                        $db->sql_freeresult($result);
627 4603 psotfx
                }
628 4603 psotfx
629 6149 acydburn
                if ($this->data['user_id'] != ANONYMOUS && !$bot)
630 3269 psotfx
                {
631 5197 acydburn
                        $this->data['session_last_visit'] = (isset($this->data['session_time']) && $this->data['session_time']) ? $this->data['session_time'] : (($this->data['user_lastvisit']) ? $this->data['user_lastvisit'] : time());
632 5175 psotfx
                }
633 5175 psotfx
                else
634 5175 psotfx
                {
635 5765 acydburn
                        $this->data['session_last_visit'] = $this->time_now;
636 5643 acydburn
                }
637 3802 psotfx
638 6475 acydburn
                // Force user id to be integer...
639 6475 acydburn
                $this->data['user_id'] = (int) $this->data['user_id'];
640 6475 acydburn
641 5175 psotfx
                // At this stage we should have a filled data array, defined cookie u and k data.
642 5175 psotfx
                // data array should contain recent session info if we're a real user and a recent
643 5175 psotfx
                // session exists in which case session_id will also be set
644 4950 psotfx
645 5175 psotfx
                // Is user banned? Are they excluded? Won't return on ban, exists within method
646 5175 psotfx
                if ($this->data['user_type'] != USER_FOUNDER)
647 5175 psotfx
                {
648 6740 naderman
                        if (!$config['forwarded_for_check'])
649 6740 naderman
                        {
650 6740 naderman
                                $this->check_ban($this->data['user_id'], $this->ip);
651 6740 naderman
                        }
652 6740 naderman
                        else
653 6740 naderman
                        {
654 10019 acydburn
                                $ips = explode(' ', $this->forwarded_for);
655 6740 naderman
                                $ips[] = $this->ip;
656 6740 naderman
                                $this->check_ban($this->data['user_id'], $ips);
657 6740 naderman
                        }
658 3267 psotfx
                }
659 6048 acydburn
660 6436 acydburn
                $this->data['is_registered'] = (!$bot && $this->data['user_id'] != ANONYMOUS && ($this->data['user_type'] == USER_NORMAL || $this->data['user_type'] == USER_FOUNDER)) ? true : false;
661 5117 acydburn
                $this->data['is_bot'] = ($bot) ? true : false;
662 5765 acydburn
663 6364 acydburn
                // If our friend is a bot, we re-assign a previously assigned session
664 6475 acydburn
                if ($this->data['is_bot'] && $bot == $this->data['user_id'] && $this->data['session_id'])
665 6364 acydburn
                {
666 6740 naderman
                        // Only assign the current session if the ip, browser and forwarded_for match...
667 7559 naderman
                        if (strpos($this->ip, ':') !== false && strpos($this->data['session_ip'], ':') !== false)
668 7559 naderman
                        {
669 7559 naderman
                                $s_ip = short_ipv6($this->data['session_ip'], $config['ip_check']);
670 7559 naderman
                                $u_ip = short_ipv6($this->ip, $config['ip_check']);
671 7559 naderman
                        }
672 7559 naderman
                        else
673 7559 naderman
                        {
674 7559 naderman
                                $s_ip = implode('.', array_slice(explode('.', $this->data['session_ip']), 0, $config['ip_check']));
675 7559 naderman
                                $u_ip = implode('.', array_slice(explode('.', $this->ip), 0, $config['ip_check']));
676 7559 naderman
                        }
677 6364 acydburn
678 8343 acydburn
                        $s_browser = ($config['browser_check']) ? trim(strtolower(substr($this->data['session_browser'], 0, 149))) : '';
679 8343 acydburn
                        $u_browser = ($config['browser_check']) ? trim(strtolower(substr($this->browser, 0, 149))) : '';
680 6364 acydburn
681 6740 naderman
                        $s_forwarded_for = ($config['forwarded_for_check']) ? substr($this->data['session_forwarded_for'], 0, 254) : '';
682 6740 naderman
                        $u_forwarded_for = ($config['forwarded_for_check']) ? substr($this->forwarded_for, 0, 254) : '';
683 6740 naderman
684 6740 naderman
                        if ($u_ip === $s_ip && $s_browser === $u_browser && $s_forwarded_for === $u_forwarded_for)
685 6364 acydburn
                        {
686 6364 acydburn
                                $this->session_id = $this->data['session_id'];
687 6364 acydburn
688 6364 acydburn
                                // Only update session DB a minute or so after last update or if page changes
689 6364 acydburn
                                if ($this->time_now - $this->data['session_time'] > 60 || ($this->update_session_page && $this->data['session_page'] != $this->page['page']))
690 6364 acydburn
                                {
691 6584 acydburn
                                        $this->data['session_time'] = $this->data['session_last_visit'] = $this->time_now;
692 6584 acydburn
693 6364 acydburn
                                        $sql_ary = array('session_time' => $this->time_now, 'session_last_visit' => $this->time_now, 'session_admin' => 0);
694 6364 acydburn
695 6364 acydburn
                                        if ($this->update_session_page)
696 6364 acydburn
                                        {
697 6364 acydburn
                                                $sql_ary['session_page'] = substr($this->page['page'], 0, 199);
698 8436 Kellanved
                                                $sql_ary['session_forum_id'] = $this->page['forum'];
699 6364 acydburn
                                        }
700 6364 acydburn
701 6364 acydburn
                                        $sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . "
702 6364 acydburn
                                                WHERE session_id = '" . $db->sql_escape($this->session_id) . "'";
703 6364 acydburn
                                        $db->sql_query($sql);
704 6584 acydburn
705 6584 acydburn
                                        // Update the last visit time
706 6584 acydburn
                                        $sql = 'UPDATE ' . USERS_TABLE . '
707 6584 acydburn
                                                SET user_lastvisit = ' . (int) $this->data['session_time'] . '
708 6584 acydburn
                                                WHERE user_id = ' . (int) $this->data['user_id'];
709 6584 acydburn
                                        $db->sql_query($sql);
710 6364 acydburn
                                }
711 6364 acydburn
712 6364 acydburn
                                $SID = '?sid=';
713 6364 acydburn
                                $_SID = '';
714 6364 acydburn
                                return true;
715 6364 acydburn
                        }
716 6364 acydburn
                        else
717 6364 acydburn
                        {
718 6364 acydburn
                                // If the ip and browser does not match make sure we only have one bot assigned to one session
719 6364 acydburn
                                $db->sql_query('DELETE FROM ' . SESSIONS_TABLE . ' WHERE session_user_id = ' . $this->data['user_id']);
720 6364 acydburn
                        }
721 6364 acydburn
                }
722 6364 acydburn
723 5765 acydburn
                $session_autologin = (($this->cookie_data['k'] || $persist_login) && $this->data['is_registered']) ? true : false;
724 6436 acydburn
                $set_admin = ($set_admin && $this->data['is_registered']) ? true : false;
725 5765 acydburn
726 2661 psotfx
                // Create or update the session
727 4970 psotfx
                $sql_ary = array(
728 5175 psotfx
                        'session_user_id'                => (int) $this->data['user_id'],
729 5175 psotfx
                        'session_start'                        => (int) $this->time_now,
730 4970 psotfx
                        'session_last_visit'        => (int) $this->data['session_last_visit'],
731 5175 psotfx
                        'session_time'                        => (int) $this->time_now,
732 8343 acydburn
                        'session_browser'                => (string) trim(substr($this->browser, 0, 149)),
733 6740 naderman
                        'session_forwarded_for'        => (string) $this->forwarded_for,
734 4977 psotfx
                        'session_ip'                        => (string) $this->ip,
735 5765 acydburn
                        'session_autologin'                => ($session_autologin) ? 1 : 0,
736 5197 acydburn
                        'session_admin'                        => ($set_admin) ? 1 : 0,
737 5197 acydburn
                        'session_viewonline'        => ($viewonline) ? 1 : 0,
738 4970 psotfx
                );
739 4970 psotfx
740 6048 acydburn
                if ($this->update_session_page)
741 6048 acydburn
                {
742 6048 acydburn
                        $sql_ary['session_page'] = (string) substr($this->page['page'], 0, 199);
743 8436 Kellanved
                        $sql_ary['session_forum_id'] = $this->page['forum'];
744 6048 acydburn
                }
745 6048 acydburn
746 5175 psotfx
                $db->sql_return_on_error(true);
747 5175 psotfx
748 6257 naderman
                $sql = 'DELETE
749 6257 naderman
                        FROM ' . SESSIONS_TABLE . '
750 6257 naderman
                        WHERE session_id = \'' . $db->sql_escape($this->session_id) . '\'
751 6257 naderman
                                AND session_user_id = ' . ANONYMOUS;
752 5388 acydburn
753 7102 acydburn
                if (!defined('IN_ERROR_HANDLER') && (!$this->session_id || !$db->sql_query($sql) || !$db->sql_affectedrows()))
754 2661 psotfx
                {
755 5175 psotfx
                        // Limit new sessions in 1 minute period (if required)
756 7966 acydburn
                        if (empty($this->data['session_time']) && $config['active_sessions'])
757 5175 psotfx
                        {
758 8441 acydburn
//                                $db->sql_return_on_error(false);
759 8438 acydburn
760 6048 acydburn
                                $sql = 'SELECT COUNT(session_id) AS sessions
761 5175 psotfx
                                        FROM ' . SESSIONS_TABLE . '
762 5175 psotfx
                                        WHERE session_time >= ' . ($this->time_now - 60);
763 5175 psotfx
                                $result = $db->sql_query($sql);
764 5175 psotfx
                                $row = $db->sql_fetchrow($result);
765 5175 psotfx
                                $db->sql_freeresult($result);
766 6048 acydburn
767 5175 psotfx
                                if ((int) $row['sessions'] > (int) $config['active_sessions'])
768 5175 psotfx
                                {
769 10788 git-gate
                                        send_status_line(503, 'Service Unavailable');
770 5175 psotfx
                                        trigger_error('BOARD_UNAVAILABLE');
771 5175 psotfx
                                }
772 5175 psotfx
                        }
773 6257 naderman
                }
774 6048 acydburn
775 8438 acydburn
                // Since we re-create the session id here, the inserted row must be unique. Therefore, we display potential errors.
776 8441 acydburn
                // Commented out because it will not allow forums to update correctly
777 8441 acydburn
//                $db->sql_return_on_error(false);
778 8438 acydburn
779 9411 acydburn
                // Something quite important: session_page always holds the *last* page visited, except for the *first* visit.
780 9411 acydburn
                // We are not able to simply have an empty session_page btw, therefore we need to tell phpBB how to detect this special case.
781 9411 acydburn
                // If the session id is empty, we have a completely new one and will set an "identifier" here. This identifier is able to be checked later.
782 9411 acydburn
                if (empty($this->data['session_id']))
783 9411 acydburn
                {
784 9411 acydburn
                        // This is a temporary variable, only set for the very first visit
785 9411 acydburn
                        $this->data['session_created'] = true;
786 9411 acydburn
                }
787 9411 acydburn
788 6257 naderman
                $this->session_id = $this->data['session_id'] = md5(unique_id());
789 2661 psotfx
790 6257 naderman
                $sql_ary['session_id'] = (string) $this->session_id;
791 6257 naderman
                $sql_ary['session_page'] = (string) substr($this->page['page'], 0, 199);
792 8436 Kellanved
                $sql_ary['session_forum_id'] = $this->page['forum'];
793 4970 psotfx
794 6257 naderman
                $sql = 'INSERT INTO ' . SESSIONS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
795 6257 naderman
                $db->sql_query($sql);
796 6257 naderman
797 8441 acydburn
                $db->sql_return_on_error(false);
798 8441 acydburn
799 5175 psotfx
                // Regenerate autologin/persistent login key
800 5765 acydburn
                if ($session_autologin)
801 5175 psotfx
                {
802 5175 psotfx
                        $this->set_login_key();
803 5175 psotfx
                }
804 6048 acydburn
805 7763 kellanved
                // refresh data
806 6248 acydburn
                $SID = '?sid=' . $this->session_id;
807 6248 acydburn
                $_SID = $this->session_id;
808 7763 kellanved
                $this->data = array_merge($this->data, $sql_ary);
809 6048 acydburn
810 4603 psotfx
                if (!$bot)
811 4603 psotfx
                {
812 5186 psotfx
                        $cookie_expire = $this->time_now + (($config['max_autologin_time']) ? 86400 * (int) $config['max_autologin_time'] : 31536000);
813 6048 acydburn
814 5186 psotfx
                        $this->set_cookie('u', $this->cookie_data['u'], $cookie_expire);
815 5186 psotfx
                        $this->set_cookie('k', $this->cookie_data['k'], $cookie_expire);
816 5339 acydburn
                        $this->set_cookie('sid', $this->session_id, $cookie_expire);
817 2661 psotfx
818 5177 psotfx
                        unset($cookie_expire);
819 8348 acydburn
820 8120 kellanved
                        $sql = 'SELECT COUNT(session_id) AS sessions
821 8120 kellanved
                                        FROM ' . SESSIONS_TABLE . '
822 8131 acydburn
                                        WHERE session_user_id = ' . (int) $this->data['user_id'] . '
823 8340 Kellanved
                                        AND session_time >= ' . (int) ($this->time_now - (max($config['session_length'], $config['form_token_lifetime'])));
824 8120 kellanved
                        $result = $db->sql_query($sql);
825 8120 kellanved
                        $row = $db->sql_fetchrow($result);
826 8120 kellanved
                        $db->sql_freeresult($result);
827 8120 kellanved
828 8120 kellanved
                        if ((int) $row['sessions'] <= 1 || empty($this->data['user_form_salt']))
829 8120 kellanved
                        {
830 8120 kellanved
                                $this->data['user_form_salt'] = unique_id();
831 8120 kellanved
                                // Update the form key
832 8120 kellanved
                                $sql = 'UPDATE ' . USERS_TABLE . '
833 8120 kellanved
                                        SET user_form_salt = \'' . $db->sql_escape($this->data['user_form_salt']) . '\'
834 8120 kellanved
                                        WHERE user_id = ' . (int) $this->data['user_id'];
835 8120 kellanved
                                $db->sql_query($sql);
836 8120 kellanved
                        }
837 4603 psotfx
                }
838 6364 acydburn
                else
839 6364 acydburn
                {
840 6740 naderman
                        $this->data['session_time'] = $this->data['session_last_visit'] = $this->time_now;
841 6740 naderman
842 6740 naderman
                        // Update the last visit time
843 6740 naderman
                        $sql = 'UPDATE ' . USERS_TABLE . '
844 6740 naderman
                                SET user_lastvisit = ' . (int) $this->data['session_time'] . '
845 6740 naderman
                                WHERE user_id = ' . (int) $this->data['user_id'];
846 6740 naderman
                        $db->sql_query($sql);
847 6740 naderman
848 6364 acydburn
                        $SID = '?sid=';
849 6364 acydburn
                        $_SID = '';
850 6364 acydburn
                }
851 7890 naderman
852 2958 psotfx
                return true;
853 2661 psotfx
        }
854 6048 acydburn
855 5175 psotfx
        /**
856 5175 psotfx
        * Kills a session
857 5175 psotfx
        *
858 5175 psotfx
        * This method does what it says on the tin. It will delete a pre-existing session.
859 5175 psotfx
        * It resets cookie information (destroying any autologin key within that cookie data)
860 5175 psotfx
        * and update the users information from the relevant session data. It will then
861 5175 psotfx
        * grab guest user information.
862 5175 psotfx
        */
863 6803 acydburn
        function session_kill($new_session = true)
864 2661 psotfx
        {
865 6015 acydburn
                global $SID, $_SID, $db, $config, $phpbb_root_path, $phpEx;
866 2661 psotfx
867 3989 psotfx
                $sql = 'DELETE FROM ' . SESSIONS_TABLE . "
868 5431 acydburn
                        WHERE session_id = '" . $db->sql_escape($this->session_id) . "'
869 5178 psotfx
                                AND session_user_id = " . (int) $this->data['user_id'];
870 2661 psotfx
                $db->sql_query($sql);
871 2661 psotfx
872 5815 naderman
                // Allow connecting logout with external auth method logout
873 6048 acydburn
                $method = basename(trim($config['auth_method']));
874 6228 acydburn
                include_once($phpbb_root_path . 'includes/auth/auth_' . $method . '.' . $phpEx);
875 5815 naderman
876 6228 acydburn
                $method = 'logout_' . $method;
877 6228 acydburn
                if (function_exists($method))
878 5815 naderman
                {
879 7971 acydburn
                        $method($this->data, $new_session);
880 5815 naderman
                }
881 5815 naderman
882 5175 psotfx
                if ($this->data['user_id'] != ANONYMOUS)
883 5175 psotfx
                {
884 5175 psotfx
                        // Delete existing session, update last visit info first!
885 5431 acydburn
                        if (!isset($this->data['session_time']))
886 5428 subblue
                        {
887 5428 subblue
                                $this->data['session_time'] = time();
888 5428 subblue
                        }
889 6048 acydburn
890 5175 psotfx
                        $sql = 'UPDATE ' . USERS_TABLE . '
891 5431 acydburn
                                SET user_lastvisit = ' . (int) $this->data['session_time'] . '
892 5431 acydburn
                                WHERE user_id = ' . (int) $this->data['user_id'];
893 5175 psotfx
                        $db->sql_query($sql);
894 2661 psotfx
895 5339 acydburn
                        if ($this->cookie_data['k'])
896 5178 psotfx
                        {
897 5178 psotfx
                                $sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
898 5178 psotfx
                                        WHERE user_id = ' . (int) $this->data['user_id'] . "
899 5339 acydburn
                                                AND key_id = '" . $db->sql_escape(md5($this->cookie_data['k'])) . "'";
900 5178 psotfx
                                $db->sql_query($sql);
901 5178 psotfx
                        }
902 6048 acydburn
903 5175 psotfx
                        // Reset the data array
904 6048 acydburn
                        $this->data = array();
905 6048 acydburn
906 5175 psotfx
                        $sql = 'SELECT *
907 5175 psotfx
                                FROM ' . USERS_TABLE . '
908 5175 psotfx
                                WHERE user_id = ' . ANONYMOUS;
909 5175 psotfx
                        $result = $db->sql_query($sql);
910 5175 psotfx
                        $this->data = $db->sql_fetchrow($result);
911 5175 psotfx
                        $db->sql_freeresult($result);
912 5175 psotfx
                }
913 6048 acydburn
914 5186 psotfx
                $cookie_expire = $this->time_now - 31536000;
915 5186 psotfx
                $this->set_cookie('u', '', $cookie_expire);
916 5186 psotfx
                $this->set_cookie('k', '', $cookie_expire);
917 5186 psotfx
                $this->set_cookie('sid', '', $cookie_expire);
918 5186 psotfx
                unset($cookie_expire);
919 6048 acydburn
920 5175 psotfx
                $SID = '?sid=';
921 6015 acydburn
                $this->session_id = $_SID = '';
922 5117 acydburn
923 6312 acydburn
                // To make sure a valid session is created we create one for the anonymous user
924 6803 acydburn
                if ($new_session)
925 6803 acydburn
                {
926 6803 acydburn
                        $this->session_create(ANONYMOUS);
927 6803 acydburn
                }
928 6312 acydburn
929 2661 psotfx
                return true;
930 2661 psotfx
        }
931 2661 psotfx
932 5175 psotfx
        /**
933 5175 psotfx
        * Session garbage collection
934 5175 psotfx
        *
935 5175 psotfx
        * This looks a lot more complex than it really is. Effectively we are
936 5175 psotfx
        * deleting any sessions older than an admin definable limit. Due to the
937 5175 psotfx
        * way in which we maintain session data we have to ensure we update user
938 5175 psotfx
        * data before those sessions are destroyed. In addition this method
939 5175 psotfx
        * removes autologin key information that is older than an admin defined
940 5175 psotfx
        * limit.
941 5175 psotfx
        */
942 5175 psotfx
        function session_gc()
943 2661 psotfx
        {
944 9524 Kellanved
                global $db, $config, $phpbb_root_path, $phpEx;
945 2661 psotfx
946 8089 kellanved
                $batch_size = 10;
947 8348 acydburn
948 5272 acydburn
                if (!$this->time_now)
949 5272 acydburn
                {
950 5272 acydburn
                        $this->time_now = time();
951 5272 acydburn
                }
952 6048 acydburn
953 6407 acydburn
                // Firstly, delete guest sessions
954 6407 acydburn
                $sql = 'DELETE FROM ' . SESSIONS_TABLE . '
955 6407 acydburn
                        WHERE session_user_id = ' . ANONYMOUS . '
956 6407 acydburn
                                AND session_time < ' . (int) ($this->time_now - $config['session_length']);
957 6407 acydburn
                $db->sql_query($sql);
958 2661 psotfx
959 6407 acydburn
                // Get expired sessions, only most recent for each user
960 6407 acydburn
                $sql = 'SELECT session_user_id, session_page, MAX(session_time) AS recent_time
961 6407 acydburn
                        FROM ' . SESSIONS_TABLE . '
962 6407 acydburn
                        WHERE session_time < ' . ($this->time_now - $config['session_length']) . '
963 6407 acydburn
                        GROUP BY session_user_id, session_page';
964 8089 kellanved
                $result = $db->sql_query_limit($sql, $batch_size);
965 4769 psotfx
966 6407 acydburn
                $del_user_id = array();
967 6407 acydburn
                $del_sessions = 0;
968 4769 psotfx
969 6527 acydburn
                while ($row = $db->sql_fetchrow($result))
970 6407 acydburn
                {
971 6407 acydburn
                        $sql = 'UPDATE ' . USERS_TABLE . '
972 6407 acydburn
                                SET user_lastvisit = ' . (int) $row['recent_time'] . ", user_lastpage = '" . $db->sql_escape($row['session_page']) . "'
973 6407 acydburn
                                WHERE user_id = " . (int) $row['session_user_id'];
974 6407 acydburn
                        $db->sql_query($sql);
975 4672 ludovic_arnaud
976 6407 acydburn
                        $del_user_id[] = (int) $row['session_user_id'];
977 6407 acydburn
                        $del_sessions++;
978 6407 acydburn
                }
979 6407 acydburn
                $db->sql_freeresult($result);
980 4672 ludovic_arnaud
981 6407 acydburn
                if (sizeof($del_user_id))
982 6407 acydburn
                {
983 6407 acydburn
                        // Delete expired sessions
984 6407 acydburn
                        $sql = 'DELETE FROM ' . SESSIONS_TABLE . '
985 6407 acydburn
                                WHERE ' . $db->sql_in_set('session_user_id', $del_user_id) . '
986 6407 acydburn
                                        AND session_time < ' . ($this->time_now - $config['session_length']);
987 6407 acydburn
                        $db->sql_query($sql);
988 6407 acydburn
                }
989 4672 ludovic_arnaud
990 8089 kellanved
                if ($del_sessions < $batch_size)
991 6407 acydburn
                {
992 8089 kellanved
                        // Less than 10 users, update gc timer ... else we want gc
993 6407 acydburn
                        // called again to delete other sessions
994 6407 acydburn
                        set_config('session_last_gc', $this->time_now, true);
995 8348 acydburn
996 8089 kellanved
                        if ($config['max_autologin_time'])
997 8089 kellanved
                        {
998 8089 kellanved
                                $sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
999 8089 kellanved
                                        WHERE last_login < ' . (time() - (86400 * (int) $config['max_autologin_time']));
1000 8089 kellanved
                                $db->sql_query($sql);
1001 8089 kellanved
                        }
1002 9554 acydburn
1003 9524 Kellanved
                        // only called from CRON; should be a safe workaround until the infrastructure gets going
1004 10586 git-gate
                        if (!class_exists('phpbb_captcha_factory'))
1005 9524 Kellanved
                        {
1006 9524 Kellanved
                                include($phpbb_root_path . "includes/captcha/captcha_factory." . $phpEx);
1007 9524 Kellanved
                        }
1008 9627 Kellanved
                        phpbb_captcha_factory::garbage_collect($config['captcha_plugin']);
1009 11215 git-gate
1010 11215 git-gate
                        $sql = 'DELETE FROM ' . LOGIN_ATTEMPT_TABLE . '
1011 11215 git-gate
                                WHERE attempt_time < ' . (time() - (int) $config['ip_login_limit_time']);
1012 11215 git-gate
                        $db->sql_query($sql);
1013 2928 psotfx
                }
1014 8348 acydburn
1015 8089 kellanved
                return;
1016 8089 kellanved
        }
1017 8348 acydburn
1018 5175 psotfx
        /**
1019 5175 psotfx
        * Sets a cookie
1020 5175 psotfx
        *
1021 8310 acydburn
        * Sets a cookie of the given name with the specified data for the given length of time. If no time is specified, a session cookie will be set.
1022 8310 acydburn
        *
1023 8310 acydburn
        * @param string $name                Name of the cookie, will be automatically prefixed with the phpBB cookie name. track becomes [cookie_name]_track then.
1024 8310 acydburn
        * @param string $cookiedata        The data to hold within the cookie
1025 8310 acydburn
        * @param int $cookietime        The expiration time as UNIX timestamp. If 0 is provided, a session cookie is set.
1026 5175 psotfx
        */
1027 2932 psotfx
        function set_cookie($name, $cookiedata, $cookietime)
1028 2932 psotfx
        {
1029 2983 psotfx
                global $config;
1030 2932 psotfx
1031 6436 acydburn
                $name_data = rawurlencode($config['cookie_name'] . '_' . $name) . '=' . rawurlencode($cookiedata);
1032 6436 acydburn
                $expire = gmdate('D, d-M-Y H:i:s \\G\\M\\T', $cookietime);
1033 6436 acydburn
                $domain = (!$config['cookie_domain'] || $config['cookie_domain'] == 'localhost' || $config['cookie_domain'] == '127.0.0.1') ? '' : '; domain=' . $config['cookie_domain'];
1034 5678 acydburn
1035 8310 acydburn
                header('Set-Cookie: ' . $name_data . (($cookietime) ? '; expires=' . $expire : '') . '; path=' . $config['cookie_path'] . $domain . ((!$config['cookie_secure']) ? '' : '; secure') . '; HttpOnly', false);
1036 5175 psotfx
        }
1037 5175 psotfx
1038 5175 psotfx
        /**
1039 5175 psotfx
        * Check for banned user
1040 5175 psotfx
        *
1041 5175 psotfx
        * Checks whether the supplied user is banned by id, ip or email. If no parameters
1042 5633 acydburn
        * are passed to the method pre-existing session data is used. If $return is false
1043 7890 naderman
        * this routine does not return on finding a banned user, it outputs a relevant
1044 5633 acydburn
        * message and stops execution.
1045 6740 naderman
        *
1046 6740 naderman
        * @param string|array        $user_ips        Can contain a string with one IP or an array of multiple IPs
1047 5175 psotfx
        */
1048 6740 naderman
        function check_ban($user_id = false, $user_ips = false, $user_email = false, $return = false)
1049 5175 psotfx
        {
1050 5175 psotfx
                global $config, $db;
1051 6048 acydburn
1052 6803 acydburn
                if (defined('IN_CHECK_BAN'))
1053 6803 acydburn
                {
1054 6803 acydburn
                        return;
1055 6803 acydburn
                }
1056 6803 acydburn
1057 5175 psotfx
                $banned = false;
1058 8202 acydburn
                $cache_ttl = 3600;
1059 8202 acydburn
                $where_sql = array();
1060 5175 psotfx
1061 5175 psotfx
                $sql = 'SELECT ban_ip, ban_userid, ban_email, ban_exclude, ban_give_reason, ban_end
1062 5175 psotfx
                        FROM ' . BANLIST_TABLE . '
1063 8202 acydburn
                        WHERE ';
1064 6114 acydburn
1065 6114 acydburn
                // Determine which entries to check, only return those
1066 6114 acydburn
                if ($user_email === false)
1067 6114 acydburn
                {
1068 8202 acydburn
                        $where_sql[] = "ban_email = ''";
1069 6114 acydburn
                }
1070 6114 acydburn
1071 6740 naderman
                if ($user_ips === false)
1072 6114 acydburn
                {
1073 8202 acydburn
                        $where_sql[] = "(ban_ip = '' OR ban_exclude = 1)";
1074 6114 acydburn
                }
1075 6114 acydburn
1076 6114 acydburn
                if ($user_id === false)
1077 6114 acydburn
                {
1078 8202 acydburn
                        $where_sql[] = '(ban_userid = 0 OR ban_exclude = 1)';
1079 6114 acydburn
                }
1080 6114 acydburn
                else
1081 6114 acydburn
                {
1082 8202 acydburn
                        $cache_ttl = ($user_id == ANONYMOUS) ? 3600 : 0;
1083 8202 acydburn
                        $_sql = '(ban_userid = ' . $user_id;
1084 6114 acydburn
1085 6114 acydburn
                        if ($user_email !== false)
1086 6114 acydburn
                        {
1087 8202 acydburn
                                $_sql .= " OR ban_email <> ''";
1088 6114 acydburn
                        }
1089 6114 acydburn
1090 6740 naderman
                        if ($user_ips !== false)
1091 6114 acydburn
                        {
1092 8202 acydburn
                                $_sql .= " OR ban_ip <> ''";
1093 6114 acydburn
                        }
1094 6114 acydburn
1095 8202 acydburn
                        $_sql .= ')';
1096 8202 acydburn
1097 8202 acydburn
                        $where_sql[] = $_sql;
1098 6114 acydburn
                }
1099 6114 acydburn
1100 8202 acydburn
                $sql .= (sizeof($where_sql)) ? implode(' AND ', $where_sql) : '';
1101 8202 acydburn
                $result = $db->sql_query($sql, $cache_ttl);
1102 5175 psotfx
1103 6447 acydburn
                $ban_triggered_by = 'user';
1104 5323 acydburn
                while ($row = $db->sql_fetchrow($result))
1105 5038 acydburn
                {
1106 8202 acydburn
                        if ($row['ban_end'] && $row['ban_end'] < time())
1107 8202 acydburn
                        {
1108 8202 acydburn
                                continue;
1109 8202 acydburn
                        }
1110 8202 acydburn
1111 6744 naderman
                        $ip_banned = false;
1112 6744 naderman
                        if (!empty($row['ban_ip']))
1113 6744 naderman
                        {
1114 6744 naderman
                                if (!is_array($user_ips))
1115 6744 naderman
                                {
1116 7808 acydburn
                                        $ip_banned = preg_match('#^' . str_replace('\*', '.*?', preg_quote($row['ban_ip'], '#')) . '$#i', $user_ips);
1117 6744 naderman
                                }
1118 6744 naderman
                                else
1119 6744 naderman
                                {
1120 6744 naderman
                                        foreach ($user_ips as $user_ip)
1121 6744 naderman
                                        {
1122 7808 acydburn
                                                if (preg_match('#^' . str_replace('\*', '.*?', preg_quote($row['ban_ip'], '#')) . '$#i', $user_ip))
1123 6744 naderman
                                                {
1124 6744 naderman
                                                        $ip_banned = true;
1125 6744 naderman
                                                        break;
1126 6744 naderman
                                                }
1127 6744 naderman
                                        }
1128 6744 naderman
                                }
1129 6744 naderman
                        }
1130 6744 naderman
1131 5323 acydburn
                        if ((!empty($row['ban_userid']) && intval($row['ban_userid']) == $user_id) ||
1132 6744 naderman
                                $ip_banned ||
1133 7808 acydburn
                                (!empty($row['ban_email']) && preg_match('#^' . str_replace('\*', '.*?', preg_quote($row['ban_email'], '#')) . '$#i', $user_email)))
1134 5175 psotfx
                        {
1135 5323 acydburn
                                if (!empty($row['ban_exclude']))
1136 5175 psotfx
                                {
1137 5323 acydburn
                                        $banned = false;
1138 5323 acydburn
                                        break;
1139 5175 psotfx
                                }
1140 5323 acydburn
                                else
1141 5323 acydburn
                                {
1142 5323 acydburn
                                        $banned = true;
1143 5323 acydburn
                                        $ban_row = $row;
1144 6447 acydburn
1145 6447 acydburn
                                        if (!empty($row['ban_userid']) && intval($row['ban_userid']) == $user_id)
1146 6447 acydburn
                                        {
1147 6447 acydburn
                                                $ban_triggered_by = 'user';
1148 6447 acydburn
                                        }
1149 8157 acydburn
                                        else if ($ip_banned)
1150 6447 acydburn
                                        {
1151 6447 acydburn
                                                $ban_triggered_by = 'ip';
1152 6447 acydburn
                                        }
1153 6447 acydburn
                                        else
1154 6447 acydburn
                                        {
1155 6447 acydburn
                                                $ban_triggered_by = 'email';
1156 6447 acydburn
                                        }
1157 6447 acydburn
1158 5323 acydburn
                                        // Don't break. Check if there is an exclude rule for this user
1159 5323 acydburn
                                }
1160 5175 psotfx
                        }
1161 5038 acydburn
                }
1162 5175 psotfx
                $db->sql_freeresult($result);
1163 5175 psotfx
1164 5633 acydburn
                if ($banned && !$return)
1165 5038 acydburn
                {
1166 7439 acydburn
                        global $template;
1167 7439 acydburn
1168 7150 acydburn
                        // If the session is empty we need to create a valid one...
1169 7150 acydburn
                        if (empty($this->session_id))
1170 7150 acydburn
                        {
1171 8224 acydburn
                                // This seems to be no longer needed? - #14971
1172 8224 acydburn
//                                $this->session_create(ANONYMOUS);
1173 7150 acydburn
                        }
1174 7150 acydburn
1175 5175 psotfx
                        // Initiate environment ... since it won't be set at this stage
1176 5175 psotfx
                        $this->setup();
1177 5175 psotfx
1178 5219 bartvb
                        // Logout the user, banned users are unable to use the normal 'logout' link
1179 5219 bartvb
                        if ($this->data['user_id'] != ANONYMOUS)
1180 5323 acydburn
                        {
1181 5219 bartvb
                                $this->session_kill();
1182 5272 acydburn
                        }
1183 6048 acydburn
1184 6803 acydburn
                        // We show a login box here to allow founders accessing the board if banned by IP
1185 6803 acydburn
                        if (defined('IN_LOGIN') && $this->data['user_id'] == ANONYMOUS)
1186 6803 acydburn
                        {
1187 6803 acydburn
                                global $phpEx;
1188 6803 acydburn
1189 7439 acydburn
                                $this->setup('ucp');
1190 7439 acydburn
                                $this->data['is_registered'] = $this->data['is_bot'] = false;
1191 7439 acydburn
1192 6803 acydburn
                                // Set as a precaution to allow login_box() handling this case correctly as well as this function not being executed again.
1193 6803 acydburn
                                define('IN_CHECK_BAN', 1);
1194 6803 acydburn
1195 6803 acydburn
                                login_box("index.$phpEx");
1196 6803 acydburn
1197 6803 acydburn
                                // The false here is needed, else the user is able to circumvent the ban.
1198 6803 acydburn
                                $this->session_kill(false);
1199 6803 acydburn
                        }
1200 6803 acydburn
1201 7150 acydburn
                        // Ok, we catch the case of an empty session id for the anonymous user...
1202 7150 acydburn
                        // This can happen if the user is logging in, banned by username and the login_box() being called "again".
1203 7439 acydburn
                        if (empty($this->session_id) && defined('IN_CHECK_BAN'))
1204 7150 acydburn
                        {
1205 7150 acydburn
                                $this->session_create(ANONYMOUS);
1206 7150 acydburn
                        }
1207 7150 acydburn
1208 7439 acydburn
1209 5175 psotfx
                        // Determine which message to output
1210 5323 acydburn
                        $till_date = ($ban_row['ban_end']) ? $this->format_date($ban_row['ban_end']) : '';
1211 5323 acydburn
                        $message = ($ban_row['ban_end']) ? 'BOARD_BAN_TIME' : 'BOARD_BAN_PERM';
1212 5175 psotfx
1213 5175 psotfx
                        $message = sprintf($this->lang[$message], $till_date, '<a href="mailto:' . $config['board_contact'] . '">', '</a>');
1214 5323 acydburn
                        $message .= ($ban_row['ban_give_reason']) ? '<br /><br />' . sprintf($this->lang['BOARD_BAN_REASON'], $ban_row['ban_give_reason']) : '';
1215 6551 davidmj
                        $message .= '<br /><br /><em>' . $this->lang['BAN_TRIGGERED_BY_' . strtoupper($ban_triggered_by)] . '</em>';
1216 6447 acydburn
1217 8225 acydburn
                        // To circumvent session_begin returning a valid value and the check_ban() not called on second page view, we kill the session again
1218 8225 acydburn
                        $this->session_kill(false);
1219 8225 acydburn
1220 8661 acydburn
                        // A very special case... we are within the cron script which is not supposed to print out the ban message... show blank page
1221 8661 acydburn
                        if (defined('IN_CRON'))
1222 8661 acydburn
                        {
1223 8661 acydburn
                                garbage_collection();
1224 8661 acydburn
                                exit_handler();
1225 8661 acydburn
                                exit;
1226 8661 acydburn
                        }
1227 8661 acydburn
1228 5175 psotfx
                        trigger_error($message);
1229 5038 acydburn
                }
1230 5633 acydburn
1231 8565 acydburn
                return ($banned && $ban_row['ban_give_reason']) ? $ban_row['ban_give_reason'] : $banned;
1232 2932 psotfx
        }
1233 6048 acydburn
1234 5175 psotfx
        /**
1235 6414 acydburn
        * Check if ip is blacklisted
1236 6414 acydburn
        * This should be called only where absolutly necessary
1237 6414 acydburn
        *
1238 6414 acydburn
        * Only IPv4 (rbldns does not support AAAA records/IPv6 lookups)
1239 6414 acydburn
        *
1240 6414 acydburn
        * @author satmd (from the php manual)
1241 6698 acydburn
        * @param string $mode register/post - spamcop for example is ommitted for posting
1242 6414 acydburn
        * @return false if ip is not blacklisted, else an array([checked server], [lookup])
1243 6414 acydburn
        */
1244 6698 acydburn
        function check_dnsbl($mode, $ip = false)
1245 6414 acydburn
        {
1246 6414 acydburn
                if ($ip === false)
1247 6414 acydburn
                {
1248 6414 acydburn
                        $ip = $this->ip;
1249 6414 acydburn
                }
1250 6414 acydburn
1251 11167 git-gate
                // Neither Spamhaus nor Spamcop supports IPv6 addresses.
1252 11167 git-gate
                if (strpos($ip, ':') !== false)
1253 11167 git-gate
                {
1254 11167 git-gate
                        return false;
1255 11167 git-gate
                }
1256 11167 git-gate
1257 6414 acydburn
                $dnsbl_check = array(
1258 9484 acydburn
                        'sbl.spamhaus.org'        => 'http://www.spamhaus.org/query/bl?ip=',
1259 6414 acydburn
                );
1260 6414 acydburn
1261 6698 acydburn
                if ($mode == 'register')
1262 6698 acydburn
                {
1263 6698 acydburn
                        $dnsbl_check['bl.spamcop.net'] = 'http://spamcop.net/bl.shtml?';
1264 6698 acydburn
                }
1265 6698 acydburn
1266 6414 acydburn
                if ($ip)
1267 6414 acydburn
                {
1268 6414 acydburn
                        $quads = explode('.', $ip);
1269 6414 acydburn
                        $reverse_ip = $quads[3] . '.' . $quads[2] . '.' . $quads[1] . '.' . $quads[0];
1270 6414 acydburn
1271 6719 acydburn
                        // Need to be listed on all servers...
1272 6719 acydburn
                        $listed = true;
1273 6719 acydburn
                        $info = array();
1274 6719 acydburn
1275 6414 acydburn
                        foreach ($dnsbl_check as $dnsbl => $lookup)
1276 6414 acydburn
                        {
1277 6414 acydburn
                                if (phpbb_checkdnsrr($reverse_ip . '.' . $dnsbl . '.', 'A') === true)
1278 6414 acydburn
                                {
1279 6719 acydburn
                                        $info = array($dnsbl, $lookup . $ip);
1280 6414 acydburn
                                }
1281 6719 acydburn
                                else
1282 6719 acydburn
                                {
1283 6719 acydburn
                                        $listed = false;
1284 6719 acydburn
                                }
1285 6414 acydburn
                        }
1286 6719 acydburn
1287 6719 acydburn
                        if ($listed)
1288 6719 acydburn
                        {
1289 6719 acydburn
                                return $info;
1290 6719 acydburn
                        }
1291 6414 acydburn
                }
1292 6414 acydburn
1293 6414 acydburn
                return false;
1294 6414 acydburn
        }
1295 6414 acydburn
1296 6414 acydburn
        /**
1297 7034 acydburn
        * Check if URI is blacklisted
1298 7034 acydburn
        * This should be called only where absolutly necessary, for example on the submitted website field
1299 7034 acydburn
        * This function is not in use at the moment and is only included for testing purposes, it may not work at all!
1300 7034 acydburn
        * This means it is untested at the moment and therefore commented out
1301 7034 acydburn
        *
1302 7034 acydburn
        * @param string $uri URI to check
1303 7034 acydburn
        * @return true if uri is on blacklist, else false. Only blacklist is checked (~zero FP), no grey lists
1304 7034 acydburn
        function check_uribl($uri)
1305 7034 acydburn
        {
1306 7034 acydburn
                // Normally parse_url() is not intended to parse uris
1307 7034 acydburn
                // We need to get the top-level domain name anyway... change.
1308 7034 acydburn
                $uri = parse_url($uri);
1309 7034 acydburn
1310 7034 acydburn
                if ($uri === false || empty($uri['host']))
1311 7034 acydburn
                {
1312 7034 acydburn
                        return false;
1313 7034 acydburn
                }
1314 7034 acydburn
1315 7034 acydburn
                $uri = trim($uri['host']);
1316 7034 acydburn
1317 7034 acydburn
                if ($uri)
1318 7034 acydburn
                {
1319 7034 acydburn
                        // One problem here... the return parameter for the "windows" method is different from what
1320 7034 acydburn
                        // we expect... this may render this check useless...
1321 7034 acydburn
                        if (phpbb_checkdnsrr($uri . '.multi.uribl.com.', 'A') === true)
1322 7034 acydburn
                        {
1323 7034 acydburn
                                return true;
1324 7034 acydburn
                        }
1325 7034 acydburn
                }
1326 7034 acydburn
1327 7034 acydburn
                return false;
1328 7034 acydburn
        }
1329 7034 acydburn
        */
1330 7034 acydburn
1331 7034 acydburn
        /**
1332 5175 psotfx
        * Set/Update a persistent login key
1333 5175 psotfx
        *
1334 5175 psotfx
        * This method creates or updates a persistent session key. When a user makes
1335 5175 psotfx
        * use of persistent (formerly auto-) logins a key is generated and stored in the
1336 5175 psotfx
        * DB. When they revisit with the same key it's automatically updated in both the
1337 5175 psotfx
        * DB and cookie. Multiple keys may exist for each user representing different
1338 5175 psotfx
        * browsers or locations. As with _any_ non-secure-socket no passphrase login this
1339 6048 acydburn
        * remains vulnerable to exploit.
1340 5175 psotfx
        */
1341 5175 psotfx
        function set_login_key($user_id = false, $key = false, $user_ip = false)
1342 5175 psotfx
        {
1343 5175 psotfx
                global $config, $db;
1344 6048 acydburn
1345 5175 psotfx
                $user_id = ($user_id === false) ? $this->data['user_id'] : $user_id;
1346 5175 psotfx
                $user_ip = ($user_ip === false) ? $this->ip : $user_ip;
1347 5339 acydburn
                $key = ($key === false) ? (($this->cookie_data['k']) ? $this->cookie_data['k'] : false) : $key;
1348 6048 acydburn
1349 5288 grahamje
                $key_id = unique_id(hexdec(substr($this->session_id, 0, 8)));
1350 6048 acydburn
1351 5175 psotfx
                $sql_ary = array(
1352 5288 grahamje
                        'key_id'                => (string) md5($key_id),
1353 5175 psotfx
                        'last_ip'                => (string) $this->ip,
1354 5175 psotfx
                        'last_login'        => (int) time()
1355 5175 psotfx
                );
1356 5339 acydburn
1357 5175 psotfx
                if (!$key)
1358 5175 psotfx
                {
1359 5175 psotfx
                        $sql_ary += array(
1360 5175 psotfx
                                'user_id'        => (int) $user_id
1361 5175 psotfx
                        );
1362 5175 psotfx
                }
1363 6048 acydburn
1364 6048 acydburn
                if ($key)
1365 6048 acydburn
                {
1366 6048 acydburn
                        $sql = 'UPDATE ' . SESSIONS_KEYS_TABLE . '
1367 6048 acydburn
                                SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
1368 6048 acydburn
                                WHERE user_id = ' . (int) $user_id . "
1369 6048 acydburn
                                        AND key_id = '" . $db->sql_escape(md5($key)) . "'";
1370 6048 acydburn
                }
1371 6048 acydburn
                else
1372 6048 acydburn
                {
1373 6048 acydburn
                        $sql = 'INSERT INTO ' . SESSIONS_KEYS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
1374 6048 acydburn
                }
1375 5175 psotfx
                $db->sql_query($sql);
1376 6048 acydburn
1377 5288 grahamje
                $this->cookie_data['k'] = $key_id;
1378 6048 acydburn
1379 5175 psotfx
                return false;
1380 5175 psotfx
        }
1381 5660 grahamje
1382 5660 grahamje
        /**
1383 5660 grahamje
        * Reset all login keys for the specified user
1384 5660 grahamje
        *
1385 5660 grahamje
        * This method removes all current login keys for a specified (or the current)
1386 5660 grahamje
        * user. It will be called on password change to render old keys unusable
1387 5660 grahamje
        */
1388 5660 grahamje
        function reset_login_keys($user_id = false)
1389 5660 grahamje
        {
1390 5660 grahamje
                global $config, $db;
1391 5660 grahamje
1392 10279 bantu
                $user_id = ($user_id === false) ? (int) $this->data['user_id'] : (int) $user_id;
1393 5660 grahamje
1394 6048 acydburn
                $sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
1395 6048 acydburn
                        WHERE user_id = ' . (int) $user_id;
1396 5660 grahamje
                $db->sql_query($sql);
1397 5660 grahamje
1398 10443 brainy
                // If the user is logged in, update last visit info first before deleting sessions
1399 10103 terrafrost
                $sql = 'SELECT session_time, session_page
1400 10103 terrafrost
                        FROM ' . SESSIONS_TABLE . '
1401 10103 terrafrost
                        WHERE session_user_id = ' . (int) $user_id . '
1402 10103 terrafrost
                        ORDER BY session_time DESC';
1403 10103 terrafrost
                $result = $db->sql_query_limit($sql, 1);
1404 10103 terrafrost
                $row = $db->sql_fetchrow($result);
1405 10103 terrafrost
                $db->sql_freeresult($result);
1406 10103 terrafrost
1407 10443 brainy
                if ($row)
1408 10443 brainy
                {
1409 10443 brainy
                        $sql = 'UPDATE ' . USERS_TABLE . '
1410 10443 brainy
                                SET user_lastvisit = ' . (int) $row['session_time'] . ", user_lastpage = '" . $db->sql_escape($row['session_page']) . "'
1411 10443 brainy
                                WHERE user_id = " . (int) $user_id;
1412 10443 brainy
                        $db->sql_query($sql);
1413 10443 brainy
                }
1414 10103 terrafrost
1415 5663 grahamje
                // Let's also clear any current sessions for the specified user_id
1416 5663 grahamje
                // If it's the current user then we'll leave this session intact
1417 5663 grahamje
                $sql_where = 'session_user_id = ' . (int) $user_id;
1418 10279 bantu
                $sql_where .= ($user_id === (int) $this->data['user_id']) ? " AND session_id <> '" . $db->sql_escape($this->session_id) . "'" : '';
1419 5663 grahamje
1420 7890 naderman
                $sql = 'DELETE FROM ' . SESSIONS_TABLE . "
1421 5663 grahamje
                        WHERE $sql_where";
1422 5663 grahamje
                $db->sql_query($sql);
1423 5663 grahamje
1424 5660 grahamje
                // We're changing the password of the current user and they have a key
1425 5660 grahamje
                // Lets regenerate it to be safe
1426 10279 bantu
                if ($user_id === (int) $this->data['user_id'] && $this->cookie_data['k'])
1427 5660 grahamje
                {
1428 5660 grahamje
                        $this->set_login_key($user_id);
1429 5660 grahamje
                }
1430 5660 grahamje
        }
1431 8565 acydburn
1432 8565 acydburn
1433 8554 Kellanved
        /**
1434 8565 acydburn
        * Check if the request originated from the same page.
1435 8554 Kellanved
        * @param bool $check_script_path If true, the path will be checked as well
1436 8554 Kellanved
        */
1437 8554 Kellanved
        function validate_referer($check_script_path = false)
1438 8554 Kellanved
        {
1439 9917 nickvergessen
                global $config;
1440 9917 nickvergessen
1441 8554 Kellanved
                // no referer - nothing to validate, user's fault for turning it off (we only check on POST; so meta can't be the reason)
1442 8846 acydburn
                if (empty($this->referer) || empty($this->host))
1443 8554 Kellanved
                {
1444 8554 Kellanved
                        return true;
1445 8554 Kellanved
                }
1446 8636 acydburn
1447 8554 Kellanved
                $host = htmlspecialchars($this->host);
1448 8554 Kellanved
                $ref = substr($this->referer, strpos($this->referer, '://') + 3);
1449 9479 Kellanved
1450 9917 nickvergessen
                if (!(stripos($ref, $host) === 0) && (!$config['force_server_vars'] || !(stripos($ref, $config['server_name']) === 0)))
1451 8554 Kellanved
                {
1452 8554 Kellanved
                        return false;
1453 8554 Kellanved
                }
1454 8559 Kellanved
                else if ($check_script_path && rtrim($this->page['root_script_path'], '/') !== '')
1455 8554 Kellanved
                {
1456 8554 Kellanved
                        $ref = substr($ref, strlen($host));
1457 8559 Kellanved
                        $server_port = (!empty($_SERVER['SERVER_PORT'])) ? (int) $_SERVER['SERVER_PORT'] : (int) getenv('SERVER_PORT');
1458 8636 acydburn
1459 8560 Kellanved
                        if ($server_port !== 80 && $server_port !== 443 && stripos($ref, ":$server_port") === 0)
1460 8559 Kellanved
                        {
1461 8559 Kellanved
                                $ref = substr($ref, strlen(":$server_port"));
1462 8559 Kellanved
                        }
1463 8636 acydburn
1464 8554 Kellanved
                        if (!(stripos(rtrim($ref, '/'), rtrim($this->page['root_script_path'], '/')) === 0))
1465 8554 Kellanved
                        {
1466 8554 Kellanved
                                return false;
1467 8554 Kellanved
                        }
1468 8554 Kellanved
                }
1469 8636 acydburn
1470 8554 Kellanved
                return true;
1471 8554 Kellanved
        }
1472 8580 Kellanved
1473 8580 Kellanved
1474 8580 Kellanved
        function unset_admin()
1475 8580 Kellanved
        {
1476 8580 Kellanved
                global $db;
1477 8580 Kellanved
                $sql = 'UPDATE ' . SESSIONS_TABLE . '
1478 8580 Kellanved
                        SET session_admin = 0
1479 8580 Kellanved
                        WHERE session_id = \'' . $db->sql_escape($this->session_id) . '\'';
1480 8580 Kellanved
                $db->sql_query($sql);
1481 8580 Kellanved
        }
1482 2661 psotfx
}
1483 2661 psotfx
1484 5177 psotfx
1485 5114 acydburn
/**
1486 5175 psotfx
* Base user class
1487 5175 psotfx
*
1488 5175 psotfx
* This is the overarching class which contains (through session extend)
1489 5175 psotfx
* all methods utilised for user functionality during a session.
1490 6058 acydburn
*
1491 6058 acydburn
* @package phpBB3
1492 5114 acydburn
*/
1493 2958 psotfx
class user extends session
1494 2923 psotfx
{
1495 2958 psotfx
        var $lang = array();
1496 4844 acydburn
        var $help = array();
1497 2958 psotfx
        var $theme = array();
1498 2923 psotfx
        var $date_format;
1499 2923 psotfx
        var $timezone;
1500 2923 psotfx
        var $dst;
1501 2880 psotfx
1502 8782 acydburn
        var $lang_name = false;
1503 8011 acydburn
        var $lang_id = false;
1504 2958 psotfx
        var $lang_path;
1505 2958 psotfx
        var $img_lang;
1506 7304 davidmj
        var $img_array = array();
1507 2958 psotfx
1508 9696 rxu
        // Able to add new options (up to id 31)
1509 9696 rxu
        var $keyoptions = array('viewimg' => 0, 'viewflash' => 1, 'viewsmilies' => 2, 'viewsigs' => 3, 'viewavatars' => 4, 'viewcensors' => 5, 'attachsig' => 6, 'bbcode' => 8, 'smilies' => 9, 'popuppm' => 10, 'sig_bbcode' => 15, 'sig_smilies' => 16, 'sig_links' => 17);
1510 4440 psotfx
1511 6048 acydburn
        /**
1512 8782 acydburn
        * Constructor to set the lang path
1513 8782 acydburn
        */
1514 8782 acydburn
        function user()
1515 8782 acydburn
        {
1516 8782 acydburn
                global $phpbb_root_path;
1517 8782 acydburn
1518 8782 acydburn
                $this->lang_path = $phpbb_root_path . 'language/';
1519 8782 acydburn
        }
1520 8782 acydburn
1521 8782 acydburn
        /**
1522 8782 acydburn
        * Function to set custom language path (able to use directory outside of phpBB)
1523 8782 acydburn
        *
1524 8782 acydburn
        * @param string $lang_path New language path used.
1525 8782 acydburn
        * @access public
1526 8782 acydburn
        */
1527 8782 acydburn
        function set_custom_lang_path($lang_path)
1528 8782 acydburn
        {
1529 8782 acydburn
                $this->lang_path = $lang_path;
1530 8782 acydburn
1531 8782 acydburn
                if (substr($this->lang_path, -1) != '/')
1532 8782 acydburn
                {
1533 8782 acydburn
                        $this->lang_path .= '/';
1534 8782 acydburn
                }
1535 8782 acydburn
        }
1536 8782 acydburn
1537 8782 acydburn
        /**
1538 6048 acydburn
        * Setup basic user-specific items (style, language, ...)
1539 6048 acydburn
        */
1540 2958 psotfx
        function setup($lang_set = false, $style = false)
1541 2923 psotfx
        {
1542 5372 acydburn
                global $db, $template, $config, $auth, $phpEx, $phpbb_root_path, $cache;
1543 2923 psotfx
1544 2997 psotfx
                if ($this->data['user_id'] != ANONYMOUS)
1545 2923 psotfx
                {
1546 8782 acydburn
                        $this->lang_name = (file_exists($this->lang_path . $this->data['user_lang'] . "/common.$phpEx")) ? $this->data['user_lang'] : basename($config['default_lang']);
1547 2923 psotfx
1548 2958 psotfx
                        $this->date_format = $this->data['user_dateformat'];
1549 2958 psotfx
                        $this->timezone = $this->data['user_timezone'] * 3600;
1550 2958 psotfx
                        $this->dst = $this->data['user_dst'] * 3600;
1551 2923 psotfx
                }
1552 2958 psotfx
                else
1553 2923 psotfx
                {
1554 7879 kellanved
                        $this->lang_name = basename($config['default_lang']);
1555 2983 psotfx
                        $this->date_format = $config['default_dateformat'];
1556 2983 psotfx
                        $this->timezone = $config['board_timezone'] * 3600;
1557 3802 psotfx
                        $this->dst = $config['board_dst'] * 3600;
1558 2942 psotfx
1559 6436 acydburn
                        /**
1560 6436 acydburn
                        * If a guest user is surfing, we try to guess his/her language first by obtaining the browser language
1561 6614 acydburn
                        * If re-enabled we need to make sure only those languages installed are checked
1562 6614 acydburn
                        * Commented out so we do not loose the code.
1563 6048 acydburn
1564 2997 psotfx
                        if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
1565 2923 psotfx
                        {
1566 2958 psotfx
                                $accept_lang_ary = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
1567 6436 acydburn
1568 2997 psotfx
                                foreach ($accept_lang_ary as $accept_lang)
1569 2923 psotfx
                                {
1570 2958 psotfx
                                        // Set correct format ... guess full xx_YY form
1571 2958 psotfx
                                        $accept_lang = substr($accept_lang, 0, 2) . '_' . strtoupper(substr($accept_lang, 3, 2));
1572 6436 acydburn
                                        $accept_lang = basename($accept_lang);
1573 6436 acydburn
1574 8782 acydburn
                                        if (file_exists($this->lang_path . $accept_lang . "/common.$phpEx"))
1575 2923 psotfx
                                        {
1576 5074 acydburn
                                                $this->lang_name = $config['default_lang'] = $accept_lang;
1577 2923 psotfx
                                                break;
1578 2923 psotfx
                                        }
1579 2958 psotfx
                                        else
1580 2958 psotfx
                                        {
1581 2958 psotfx
                                                // No match on xx_YY so try xx
1582 2958 psotfx
                                                $accept_lang = substr($accept_lang, 0, 2);
1583 6436 acydburn
                                                $accept_lang = basename($accept_lang);
1584 6436 acydburn
1585 8782 acydburn
                                                if (file_exists($this->lang_path . $accept_lang . "/common.$phpEx"))
1586 2958 psotfx
                                                {
1587 5074 acydburn
                                                        $this->lang_name = $config['default_lang'] = $accept_lang;
1588 2958 psotfx
                                                        break;
1589 2958 psotfx
                                                }
1590 2958 psotfx
                                        }
1591 2923 psotfx
                                }
1592 2923 psotfx
                        }
1593 6436 acydburn
                        */
1594 2923 psotfx
                }
1595 7890 naderman
1596 4962 acydburn
                // We include common language file here to not load it every time a custom language file is included
1597 4962 acydburn
                $lang = &$this->lang;
1598 7879 kellanved
1599 9383 acydburn
                // Do not suppress error if in DEBUG_EXTRA mode
1600 9383 acydburn
                $include_result = (defined('DEBUG_EXTRA')) ? (include $this->lang_path . $this->lang_name . "/common.$phpEx") : (@include $this->lang_path . $this->lang_name . "/common.$phpEx");
1601 9383 acydburn
1602 9383 acydburn
                if ($include_result === false)
1603 5104 bartvb
                {
1604 8782 acydburn
                        die('Language file ' . $this->lang_path . $this->lang_name . "/common.$phpEx" . " couldn't be opened.");
1605 5104 bartvb
                }
1606 4962 acydburn
1607 4844 acydburn
                $this->add_lang($lang_set);
1608 4844 acydburn
                unset($lang_set);
1609 4970 psotfx
1610 9841 nickvergessen
                if (!empty($_GET['style']) && $auth->acl_get('a_styles') && !defined('ADMIN_START'))
1611 4250 psotfx
                {
1612 6015 acydburn
                        global $SID, $_EXTRA_URL;
1613 4473 psotfx
1614 5064 acydburn
                        $style = request_var('style', 0);
1615 5064 acydburn
                        $SID .= '&amp;style=' . $style;
1616 6015 acydburn
                        $_EXTRA_URL = array('style=' . $style);
1617 4250 psotfx
                }
1618 4250 psotfx
                else
1619 4250 psotfx
                {
1620 4250 psotfx
                        // Set up style
1621 8075 acydburn
                        $style = ($style) ? $style : ((!$config['override_user_style']) ? $this->data['user_style'] : $config['default_style']);
1622 4250 psotfx
                }
1623 2923 psotfx
1624 8697 Kellanved
                $sql = 'SELECT s.style_id, t.template_storedb, t.template_path, t.template_id, t.bbcode_bitfield, t.template_inherits_id, t.template_inherit_path, c.theme_path, c.theme_name, c.theme_storedb, c.theme_id, i.imageset_path, i.imageset_id, i.imageset_name
1625 6021 acydburn
                        FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . " i
1626 5372 acydburn
                        WHERE s.style_id = $style
1627 5372 acydburn
                                AND t.template_id = s.template_id
1628 5372 acydburn
                                AND c.theme_id = s.theme_id
1629 5372 acydburn
                                AND i.imageset_id = s.imageset_id";
1630 4473 psotfx
                $result = $db->sql_query($sql, 3600);
1631 5372 acydburn
                $this->theme = $db->sql_fetchrow($result);
1632 6048 acydburn
                $db->sql_freeresult($result);
1633 2923 psotfx
1634 5486 acydburn
                // User has wrong style
1635 5486 acydburn
                if (!$this->theme && $style == $this->data['user_style'])
1636 5486 acydburn
                {
1637 5486 acydburn
                        $style = $this->data['user_style'] = $config['default_style'];
1638 5486 acydburn
1639 7890 naderman
                        $sql = 'UPDATE ' . USERS_TABLE . "
1640 7890 naderman
                                SET user_style = $style
1641 5486 acydburn
                                WHERE user_id = {$this->data['user_id']}";
1642 5486 acydburn
                        $db->sql_query($sql);
1643 5486 acydburn
1644 7914 davidmj
                        $sql = 'SELECT s.style_id, t.template_storedb, t.template_path, t.template_id, t.bbcode_bitfield, c.theme_path, c.theme_name, c.theme_storedb, c.theme_id, i.imageset_path, i.imageset_id, i.imageset_name
1645 6021 acydburn
                                FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . " i
1646 5486 acydburn
                                WHERE s.style_id = $style
1647 5486 acydburn
                                        AND t.template_id = s.template_id
1648 5486 acydburn
                                        AND c.theme_id = s.theme_id
1649 5486 acydburn
                                        AND i.imageset_id = s.imageset_id";
1650 5643 acydburn
                        $result = $db->sql_query($sql, 3600);
1651 5486 acydburn
                        $this->theme = $db->sql_fetchrow($result);
1652 5486 acydburn
                        $db->sql_freeresult($result);
1653 5486 acydburn
                }
1654 5486 acydburn
1655 5372 acydburn
                if (!$this->theme)
1656 2923 psotfx
                {
1657 5426 grahamje
                        trigger_error('Could not get style data', E_USER_ERROR);
1658 2923 psotfx
                }
1659 2923 psotfx
1660 5372 acydburn
                // Now parse the cfg file and cache it
1661 5372 acydburn
                $parsed_items = $cache->obtain_cfg_items($this->theme);
1662 5643 acydburn
1663 5372 acydburn
                // We are only interested in the theme configuration for now
1664 5372 acydburn
                $parsed_items = $parsed_items['theme'];
1665 2923 psotfx
1666 5372 acydburn
                $check_for = array(
1667 5372 acydburn
                        'parse_css_file'        => (int) 0,
1668 5372 acydburn
                        'pagination_sep'        => (string) ', '
1669 5372 acydburn
                );
1670 2923 psotfx
1671 5372 acydburn
                foreach ($check_for as $key => $default_value)
1672 4897 acydburn
                {
1673 5374 subblue
                        $this->theme[$key] = (isset($parsed_items[$key])) ? $parsed_items[$key] : $default_value;
1674 5372 acydburn
                        settype($this->theme[$key], gettype($default_value));
1675 5372 acydburn
1676 5372 acydburn
                        if (is_string($default_value))
1677 5372 acydburn
                        {
1678 5372 acydburn
                                $this->theme[$key] = htmlspecialchars($this->theme[$key]);
1679 5372 acydburn
                        }
1680 4897 acydburn
                }
1681 4897 acydburn
1682 6048 acydburn
                // If the style author specified the theme needs to be cached
1683 6048 acydburn
                // (because of the used paths and variables) than make sure it is the case.
1684 6048 acydburn
                // For example, if the theme uses language-specific images it needs to be stored in db.
1685 5372 acydburn
                if (!$this->theme['theme_storedb'] && $this->theme['parse_css_file'])
1686 5068 acydburn
                {
1687 5372 acydburn
                        $this->theme['theme_storedb'] = 1;
1688 5175 psotfx
1689 6254 naderman
                        $stylesheet = file_get_contents("{$phpbb_root_path}styles/{$this->theme['theme_path']}/theme/stylesheet.css");
1690 6254 naderman
                        // Match CSS imports
1691 6254 naderman
                        $matches = array();
1692 6254 naderman
                        preg_match_all('/@import url\(["\'](.*)["\']\);/i', $stylesheet, $matches);
1693 7890 naderman
1694 6254 naderman
                        if (sizeof($matches))
1695 6254 naderman
                        {
1696 6254 naderman
                                $content = '';
1697 6254 naderman
                                foreach ($matches[0] as $idx => $match)
1698 6254 naderman
                                {
1699 6254 naderman
                                        if ($content = @file_get_contents("{$phpbb_root_path}styles/{$this->theme['theme_path']}/theme/" . $matches[1][$idx]))
1700 6254 naderman
                                        {
1701 6254 naderman
                                                $content = trim($content);
1702 6254 naderman
                                        }
1703 6254 naderman
                                        else
1704 6254 naderman
                                        {
1705 6254 naderman
                                                $content = '';
1706 6254 naderman
                                        }
1707 6254 naderman
                                        $stylesheet = str_replace($match, $content, $stylesheet);
1708 6254 naderman
                                }
1709 6912 acydburn
                                unset($content);
1710 6254 naderman
                        }
1711 6254 naderman
1712 6254 naderman
                        $stylesheet = str_replace('./', 'styles/' . $this->theme['theme_path'] . '/theme/', $stylesheet);
1713 6254 naderman
1714 5068 acydburn
                        $sql_ary = array(
1715 6254 naderman
                                'theme_data'        => $stylesheet,
1716 5068 acydburn
                                'theme_mtime'        => time(),
1717 5068 acydburn
                                'theme_storedb'        => 1
1718 5068 acydburn
                        );
1719 5068 acydburn
1720 6048 acydburn
                        $sql = 'UPDATE ' . STYLES_THEME_TABLE . '
1721 6048 acydburn
                                SET ' . $db->sql_build_array('UPDATE', $sql_ary) . '
1722 6048 acydburn
                                WHERE theme_id = ' . $this->theme['theme_id'];
1723 6048 acydburn
                        $db->sql_query($sql);
1724 5175 psotfx
1725 5068 acydburn
                        unset($sql_ary);
1726 5068 acydburn
                }
1727 5068 acydburn
1728 4235 psotfx
                $template->set_template();
1729 4235 psotfx
1730 5372 acydburn
                $this->img_lang = (file_exists($phpbb_root_path . 'styles/' . $this->theme['imageset_path'] . '/imageset/' . $this->lang_name)) ? $this->lang_name : $config['default_lang'];
1731 4235 psotfx
1732 9366 acydburn
                // Same query in style.php
1733 9366 acydburn
                $sql = 'SELECT *
1734 7304 davidmj
                        FROM ' . STYLES_IMAGESET_DATA_TABLE . '
1735 7304 davidmj
                        WHERE imageset_id = ' . $this->theme['imageset_id'] . "
1736 8348 acydburn
                        AND image_filename <> ''
1737 8049 acydburn
                        AND image_lang IN ('" . $db->sql_escape($this->img_lang) . "', '')";
1738 7304 davidmj
                $result = $db->sql_query($sql, 3600);
1739 7304 davidmj
1740 7654 naderman
                $localised_images = false;
1741 7304 davidmj
                while ($row = $db->sql_fetchrow($result))
1742 7304 davidmj
                {
1743 7654 naderman
                        if ($row['image_lang'])
1744 7654 naderman
                        {
1745 7654 naderman
                                $localised_images = true;
1746 7654 naderman
                        }
1747 7897 davidmj
1748 8670 acydburn
                        $row['image_filename'] = rawurlencode($row['image_filename']);
1749 7304 davidmj
                        $this->img_array[$row['image_name']] = $row;
1750 7304 davidmj
                }
1751 7655 naderman
                $db->sql_freeresult($result);
1752 7304 davidmj
1753 7654 naderman
                // there were no localised images, try to refresh the localised imageset for the user's language
1754 7654 naderman
                if (!$localised_images)
1755 7654 naderman
                {
1756 7654 naderman
                        // Attention: this code ignores the image definition list from acp_styles and just takes everything
1757 7654 naderman
                        // that the config file contains
1758 7654 naderman
                        $sql_ary = array();
1759 7890 naderman
1760 7654 naderman
                        $db->sql_transaction('begin');
1761 7890 naderman
1762 7654 naderman
                        $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . '
1763 7654 naderman
                                WHERE imageset_id = ' . $this->theme['imageset_id'] . '
1764 7654 naderman
                                        AND image_lang = \'' . $db->sql_escape($this->img_lang) . '\'';
1765 7654 naderman
                        $result = $db->sql_query($sql);
1766 7654 naderman
1767 7654 naderman
                        if (@file_exists("{$phpbb_root_path}styles/{$this->theme['imageset_path']}/imageset/{$this->img_lang}/imageset.cfg"))
1768 7654 naderman
                        {
1769 7654 naderman
                                $cfg_data_imageset_data = parse_cfg_file("{$phpbb_root_path}styles/{$this->theme['imageset_path']}/imageset/{$this->img_lang}/imageset.cfg");
1770 7654 naderman
                                foreach ($cfg_data_imageset_data as $image_name => $value)
1771 7654 naderman
                                {
1772 7654 naderman
                                        if (strpos($value, '*') !== false)
1773 7654 naderman
                                        {
1774 7654 naderman
                                                if (substr($value, -1, 1) === '*')
1775 7654 naderman
                                                {
1776 7654 naderman
                                                        list($image_filename, $image_height) = explode('*', $value);
1777 7654 naderman
                                                        $image_width = 0;
1778 7654 naderman
                                                }
1779 7654 naderman
                                                else
1780 7654 naderman
                                                {
1781 7654 naderman
                                                        list($image_filename, $image_height, $image_width) = explode('*', $value);
1782 7654 naderman
                                                }
1783 7654 naderman
                                        }
1784 7654 naderman
                                        else
1785 7654 naderman
                                        {
1786 7654 naderman
                                                $image_filename = $value;
1787 7654 naderman
                                                $image_height = $image_width = 0;
1788 7654 naderman
                                        }
1789 7654 naderman
1790 7654 naderman
                                        if (strpos($image_name, 'img_') === 0 && $image_filename)
1791 7654 naderman
                                        {
1792 7654 naderman
                                                $image_name = substr($image_name, 4);
1793 7654 naderman
                                                $sql_ary[] = array(
1794 7961 acydburn
                                                        'image_name'                => (string) $image_name,
1795 7961 acydburn
                                                        'image_filename'        => (string) $image_filename,
1796 7961 acydburn
                                                        'image_height'                => (int) $image_height,
1797 7961 acydburn
                                                        'image_width'                => (int) $image_width,
1798 7961 acydburn
                                                        'imageset_id'                => (int) $this->theme['imageset_id'],
1799 7961 acydburn
                                                        'image_lang'                => (string) $this->img_lang,
1800 7654 naderman
                                                );
1801 7654 naderman
                                        }
1802 7654 naderman
                                }
1803 7654 naderman
                        }
1804 7890 naderman
1805 7890 naderman
                        if (sizeof($sql_ary))
1806 7890 naderman
                        {
1807 7890 naderman
                                $db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary);
1808 7890 naderman
                                $db->sql_transaction('commit');
1809 7890 naderman
                                $cache->destroy('sql', STYLES_IMAGESET_DATA_TABLE);
1810 7890 naderman
1811 7890 naderman
                                add_log('admin', 'LOG_IMAGESET_LANG_REFRESHED', $this->theme['imageset_name'], $this->img_lang);
1812 7890 naderman
                        }
1813 7890 naderman
                        else
1814 7890 naderman
                        {
1815 7890 naderman
                                $db->sql_transaction('commit');
1816 7890 naderman
                                add_log('admin', 'LOG_IMAGESET_LANG_MISSING', $this->theme['imageset_name'], $this->img_lang);
1817 7890 naderman
                        }
1818 7654 naderman
                }
1819 7654 naderman
1820 8100 acydburn
                // Call phpbb_user_session_handler() in case external application want to "bend" some variables or replace classes...
1821 8100 acydburn
                // After calling it we continue script execution...
1822 8100 acydburn
                phpbb_user_session_handler();
1823 8100 acydburn
1824 7102 acydburn
                // If this function got called from the error handler we are finished here.
1825 7102 acydburn
                if (defined('IN_ERROR_HANDLER'))
1826 7102 acydburn
                {
1827 7102 acydburn
                        return;
1828 7102 acydburn
                }
1829 7102 acydburn
1830 6628 acydburn
                // Disable board if the install/ directory is still present
1831 6628 acydburn
                // For the brave development army we do not care about this, else we need to comment out this everytime we develop locally
1832 9654 rxu
                if (!defined('DEBUG_EXTRA') && !defined('ADMIN_START') && !defined('IN_INSTALL') && !defined('IN_LOGIN') && file_exists($phpbb_root_path . 'install') && !is_file($phpbb_root_path . 'install'))
1833 6628 acydburn
                {
1834 6628 acydburn
                        // Adjust the message slightly according to the permissions
1835 6708 naderman
                        if ($auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))
1836 6628 acydburn
                        {
1837 6628 acydburn
                                $message = 'REMOVE_INSTALL';
1838 6628 acydburn
                        }
1839 6628 acydburn
                        else
1840 6628 acydburn
                        {
1841 6628 acydburn
                                $message = (!empty($config['board_disable_msg'])) ? $config['board_disable_msg'] : 'BOARD_DISABLE';
1842 6628 acydburn
                        }
1843 6628 acydburn
                        trigger_error($message);
1844 6628 acydburn
                }
1845 6628 acydburn
1846 4950 psotfx
                // Is board disabled and user not an admin or moderator?
1847 6708 naderman
                if ($config['board_disable'] && !defined('IN_LOGIN') && !$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_'))
1848 4950 psotfx
                {
1849 9490 acydburn
                        if ($this->data['is_bot'])
1850 9490 acydburn
                        {
1851 10788 git-gate
                                send_status_line(503, 'Service Unavailable');
1852 9490 acydburn
                        }
1853 7054 acydburn
1854 4950 psotfx
                        $message = (!empty($config['board_disable_msg'])) ? $config['board_disable_msg'] : 'BOARD_DISABLE';
1855 4950 psotfx
                        trigger_error($message);
1856 4950 psotfx
                }
1857 4950 psotfx
1858 5902 acydburn
                // Is load exceeded?
1859 5902 acydburn
                if ($config['limit_load'] && $this->load !== false)
1860 5902 acydburn
                {
1861 10742 git-gate
                        if ($this->load > floatval($config['limit_load']) && !defined('IN_LOGIN') && !defined('IN_ADMIN'))
1862 5902 acydburn
                        {
1863 7875 acydburn
                                // Set board disabled to true to let the admins/mods get the proper notification
1864 7875 acydburn
                                $config['board_disable'] = '1';
1865 7875 acydburn
1866 7875 acydburn
                                if (!$auth->acl_gets('a_', 'm_') && !$auth->acl_getf_global('m_'))
1867 7875 acydburn
                                {
1868 9490 acydburn
                                        if ($this->data['is_bot'])
1869 9490 acydburn
                                        {
1870 10788 git-gate
                                                send_status_line(503, 'Service Unavailable');
1871 9490 acydburn
                                        }
1872 7875 acydburn
                                        trigger_error('BOARD_UNAVAILABLE');
1873 7875 acydburn
                                }
1874 5902 acydburn
                        }
1875 5902 acydburn
                }
1876 7890 naderman
1877 7801 kellanved
                if (isset($this->data['session_viewonline']))
1878 7755 kellanved
                {
1879 7801 kellanved
                        // Make sure the user is able to hide his session
1880 7801 kellanved
                        if (!$this->data['session_viewonline'])
1881 7755 kellanved
                        {
1882 7801 kellanved
                                // Reset online status if not allowed to hide the session...
1883 7801 kellanved
                                if (!$auth->acl_get('u_hideonline'))
1884 7801 kellanved
                                {
1885 7801 kellanved
                                        $sql = 'UPDATE ' . SESSIONS_TABLE . '
1886 7801 kellanved
                                                SET session_viewonline = 1
1887 7801 kellanved
                                                WHERE session_user_id = ' . $this->data['user_id'];
1888 7801 kellanved
                                        $db->sql_query($sql);
1889 7801 kellanved
                                        $this->data['session_viewonline'] = 1;
1890 7801 kellanved
                                }
1891 7755 kellanved
                        }
1892 7801 kellanved
                        else if (!$this->data['user_allow_viewonline'])
1893 7755 kellanved
                        {
1894 7801 kellanved
                                // the user wants to hide and is allowed to  -> cloaking device on.
1895 7801 kellanved
                                if ($auth->acl_get('u_hideonline'))
1896 7801 kellanved
                                {
1897 7801 kellanved
                                        $sql = 'UPDATE ' . SESSIONS_TABLE . '
1898 7801 kellanved
                                                SET session_viewonline = 0
1899 7801 kellanved
                                                WHERE session_user_id = ' . $this->data['user_id'];
1900 7801 kellanved
                                        $db->sql_query($sql);
1901 7801 kellanved
                                        $this->data['session_viewonline'] = 0;
1902 7801 kellanved
                                }
1903 7755 kellanved
                        }
1904 7755 kellanved
                }
1905 5902 acydburn
1906 7755 kellanved
1907 4793 psotfx
                // Does the user need to change their password? If so, redirect to the
1908 6048 acydburn
                // ucp profile reg_details page ... of course do not redirect if we're already in the ucp
1909 9665 leviatan21
                if (!defined('IN_ADMIN') && !defined('ADMIN_START') && $config['chg_passforce'] && !empty($this->data['is_registered']) && $auth->acl_get('u_chgpasswd') && $this->data['user_passchg'] < time() - ($config['chg_passforce'] * 86400))
1910 4793 psotfx
                {
1911 6170 acydburn
                        if (strpos($this->page['query_string'], 'mode=reg_details') === false && $this->page['page_name'] != "ucp.$phpEx")
1912 4793 psotfx
                        {
1913 6015 acydburn
                                redirect(append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=profile&amp;mode=reg_details'));
1914 4793 psotfx
                        }
1915 4793 psotfx
                }
1916 4793 psotfx
1917 2923 psotfx
                return;
1918 2923 psotfx
        }
1919 2923 psotfx
1920 6048 acydburn
        /**
1921 8800 acydburn
        * More advanced language substitution
1922 8800 acydburn
        * Function to mimic sprintf() with the possibility of using phpBB's language system to substitute nullar/singular/plural forms.
1923 8800 acydburn
        * Params are the language key and the parameters to be substituted.
1924 8800 acydburn
        * This function/functionality is inspired by SHS` and Ashe.
1925 8800 acydburn
        *
1926 8800 acydburn
        * Example call: <samp>$user->lang('NUM_POSTS_IN_QUEUE', 1);</samp>
1927 8800 acydburn
        */
1928 8800 acydburn
        function lang()
1929 8800 acydburn
        {
1930 8800 acydburn
                $args = func_get_args();
1931 8800 acydburn
                $key = $args[0];
1932 8800 acydburn
1933 9136 acydburn
                if (is_array($key))
1934 9136 acydburn
                {
1935 9136 acydburn
                        $lang = &$this->lang[array_shift($key)];
1936 9136 acydburn
1937 9136 acydburn
                        foreach ($key as $_key)
1938 9136 acydburn
                        {
1939 9136 acydburn
                                $lang = &$lang[$_key];
1940 9136 acydburn
                        }
1941 9136 acydburn
                }
1942 9136 acydburn
                else
1943 9136 acydburn
                {
1944 9136 acydburn
                        $lang = &$this->lang[$key];
1945 9136 acydburn
                }
1946 9136 acydburn
1947 8800 acydburn
                // Return if language string does not exist
1948 9136 acydburn
                if (!isset($lang) || (!is_string($lang) && !is_array($lang)))
1949 8800 acydburn
                {
1950 8800 acydburn
                        return $key;
1951 8800 acydburn
                }
1952 8800 acydburn
1953 8800 acydburn
                // If the language entry is a string, we simply mimic sprintf() behaviour
1954 9136 acydburn
                if (is_string($lang))
1955 8800 acydburn
                {
1956 8800 acydburn
                        if (sizeof($args) == 1)
1957 8800 acydburn
                        {
1958 9136 acydburn
                                return $lang;
1959 8800 acydburn
                        }
1960 8800 acydburn
1961 8800 acydburn
                        // Replace key with language entry and simply pass along...
1962 9136 acydburn
                        $args[0] = $lang;
1963 8800 acydburn
                        return call_user_func_array('sprintf', $args);
1964 8800 acydburn
                }
1965 8800 acydburn
1966 8800 acydburn
                // It is an array... now handle different nullar/singular/plural forms
1967 8800 acydburn
                $key_found = false;
1968 8800 acydburn
1969 8800 acydburn
                // We now get the first number passed and will select the key based upon this number
1970 8800 acydburn
                for ($i = 1, $num_args = sizeof($args); $i < $num_args; $i++)
1971 8800 acydburn
                {
1972 8800 acydburn
                        if (is_int($args[$i]))
1973 8800 acydburn
                        {
1974 9136 acydburn
                                $numbers = array_keys($lang);
1975 8800 acydburn
1976 8800 acydburn
                                foreach ($numbers as $num)
1977 8800 acydburn
                                {
1978 8800 acydburn
                                        if ($num > $args[$i])
1979 8800 acydburn
                                        {
1980 8800 acydburn
                                                break;
1981 8800 acydburn
                                        }
1982 8800 acydburn
1983 8800 acydburn
                                        $key_found = $num;
1984 8800 acydburn
                                }
1985 10958 git-gate
                                break;
1986 8800 acydburn
                        }
1987 8800 acydburn
                }
1988 8800 acydburn
1989 8800 acydburn
                // Ok, let's check if the key was found, else use the last entry (because it is mostly the plural form)
1990 8800 acydburn
                if ($key_found === false)
1991 8800 acydburn
                {
1992 9136 acydburn
                        $numbers = array_keys($lang);
1993 8800 acydburn
                        $key_found = end($numbers);
1994 8800 acydburn
                }
1995 8800 acydburn
1996 8800 acydburn
                // Use the language string we determined and pass it to sprintf()
1997 9136 acydburn
                $args[0] = $lang[$key_found];
1998 8800 acydburn
                return call_user_func_array('sprintf', $args);
1999 8800 acydburn
        }
2000 8800 acydburn
2001 8800 acydburn
        /**
2002 6048 acydburn
        * Add Language Items - use_db and use_help are assigned where needed (only use them to force inclusion)
2003 6048 acydburn
        *
2004 6048 acydburn
        * @param mixed $lang_set specifies the language entries to include
2005 6048 acydburn
        * @param bool $use_db internal variable for recursion, do not use
2006 6048 acydburn
        * @param bool $use_help internal variable for recursion, do not use
2007 6048 acydburn
        *
2008 6048 acydburn
        * Examples:
2009 6048 acydburn
        * <code>
2010 6048 acydburn
        * $lang_set = array('posting', 'help' => 'faq');
2011 6048 acydburn
        * $lang_set = array('posting', 'viewtopic', 'help' => array('bbcode', 'faq'))
2012 6048 acydburn
        * $lang_set = array(array('posting', 'viewtopic'), 'help' => array('bbcode', 'faq'))
2013 6048 acydburn
        * $lang_set = 'posting'
2014 6048 acydburn
        * $lang_set = array('help' => 'faq', 'db' => array('help:faq', 'posting'))
2015 6048 acydburn
        * </code>
2016 6048 acydburn
        */
2017 4844 acydburn
        function add_lang($lang_set, $use_db = false, $use_help = false)
2018 4844 acydburn
        {
2019 4962 acydburn
                global $phpEx;
2020 4844 acydburn
2021 4844 acydburn
                if (is_array($lang_set))
2022 4844 acydburn
                {
2023 4844 acydburn
                        foreach ($lang_set as $key => $lang_file)
2024 4844 acydburn
                        {
2025 4950 psotfx
                                // Please do not delete this line.
2026 4859 acydburn
                                // We have to force the type here, else [array] language inclusion will not work
2027 4859 acydburn
                                $key = (string) $key;
2028 4859 acydburn
2029 4844 acydburn
                                if ($key == 'db')
2030 4844 acydburn
                                {
2031 4844 acydburn
                                        $this->add_lang($lang_file, true, $use_help);
2032 4844 acydburn
                                }
2033 4844 acydburn
                                else if ($key == 'help')
2034 4844 acydburn
                                {
2035 4844 acydburn
                                        $this->add_lang($lang_file, $use_db, true);
2036 4844 acydburn
                                }
2037 4844 acydburn
                                else if (!is_array($lang_file))
2038 4844 acydburn
                                {
2039 4962 acydburn
                                        $this->set_lang($this->lang, $this->help, $lang_file, $use_db, $use_help);
2040 4844 acydburn
                                }
2041 4844 acydburn
                                else
2042 4844 acydburn
                                {
2043 4844 acydburn
                                        $this->add_lang($lang_file, $use_db, $use_help);
2044 4844 acydburn
                                }
2045 4844 acydburn
                        }
2046 4844 acydburn
                        unset($lang_set);
2047 4844 acydburn
                }
2048 4844 acydburn
                else if ($lang_set)
2049 4844 acydburn
                {
2050 4962 acydburn
                        $this->set_lang($this->lang, $this->help, $lang_set, $use_db, $use_help);
2051 4844 acydburn
                }
2052 4844 acydburn
        }
2053 4844 acydburn
2054 6048 acydburn
        /**
2055 6048 acydburn
        * Set language entry (called by add_lang)
2056 6312 acydburn
        * @access private
2057 6048 acydburn
        */
2058 4962 acydburn
        function set_lang(&$lang, &$help, $lang_file, $use_db = false, $use_help = false)
2059 4847 psotfx
        {
2060 4962 acydburn
                global $phpEx;
2061 4847 psotfx
2062 8782 acydburn
                // Make sure the language name is set (if the user setup did not happen it is not set)
2063 8782 acydburn
                if (!$this->lang_name)
2064 5494 acydburn
                {
2065 8785 acydburn
                        global $config;
2066 8782 acydburn
                        $this->lang_name = basename($config['default_lang']);
2067 5494 acydburn
                }
2068 5494 acydburn
2069 4962 acydburn
                // $lang == $this->lang
2070 4962 acydburn
                // $help == $this->help
2071 6915 acydburn
                // - add appropriate variables here, name them as they are used within the language file...
2072 4847 psotfx
                if (!$use_db)
2073 4847 psotfx
                {
2074 7805 acydburn
                        if ($use_help && strpos($lang_file, '/') !== false)
2075 5104 bartvb
                        {
2076 8782 acydburn
                                $language_filename = $this->lang_path . $this->lang_name . '/' . substr($lang_file, 0, stripos($lang_file, '/') + 1) . 'help_' . substr($lang_file, stripos($lang_file, '/') + 1) . '.' . $phpEx;
2077 5104 bartvb
                        }
2078 7805 acydburn
                        else
2079 7805 acydburn
                        {
2080 8782 acydburn
                                $language_filename = $this->lang_path . $this->lang_name . '/' . (($use_help) ? 'help_' : '') . $lang_file . '.' . $phpEx;
2081 7805 acydburn
                        }
2082 7805 acydburn
2083 9901 acydburn
                        if (!file_exists($language_filename))
2084 9901 acydburn
                        {
2085 9901 acydburn
                                global $config;
2086 9901 acydburn
2087 9901 acydburn
                                if ($this->lang_name == 'en')
2088 9901 acydburn
                                {
2089 9901 acydburn
                                        // The user's selected language is missing the file, the board default's language is missing the file, and the file doesn't exist in /en.
2090 9901 acydburn
                                        $language_filename = str_replace($this->lang_path . 'en', $this->lang_path . $this->data['user_lang'], $language_filename);
2091 9901 acydburn
                                        trigger_error('Language file ' . $language_filename . ' couldn\'t be opened.', E_USER_ERROR);
2092 9901 acydburn
                                }
2093 9901 acydburn
                                else if ($this->lang_name == basename($config['default_lang']))
2094 9901 acydburn
                                {
2095 9901 acydburn
                                        // Fall back to the English Language
2096 9901 acydburn
                                        $this->lang_name = 'en';
2097 9901 acydburn
                                        $this->set_lang($lang, $help, $lang_file, $use_db, $use_help);
2098 9901 acydburn
                                }
2099 9901 acydburn
                                else if ($this->lang_name == $this->data['user_lang'])
2100 9901 acydburn
                                {
2101 9901 acydburn
                                        // Fall back to the board default language
2102 9901 acydburn
                                        $this->lang_name = basename($config['default_lang']);
2103 9901 acydburn
                                        $this->set_lang($lang, $help, $lang_file, $use_db, $use_help);
2104 9901 acydburn
                                }
2105 9901 acydburn
2106 9901 acydburn
                                // Reset the lang name
2107 9901 acydburn
                                $this->lang_name = (file_exists($this->lang_path . $this->data['user_lang'] . "/common.$phpEx")) ? $this->data['user_lang'] : basename($config['default_lang']);
2108 9901 acydburn
                                return;
2109 9901 acydburn
                        }
2110 9901 acydburn
2111 9383 acydburn
                        // Do not suppress error if in DEBUG_EXTRA mode
2112 9383 acydburn
                        $include_result = (defined('DEBUG_EXTRA')) ? (include $language_filename) : (@include $language_filename);
2113 9383 acydburn
2114 9383 acydburn
                        if ($include_result === false)
2115 7805 acydburn
                        {
2116 8691 acydburn
                                trigger_error('Language file ' . $language_filename . ' couldn\'t be opened.', E_USER_ERROR);
2117 7805 acydburn
                        }
2118 4847 psotfx
                }
2119 4847 psotfx
                else if ($use_db)
2120 4847 psotfx
                {
2121 4847 psotfx
                        // Get Database Language Strings
2122 4847 psotfx
                        // Put them into $lang if nothing is prefixed, put them into $help if help: is prefixed
2123 4847 psotfx
                        // For example: help:faq, posting
2124 4847 psotfx
                }
2125 4847 psotfx
        }
2126 4847 psotfx
2127 6048 acydburn
        /**
2128 6048 acydburn
        * Format user date
2129 9136 acydburn
        *
2130 9136 acydburn
        * @param int $gmepoch unix timestamp
2131 9136 acydburn
        * @param string $format date format in date() notation. | used to indicate relative dates, for example |d m Y|, h:i is translated to Today, h:i.
2132 9136 acydburn
        * @param bool $forcedate force non-relative date format.
2133 9136 acydburn
        *
2134 9136 acydburn
        * @return mixed translated date
2135 6048 acydburn
        */
2136 4950 psotfx
        function format_date($gmepoch, $format = false, $forcedate = false)
2137 2923 psotfx
        {
2138 6114 acydburn
                static $midnight;
2139 9136 acydburn
                static $date_cache;
2140 2923 psotfx
2141 6114 acydburn
                $format = (!$format) ? $this->date_format : $format;
2142 9170 toonarmy
                $now = time();
2143 9170 toonarmy
                $delta = $now - $gmepoch;
2144 6114 acydburn
2145 9136 acydburn
                if (!isset($date_cache[$format]))
2146 2923 psotfx
                {
2147 9136 acydburn
                        // Is the user requesting a friendly date format (i.e. 'Today 12:42')?
2148 9136 acydburn
                        $date_cache[$format] = array(
2149 9136 acydburn
                                'is_short'                => strpos($format, '|'),
2150 9136 acydburn
                                'format_short'        => substr($format, 0, strpos($format, '|')) . '||' . substr(strrchr($format, '|'), 1),
2151 9136 acydburn
                                'format_long'        => str_replace('|', '', $format),
2152 9136 acydburn
                                'lang'                        => $this->lang['datetime'],
2153 9136 acydburn
                        );
2154 9136 acydburn
2155 9136 acydburn
                        // Short representation of month in format? Some languages use different terms for the long and short format of May
2156 9136 acydburn
                        if ((strpos($format, '\M') === false && strpos($format, 'M') !== false) || (strpos($format, '\r') === false && strpos($format, 'r') !== false))
2157 9136 acydburn
                        {
2158 9136 acydburn
                                $date_cache[$format]['lang']['May'] = $this->lang['datetime']['May_short'];
2159 9136 acydburn
                        }
2160 2923 psotfx
                }
2161 4748 psotfx
2162 9301 acydburn
                // Zone offset
2163 9301 acydburn
                $zone_offset = $this->timezone + $this->dst;
2164 9301 acydburn
2165 10688 git-gate
                // Show date <= 1 hour ago as 'xx min ago' but not greater than 60 seconds in the future
2166 9298 acydburn
                // A small tolerence is given for times in the future but in the same minute are displayed as '< than a minute ago'
2167 10688 git-gate
                if ($delta <= 3600 && $delta > -60 && ($delta >= -5 || (($now / 60) % 60) == (($gmepoch / 60) % 60)) && $date_cache[$format]['is_short'] !== false && !$forcedate && isset($this->lang['datetime']['AGO']))
2168 9136 acydburn
                {
2169 9170 toonarmy
                        return $this->lang(array('datetime', 'AGO'), max(0, (int) floor($delta / 60)));
2170 9136 acydburn
                }
2171 4748 psotfx
2172 4950 psotfx
                if (!$midnight)
2173 4950 psotfx
                {
2174 9301 acydburn
                        list($d, $m, $y) = explode(' ', gmdate('j n Y', time() + $zone_offset));
2175 9301 acydburn
                        $midnight = gmmktime(0, 0, 0, $m, $d, $y) - $zone_offset;
2176 4950 psotfx
                }
2177 4950 psotfx
2178 9298 acydburn
                if ($date_cache[$format]['is_short'] !== false && !$forcedate && !($gmepoch < $midnight - 86400 || $gmepoch > $midnight + 172800))
2179 5068 acydburn
                {
2180 9136 acydburn
                        $day = false;
2181 5175 psotfx
2182 9136 acydburn
                        if ($gmepoch > $midnight + 86400)
2183 9136 acydburn
                        {
2184 9136 acydburn
                                $day = 'TOMORROW';
2185 9136 acydburn
                        }
2186 9136 acydburn
                        else if ($gmepoch > $midnight)
2187 9136 acydburn
                        {
2188 9136 acydburn
                                $day = 'TODAY';
2189 9136 acydburn
                        }
2190 9136 acydburn
                        else if ($gmepoch > $midnight - 86400)
2191 9136 acydburn
                        {
2192 9136 acydburn
                                $day = 'YESTERDAY';
2193 9136 acydburn
                        }
2194 9136 acydburn
2195 9136 acydburn
                        if ($day !== false)
2196 9136 acydburn
                        {
2197 9301 acydburn
                                return str_replace('||', $this->lang['datetime'][$day], strtr(@gmdate($date_cache[$format]['format_short'], $gmepoch + $zone_offset), $date_cache[$format]['lang']));
2198 9136 acydburn
                        }
2199 6426 grahamje
                }
2200 5967 acydburn
2201 9301 acydburn
                return strtr(@gmdate($date_cache[$format]['format_long'], $gmepoch + $zone_offset), $date_cache[$format]['lang']);
2202 2923 psotfx
        }
2203 2958 psotfx
2204 6048 acydburn
        /**
2205 6048 acydburn
        * Get language id currently used by the user
2206 6048 acydburn
        */
2207 4740 acydburn
        function get_iso_lang_id()
2208 4740 acydburn
        {
2209 4740 acydburn
                global $config, $db;
2210 4740 acydburn
2211 8011 acydburn
                if (!empty($this->lang_id))
2212 4740 acydburn
                {
2213 4740 acydburn
                        return $this->lang_id;
2214 4740 acydburn
                }
2215 4740 acydburn
2216 4748 psotfx
                if (!$this->lang_name)
2217 4740 acydburn
                {
2218 4740 acydburn
                        $this->lang_name = $config['default_lang'];
2219 4740 acydburn
                }
2220 4950 psotfx
2221 4950 psotfx
                $sql = 'SELECT lang_id
2222 4836 acydburn
                        FROM ' . LANG_TABLE . "
2223 5699 acydburn
                        WHERE lang_iso = '" . $db->sql_escape($this->lang_name) . "'";
2224 4748 psotfx
                $result = $db->sql_query($sql);
2225 8011 acydburn
                $this->lang_id = (int) $db->sql_fetchfield('lang_id');
2226 5699 acydburn
                $db->sql_freeresult($result);
2227 4748 psotfx
2228 8011 acydburn
                return $this->lang_id;
2229 4740 acydburn
        }
2230 4740 acydburn
2231 6048 acydburn
        /**
2232 6048 acydburn
        * Get users profile fields
2233 6048 acydburn
        */
2234 4740 acydburn
        function get_profile_fields($user_id)
2235 4740 acydburn
        {
2236 5237 acydburn
                global $db;
2237 4950 psotfx
2238 5237 acydburn
                if (isset($this->profile_fields))
2239 4740 acydburn
                {
2240 4740 acydburn
                        return;
2241 4740 acydburn
                }
2242 4740 acydburn
2243 6048 acydburn
                $sql = 'SELECT *
2244 6048 acydburn
                        FROM ' . PROFILE_FIELDS_DATA_TABLE . "
2245 4836 acydburn
                        WHERE user_id = $user_id";
2246 4950 psotfx
                $result = $db->sql_query_limit($sql, 1);
2247 5237 acydburn
                $this->profile_fields = (!($row = $db->sql_fetchrow($result))) ? array() : $row;
2248 4904 acydburn
                $db->sql_freeresult($result);
2249 4740 acydburn
        }
2250 4740 acydburn
2251 6048 acydburn
        /**
2252 6048 acydburn
        * Specify/Get image
2253 8857 acydburn
        * $suffix is no longer used - we know it. ;) It is there for backward compatibility.
2254 6048 acydburn
        */
2255 5126 acydburn
        function img($img, $alt = '', $width = false, $suffix = '', $type = 'full_tag')
2256 2958 psotfx
        {
2257 4957 acydburn
                static $imgs;
2258 4957 acydburn
                global $phpbb_root_path;
2259 2958 psotfx
2260 7304 davidmj
                $img_data = &$imgs[$img];
2261 6321 naderman
2262 7687 acydburn
                if (empty($img_data))
2263 2958 psotfx
                {
2264 7304 davidmj
                        if (!isset($this->img_array[$img]))
2265 4897 acydburn
                        {
2266 4908 acydburn
                                // Do not fill the image to let designers decide what to do if the image is empty
2267 6321 naderman
                                $img_data = '';
2268 6321 naderman
                                return $img_data;
2269 4897 acydburn
                        }
2270 4950 psotfx
2271 10008 acydburn
                        // Use URL if told so
2272 10008 acydburn
                        $root_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? generate_board_url() . '/' : $phpbb_root_path;
2273 10008 acydburn
2274 11283 git-gate
                        $path = 'styles/' . rawurlencode($this->theme['imageset_path']) . '/imageset/' . ($this->img_array[$img]['image_lang'] ? $this->img_array[$img]['image_lang'] .'/' : '') . $this->img_array[$img]['image_filename'];
2275 11283 git-gate
2276 11283 git-gate
                        $img_data['src'] = $root_path . $path;
2277 7304 davidmj
                        $img_data['width'] = $this->img_array[$img]['image_width'];
2278 7304 davidmj
                        $img_data['height'] = $this->img_array[$img]['image_height'];
2279 11283 git-gate
2280 11283 git-gate
                        // We overwrite the width and height to the phpbb logo's width
2281 11283 git-gate
                        // and height here if the contents of the site_logo file are
2282 11283 git-gate
                        // really equal to the phpbb_logo
2283 11283 git-gate
                        // This allows us to change the dimensions of the phpbb_logo without
2284 11283 git-gate
                        // modifying the imageset.cfg and causing a conflict for everyone
2285 11283 git-gate
                        // who modified it for their custom logo on updating
2286 11283 git-gate
                        if ($img == 'site_logo' && file_exists($phpbb_root_path . $path))
2287 11283 git-gate
                        {
2288 11283 git-gate
                                global $cache;
2289 11283 git-gate
2290 11283 git-gate
                                $img_file_hashes = $cache->get('imageset_site_logo_md5');
2291 11283 git-gate
2292 11283 git-gate
                                if ($img_file_hashes === false)
2293 11283 git-gate
                                {
2294 11283 git-gate
                                        $img_file_hashes = array();
2295 11283 git-gate
                                }
2296 11283 git-gate
2297 11283 git-gate
                                $key = $this->theme['imageset_path'] . '::' . $this->img_array[$img]['image_lang'];
2298 11283 git-gate
                                if (!isset($img_file_hashes[$key]))
2299 11283 git-gate
                                {
2300 11283 git-gate
                                        $img_file_hashes[$key] = md5(file_get_contents($phpbb_root_path . $path));
2301 11283 git-gate
                                        $cache->put('imageset_site_logo_md5', $img_file_hashes);
2302 11283 git-gate
                                }
2303 11283 git-gate
2304 11283 git-gate
                                $phpbb_logo_hash = '0c461a32cd3621643105f0d02a772c10';
2305 11283 git-gate
2306 11283 git-gate
                                if ($phpbb_logo_hash == $img_file_hashes[$key])
2307 11283 git-gate
                                {
2308 11283 git-gate
                                        $img_data['width'] = '149';
2309 11283 git-gate
                                        $img_data['height'] = '52';
2310 11283 git-gate
                                }
2311 11283 git-gate
                        }
2312 2958 psotfx
                }
2313 4729 psotfx
2314 5002 acydburn
                $alt = (!empty($this->lang[$alt])) ? $this->lang[$alt] : $alt;
2315 6048 acydburn
2316 5126 acydburn
                switch ($type)
2317 5126 acydburn
                {
2318 5126 acydburn
                        case 'src':
2319 6321 naderman
                                return $img_data['src'];
2320 5957 acydburn
                        break;
2321 7890 naderman
2322 5126 acydburn
                        case 'width':
2323 7687 acydburn
                                return ($width === false) ? $img_data['width'] : $width;
2324 5957 acydburn
                        break;
2325 5126 acydburn
2326 5126 acydburn
                        case 'height':
2327 6321 naderman
                                return $img_data['height'];
2328 5957 acydburn
                        break;
2329 5126 acydburn
2330 5126 acydburn
                        default:
2331 7687 acydburn
                                $use_width = ($width === false) ? $img_data['width'] : $width;
2332 8348 acydburn
2333 7687 acydburn
                                return '<img src="' . $img_data['src'] . '"' . (($use_width) ? ' width="' . $use_width . '"' : '') . (($img_data['height']) ? ' height="' . $img_data['height'] . '"' : '') . ' alt="' . $alt . '" title="' . $alt . '" />';
2334 5957 acydburn
                        break;
2335 5126 acydburn
                }
2336 2958 psotfx
        }
2337 4440 psotfx
2338 6048 acydburn
        /**
2339 11643 git-gate
        * Get option bit field from user options.
2340 11643 git-gate
        *
2341 11643 git-gate
        * @param int $key option key, as defined in $keyoptions property.
2342 11643 git-gate
        * @param int $data bit field value to use, or false to use $this->data['user_options']
2343 11643 git-gate
        * @return bool true if the option is set in the bit field, false otherwise
2344 6048 acydburn
        */
2345 4821 psotfx
        function optionget($key, $data = false)
2346 4440 psotfx
        {
2347 11643 git-gate
                $var = ($data !== false) ? $data : $this->data['user_options'];
2348 11643 git-gate
                return phpbb_optionget($this->keyoptions[$key], $var);
2349 4440 psotfx
        }
2350 4446 psotfx
2351 6048 acydburn
        /**
2352 11643 git-gate
        * Set option bit field for user options.
2353 11643 git-gate
        *
2354 11643 git-gate
        * @param int $key Option key, as defined in $keyoptions property.
2355 11643 git-gate
        * @param bool $value True to set the option, false to clear the option.
2356 11643 git-gate
        * @param int $data Current bit field value, or false to use $this->data['user_options']
2357 11643 git-gate
        * @return int|bool If $data is false, the bit field is modified and
2358 11643 git-gate
        *                  written back to $this->data['user_options'], and
2359 11643 git-gate
        *                  return value is true if the bit field changed and
2360 11643 git-gate
        *                  false otherwise. If $data is not false, the new
2361 11643 git-gate
        *                  bitfield value is returned.
2362 6048 acydburn
        */
2363 4821 psotfx
        function optionset($key, $value, $data = false)
2364 4446 psotfx
        {
2365 11643 git-gate
                $var = ($data !== false) ? $data : $this->data['user_options'];
2366 4821 psotfx
2367 11643 git-gate
                $new_var = phpbb_optionset($this->keyoptions[$key], $value, $var);
2368 4559 psotfx
2369 11643 git-gate
                if ($data === false)
2370 4821 psotfx
                {
2371 11643 git-gate
                        if ($new_var != $var)
2372 11643 git-gate
                        {
2373 11643 git-gate
                                $this->data['user_options'] = $new_var;
2374 11643 git-gate
                                return true;
2375 11643 git-gate
                        }
2376 11643 git-gate
                        else
2377 11643 git-gate
                        {
2378 11643 git-gate
                                return false;
2379 11643 git-gate
                        }
2380 4821 psotfx
                }
2381 4821 psotfx
                else
2382 4821 psotfx
                {
2383 11643 git-gate
                        return $new_var;
2384 4821 psotfx
                }
2385 4446 psotfx
        }
2386 9636 acydburn
2387 9636 acydburn
        /**
2388 9636 acydburn
        * Funtion to make the user leave the NEWLY_REGISTERED system group.
2389 9636 acydburn
        * @access public
2390 9636 acydburn
        */
2391 9636 acydburn
        function leave_newly_registered()
2392 9636 acydburn
        {
2393 9636 acydburn
                global $db;
2394 9636 acydburn
2395 9644 acydburn
                if (empty($this->data['user_new']))
2396 9644 acydburn
                {
2397 9644 acydburn
                        return false;
2398 9644 acydburn
                }
2399 9644 acydburn
2400 9646 Kellanved
                if (!function_exists('remove_newly_registered'))
2401 9636 acydburn
                {
2402 9636 acydburn
                        global $phpbb_root_path, $phpEx;
2403 9636 acydburn
2404 9636 acydburn
                        include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
2405 9636 acydburn
                }
2406 9646 Kellanved
                if ($group = remove_newly_registered($this->data['user_id'], $this->data))
2407 9636 acydburn
                {
2408 9646 Kellanved
                        $this->data['group_id'] = $group;
2409 9901 acydburn
2410 9636 acydburn
                }
2411 9636 acydburn
                $this->data['user_permissions'] = '';
2412 9636 acydburn
                $this->data['user_new'] = 0;
2413 9901 acydburn
2414 9636 acydburn
                return true;
2415 9636 acydburn
        }
2416 11385 git-gate
2417 11385 git-gate
        /**
2418 11385 git-gate
        * Returns all password protected forum ids the user is currently NOT authenticated for.
2419 11385 git-gate
        *
2420 11385 git-gate
        * @return array                Array of forum ids
2421 11385 git-gate
        * @access public
2422 11385 git-gate
        */
2423 11385 git-gate
        function get_passworded_forums()
2424 11385 git-gate
        {
2425 11385 git-gate
                global $db;
2426 11385 git-gate
2427 11385 git-gate
                $sql = 'SELECT f.forum_id, fa.user_id
2428 11385 git-gate
                        FROM ' . FORUMS_TABLE . ' f
2429 11385 git-gate
                        LEFT JOIN ' . FORUMS_ACCESS_TABLE . " fa
2430 11385 git-gate
                                ON (fa.forum_id = f.forum_id
2431 11385 git-gate
                                        AND fa.session_id = '" . $db->sql_escape($this->session_id) . "')
2432 11385 git-gate
                        WHERE f.forum_password <> ''";
2433 11385 git-gate
                $result = $db->sql_query($sql);
2434 11385 git-gate
2435 11385 git-gate
                $forum_ids = array();
2436 11385 git-gate
                while ($row = $db->sql_fetchrow($result))
2437 11385 git-gate
                {
2438 11385 git-gate
                        $forum_id = (int) $row['forum_id'];
2439 11385 git-gate
2440 11385 git-gate
                        if ($row['user_id'] != $this->data['user_id'])
2441 11385 git-gate
                        {
2442 11385 git-gate
                                $forum_ids[$forum_id] = $forum_id;
2443 11385 git-gate
                        }
2444 11385 git-gate
                }
2445 11385 git-gate
                $db->sql_freeresult($result);
2446 11385 git-gate
2447 11385 git-gate
                return $forum_ids;
2448 11385 git-gate
        }
2449 2923 psotfx
}
2450 2923 psotfx
2451 5423 acydburn
?>