5 * Core and commonly used functions
18 * If you are behind a reverse proxy, we use the X-Forwarded-For header
19 * instead of $_SERVER['REMOTE_ADDR'], which would be the IP address
20 * of the proxy server, and not the client's.
23 * IP address of client machine, adjusted for reverse proxy.
25 function core_ip_address() {
28 if (!isset($ip_address)) {
29 $settings['ip_address'] = $_SERVER['REMOTE_ADDR'];
30 if (core_variable_get('reverse_proxy', 0) && array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
31 // If an array of known reverse proxy IPs is provided, then trust
32 // the XFF header if request really comes from one of them.
33 $reverse_proxy_addresses = core_variable_get('reverse_proxy_addresses', array());
34 if (!empty($reverse_proxy_addresses) && in_array($ip_address, $reverse_proxy_addresses, TRUE)) {
35 // If there are several arguments, we need to check the most
36 // recently added one, i.e. the last one.
37 $settings['ip_address'] = array_pop(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']));
41 return $settings['ip_address'];
45 * Validate that a hostname (for example $_SERVER['HTTP_HOST']) is safe.
47 * As $_SERVER['HTTP_HOST'] is user input, ensure it only contains characters
48 * allowed in hostnames. See RFC 952 (and RFC 2181). $_SERVER['HTTP_HOST'] is
52 * TRUE if only containing valid characters, or FALSE otherwise.
54 function core_valid_http_host($host) {
55 return preg_match('/^\[?(?:[a-z0-9-:\]_]+\.?)+$/', $host);
59 * The files that we look for are the module files, we then assume that all other files concerning such module
60 * are located in the same directory.
62 * Verify if mysql_query is used for some reason, use db_query
65 function core_get_filename($name, $type = 'module', $reset = FALSE){
69 static $files = array();
75 if(isset($files[$type][$name])){
76 return $files[$type][$name];
79 $query = mysql_query("SELECT filename FROM".$db['pre']." system WHERE name = '".$name."' AND type = '".$type."'");
80 $file = mysql_fetch_assoc($query);
82 $files[$type][$name] = $file['filename'];
84 return $files[$type][$name];
89 * Loads files of any kind in the system. If you are not sure of where a module is located or a theme, use this.
92 * The debug section won't return the entire array of loaded files
94 function core_load($name, $ext = 'module', $type = 'module', $filename = NULL){
96 //Locate the file. We use include_once so that it will not be loaded more than once.
99 //Special for debuging
100 if($name == 'PRINT_FOR_DEBUG'){
101 return $loaded_files;
104 if($loaded_files[$type][$name][$ext] == TRUE){
108 //Used in core modules to avoid extra queries
109 if(!isset($filename)){
110 $filename = core_get_filename($name, $type);
114 //For other parts of the module
115 if($ext != 'module'){
116 $filename = str_replace('.module', '.' . $ext, $filename);
119 if(file_exists($filename)){
120 $loaded_files[$type][$name][$ext] = TRUE;
121 return (include_once "./$filename");
129 * Loads the configuration and sets the base URL, cookie domain, and
130 * session name correctly. From the user's settings.php
131 * Most of it as seen in Drupal v6.13
133 * Revisit this function, there is a lot to change in order to adjust it to the new system
135 function core_conf_init() {
137 global $settings, $db;
139 if(!file_exists('./includes/settings.php') || substr(sprintf('%o', fileperms('./includes/settings.php')), -4) != '0444'){
140 echo 'No installation detected. <br> If you already installed your system, you may want to verify the /includes/setings.php file, they must be \'0400\'. <br> You may want to try installing the system by going <a href="install">Here</a>';
141 echo '<meta http-equiv="Refresh" content="10; url=install"> <br/>';
142 echo 'Redirecting... now....';
146 include_once './includes/settings.php';
149 $settings['conf'] = array();
151 if (isset($_SERVER['HTTP_HOST'])) {
152 // As HTTP_HOST is user input, ensure it only contains characters allowed
153 // in hostnames. See RFC 952 (and RFC 2181).
154 // $_SERVER['HTTP_HOST'] is lowercased here per specifications.
155 $_SERVER['HTTP_HOST'] = strtolower($_SERVER['HTTP_HOST']);
156 if (!core_valid_http_host($_SERVER['HTTP_HOST'])) {
157 // HTTP_HOST is invalid, e.g. if containing slashes it may be an attack.
158 header('HTTP/1.1 400 Bad Request');
163 // Some pre-HTTP/1.1 clients will not send a Host header. Ensure the key is
164 // defined for E_ALL compliance.
165 $_SERVER['HTTP_HOST'] = '';
168 if (isset($base_url)) {
169 // Parse fixed base URL from settings.php.
170 $settings['base_url'] = $base_url;
171 $parts = parse_url($base_url);
172 if (!isset($parts['path'])) {
175 $settigns['base_path'] = $parts['path'] .'/';
176 // Build $base_root (everything until first slash after "scheme://").
177 $settings['base_root'] = substr($base_url, 0, strlen($base_url) - strlen($parts['path']));
181 $settings['base_root'] = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
183 $settings['base_url'] = $base_root .= '://'. $_SERVER['HTTP_HOST'];
185 // $_SERVER['SCRIPT_NAME'] can, in contrast to $_SERVER['PHP_SELF'], not
186 // be modified by a visitor.
187 if ($dir = trim(dirname($_SERVER['SCRIPT_NAME']), '\,/')) {
188 $settings['base_path'] = "/$dir";
189 $settings['base_url'] .= $base_path;
190 $settings['base_path'] .= '/';
193 $settings['base_path'] = '/';
197 //This name may change
198 $settings['base_x'] = $settings['base_root'] . $settings['base_url'] . $settings['base_path'];
200 if ($cookie_domain) {
201 // If the user specifies the cookie domain, also use it for session name.
202 $settings['cookie_domain'] = $cookie_domain;
203 $settings['session_name'] = $settings['cookie_domain'];
206 // Otherwise use $base_url as session name, without the protocol
207 // to use the same session identifiers across http and https.
208 list( , $settings['session_name']) = explode('://', $settings['base_url'], 2);
209 // We escape the hostname because it can be modified by a visitor.
210 if (!empty($_SERVER['HTTP_HOST'])) {
211 $settings['cookie_domain'] = text_check_plain($_SERVER['HTTP_HOST']);
214 // To prevent session cookies from being hijacked, a user can configure the
215 // SSL version of their website to only transfer session cookies via SSL by
216 // using PHP's session.cookie_secure setting. The browser will then use two
217 // separate session cookies for the HTTPS and HTTP versions of the site. So we
218 // must use different session identifiers for HTTPS and HTTP to prevent a
220 if (ini_get('session.cookie_secure')) {
221 $settings['session_name'] .= 'SSL';
223 // Strip leading periods, www., and port numbers from cookie domain.
224 $settings['cookie_domain'] = ltrim($settings['cookie_domain'], '.');
225 if (strpos($settings['cookie_domain'], 'www.') === 0) {
226 $settings['cookie_domain'] = substr($settigns['cookie_domain'], 4);
228 $settings['cookie_domain'] = explode(':', $settings['cookie_domain']);
229 $settings['cookie_domain'] = '.'. $settings['cookie_domain'][0];
230 // Per RFC 2109, cookie domains must contain at least one dot other than the
231 // first. For hosts such as 'localhost' or IP Addresses we don't set a cookie domain.
232 if (count(explode('.', $settings['cookie_domain'])) > 2 && !is_numeric(str_replace('.', '', $settings['cookie_domain']))) {
233 // ini_set('session.cookie_domain', $settings['cookie_domain']);
235 // session_name('SESS'. md5($settings['session_name']));
238 function core_variable_get($name, $default, $owner = 'system'){
242 if($owner != 'system' && !isset($settings[$owner])){
243 boot_variable_init($owner);
246 return (isset($settings['variables'][$owner][$name]) && $settings['variables'][$owner][$name] != '' ? $settings['variables'][$owner][$name] : $default);
251 * Set a persistent variable.
254 * The name of the variable to set.
256 * The value to set. This can be any PHP data type; these functions take care
257 * of serialization as necessary.
259 * The owner of the variable
262 function core_variable_set($name, $value, $owner) {
263 global $db, $settings;
265 $serialized_value = serialize($value);
267 db_query("DELETE FROM {PRE_}variable WHERE name ='".$name."' AND owner ='".$owner."'");
269 db_query("INSERT INTO {PRE_}variable (name, value, owner) VALUES ('".$name."', '".$serialized_value."', '".$owner."')");
271 $setings['variables'][$owner][$name] = $value;
275 * Removes a variable(s).
278 * The name of the variable to set.
280 * The owner of this variable(s)
282 * If you want to remove all variables for this owner
284 function core_variable_rm($name, $owner, $all = FALSE){
289 db_query("DELETE FROM {PRE_}variable WHERE name = '".$name."' AND owner = '".$owner."'");
290 unset($setings['variables'][$owner][$name]);
292 //Just for security you must specify the $all parameter
293 elseif(!$name && $all){
294 db_query("DELETE FROM {PRE_}variable WHERE owner = '".$owner."'");
295 unset($setings['variables'][$owner]);
301 * Determines which module handles the current page request
302 * If no 'obvious' module handles this, will ask everybody to see if there is someone who can take care of it
304 function core_who_handles_this(){
306 global $x, $xx, $xxx;
308 $modules = modules_list();
309 $content = PATH_NOT_FOUND;
311 //If there is a module who's name is equals to the first part of the path, we'll call him first
313 if(isset($modules[$xx[0]])){
314 core_load($xx[0], 'boot');
315 if(function_exists($xx[0].'_isityou')){
316 if($content = call_user_func($xx[0].'_isityou')){
321 //Lets see if someone else handles this
323 foreach($modules as $module => $path){
324 core_load($module, 'boot');
325 if(function_exists($module.'_isityou')){
326 if($content = call_user_func($module.'_isityou')){
333 if(!$content || $content == 0){
334 $content = PATH_NOT_FOUND;