]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/MVC/SugarApplication.php
Release 6.2.0beta4
[Github/sugarcrm.git] / include / MVC / SugarApplication.php
1 <?php
2 /*********************************************************************************
3  * SugarCRM is a customer relationship management program developed by
4  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
5  * 
6  * This program is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  * 
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
16  * details.
17  * 
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  * 
23  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
24  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
25  * 
26  * The interactive user interfaces in modified source and object code versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  * 
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the "Powered by
32  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
33  * technical reasons, the Appropriate Legal Notices must display the words
34  * "Powered by SugarCRM".
35  ********************************************************************************/
36
37 /*
38  * Created on Mar 21, 2007
39  *
40  * To change the template for this generated file go to
41  * Window - Preferences - PHPeclipse - PHP - Code Templates
42  */
43 require_once('include/MVC/Controller/ControllerFactory.php');
44 require_once('include/MVC/View/ViewFactory.php');
45
46 class SugarApplication
47 {
48         var $controller = null;
49         var $headerDisplayed = false;
50         var $default_module = 'Home';
51         var $default_action = 'index';
52
53         function SugarApplication()
54         {}
55
56         /**
57          * Perform execution of the application. This method is called from index2.php
58          */
59         function execute(){
60                 global $sugar_config;
61                 if(!empty($sugar_config['default_module']))
62                         $this->default_module = $sugar_config['default_module'];
63                 $module = $this->default_module;
64                 if(!empty($_REQUEST['module']))$module = $_REQUEST['module'];
65                 insert_charset_header();
66                 $this->setupPrint();
67                 $this->controller = ControllerFactory::getController($module);
68         // if the entry point is defined to not need auth, then don't authenicate
69                 if( empty($_REQUEST['entryPoint'])
70                 || $this->controller->checkEntryPointRequiresAuth($_REQUEST['entryPoint']) ){
71             $this->loadUser();
72             $this->ACLFilter();
73             $this->preProcess();
74             $this->controller->preProcess();
75         }
76
77         SugarThemeRegistry::buildRegistry();
78         $this->loadLanguages();
79                 $this->checkDatabaseVersion();
80                 $this->loadDisplaySettings();
81                 $this->loadLicense();
82                 $this->loadGlobals();
83                 $this->setupResourceManagement($module);
84                 $this->checkHTTPReferer();
85                 $this->controller->execute();
86                 sugar_cleanup();
87         }
88
89         /**
90          * Load the authenticated user. If there is not an authenticated user then redirect to login screen.
91          */
92         function loadUser(){
93                 global $authController, $sugar_config;
94                 // Double check the server's unique key is in the session.  Make sure this is not an attempt to hijack a session
95                 $user_unique_key = (isset($_SESSION['unique_key'])) ? $_SESSION['unique_key'] : '';
96                 $server_unique_key = (isset($sugar_config['unique_key'])) ? $sugar_config['unique_key'] : '';
97                 $allowed_actions = (!empty($this->controller->allowed_actions)) ? $this->controller->allowed_actions : $allowed_actions = array('Authenticate', 'Login',);
98
99                 if(($user_unique_key != $server_unique_key) && (!in_array($this->controller->action, $allowed_actions)) &&
100                    (!isset($_SESSION['login_error'])))
101                    {
102                         session_destroy();
103                         $post_login_nav = '';
104
105                         if(!empty($this->controller->module)){
106                                 $post_login_nav .= '&login_module='.$this->controller->module;
107                         }
108                         if(!empty($this->controller->action)){
109                             if(in_array(strtolower($this->controller->action), array('delete')))
110                                 $post_login_nav .= '&login_action=DetailView';
111                             elseif(in_array(strtolower($this->controller->action), array('save')))
112                                 $post_login_nav .= '&login_action=EditView';
113                             elseif(isset($_REQUEST['massupdate'])|| isset($_GET['massupdate']) || isset($_POST['massupdate']))
114                                 $post_login_nav .= '&login_action=index';
115                             else
116                                     $post_login_nav .= '&login_action='.$this->controller->action;
117                         }
118                         if(!empty($this->controller->record)){
119                                 $post_login_nav .= '&login_record='.$this->controller->record;
120                         }
121
122                         header('Location: index.php?action=Login&module=Users'.$post_login_nav);
123                         exit ();
124                 }
125
126                 $authController = new AuthenticationController((!empty($GLOBALS['sugar_config']['authenticationClass'])? $GLOBALS['sugar_config']['authenticationClass'] : 'SugarAuthenticate'));
127                 $GLOBALS['current_user'] = new User();
128                 if(isset($_SESSION['authenticated_user_id'])){
129                         // set in modules/Users/Authenticate.php
130                         if(!$authController->sessionAuthenticate()){
131                                  // if the object we get back is null for some reason, this will break - like user prefs are corrupted
132                                 $GLOBALS['log']->fatal('User retrieval for ID: ('.$_SESSION['authenticated_user_id'].') does not exist in database or retrieval failed catastrophically.  Calling session_destroy() and sending user to Login page.');
133                                 session_destroy();
134                                 SugarApplication::redirect('index.php?action=Login&module=Users');
135                                 die();
136                         }//fi
137                 }elseif(!($this->controller->module == 'Users' && in_array($this->controller->action, $allowed_actions))){
138                         session_destroy();
139                         SugarApplication::redirect('index.php?action=Login&module=Users');
140                         die();
141                 }
142                 $GLOBALS['log']->debug('Current user is: '.$GLOBALS['current_user']->user_name);
143
144                 //set cookies
145                 if(isset($_SESSION['authenticated_user_id'])){
146                         $GLOBALS['log']->debug("setting cookie ck_login_id_20 to ".$_SESSION['authenticated_user_id']);
147                         self::setCookie('ck_login_id_20', $_SESSION['authenticated_user_id'], time() + 86400 * 90);
148                 }
149                 if(isset($_SESSION['authenticated_user_theme'])){
150                         $GLOBALS['log']->debug("setting cookie ck_login_theme_20 to ".$_SESSION['authenticated_user_theme']);
151                         self::setCookie('ck_login_theme_20', $_SESSION['authenticated_user_theme'], time() + 86400 * 90);
152                 }
153                 if(isset($_SESSION['authenticated_user_theme_color'])){
154                         $GLOBALS['log']->debug("setting cookie ck_login_theme_color_20 to ".$_SESSION['authenticated_user_theme_color']);
155                         self::setCookie('ck_login_theme_color_20', $_SESSION['authenticated_user_theme_color'], time() + 86400 * 90);
156                 }
157                 if(isset($_SESSION['authenticated_user_theme_font'])){
158                         $GLOBALS['log']->debug("setting cookie ck_login_theme_font_20 to ".$_SESSION['authenticated_user_theme_font']);
159                         self::setCookie('ck_login_theme_font_20', $_SESSION['authenticated_user_theme_font'], time() + 86400 * 90);
160                 }
161                 if(isset($_SESSION['authenticated_user_language'])){
162                         $GLOBALS['log']->debug("setting cookie ck_login_language_20 to ".$_SESSION['authenticated_user_language']);
163                         self::setCookie('ck_login_language_20', $_SESSION['authenticated_user_language'], time() + 86400 * 90);
164                 }
165                 //check if user can access
166
167         }
168
169         function ACLFilter(){
170                 ACLController :: filterModuleList($GLOBALS['moduleList']);
171         }
172
173         /**
174          * setupResourceManagement
175          * This function initialize the ResourceManager and calls the setup method
176          * on the ResourceManager instance.
177          *
178          */
179         function setupResourceManagement($module) {
180                 require_once('include/resource/ResourceManager.php');
181                 $resourceManager = ResourceManager::getInstance();
182                 $resourceManager->setup($module);
183         }
184
185         function setupPrint() {
186                 $GLOBALS['request_string'] = '';
187
188                 // merge _GET and _POST, but keep the results local
189                 // this handles the issues where values come in one way or the other
190                 // without affecting the main super globals
191                 $merged = array_merge($_GET, $_POST);
192                 foreach ($merged as $key => $val)
193                 {
194                    if(is_array($val))
195                    {
196                        foreach ($val as $k => $v)
197                        {
198                            //If an array, then skip the urlencoding. This should be handled with stringify instead.
199                            if(is_array($v))
200                                 continue;
201
202                            $GLOBALS['request_string'] .= urlencode($key).'['.$k.']='.urlencode($v).'&';
203                        }
204                    }
205                    else
206                    {
207                        $GLOBALS['request_string'] .= urlencode($key).'='.urlencode($val).'&';
208                    }
209                 }
210                 $GLOBALS['request_string'] .= 'print=true';
211         }
212
213         function preProcess(){
214             $config = new Administration;
215             $config->retrieveSettings();
216                 if(!empty($_SESSION['authenticated_user_id'])){
217                         if(isset($_SESSION['hasExpiredPassword']) && $_SESSION['hasExpiredPassword'] == '1'){
218                                 if( $this->controller->action!= 'Save' && $this->controller->action != 'Logout') {
219                         $this->controller->module = 'Users';
220                         $this->controller->action = 'ChangePassword';
221                         $record = $GLOBALS['current_user']->id;
222                      }else{
223                                         $this->handleOfflineClient();
224                                  }
225                         }else{
226                                 $ut = $GLOBALS['current_user']->getPreference('ut');
227                             if(empty($ut)
228                                     && $this->controller->action != 'AdminWizard'
229                                     && $this->controller->action != 'EmailUIAjax'
230                                     && $this->controller->action != 'Wizard'
231                                     && $this->controller->action != 'SaveAdminWizard'
232                                     && $this->controller->action != 'SaveUserWizard'
233                                     && $this->controller->action != 'SaveTimezone'
234                                     && $this->controller->action != 'Logout') {
235                                         $this->controller->module = 'Users';
236                                         $this->controller->action = 'SetTimezone';
237                                         $record = $GLOBALS['current_user']->id;
238                                 }else{
239                                         if($this->controller->action != 'AdminWizard'
240                                     && $this->controller->action != 'EmailUIAjax'
241                                     && $this->controller->action != 'Wizard'
242                                     && $this->controller->action != 'SaveAdminWizard'
243                                     && $this->controller->action != 'SaveUserWizard'){
244                                                         $this->handleOfflineClient();
245                                     }
246                                 }
247                         }
248                 }
249                 $this->handleAccessControl();
250         }
251
252         function handleOfflineClient(){
253                 if(isset($GLOBALS['sugar_config']['disc_client']) && $GLOBALS['sugar_config']['disc_client']){
254                         if(isset($_REQUEST['action']) && $_REQUEST['action'] != 'SaveTimezone'){
255                                 if (!file_exists('modules/Sync/file_config.php')){
256                                         if($_REQUEST['action'] != 'InitialSync' && $_REQUEST['action'] != 'Logout' &&
257                                            ($_REQUEST['action'] != 'Popup' && $_REQUEST['module'] != 'Sync')){
258                                                 //echo $_REQUEST['action'];
259                                                 //die();
260                                                         $this->controller->module = 'Sync';
261                                                         $this->controller->action = 'InitialSync';
262                                                 }
263                         }else{
264                                 require_once ('modules/Sync/file_config.php');
265                                 if(isset($file_sync_info['is_first_sync']) && $file_sync_info['is_first_sync']){
266                                         if($_REQUEST['action'] != 'InitialSync' && $_REQUEST['action'] != 'Logout' &&
267                                            ( $_REQUEST['action'] != 'Popup' && $_REQUEST['module'] != 'Sync')){
268                                                                 $this->controller->module = 'Sync';
269                                                                 $this->controller->action = 'InitialSync';
270                                                 }
271                                 }
272                         }
273                         }
274                         global $moduleList, $sugar_config, $sync_modules;
275                         require_once('modules/Sync/SyncController.php');
276                         $GLOBALS['current_user']->is_admin = '0'; //No admins for disc client
277                 }
278         }
279
280         /**
281          * Handles everything related to authorization.
282          */
283         function handleAccessControl(){
284                 if(is_admin($GLOBALS['current_user']) || is_admin_for_any_module($GLOBALS['current_user']))
285                         return;
286             if(!empty($_REQUEST['action']) && $_REQUEST['action']=="RetrieveEmail")
287             return;
288                 if(!is_admin($GLOBALS['current_user']) && !empty($GLOBALS['adminOnlyList'][$this->controller->module])
289                 && !empty($GLOBALS['adminOnlyList'][$this->controller->module]['all'])
290                 && (empty($GLOBALS['adminOnlyList'][$this->controller->module][$this->controller->action]) || $GLOBALS['adminOnlyList'][$this->controller->module][$this->controller->action] != 'allow')) {
291                         $this->controller->hasAccess = false;
292                         return;
293                 }
294
295                 // Bug 20916 - Special case for check ACL access rights for Subpanel QuickCreates
296                 if(isset($_POST['action']) && $_POST['action'] == 'SubpanelCreates') {
297             $actual_module = $_POST['target_module'];
298             if(!empty($GLOBALS['modListHeader']) && !in_array($actual_module,$GLOBALS['modListHeader'])) {
299                 $this->controller->hasAccess = false;
300             }
301             return;
302         }
303
304                 if(!empty($GLOBALS['current_user']) && empty($GLOBALS['modListHeader']))
305                         $GLOBALS['modListHeader'] = query_module_access_list($GLOBALS['current_user']);
306         }
307
308         /**
309          * Load only bare minimum of language that can be done before user init and MVC stuff
310          */
311         static function preLoadLanguages()
312         {
313                 if(!empty($_SESSION['authenticated_user_language'])) {
314                         $GLOBALS['current_language'] = $_SESSION['authenticated_user_language'];
315                 }
316                 else {
317                         $GLOBALS['current_language'] = $GLOBALS['sugar_config']['default_language'];
318                 }
319                 $GLOBALS['log']->debug('current_language is: '.$GLOBALS['current_language']);
320                 //set module and application string arrays based upon selected language
321                 $GLOBALS['app_strings'] = return_application_language($GLOBALS['current_language']);
322         }
323
324         /**
325          * Load application wide languages as well as module based languages so they are accessible
326          * from the module.
327          */
328         function loadLanguages(){
329                 if(!empty($_SESSION['authenticated_user_language'])) {
330                         $GLOBALS['current_language'] = $_SESSION['authenticated_user_language'];
331                 }
332                 else {
333                         $GLOBALS['current_language'] = $GLOBALS['sugar_config']['default_language'];
334                 }
335                 $GLOBALS['log']->debug('current_language is: '.$GLOBALS['current_language']);
336                 //set module and application string arrays based upon selected language
337                 $GLOBALS['app_strings'] = return_application_language($GLOBALS['current_language']);
338                 if(empty($GLOBALS['current_user']->id))$GLOBALS['app_strings']['NTC_WELCOME'] = '';
339                 if(!empty($GLOBALS['system_config']->settings['system_name']))$GLOBALS['app_strings']['LBL_BROWSER_TITLE'] = $GLOBALS['system_config']->settings['system_name'];
340                 $GLOBALS['app_list_strings'] = return_app_list_strings_language($GLOBALS['current_language']);
341                 $GLOBALS['mod_strings'] = return_module_language($GLOBALS['current_language'], $this->controller->module);
342         }
343         /**
344         * checkDatabaseVersion
345         * Check the db version sugar_version.php and compare to what the version is stored in the config table.
346         * Ensure that both are the same.
347         */
348         function checkDatabaseVersion($dieOnFailure = true)
349         {
350             $row_count = sugar_cache_retrieve('checkDatabaseVersion_row_count');
351             if ( empty($row_count) ) {
352             global $sugar_db_version;
353             $version_query = 'SELECT count(*) as the_count FROM config WHERE category=\'info\' AND name=\'sugar_version\'';
354
355             if($GLOBALS['db']->dbType == 'oci8'){
356             }
357             else if ($GLOBALS['db']->dbType == 'mssql'){
358                 $version_query .= " AND CAST(value AS varchar(8000)) = '$sugar_db_version'";
359             }
360             else {
361                 $version_query .= " AND value = '$sugar_db_version'";
362             }
363
364             $result = $GLOBALS['db']->query($version_query);
365             $row = $GLOBALS['db']->fetchByAssoc($result, -1, true);
366             $row_count = $row['the_count'];
367             sugar_cache_put('checkDatabaseVersion_row_count', $row_count);
368         }
369
370                 if($row_count == 0 && empty($GLOBALS['sugar_config']['disc_client'])){
371                         $sugar_version = $GLOBALS['sugar_version'];
372                         if ( $dieOnFailure )
373                                 sugar_die("Sugar CRM $sugar_version Files May Only Be Used With A Sugar CRM $sugar_db_version Database.");
374                         else
375                             return false;
376                 }
377
378                 return true;
379         }
380
381         /**
382          * Load the themes/images.
383          */
384         function loadDisplaySettings()
385     {
386         global $theme;
387
388         // load the user's default theme
389         $theme = $GLOBALS['current_user']->getPreference('user_theme');
390
391         if (is_null($theme)) {
392             $theme = $GLOBALS['sugar_config']['default_theme'];
393             if(!empty($_SESSION['authenticated_user_theme'])){
394                 $theme = $_SESSION['authenticated_user_theme'];
395             }
396             else if(!empty($_COOKIE['sugar_user_theme'])){
397                 $theme = $_COOKIE['sugar_user_theme'];
398             }
399             
400                         if(isset($_SESSION['authenticated_user_theme']) && $_SESSION['authenticated_user_theme'] != '') {
401                                 $_SESSION['theme_changed'] = false;
402                         }
403                 }
404                    
405         if(!is_null($theme) && !headers_sent())
406         {
407             setcookie('sugar_user_theme', $theme, time() + 31536000); // expires in a year
408         }
409                 
410         SugarThemeRegistry::set($theme);
411         require_once('include/utils/layout_utils.php');
412         $GLOBALS['image_path'] = SugarThemeRegistry::current()->getImagePath().'/';
413         if ( defined('TEMPLATE_URL') )
414             $GLOBALS['image_path'] = TEMPLATE_URL . '/'. $GLOBALS['image_path'];
415
416         if ( isset($GLOBALS['current_user']) ) {
417             $GLOBALS['gridline'] = (int) ($GLOBALS['current_user']->getPreference('gridline') == 'on');
418             $GLOBALS['current_user']->setPreference('user_theme', $theme, 0, 'global');
419         }
420         }
421
422         function loadLicense(){
423                 loadLicense();
424                 global $user_unique_key, $server_unique_key;
425                 $user_unique_key = (isset($_SESSION['unique_key'])) ? $_SESSION['unique_key'] : '';
426                 $server_unique_key = (isset($sugar_config['unique_key'])) ? $sugar_config['unique_key'] : '';
427         }
428
429         function loadGlobals(){
430                 global $currentModule;
431                 $currentModule = $this->controller->module;
432                 if($this->controller->module == $this->default_module){
433                         $_REQUEST['module'] = $this->controller->module;
434                         if(empty($_REQUEST['action']))
435                         $_REQUEST['action'] = $this->default_action;
436                 }
437         }
438         /**
439          *
440          * Checks a request to ensure the request is coming from a valid source or it is for one of the white listed actions
441          */
442         protected function checkHTTPReferer($dieIfInvalid = true)
443         {
444                 global $sugar_config;
445                 $whiteListActions = (!empty($sugar_config['http_referer']['actions']))?$sugar_config['http_referer']['actions']:array('index', 'ListView', 'DetailView', 'EditView','oauth');
446                 // Bug 39691 - Make sure localhost and 127.0.0.1 are always valid HTTP referers
447                 $whiteListReferers = array('127.0.0.1','localhost');
448                 if(!empty($_SERVER['SERVER_ADDR']))$whiteListReferers[]  = $_SERVER['SERVER_ADDR'];
449                 if ( !empty($sugar_config['http_referer']['list']) ) {
450                         $whiteListReferers = array_merge($whiteListReferers,$sugar_config['http_referer']['list']);
451                 }
452                 if(!empty($_SERVER['HTTP_REFERER']) && !empty($_SERVER['SERVER_NAME'])){
453                         $http_ref = parse_url($_SERVER['HTTP_REFERER']);
454                         if($http_ref['host'] !== $_SERVER['SERVER_NAME']  && !in_array($this->controller->action, $whiteListActions) &&
455                                     (empty($whiteListReferers) || !in_array($http_ref['host'], $whiteListReferers))){
456                 if ( $dieIfInvalid ) {
457                     header("Cache-Control: no-cache, must-revalidate");
458                     $whiteListActions[] = $this->controller->action;
459                     $whiteListString = "'" . implode("', '", $whiteListActions) . "'";
460                     $ss = new Sugar_Smarty;
461                     $ss->assign('host',$http_ref['host']);
462                     $ss->assign('action',$this->controller->action);
463                     $ss->assign('whiteListString',$whiteListString);
464                     $ss->display('include/MVC/View/tpls/xsrf.tpl');
465                     sugar_cleanup(true);
466                 }
467                 return false;
468                         }
469                 }
470                 
471                 return true;
472         }
473         function startSession()
474         {
475             $sessionIdCookie = isset($_COOKIE['PHPSESSID']) ? $_COOKIE['PHPSESSID'] : null;
476             if(isset($_REQUEST['MSID'])) {
477                         session_id($_REQUEST['MSID']);
478                         session_start();
479                         if(isset($_SESSION['user_id']) && isset($_SESSION['seamless_login'])){
480                                 unset ($_SESSION['seamless_login']);
481                         }else{
482                                 if(isset($_COOKIE['PHPSESSID'])){
483                                 self::setCookie('PHPSESSID', '', time()-42000, '/');
484                         }
485                         sugar_cleanup(false);
486                         session_destroy();
487                         exit('Not a valid entry method');
488                         }
489                 }else{
490                         if(can_start_session()){
491                                 session_start();
492                         }
493                 }
494
495                 if ( isset($_REQUEST['login_module']) && isset($_REQUEST['login_action'])
496                         && !($_REQUEST['login_module'] == 'Home' && $_REQUEST['login_action'] == 'index') ) {
497             if ( !is_null($sessionIdCookie) && empty($_SESSION) ) {
498                 self::setCookie('loginErrorMessage', 'LBL_SESSION_EXPIRED', time()+30, '/');
499             }
500         }
501
502         }
503
504         function endSession(){
505                 session_destroy();
506         }
507         /**
508          * Redirect to another URL
509          *
510          * @access      public
511          * @param       string  $url    The URL to redirect to
512          */
513         function redirect(
514             $url
515             )
516         {
517                 /*
518                  * If the headers have been sent, then we cannot send an additional location header
519                  * so we will output a javascript redirect statement.
520                  */
521                 if (headers_sent()) {
522                         echo "<script>document.location.href='$url';</script>\n";
523                 } else {
524                         //@ob_end_clean(); // clear output buffer
525                         session_write_close();
526                         header( 'HTTP/1.1 301 Moved Permanently' );
527                         header( "Location: ". $url );
528                 }
529                 exit();
530         }
531
532     /**
533          * Redirect to another URL
534          *
535          * @access      public
536          * @param       string  $url    The URL to redirect to
537          */
538         public static function appendErrorMessage($error_message)
539         {
540         if (empty($_SESSION['user_error_message']) || !is_array($_SESSION['user_error_message'])){
541             $_SESSION['user_error_message'] = array();
542         }
543                 $_SESSION['user_error_message'][] = $error_message;
544         }
545
546     public static function getErrorMessages()
547         {
548                 if (isset($_SESSION['user_error_message']) && is_array($_SESSION['user_error_message']) ) {
549             $msgs = $_SESSION['user_error_message'];
550             unset($_SESSION['user_error_message']);
551             return $msgs;
552         }else{
553             return array();
554         }
555         }
556
557         /**
558          * Wrapper for the PHP setcookie() function, to handle cases where headers have
559          * already been sent
560          */
561         public static function setCookie(
562             $name,
563             $value,
564             $expire = 0,
565             $path = '/',
566             $domain = null,
567             $secure = false,
568             $httponly = false
569             )
570         {
571             if ( is_null($domain) )
572                 if ( isset($_SERVER["HTTP_HOST"]) )
573                     $domain = $_SERVER["HTTP_HOST"];
574                 else
575                     $domain = 'localhost';
576
577             if (!headers_sent())
578                 setcookie($name,$value,$expire,$path,$domain,$secure,$httponly);
579
580             $_COOKIE[$name] = $value;
581         }
582 }