New wilcard path detection and modifications in the node admin hook
[estigi.git] / includes / core.inc
blob90ca2949e69eb684c22d3d94c5fcc344f54086fb
1 <?php
3 /**
4  * @file
5  *  Core and commonly used functions
6  * 
7  * @ingroup System
8  */
11 /**
12  * Variables:
13  *   guest_name
14  *   cache_expire
15  */
17 /**
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.
21  *
22  * @return
23  *   IP address of client machine, adjusted for reverse proxy.
24  */
25 function core_ip_address() {
26         global $settings;
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']));
38                         }
39                 }
40         }
41         return $settings['ip_address'];
44 /**
45  * Validate that a hostname (for example $_SERVER['HTTP_HOST']) is safe.
46  *
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
49  * lowercased.
50  *
51  * @return
52  *  TRUE if only containing valid characters, or FALSE otherwise.
53  */
54 function core_valid_http_host($host) {
55   return preg_match('/^\[?(?:[a-z0-9-:\]_]+\.?)+$/', $host);
58  /**
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.
61  * @todo
62  *   Verify if mysql_query is used for some reason, use db_query
63  */
65 function core_get_filename($name, $type = 'module', $reset = FALSE){
67         global $db;
69         static $files = array();
71         if($reset){
72                 $files = array();
73         }
75         if(isset($files[$type][$name])){
76                 return $files[$type][$name];
77         }
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];
88 /**
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.
90  *
91  * @bug
92  *  The debug section won't return the entire array of loaded files
93  */
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.
97         static $loaded_files;
99         //Special for debuging
100         if($name == 'PRINT_FOR_DEBUG'){
101                 return $loaded_files;
102         }
104         if($loaded_files[$type][$name][$ext] == TRUE){
105                 return TRUE;
106         }
108         //Used in core modules to avoid extra queries
109         if(!isset($filename)){
110                 $filename = core_get_filename($name, $type);
111         }
113         if($filename) {
114                 //For other parts of the module
115                 if($ext != 'module'){
116                         $filename = str_replace('.module', '.' . $ext, $filename);
117                 }
119                 if(file_exists($filename)){
120                         $loaded_files[$type][$name][$ext] = TRUE;
121                         return (include_once "./$filename");
122                 }
123         }
125         return FALSE;
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
132  * @todo
133  *  Revisit this function, there is a lot to change in order to adjust it to the new system
134  */
135 function core_conf_init() {
136         global $settings, $db;
138         require_once './settings.php';
140         $settings['conf'] = array();
142         if (isset($_SERVER['HTTP_HOST'])) {
143                 // As HTTP_HOST is user input, ensure it only contains characters allowed
144                 // in hostnames. See RFC 952 (and RFC 2181).
145                 // $_SERVER['HTTP_HOST'] is lowercased here per specifications.
146                 $_SERVER['HTTP_HOST'] = strtolower($_SERVER['HTTP_HOST']);
147                 if (!core_valid_http_host($_SERVER['HTTP_HOST'])) {
148                 // HTTP_HOST is invalid, e.g. if containing slashes it may be an attack.
149                 header('HTTP/1.1 400 Bad Request');
150                 exit;
151                 }
152         }
153         else {
154                 // Some pre-HTTP/1.1 clients will not send a Host header. Ensure the key is
155                 // defined for E_ALL compliance.
156                 $_SERVER['HTTP_HOST'] = '';
157         }
159         if (isset($base_url)) {
160                 // Parse fixed base URL from settings.php.
161                 $settings['base_url'] = $base_url;
162                 $parts = parse_url($base_url);
163                 if (!isset($parts['path'])) {
164                         $parts['path'] = '';
165                 }
166     $settigns['base_path'] = $parts['path'] .'/';
167     // Build $base_root (everything until first slash after "scheme://").
168     $settings['base_root'] = substr($base_url, 0, strlen($base_url) - strlen($parts['path']));
169   }
170   else {
171     // Create base URL
172     $settings['base_root'] = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https' : 'http';
174     $settings['base_url'] = $base_root .= '://'. $_SERVER['HTTP_HOST'];
176     // $_SERVER['SCRIPT_NAME'] can, in contrast to $_SERVER['PHP_SELF'], not
177     // be modified by a visitor.
178     if ($dir = trim(dirname($_SERVER['SCRIPT_NAME']), '\,/')) {
179       $settings['base_path'] = "/$dir";
180       $settings['base_url'] .= $base_path;
181       $settings['base_path'] .= '/';
182     }
183     else {
184                 $settings['base_path'] = '/';
185     }
186   }
188   if ($cookie_domain) {
189                 // If the user specifies the cookie domain, also use it for session name.
190                 $settings['cookie_domain'] = $cookie_domain;
191                 $settings['session_name'] = $settings['cookie_domain'];
192         }
193   else {
194     // Otherwise use $base_url as session name, without the protocol
195     // to use the same session identifiers across http and https.
196     list( , $settings['session_name']) = explode('://', $settings['base_url'], 2);
197     // We escape the hostname because it can be modified by a visitor.
198     if (!empty($_SERVER['HTTP_HOST'])) {
199       $settings['cookie_domain'] = text_check_plain($_SERVER['HTTP_HOST']);
200     }
201   }
202   // To prevent session cookies from being hijacked, a user can configure the
203   // SSL version of their website to only transfer session cookies via SSL by
204   // using PHP's session.cookie_secure setting. The browser will then use two
205   // separate session cookies for the HTTPS and HTTP versions of the site. So we
206   // must use different session identifiers for HTTPS and HTTP to prevent a
207   // cookie collision.
208   if (ini_get('session.cookie_secure')) {
209     $settings['session_name'] .= 'SSL';
210   }
211   // Strip leading periods, www., and port numbers from cookie domain.
212   $settings['cookie_domain'] = ltrim($settings['cookie_domain'], '.');
213   if (strpos($settings['cookie_domain'], 'www.') === 0) {
214     $settings['cookie_domain'] = substr($settigns['cookie_domain'], 4);
215   }
216   $settings['cookie_domain'] = explode(':', $settings['cookie_domain']);
217   $settings['cookie_domain'] = '.'. $settings['cookie_domain'][0];
218   // Per RFC 2109, cookie domains must contain at least one dot other than the
219   // first. For hosts such as 'localhost' or IP Addresses we don't set a cookie domain.
220   if (count(explode('.', $settings['cookie_domain'])) > 2 && !is_numeric(str_replace('.', '', $settings['cookie_domain']))) {
221    // ini_set('session.cookie_domain', $settings['cookie_domain']);
222   }
223  // session_name('SESS'. md5($settings['session_name']));
226 function core_variable_get($name, $default, $owner = 'system'){
228         global $settings;
230         if($owner != 'system' && !isset($settings[$owner])){
231                 boot_variable_init($owner);
232         }
234         return (isset($settings['variables'][$owner][$name]) && $settings['variables'][$owner][$name] != '' ? $settings['variables'][$owner][$name] : $default);
239  * Set a persistent variable.
241  * @param $name
242  *   The name of the variable to set.
243  * @param $value
244  *   The value to set. This can be any PHP data type; these functions take care
245  *   of serialization as necessary.
246  */
247 function core_variable_set($name, $value, $owner) {
249         global $db, $settings;
251         $serialized_value = serialize($value);
253         //db_query("UPDATE {PRE_}variable SET value = '".$serialized_value."' WHERE name ='".$name."' AND owner ='".$owner."'");
254         db_query("DELETE FROM {PRE_}variable WHERE name ='".$name."' AND owner ='".$owner."'");
255 //echo "UPDATE {PRE_}variable SET value = '".$serialized_value."' WHERE name = '".$name."' AND owner = '".$owner."'";
256 //print_r($db); exit;
258         //if ($db['affected_rows'] == 0) {
259                 db_query("INSERT INTO {PRE_}variable (name, value, owner) VALUES ('".$name."', '".$serialized_value."', '".$owner."')");
260 //print_r($db); exit;
261         //}
263         $setings['variables'][$owner][$name] = $value;
267  * Removes a variable(s).
269  * @param $name
270  *   The name of the variable to set.
271  * @param $owner
272  *  The owner of this variable(s)
273  * @param @all
274  *  If you want to remove all variables for this owner
275  */
276 function core_variable_rm($name, $owner, $all = FALSE){
278         global $settings;
280         if($name){
281                 db_query("DELETE FROM {PRE_}variable WHERE name = '".$name."' AND owner = '".$owner."'");
282                 unset($setings['variables'][$owner][$name]);
283         }
284         else{
285                 db_query("DELETE FROM {PRE_}variable WHERE owner = '".$owner."'");
286                 unset($setings['variables'][$owner]);
287         }
292  * Determines which module handles the current page request
293  * If no 'obvious' module handles this, will ask everybody to see if there is someone who can take care of it
295 function core_who_handles_this(){
297         global $x, $xx, $xxx;
299         $modules = modules_list();
300         $content = PATH_NOT_FOUND;
302         //If there is a module who's name is equals to the first part of the path, we'll call him first
304                 if(isset($modules[$xx[0]])){
305                         core_load($xx[0], 'boot');
306                         if(function_exists($xx[0].'_isityou')){
307                                 if($content = call_user_func($xx[0].'_isityou')){
308                                         return $content;
309                                 }
310                         }
311                 }
312                 //Lets see if someone else handles this
313                 else{
314                         foreach($modules as $module => $path){
315                                 core_load($module, 'boot');
316                                 if(function_exists($module.'_isityou')){
317                                         if($content = call_user_func($module.'_isityou')){
318                                                 return $content;
319                                         }
320                                 }
321                         }
322                 }
324         if(!$content || $content == 0){
325                 $content = PATH_NOT_FOUND;
326         }
328         return $content;