]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/MVC/SugarApplication.php
Release 6.2.2
[Github/sugarcrm.git] / include / MVC / SugarApplication.php
1 <?php
2 /*********************************************************************************
3  * SugarCRM Community Edition 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             $this->checkHTTPReferer();
76         }
77
78         SugarThemeRegistry::buildRegistry();
79         $this->loadLanguages();
80                 $this->checkDatabaseVersion();
81                 $this->loadDisplaySettings();
82                 $this->loadLicense();
83                 $this->loadGlobals();
84                 $this->setupResourceManagement($module);
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($GLOBALS['current_user']->isDeveloperForAnyModule())
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
305                 if(!empty($GLOBALS['current_user']) && empty($GLOBALS['modListHeader']))
306                         $GLOBALS['modListHeader'] = query_module_access_list($GLOBALS['current_user']);
307
308                 if(in_array($this->controller->module, $GLOBALS['modInvisList']) &&
309                         ((in_array('Activities', $GLOBALS['moduleList'])              &&
310                         in_array('Calendar',$GLOBALS['moduleList']))                 &&
311                         in_array($this->controller->module, $GLOBALS['modInvisListActivities']))
312                         ){
313                                 $this->controller->hasAccess = false;
314                                 return;
315                 }
316         }
317
318         /**
319          * Load only bare minimum of language that can be done before user init and MVC stuff
320          */
321         static function preLoadLanguages()
322         {
323                 if(!empty($_SESSION['authenticated_user_language'])) {
324                         $GLOBALS['current_language'] = $_SESSION['authenticated_user_language'];
325                 }
326                 else {
327                         $GLOBALS['current_language'] = $GLOBALS['sugar_config']['default_language'];
328                 }
329                 $GLOBALS['log']->debug('current_language is: '.$GLOBALS['current_language']);
330                 //set module and application string arrays based upon selected language
331                 $GLOBALS['app_strings'] = return_application_language($GLOBALS['current_language']);
332         }
333
334         /**
335          * Load application wide languages as well as module based languages so they are accessible
336          * from the module.
337          */
338         function loadLanguages(){
339                 if(!empty($_SESSION['authenticated_user_language'])) {
340                         $GLOBALS['current_language'] = $_SESSION['authenticated_user_language'];
341                 }
342                 else {
343                         $GLOBALS['current_language'] = $GLOBALS['sugar_config']['default_language'];
344                 }
345                 $GLOBALS['log']->debug('current_language is: '.$GLOBALS['current_language']);
346                 //set module and application string arrays based upon selected language
347                 $GLOBALS['app_strings'] = return_application_language($GLOBALS['current_language']);
348                 if(empty($GLOBALS['current_user']->id))$GLOBALS['app_strings']['NTC_WELCOME'] = '';
349                 if(!empty($GLOBALS['system_config']->settings['system_name']))$GLOBALS['app_strings']['LBL_BROWSER_TITLE'] = $GLOBALS['system_config']->settings['system_name'];
350                 $GLOBALS['app_list_strings'] = return_app_list_strings_language($GLOBALS['current_language']);
351                 $GLOBALS['mod_strings'] = return_module_language($GLOBALS['current_language'], $this->controller->module);
352         }
353         /**
354         * checkDatabaseVersion
355         * Check the db version sugar_version.php and compare to what the version is stored in the config table.
356         * Ensure that both are the same.
357         */
358         function checkDatabaseVersion($dieOnFailure = true)
359         {
360             $row_count = sugar_cache_retrieve('checkDatabaseVersion_row_count');
361             if ( empty($row_count) ) {
362             global $sugar_db_version;
363             $version_query = 'SELECT count(*) as the_count FROM config WHERE category=\'info\' AND name=\'sugar_version\'';
364
365             if($GLOBALS['db']->dbType == 'oci8'){
366             }
367             else if ($GLOBALS['db']->dbType == 'mssql'){
368                 $version_query .= " AND CAST(value AS varchar(8000)) = '$sugar_db_version'";
369             }
370             else {
371                 $version_query .= " AND value = '$sugar_db_version'";
372             }
373
374             $result = $GLOBALS['db']->query($version_query);
375             $row = $GLOBALS['db']->fetchByAssoc($result, -1, true);
376             $row_count = $row['the_count'];
377             sugar_cache_put('checkDatabaseVersion_row_count', $row_count);
378         }
379
380                 if($row_count == 0 && empty($GLOBALS['sugar_config']['disc_client'])){
381                         $sugar_version = $GLOBALS['sugar_version'];
382                         if ( $dieOnFailure )
383                                 sugar_die("Sugar CRM $sugar_version Files May Only Be Used With A Sugar CRM $sugar_db_version Database.");
384                         else
385                             return false;
386                 }
387
388                 return true;
389         }
390
391         /**
392          * Load the themes/images.
393          */
394         function loadDisplaySettings()
395     {
396         global $theme;
397
398         // load the user's default theme
399         $theme = $GLOBALS['current_user']->getPreference('user_theme');
400
401         if (is_null($theme)) {
402             $theme = $GLOBALS['sugar_config']['default_theme'];
403             if(!empty($_SESSION['authenticated_user_theme'])){
404                 $theme = $_SESSION['authenticated_user_theme'];
405             }
406             else if(!empty($_COOKIE['sugar_user_theme'])){
407                 $theme = $_COOKIE['sugar_user_theme'];
408             }
409
410                         if(isset($_SESSION['authenticated_user_theme']) && $_SESSION['authenticated_user_theme'] != '') {
411                                 $_SESSION['theme_changed'] = false;
412                         }
413                 }
414
415         if(!is_null($theme) && !headers_sent())
416         {
417             setcookie('sugar_user_theme', $theme, time() + 31536000); // expires in a year
418         }
419
420         SugarThemeRegistry::set($theme);
421         require_once('include/utils/layout_utils.php');
422         $GLOBALS['image_path'] = SugarThemeRegistry::current()->getImagePath().'/';
423         if ( defined('TEMPLATE_URL') )
424             $GLOBALS['image_path'] = TEMPLATE_URL . '/'. $GLOBALS['image_path'];
425
426         if ( isset($GLOBALS['current_user']) ) {
427             $GLOBALS['gridline'] = (int) ($GLOBALS['current_user']->getPreference('gridline') == 'on');
428             $GLOBALS['current_user']->setPreference('user_theme', $theme, 0, 'global');
429         }
430         }
431
432         function loadLicense(){
433                 loadLicense();
434                 global $user_unique_key, $server_unique_key;
435                 $user_unique_key = (isset($_SESSION['unique_key'])) ? $_SESSION['unique_key'] : '';
436                 $server_unique_key = (isset($sugar_config['unique_key'])) ? $sugar_config['unique_key'] : '';
437         }
438
439         function loadGlobals(){
440                 global $currentModule;
441                 $currentModule = $this->controller->module;
442                 if($this->controller->module == $this->default_module){
443                         $_REQUEST['module'] = $this->controller->module;
444                         if(empty($_REQUEST['action']))
445                         $_REQUEST['action'] = $this->default_action;
446                 }
447         }
448
449         /**
450          * Actions that modify data in this controller's instance and thus require referrers
451          * @var array
452          */
453         protected $modifyActions = array();
454         /**
455          * Actions that always modify data and thus require referrers
456          * save* and delete* hardcoded as modified
457          * @var array
458          */
459         private $globalModifyActions = array(
460                 'massupdate', 'configuredashlet', 'import', 'importvcardsave', 'inlinefieldsave',
461             'wlsave', 'quicksave'
462         );
463
464         /**
465          * Modules that modify data and thus require referrers for all actions
466          */
467         private $modifyModules = array(
468                 'Administration' => true,
469                 'UpgradeWizard' => true,
470                 'Configurator' => true,
471                 'Studio' => true,
472                 'ModuleBuilder' => true,
473                 'Emails' => true,
474             'DCETemplates' => true,
475                 'DCEInstances' => true,
476                 'DCEActions' => true,
477                 'Trackers' => array('trackersettings'),
478             'SugarFavorites' => array('tag'),
479             'Import' => array('last', 'undo'),
480         );
481
482         protected function isModifyAction()
483         {
484             $action = strtolower($this->controller->action);
485             if(substr($action, 0, 4) == "save" || substr($action, 0, 6) == "delete") {
486                 return true;
487             }
488             if(isset($this->modifyModules[$this->controller->module])) {
489                 if($this->modifyModules[$this->controller->module] == true) {
490                     return true;
491                 }
492                 if(in_array($this->controller->action, $this->modifyModules[$this->controller->module])) {
493                     return true;
494
495                 }
496             }
497             if(in_array($this->controller->action, $this->globalModifyActions)) {
498             return true;
499         }
500             if(in_array($this->controller->action, $this->modifyActions)) {
501             return true;
502         }
503         return false;
504         }
505
506         /**
507          *
508          * Checks a request to ensure the request is coming from a valid source or it is for one of the white listed actions
509          */
510         protected function checkHTTPReferer($dieIfInvalid = true)
511         {
512                 global $sugar_config;
513                 $whiteListActions = (!empty($sugar_config['http_referer']['actions']))?$sugar_config['http_referer']['actions']:array('index', 'ListView', 'DetailView', 'EditView','oauth', 'Authenticate', 'Login', 'SupportPortal');
514
515                 $strong = empty($sugar_config['http_referer']['weak']);
516
517                 // Bug 39691 - Make sure localhost and 127.0.0.1 are always valid HTTP referers
518                 $whiteListReferers = array('127.0.0.1','localhost');
519                 if(!empty($_SERVER['SERVER_ADDR']))$whiteListReferers[]  = $_SERVER['SERVER_ADDR'];
520                 if ( !empty($sugar_config['http_referer']['list']) ) {
521                         $whiteListReferers = array_merge($whiteListReferers,$sugar_config['http_referer']['list']);
522                 }
523
524                 if($strong && empty($_SERVER['HTTP_REFERER']) && !in_array($this->controller->action, $whiteListActions) && $this->isModifyAction()) {
525                     $http_host = explode(':', $_SERVER['HTTP_HOST']);
526
527                         $whiteListActions[] = $this->controller->action;
528                         $whiteListString = "'" . implode("', '", $whiteListActions) . "'";
529             if ( $dieIfInvalid ) {
530                 header("Cache-Control: no-cache, must-revalidate");
531                 $ss = new Sugar_Smarty;
532                 $ss->assign('host', $http_host[0]);
533                 $ss->assign('action',$this->controller->action);
534                 $ss->assign('whiteListString',$whiteListString);
535                 $ss->display('include/MVC/View/tpls/xsrf.tpl');
536                 sugar_cleanup(true);
537             }
538             return false;
539                 } else
540                 if(!empty($_SERVER['HTTP_REFERER']) && !empty($_SERVER['SERVER_NAME'])){
541                         $http_ref = parse_url($_SERVER['HTTP_REFERER']);
542                         if($http_ref['host'] !== $_SERVER['SERVER_NAME']  && !in_array($this->controller->action, $whiteListActions) &&
543
544                                 (empty($whiteListReferers) || !in_array($http_ref['host'], $whiteListReferers))){
545                 if ( $dieIfInvalid ) {
546                     header("Cache-Control: no-cache, must-revalidate");
547                     $whiteListActions[] = $this->controller->action;
548                     $whiteListString = "'" . implode("', '", $whiteListActions) . "'";
549
550                     $ss = new Sugar_Smarty;
551                     $ss->assign('host',$http_ref['host']);
552                     $ss->assign('action',$this->controller->action);
553                     $ss->assign('whiteListString',$whiteListString);
554                     $ss->display('include/MVC/View/tpls/xsrf.tpl');
555                     sugar_cleanup(true);
556                 }
557                 return false;
558                         }
559                 }
560          return true;
561         }
562         function startSession()
563         {
564             $sessionIdCookie = isset($_COOKIE['PHPSESSID']) ? $_COOKIE['PHPSESSID'] : null;
565             if(isset($_REQUEST['MSID'])) {
566                         session_id($_REQUEST['MSID']);
567                         session_start();
568                         if(isset($_SESSION['user_id']) && isset($_SESSION['seamless_login'])){
569                                 unset ($_SESSION['seamless_login']);
570                         }else{
571                                 if(isset($_COOKIE['PHPSESSID'])){
572                                 self::setCookie('PHPSESSID', '', time()-42000, '/');
573                         }
574                         sugar_cleanup(false);
575                         session_destroy();
576                         exit('Not a valid entry method');
577                         }
578                 }else{
579                         if(can_start_session()){
580                                 session_start();
581                         }
582                 }
583
584                 if ( isset($_REQUEST['login_module']) && isset($_REQUEST['login_action'])
585                         && !($_REQUEST['login_module'] == 'Home' && $_REQUEST['login_action'] == 'index') ) {
586             if ( !is_null($sessionIdCookie) && empty($_SESSION) ) {
587                 self::setCookie('loginErrorMessage', 'LBL_SESSION_EXPIRED', time()+30, '/');
588             }
589         }
590
591         }
592
593         function endSession(){
594                 session_destroy();
595         }
596         /**
597          * Redirect to another URL
598          *
599          * @access      public
600          * @param       string  $url    The URL to redirect to
601          */
602         function redirect(
603             $url
604             )
605         {
606                 /*
607                  * If the headers have been sent, then we cannot send an additional location header
608                  * so we will output a javascript redirect statement.
609                  */
610                 if (headers_sent()) {
611                         echo "<script>document.location.href='$url';</script>\n";
612                 } else {
613                         //@ob_end_clean(); // clear output buffer
614                         session_write_close();
615                         header( 'HTTP/1.1 301 Moved Permanently' );
616                         header( "Location: ". $url );
617                 }
618                 exit();
619         }
620
621     /**
622          * Redirect to another URL
623          *
624          * @access      public
625          * @param       string  $url    The URL to redirect to
626          */
627         public static function appendErrorMessage($error_message)
628         {
629         if (empty($_SESSION['user_error_message']) || !is_array($_SESSION['user_error_message'])){
630             $_SESSION['user_error_message'] = array();
631         }
632                 $_SESSION['user_error_message'][] = $error_message;
633         }
634
635     public static function getErrorMessages()
636         {
637                 if (isset($_SESSION['user_error_message']) && is_array($_SESSION['user_error_message']) ) {
638             $msgs = $_SESSION['user_error_message'];
639             unset($_SESSION['user_error_message']);
640             return $msgs;
641         }else{
642             return array();
643         }
644         }
645
646         /**
647          * Wrapper for the PHP setcookie() function, to handle cases where headers have
648          * already been sent
649          */
650         public static function setCookie(
651             $name,
652             $value,
653             $expire = 0,
654             $path = '/',
655             $domain = null,
656             $secure = false,
657             $httponly = false
658             )
659         {
660             if ( is_null($domain) )
661                 if ( isset($_SERVER["HTTP_HOST"]) )
662                     $domain = $_SERVER["HTTP_HOST"];
663                 else
664                     $domain = 'localhost';
665
666             if (!headers_sent())
667                 setcookie($name,$value,$expire,$path,$domain,$secure,$httponly);
668
669             $_COOKIE[$name] = $value;
670         }
671 }