add some properties
[phpbb.git] / phpBB / includes / core / system_info.php
blob56a5d3bcd01668490a385e3f9064d3170d22b930
1 <?php
2 /**
4 * @package core
5 * @version $Id$
6 * @copyright (c) 2008 phpBB Group
7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
9 */
11 /**
12 * @ignore
14 if (!defined('IN_PHPBB'))
16 exit();
19 /**
20 * Get system/server information variables.
22 * @package core
24 class phpbb_system_info extends phpbb_plugin_support implements ArrayAccess
26 /**
27 * @var array required phpBB objects
29 public $phpbb_required = array('config', 'url');
31 /**
32 * @var array Optional phpBB objects
34 public $phpbb_optional = array();
36 /**
37 * @var array Array for storing/accessing information
39 private $data = array();
41 /**#@+
42 * Part of the ArrayAccess implementation.
43 * @access public
45 public function offsetSet($offset, $value)
47 $this->data[$offset] = $value;
50 public function offsetExists($offset)
52 return isset($this->data[$offset]);
55 public function offsetUnset($offset)
57 unset($this->data[$offset]);
59 /**#@-*/
61 /**
62 * Get system information - Part of the ArrayAccess implementation.
64 * System information ought to be received from {@link $data phpbb::$user->system[key]}.
65 * The key used is mapped to a method with get_ as prefix.
66 * For example getting phpbb::$user->system['host'] results in calling the method get_host().
68 * @param string $offset The key to get.
69 * @return mixed The result
70 * @access public
72 public function offsetGet($offset)
74 if (isset($this->data[$offset]))
76 return $this->data[$offset];
79 $identifier = 'get_' . strtolower($offset);
81 // Not static, because we are not able to use late static bindings
82 $this->data[$offset] = $this->$identifier();
83 return $this->data[$offset];
86 /**
87 * Get valid hostname/port. HTTP_HOST is used, SERVER_NAME if HTTP_HOST not present.
89 * @return string Host (lowercase, not specialchared)
90 * @access protected
92 protected function get_host()
94 // Get hostname
95 $host = (!empty($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : ((!empty($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : getenv('SERVER_NAME'));
97 // Should be a string and lowered
98 $host = (string) strtolower($host);
100 // If host is equal the cookie domain or the server name (if config is set), then we assume it is valid
101 if ((isset(phpbb::$config['cookie_domain']) && $host === phpbb::$config['cookie_domain']) || (isset(phpbb::$config['server_name']) && $host === phpbb::$config['server_name']))
103 return $host;
106 // Is the host actually a IP? If so, we use the IP... (IPv4)
107 if (long2ip(ip2long($host)) === $host)
109 return $host;
112 // 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
113 $host = @parse_url('http://' . $host, PHP_URL_HOST);
115 // Remove any portions not removed by parse_url (#)
116 $host = str_replace('#', '', $host);
118 // If, by any means, the host is now empty, we will use a "best approach" way to guess one
119 if (empty($host))
121 if (!empty(phpbb::$config['server_name']))
123 $host = phpbb::$config['server_name'];
125 else if (!empty(phpbb::$config['cookie_domain']))
127 $host = (strpos(phpbb::$config['cookie_domain'], '.') === 0) ? substr(phpbb::$config['cookie_domain'], 1) : phpbb::$config['cookie_domain'];
129 else
131 // Set to OS hostname or localhost
132 $host = (function_exists('php_uname')) ? strtolower(php_uname('n')) : 'localhost';
136 // It may be still no valid host, but for sure only a hostname (we may further expand on the cookie domain... if set)
137 return $host;
141 * Extract current session page, relative from current root path (PHPBB_ROOT_PATH)
143 * The array returned consist of the following key/value pairs:
144 * page_name: The current basename'd page name, for example: index.php (urlencoded, htmlspecialchared)
145 * page_dir: The current directory within the phpBB root, for example: adm
146 * query_string: The current query string, for example: i=10&b=2 (the parameter 'sid' is never included)
147 * script_path: The script path from the webroot to the current directory, for example: /phpBB3/adm/
148 * The script path is always prefixed with / and ends in /. Specialchared, whitespace replaced with %20.
149 * root_script_path: The script path from the webroot to the phpBB root, for example: /phpBB3/
150 * The root script path is always prefixed with / and ends in /. Specialchared, whitespace replaced with %20.
151 * page: Current page from phpBB root, for example: adm/index.php?i=10&b=2
152 * forum: Current forum id (determined by {@link request_var() request_var('f', 0)})
154 * @return array Array containing page information.
155 * @plugin-support return
156 * @access protected
158 protected function get_page()
160 $page_array = array();
162 // First of all, get the request uri...
163 $script_name = (!empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : getenv('PHP_SELF');
164 $args = (!empty($_SERVER['QUERY_STRING'])) ? explode('&', $_SERVER['QUERY_STRING']) : explode('&', getenv('QUERY_STRING'));
166 // 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...
167 if (!$script_name)
169 $script_name = (!empty($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : getenv('REQUEST_URI');
170 $script_name = (($pos = strpos($script_name, '?')) !== false) ? substr($script_name, 0, $pos) : $script_name;
171 $page_array['failover'] = 1;
174 // Replace backslashes and doubled slashes (could happen on some proxy setups)
175 $script_name = str_replace(array('\\', '//'), '/', $script_name);
177 // Now, remove the sid and let us get a clean query string...
178 $use_args = array();
180 // Since some browser do not encode correctly we need to do this with some "special" characters...
181 // " -> %22, ' => %27, < -> %3C, > -> %3E
182 $find = array('"', "'", '<', '>');
183 $replace = array('%22', '%27', '%3C', '%3E');
185 foreach ($args as $argument)
187 if (strpos($argument, 'sid=') === 0)
189 continue;
192 $use_args[] = str_replace($find, $replace, $argument);
194 unset($args);
196 // The following examples given are for an request uri of {path to the phpbb directory}/adm/index.php?i=10&b=2
198 // The current query string
199 $query_string = trim(implode('&', $use_args));
201 // basenamed page name (for example: index.php)
202 $page_name = basename($script_name);
203 $page_name = urlencode(htmlspecialchars($page_name));
205 // current directory within the phpBB root (for example: adm)
206 $root_dirs = explode('/', str_replace('\\', '/', phpbb::$url->realpath(PHPBB_ROOT_PATH)));
207 $page_dirs = explode('/', str_replace('\\', '/', phpbb::$url->realpath('./')));
208 $intersection = array_intersect_assoc($root_dirs, $page_dirs);
210 $root_dirs = array_diff_assoc($root_dirs, $intersection);
211 $page_dirs = array_diff_assoc($page_dirs, $intersection);
213 $page_dir = str_repeat('../', sizeof($root_dirs)) . implode('/', $page_dirs);
215 if ($page_dir && substr($page_dir, -1, 1) == '/')
217 $page_dir = substr($page_dir, 0, -1);
220 // Current page from phpBB root (for example: adm/index.php?i=10&b=2)
221 $page = (($page_dir) ? $page_dir . '/' : '') . $page_name . (($query_string) ? "?$query_string" : '');
223 // The script path from the webroot to the current directory (for example: /phpBB3/adm/) : always prefixed with / and ends in /
224 $script_path = trim(str_replace('\\', '/', dirname($script_name)));
226 // The script path from the webroot to the phpBB root (for example: /phpBB3/)
227 $script_dirs = explode('/', $script_path);
228 array_splice($script_dirs, -sizeof($page_dirs));
229 $root_script_path = implode('/', $script_dirs) . (sizeof($root_dirs) ? '/' . implode('/', $root_dirs) : '');
231 // We are on the base level (phpBB root == webroot), lets adjust the variables a bit...
232 if (!$root_script_path)
234 $root_script_path = ($page_dir) ? str_replace($page_dir, '', $script_path) : $script_path;
237 $script_path .= (substr($script_path, -1, 1) == '/') ? '' : '/';
238 $root_script_path .= (substr($root_script_path, -1, 1) == '/') ? '' : '/';
240 $page_array += array(
241 'page_name' => $page_name,
242 'page_dir' => $page_dir,
244 'query_string' => $query_string,
245 'script_path' => str_replace(' ', '%20', htmlspecialchars($script_path)),
246 'root_script_path' => str_replace(' ', '%20', htmlspecialchars($root_script_path)),
248 'page' => $page,
249 'forum' => request_var('f', 0),
252 return ($this->method_inject(__FUNCTION__, 'return')) ? $this->call_inject(__FUNCTION__, array('return', $page_array)) : $page_array;
256 * Get user agent string.
258 * @return string User agent, determined from $_SERVER['HTTP_USER_AGENT']. Specialchared.
259 * @access protected
261 protected function get_browser()
263 return (!empty($_SERVER['HTTP_USER_AGENT'])) ? htmlspecialchars((string) $_SERVER['HTTP_USER_AGENT']) : '';
267 * Get current referer
269 * @return string Referer, determined from $_SERVER['HTTP_REFERER']. Specialchared.
270 * @access protected
272 protected function get_referer()
274 return (!empty($_SERVER['HTTP_REFERER'])) ? htmlspecialchars((string) $_SERVER['HTTP_REFERER']) : '';
278 * Get server port
280 * @return int Sertver port, determined from $_SERVER/$_ENV['SERVER_PORT'].
281 * @access protected
283 protected function get_port()
285 return (!empty($_SERVER['SERVER_PORT'])) ? (int) $_SERVER['SERVER_PORT'] : (int) getenv('SERVER_PORT');
289 * Get forwarded-for string.
290 * If the forwarded for check is enabled in phpBB the ip's are checked for valid data and invalid data being removed.
292 * @return string Forwarded-for string, determined from $_SERVER['HTTP_X_FORWARDED_FOR'].
293 * @access protected
295 protected function get_forwarded_for()
297 $forwarded_for = (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) ? (string) $_SERVER['HTTP_X_FORWARDED_FOR'] : '';
299 // if the forwarded for header shall be checked we have to validate its contents
300 if (phpbb::$config['forwarded_for_check'])
302 $forwarded_for = preg_replace('#, +#', ', ', $forwarded_for);
304 // split the list of IPs
305 $ips = explode(', ', $forwarded_for);
306 foreach ($ips as $ip)
308 // check IPv4 first, the IPv6 is hopefully only going to be used very seldomly
309 if (!empty($ip) && !preg_match(get_preg_expression('ipv4'), $ip) && !preg_match(get_preg_expression('ipv6'), $ip))
311 // contains invalid data, don't use the forwarded for header
312 return '';
316 else
318 return '';
323 * Get remote ip
325 * @return string Remote IP, determined from $_SERVER['REMOTE_ADDR']. Specialchared.
326 * @access protected
328 protected function get_ip()
330 return (!empty($_SERVER['REMOTE_ADDR'])) ? htmlspecialchars($_SERVER['REMOTE_ADDR']) : '';
334 * Get server load.
336 * Server load is retrieved if load limitation is enabled in phpBB and server supports {@link sys_getloadavg() sys_getloadavg}
337 * or file /proc/loadavg exists on the server.
339 * @return double Server load.
340 * @access protected
342 protected function get_load()
344 $load = false;
346 // Load limit check (if applicable)
347 if (phpbb::$config['limit_load'] || phpbb::$config['limit_search_load'])
349 if ((function_exists('sys_getloadavg') && $load = sys_getloadavg()) || ($load = explode(' ', @file_get_contents('/proc/loadavg'))))
351 $load = array_slice($load, 0, 1);
352 $load = floatval($load[0]);
354 else
356 set_config('limit_load', '0');
357 set_config('limit_search_load', '0');
361 return $load;
365 * Get current request method.
367 * @return string Request method, determined from $_SERVER['REQUEST_METHOD']. Specialchared, lowercase.
368 * @access protected
370 protected function get_request_method()
372 return (isset($_SERVER['REQUEST_METHOD'])) ? strtolower(htmlspecialchars((string) $_SERVER['REQUEST_METHOD'])) : '';