New automatic installer
[estigi.git] / includes / core.inc
blobd4182c63fb4e96d5c1c3cfed029b803510bd87a7
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() {
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....';
143                 exit;
144         }
145         else{
146                 include_once './includes/settings.php';
147         }
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');
159                 exit;
160                 }
161         }
162         else {
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'] = '';
166         }
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'])) {
173                         $parts['path'] = '';
174                 }
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']));
178   }
179   else {
180     // Create base URL
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'] .= '/';
191     }
192     else {
193                 $settings['base_path'] = '/';
194     }
195   }
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'];
204         }
205   else {
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']);
212     }
213   }
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
219   // cookie collision.
220   if (ini_get('session.cookie_secure')) {
221     $settings['session_name'] .= 'SSL';
222   }
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);
227   }
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']);
234   }
235  // session_name('SESS'. md5($settings['session_name']));
238 function core_variable_get($name, $default, $owner = 'system'){
240         global $settings;
242         if($owner != 'system' && !isset($settings[$owner])){
243                 boot_variable_init($owner);
244         }
246         return (isset($settings['variables'][$owner][$name]) && $settings['variables'][$owner][$name] != '' ? $settings['variables'][$owner][$name] : $default);
251  * Set a persistent variable.
253  * @param $name
254  *   The name of the variable to set.
255  * @param $value
256  *   The value to set. This can be any PHP data type; these functions take care
257  *   of serialization as necessary.
258  * @param $owner
259  *  The owner of the variable
261  */
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).
277  * @param $name
278  *   The name of the variable to set.
279  * @param $owner
280  *  The owner of this variable(s)
281  * @param @all
282  *  If you want to remove all variables for this owner
283  */
284 function core_variable_rm($name, $owner, $all = FALSE){
286         global $settings;
288         if($name){
289                 db_query("DELETE FROM {PRE_}variable WHERE name = '".$name."' AND owner = '".$owner."'");
290                 unset($setings['variables'][$owner][$name]);
291         }
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]);
296         }
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')){
317                                         return $content;
318                                 }
319                         }
320                 }
321                 //Lets see if someone else handles this
322                 else{
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')){
327                                                 return $content;
328                                         }
329                                 }
330                         }
331                 }
333         if(!$content || $content == 0){
334                 $content = PATH_NOT_FOUND;
335         }
337         return $content;