]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/MVC/SugarApplication.php
Release 6.5.0
[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-2012 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 /**
47  * SugarCRM application
48  * @api
49  */
50 class SugarApplication
51 {
52         var $controller = null;
53         var $headerDisplayed = false;
54         var $default_module = 'Home';
55         var $default_action = 'index';
56
57         function SugarApplication()
58         {}
59
60         /**
61          * Perform execution of the application. This method is called from index2.php
62          */
63         function execute(){
64                 global $sugar_config;
65                 if(!empty($sugar_config['default_module']))
66                         $this->default_module = $sugar_config['default_module'];
67                 $module = $this->default_module;
68                 if(!empty($_REQUEST['module']))$module = $_REQUEST['module'];
69                 insert_charset_header();
70                 $this->setupPrint();
71                 $this->controller = ControllerFactory::getController($module);
72         // If the entry point is defined to not need auth, then don't authenticate.
73                 if( empty($_REQUEST['entryPoint'])
74                 || $this->controller->checkEntryPointRequiresAuth($_REQUEST['entryPoint']) ){
75             $this->loadUser();
76             $this->ACLFilter();
77             $this->preProcess();
78             $this->controller->preProcess();
79             $this->checkHTTPReferer();
80         }
81
82         SugarThemeRegistry::buildRegistry();
83         $this->loadLanguages();
84                 $this->checkDatabaseVersion();
85                 $this->loadDisplaySettings();
86                 $this->loadLicense();
87                 $this->loadGlobals();
88                 $this->setupResourceManagement($module);
89                 $this->controller->execute();
90                 sugar_cleanup();
91         }
92
93         /**
94          * Load the authenticated user. If there is not an authenticated user then redirect to login screen.
95          */
96         function loadUser(){
97                 global $authController, $sugar_config;
98                 // Double check the server's unique key is in the session.  Make sure this is not an attempt to hijack a session
99                 $user_unique_key = (isset($_SESSION['unique_key'])) ? $_SESSION['unique_key'] : '';
100                 $server_unique_key = (isset($sugar_config['unique_key'])) ? $sugar_config['unique_key'] : '';
101                 $allowed_actions = (!empty($this->controller->allowed_actions)) ? $this->controller->allowed_actions : $allowed_actions = array('Authenticate', 'Login',);
102
103                 if(($user_unique_key != $server_unique_key) && (!in_array($this->controller->action, $allowed_actions)) &&
104                    (!isset($_SESSION['login_error'])))
105                    {
106                         session_destroy();
107
108                         if(!empty($this->controller->action)){
109                             if(strtolower($this->controller->action) == 'delete')
110                                 $this->controller->action = 'DetailView';
111                             elseif(strtolower($this->controller->action) == 'save')
112                                 $this->controller->action = 'EditView';
113                 elseif(strtolower($this->controller->action) == 'quickcreate') {
114                     $this->controller->action = 'index';
115                     $this->controller->module = 'home';
116                 }
117                             elseif(isset($_REQUEST['massupdate'])|| isset($_GET['massupdate']) || isset($_POST['massupdate']))
118                                 $this->controller->action = 'index';
119                             elseif($this->isModifyAction())
120                                 $this->controller->action = 'index';
121                         }
122
123                         header('Location: index.php?action=Login&module=Users'.$this->createLoginVars());
124                         exit ();
125                 }
126
127                 $authController = new AuthenticationController((!empty($GLOBALS['sugar_config']['authenticationClass'])? $GLOBALS['sugar_config']['authenticationClass'] : 'SugarAuthenticate'));
128                 $GLOBALS['current_user'] = new User();
129                 if(isset($_SESSION['authenticated_user_id'])){
130                         // set in modules/Users/Authenticate.php
131                         if(!$authController->sessionAuthenticate()){
132                                  // if the object we get back is null for some reason, this will break - like user prefs are corrupted
133                                 $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.');
134                                 session_destroy();
135                                 SugarApplication::redirect('index.php?action=Login&module=Users');
136                                 die();
137                         }//fi
138                 }elseif(!($this->controller->module == 'Users' && in_array($this->controller->action, $allowed_actions))){
139                         session_destroy();
140                         SugarApplication::redirect('index.php?action=Login&module=Users');
141                         die();
142                 }
143                 $GLOBALS['log']->debug('Current user is: '.$GLOBALS['current_user']->user_name);
144
145                 //set cookies
146                 if(isset($_SESSION['authenticated_user_id'])){
147                         $GLOBALS['log']->debug("setting cookie ck_login_id_20 to ".$_SESSION['authenticated_user_id']);
148                         self::setCookie('ck_login_id_20', $_SESSION['authenticated_user_id'], time() + 86400 * 90);
149                 }
150                 if(isset($_SESSION['authenticated_user_theme'])){
151                         $GLOBALS['log']->debug("setting cookie ck_login_theme_20 to ".$_SESSION['authenticated_user_theme']);
152                         self::setCookie('ck_login_theme_20', $_SESSION['authenticated_user_theme'], time() + 86400 * 90);
153                 }
154                 if(isset($_SESSION['authenticated_user_theme_color'])){
155                         $GLOBALS['log']->debug("setting cookie ck_login_theme_color_20 to ".$_SESSION['authenticated_user_theme_color']);
156                         self::setCookie('ck_login_theme_color_20', $_SESSION['authenticated_user_theme_color'], time() + 86400 * 90);
157                 }
158                 if(isset($_SESSION['authenticated_user_theme_font'])){
159                         $GLOBALS['log']->debug("setting cookie ck_login_theme_font_20 to ".$_SESSION['authenticated_user_theme_font']);
160                         self::setCookie('ck_login_theme_font_20', $_SESSION['authenticated_user_theme_font'], time() + 86400 * 90);
161                 }
162                 if(isset($_SESSION['authenticated_user_language'])){
163                         $GLOBALS['log']->debug("setting cookie ck_login_language_20 to ".$_SESSION['authenticated_user_language']);
164                         self::setCookie('ck_login_language_20', $_SESSION['authenticated_user_language'], time() + 86400 * 90);
165                 }
166                 //check if user can access
167
168         }
169
170         function ACLFilter(){
171                 ACLController :: filterModuleList($GLOBALS['moduleList']);
172         }
173
174         /**
175          * setupResourceManagement
176          * This function initialize the ResourceManager and calls the setup method
177          * on the ResourceManager instance.
178          *
179          */
180         function setupResourceManagement($module) {
181                 require_once('include/resource/ResourceManager.php');
182                 $resourceManager = ResourceManager::getInstance();
183                 $resourceManager->setup($module);
184         }
185
186         function setupPrint() {
187                 $GLOBALS['request_string'] = '';
188
189                 // merge _GET and _POST, but keep the results local
190                 // this handles the issues where values come in one way or the other
191                 // without affecting the main super globals
192                 $merged = array_merge($_GET, $_POST);
193                 foreach ($merged as $key => $val)
194                 {
195                    if(is_array($val))
196                    {
197                        foreach ($val as $k => $v)
198                        {
199                            //If an array, then skip the urlencoding. This should be handled with stringify instead.
200                            if(is_array($v))
201                                 continue;
202
203                            $GLOBALS['request_string'] .= urlencode($key).'['.$k.']='.urlencode($v).'&';
204                        }
205                    }
206                    else
207                    {
208                        $GLOBALS['request_string'] .= urlencode($key).'='.urlencode($val).'&';
209                    }
210                 }
211                 $GLOBALS['request_string'] .= 'print=true';
212         }
213
214         function preProcess(){
215             $config = new Administration;
216             $config->retrieveSettings();
217                 if(!empty($_SESSION['authenticated_user_id'])){
218                         if(isset($_SESSION['hasExpiredPassword']) && $_SESSION['hasExpiredPassword'] == '1'){
219                                 if( $this->controller->action!= 'Save' && $this->controller->action != 'Logout') {
220                         $this->controller->module = 'Users';
221                         $this->controller->action = 'ChangePassword';
222                         $record = $GLOBALS['current_user']->id;
223                      }else{
224                                         $this->handleOfflineClient();
225                                  }
226                         }else{
227                                 $ut = $GLOBALS['current_user']->getPreference('ut');
228                             if(empty($ut)
229                                     && $this->controller->action != 'AdminWizard'
230                                     && $this->controller->action != 'EmailUIAjax'
231                                     && $this->controller->action != 'Wizard'
232                                     && $this->controller->action != 'SaveAdminWizard'
233                                     && $this->controller->action != 'SaveUserWizard'
234                                     && $this->controller->action != 'SaveTimezone'
235                                     && $this->controller->action != 'Logout') {
236                                         $this->controller->module = 'Users';
237                                         $this->controller->action = 'SetTimezone';
238                                         $record = $GLOBALS['current_user']->id;
239                                 }else{
240                                         if($this->controller->action != 'AdminWizard'
241                                     && $this->controller->action != 'EmailUIAjax'
242                                     && $this->controller->action != 'Wizard'
243                                     && $this->controller->action != 'SaveAdminWizard'
244                                     && $this->controller->action != 'SaveUserWizard'){
245                                                         $this->handleOfflineClient();
246                                     }
247                                 }
248                         }
249                 }
250                 $this->handleAccessControl();
251         }
252
253         function handleOfflineClient(){
254                 if(isset($GLOBALS['sugar_config']['disc_client']) && $GLOBALS['sugar_config']['disc_client']){
255                         if(isset($_REQUEST['action']) && $_REQUEST['action'] != 'SaveTimezone'){
256                                 if (!file_exists('modules/Sync/file_config.php')){
257                                         if($_REQUEST['action'] != 'InitialSync' && $_REQUEST['action'] != 'Logout' &&
258                                            ($_REQUEST['action'] != 'Popup' && $_REQUEST['module'] != 'Sync')){
259                                                 //echo $_REQUEST['action'];
260                                                 //die();
261                                                         $this->controller->module = 'Sync';
262                                                         $this->controller->action = 'InitialSync';
263                                                 }
264                         }else{
265                                 require_once ('modules/Sync/file_config.php');
266                                 if(isset($file_sync_info['is_first_sync']) && $file_sync_info['is_first_sync']){
267                                         if($_REQUEST['action'] != 'InitialSync' && $_REQUEST['action'] != 'Logout' &&
268                                            ( $_REQUEST['action'] != 'Popup' && $_REQUEST['module'] != 'Sync')){
269                                                                 $this->controller->module = 'Sync';
270                                                                 $this->controller->action = 'InitialSync';
271                                                 }
272                                 }
273                         }
274                         }
275                         global $moduleList, $sugar_config, $sync_modules;
276                         require_once('modules/Sync/SyncController.php');
277                         $GLOBALS['current_user']->is_admin = '0'; //No admins for disc client
278                 }
279         }
280
281         /**
282          * Handles everything related to authorization.
283          */
284         function handleAccessControl(){
285                 if($GLOBALS['current_user']->isDeveloperForAnyModule())
286                         return;
287             if(!empty($_REQUEST['action']) && $_REQUEST['action']=="RetrieveEmail")
288             return;
289                 if(!is_admin($GLOBALS['current_user']) && !empty($GLOBALS['adminOnlyList'][$this->controller->module])
290                 && !empty($GLOBALS['adminOnlyList'][$this->controller->module]['all'])
291                 && (empty($GLOBALS['adminOnlyList'][$this->controller->module][$this->controller->action]) || $GLOBALS['adminOnlyList'][$this->controller->module][$this->controller->action] != 'allow')) {
292                         $this->controller->hasAccess = false;
293                         return;
294                 }
295
296                 // Bug 20916 - Special case for check ACL access rights for Subpanel QuickCreates
297                 if(isset($_POST['action']) && $_POST['action'] == 'SubpanelCreates') {
298             $actual_module = $_POST['target_module'];
299             if(!empty($GLOBALS['modListHeader']) && !in_array($actual_module,$GLOBALS['modListHeader'])) {
300                 $this->controller->hasAccess = false;
301             }
302             return;
303         }
304
305
306                 if(!empty($GLOBALS['current_user']) && empty($GLOBALS['modListHeader']))
307                         $GLOBALS['modListHeader'] = query_module_access_list($GLOBALS['current_user']);
308
309                 if(in_array($this->controller->module, $GLOBALS['modInvisList']) &&
310                         ((in_array('Activities', $GLOBALS['moduleList'])              &&
311                         in_array('Calendar',$GLOBALS['moduleList']))                 &&
312                         in_array($this->controller->module, $GLOBALS['modInvisListActivities']))
313                         ){
314                                 $this->controller->hasAccess = false;
315                                 return;
316                 }
317         }
318
319         /**
320          * Load only bare minimum of language that can be done before user init and MVC stuff
321          */
322         static function preLoadLanguages()
323         {
324                 if(!empty($_SESSION['authenticated_user_language'])) {
325                         $GLOBALS['current_language'] = $_SESSION['authenticated_user_language'];
326                 }
327                 else {
328                         $GLOBALS['current_language'] = $GLOBALS['sugar_config']['default_language'];
329                 }
330                 $GLOBALS['log']->debug('current_language is: '.$GLOBALS['current_language']);
331                 //set module and application string arrays based upon selected language
332                 $GLOBALS['app_strings'] = return_application_language($GLOBALS['current_language']);
333         }
334
335         /**
336          * Load application wide languages as well as module based languages so they are accessible
337          * from the module.
338          */
339         function loadLanguages(){
340                 if(!empty($_SESSION['authenticated_user_language'])) {
341                         $GLOBALS['current_language'] = $_SESSION['authenticated_user_language'];
342                 }
343                 else {
344                         $GLOBALS['current_language'] = $GLOBALS['sugar_config']['default_language'];
345                 }
346                 $GLOBALS['log']->debug('current_language is: '.$GLOBALS['current_language']);
347                 //set module and application string arrays based upon selected language
348                 $GLOBALS['app_strings'] = return_application_language($GLOBALS['current_language']);
349                 if(empty($GLOBALS['current_user']->id))$GLOBALS['app_strings']['NTC_WELCOME'] = '';
350                 if(!empty($GLOBALS['system_config']->settings['system_name']))$GLOBALS['app_strings']['LBL_BROWSER_TITLE'] = $GLOBALS['system_config']->settings['system_name'];
351                 $GLOBALS['app_list_strings'] = return_app_list_strings_language($GLOBALS['current_language']);
352                 $GLOBALS['mod_strings'] = return_module_language($GLOBALS['current_language'], $this->controller->module);
353         }
354         /**
355         * checkDatabaseVersion
356         * Check the db version sugar_version.php and compare to what the version is stored in the config table.
357         * Ensure that both are the same.
358         */
359         function checkDatabaseVersion($dieOnFailure = true)
360         {
361             $row_count = sugar_cache_retrieve('checkDatabaseVersion_row_count');
362             if ( empty($row_count) ) {
363             global $sugar_db_version;
364             $version_query = "SELECT count(*) as the_count FROM config WHERE category='info' AND name='sugar_version' AND ".
365                 $GLOBALS['db']->convert('value', 'text2char')." = ".$GLOBALS['db']->quoted($sugar_db_version);
366
367             $result = $GLOBALS['db']->query($version_query);
368             $row = $GLOBALS['db']->fetchByAssoc($result);
369             $row_count = $row['the_count'];
370             sugar_cache_put('checkDatabaseVersion_row_count', $row_count);
371         }
372
373                 if($row_count == 0 && empty($GLOBALS['sugar_config']['disc_client'])){
374                         $sugar_version = $GLOBALS['sugar_version'];
375                         if ( $dieOnFailure )
376                                 sugar_die("Sugar CRM $sugar_version Files May Only Be Used With A Sugar CRM $sugar_db_version Database.");
377                         else
378                             return false;
379                 }
380
381                 return true;
382         }
383
384         /**
385          * Load the themes/images.
386          */
387         function loadDisplaySettings()
388     {
389         global $theme;
390
391         // load the user's default theme
392         $theme = $GLOBALS['current_user']->getPreference('user_theme');
393
394         if (is_null($theme)) {
395             $theme = $GLOBALS['sugar_config']['default_theme'];
396             if(!empty($_SESSION['authenticated_user_theme'])){
397                 $theme = $_SESSION['authenticated_user_theme'];
398             }
399             else if(!empty($_COOKIE['sugar_user_theme'])){
400                 $theme = $_COOKIE['sugar_user_theme'];
401             }
402
403                         if(isset($_SESSION['authenticated_user_theme']) && $_SESSION['authenticated_user_theme'] != '') {
404                                 $_SESSION['theme_changed'] = false;
405                         }
406                 }
407
408         if(!is_null($theme) && !headers_sent())
409         {
410             setcookie('sugar_user_theme', $theme, time() + 31536000); // expires in a year
411         }
412
413         SugarThemeRegistry::set($theme);
414         require_once('include/utils/layout_utils.php');
415         $GLOBALS['image_path'] = SugarThemeRegistry::current()->getImagePath().'/';
416         if ( defined('TEMPLATE_URL') )
417             $GLOBALS['image_path'] = TEMPLATE_URL . '/'. $GLOBALS['image_path'];
418
419         if ( isset($GLOBALS['current_user']) ) {
420             $GLOBALS['gridline'] = (int) ($GLOBALS['current_user']->getPreference('gridline') == 'on');
421             $GLOBALS['current_user']->setPreference('user_theme', $theme, 0, 'global');
422         }
423         }
424
425         function loadLicense(){
426                 loadLicense();
427                 global $user_unique_key, $server_unique_key;
428                 $user_unique_key = (isset($_SESSION['unique_key'])) ? $_SESSION['unique_key'] : '';
429                 $server_unique_key = (isset($sugar_config['unique_key'])) ? $sugar_config['unique_key'] : '';
430         }
431
432         function loadGlobals(){
433                 global $currentModule;
434                 $currentModule = $this->controller->module;
435                 if($this->controller->module == $this->default_module){
436                         $_REQUEST['module'] = $this->controller->module;
437                         if(empty($_REQUEST['action']))
438                         $_REQUEST['action'] = $this->default_action;
439                 }
440         }
441
442         /**
443          * Actions that modify data in this controller's instance and thus require referrers
444          * @var array
445          */
446         protected $modifyActions = array();
447         /**
448          * Actions that always modify data and thus require referrers
449          * save* and delete* hardcoded as modified
450          * @var array
451          */
452         private $globalModifyActions = array(
453                 'massupdate', 'configuredashlet', 'import', 'importvcardsave', 'inlinefieldsave',
454             'wlsave', 'quicksave'
455         );
456
457         /**
458          * Modules that modify data and thus require referrers for all actions
459          */
460         private $modifyModules = array(
461                 'Administration' => true,
462                 'UpgradeWizard' => true,
463                 'Configurator' => true,
464                 'Studio' => true,
465                 'ModuleBuilder' => true,
466                 'Emails' => true,
467             'DCETemplates' => true,
468                 'DCEInstances' => true,
469                 'DCEActions' => true,
470                 'Trackers' => array('trackersettings'),
471             'SugarFavorites' => array('tag'),
472             'Import' => array('last', 'undo'),
473             'Users' => array('changepassword', "generatepassword"),
474         );
475
476         protected function isModifyAction()
477         {
478             $action = strtolower($this->controller->action);
479             if(substr($action, 0, 4) == "save" || substr($action, 0, 6) == "delete") {
480                 return true;
481             }
482             if(isset($this->modifyModules[$this->controller->module])) {
483                 if($this->modifyModules[$this->controller->module] === true) {
484                     return true;
485                 }
486                 if(in_array($this->controller->action, $this->modifyModules[$this->controller->module])) {
487                     return true;
488
489                 }
490             }
491             if(in_array($this->controller->action, $this->globalModifyActions)) {
492             return true;
493         }
494             if(in_array($this->controller->action, $this->modifyActions)) {
495             return true;
496         }
497         return false;
498         }
499
500     /**
501      * The list of the actions excepted from referer checks by default
502      * @var array
503      */
504         protected $whiteListActions = array('index', 'ListView', 'DetailView', 'EditView', 'oauth', 'authorize', 'Authenticate', 'Login', 'SupportPortal');
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                 if(!empty($sugar_config['http_referer']['actions'])) {
514                     $this->whiteListActions = array_merge($sugar_config['http_referer']['actions'], $this->whiteListActions);
515                 }
516
517                 $strong = empty($sugar_config['http_referer']['weak']);
518
519                 // Bug 39691 - Make sure localhost and 127.0.0.1 are always valid HTTP referers
520                 $whiteListReferers = array('127.0.0.1','localhost');
521                 if(!empty($_SERVER['SERVER_ADDR']))$whiteListReferers[]  = $_SERVER['SERVER_ADDR'];
522                 if ( !empty($sugar_config['http_referer']['list']) ) {
523                         $whiteListReferers = array_merge($whiteListReferers,$sugar_config['http_referer']['list']);
524                 }
525
526                 if($strong && empty($_SERVER['HTTP_REFERER']) && !in_array($this->controller->action, $this->whiteListActions ) && $this->isModifyAction()) {
527                     $http_host = explode(':', $_SERVER['HTTP_HOST']);
528             $whiteListActions = $this->whiteListActions;
529                         $whiteListActions[] = $this->controller->action;
530                         $whiteListString = "'" . implode("', '", $whiteListActions) . "'";
531             if ( $dieIfInvalid ) {
532                 header("Cache-Control: no-cache, must-revalidate");
533                 $ss = new Sugar_Smarty;
534                 $ss->assign('host', $http_host[0]);
535                 $ss->assign('action',$this->controller->action);
536                 $ss->assign('whiteListString',$whiteListString);
537                 $ss->display('include/MVC/View/tpls/xsrf.tpl');
538                 sugar_cleanup(true);
539             }
540             return false;
541                 } else
542                 if(!empty($_SERVER['HTTP_REFERER']) && !empty($_SERVER['SERVER_NAME'])){
543                         $http_ref = parse_url($_SERVER['HTTP_REFERER']);
544                         if($http_ref['host'] !== $_SERVER['SERVER_NAME']  && !in_array($this->controller->action, $this->whiteListActions) &&
545
546                                 (empty($whiteListReferers) || !in_array($http_ref['host'], $whiteListReferers))){
547                 if ( $dieIfInvalid ) {
548                     header("Cache-Control: no-cache, must-revalidate");
549                     $whiteListActions = $this->whiteListActions;
550                     $whiteListActions[] = $this->controller->action;
551                     $whiteListString = "'" . implode("', '", $whiteListActions) . "'";
552
553                     $ss = new Sugar_Smarty;
554                     $ss->assign('host',$http_ref['host']);
555                     $ss->assign('action',$this->controller->action);
556                     $ss->assign('whiteListString',$whiteListString);
557                     $ss->display('include/MVC/View/tpls/xsrf.tpl');
558                     sugar_cleanup(true);
559                 }
560                 return false;
561                         }
562                 }
563          return true;
564         }
565         function startSession()
566         {
567             $sessionIdCookie = isset($_COOKIE['PHPSESSID']) ? $_COOKIE['PHPSESSID'] : null;
568             if(isset($_REQUEST['MSID'])) {
569                         session_id($_REQUEST['MSID']);
570                         session_start();
571                         if(isset($_SESSION['user_id']) && isset($_SESSION['seamless_login'])){
572                                 unset ($_SESSION['seamless_login']);
573                         }else{
574                                 if(isset($_COOKIE['PHPSESSID'])){
575                                 self::setCookie('PHPSESSID', '', time()-42000, '/');
576                         }
577                         sugar_cleanup(false);
578                         session_destroy();
579                         exit('Not a valid entry method');
580                         }
581                 }else{
582                         if(can_start_session()){
583                                 session_start();
584                         }
585                 }
586
587                 if ( isset($_REQUEST['login_module']) && isset($_REQUEST['login_action'])
588                         && !($_REQUEST['login_module'] == 'Home' && $_REQUEST['login_action'] == 'index') ) {
589             if ( !is_null($sessionIdCookie) && empty($_SESSION) ) {
590                 self::setCookie('loginErrorMessage', 'LBL_SESSION_EXPIRED', time()+30, '/');
591             }
592         }
593
594
595         LogicHook::initialize()->call_custom_logic('', 'after_session_start');
596         }
597
598
599
600
601         function endSession(){
602                 session_destroy();
603         }
604         /**
605          * Redirect to another URL
606          *
607          * @access      public
608          * @param       string  $url    The URL to redirect to
609          */
610         function redirect(
611             $url
612             )
613         {
614                 /*
615                  * If the headers have been sent, then we cannot send an additional location header
616                  * so we will output a javascript redirect statement.
617                  */
618                 if (!empty($_REQUEST['ajax_load']))
619         {
620             ob_get_clean();
621             $ajax_ret = array(
622                  'content' => "<script>SUGAR.ajaxUI.loadContent('$url');</script>\n",
623                  'menu' => array(
624                      'module' => $_REQUEST['module'],
625                      'label' => translate($_REQUEST['module']),
626                  ),
627             );
628             $json = getJSONobj();
629             echo $json->encode($ajax_ret);
630         } else {
631             if (headers_sent()) {
632                 echo "<script>SUGAR.ajaxUI.loadContent('$url');</script>\n";
633             } else {
634                 //@ob_end_clean(); // clear output buffer
635                 session_write_close();
636                 header( 'HTTP/1.1 301 Moved Permanently' );
637                 header( "Location: ". $url );
638             }
639         }
640                 exit();
641         }
642
643     /**
644          * Redirect to another URL
645          *
646          * @access      public
647          * @param       string  $url    The URL to redirect to
648          */
649         public static function appendErrorMessage($error_message)
650         {
651         if (empty($_SESSION['user_error_message']) || !is_array($_SESSION['user_error_message'])){
652             $_SESSION['user_error_message'] = array();
653         }
654                 $_SESSION['user_error_message'][] = $error_message;
655         }
656
657     public static function getErrorMessages()
658         {
659                 if (isset($_SESSION['user_error_message']) && is_array($_SESSION['user_error_message']) ) {
660             $msgs = $_SESSION['user_error_message'];
661             unset($_SESSION['user_error_message']);
662             return $msgs;
663         }else{
664             return array();
665         }
666         }
667
668         /**
669          * Wrapper for the PHP setcookie() function, to handle cases where headers have
670          * already been sent
671          */
672         public static function setCookie(
673             $name,
674             $value,
675             $expire = 0,
676             $path = '/',
677             $domain = null,
678             $secure = false,
679             $httponly = false
680             )
681         {
682             if ( is_null($domain) )
683                 if ( isset($_SERVER["HTTP_HOST"]) )
684                     $domain = $_SERVER["HTTP_HOST"];
685                 else
686                     $domain = 'localhost';
687
688             if (!headers_sent())
689                 setcookie($name,$value,$expire,$path,$domain,$secure,$httponly);
690
691             $_COOKIE[$name] = $value;
692         }
693
694         protected $redirectVars = array('module', 'action', 'record', 'token', 'oauth_token', 'mobile');
695
696         /**
697          * Create string to attach to login URL with vars to preserve post-login
698          * @return string URL part with login vars
699          */
700         public function createLoginVars()
701         {
702             $ret = array();
703         foreach($this->redirectVars as $var) {
704             if(!empty($this->controller->$var)) {
705                 $ret["login_".$var] = $this->controller->$var;
706                 continue;
707             }
708             if(!empty($_REQUEST[$var])) {
709                 $ret["login_".$var] = $_REQUEST[$var];
710             }
711         }
712         if(isset($_REQUEST['mobile'])) {
713             $ret['mobile'] = $_REQUEST['mobile'];
714         }
715         if(empty($ret)) return '';
716         return "&".http_build_query($ret);
717         }
718
719         /**
720          * Get the list of vars passed with login form
721          * @param bool $add_empty Add empty vars to the result?
722          * @return array List of vars passed with login
723          */
724         public function getLoginVars($add_empty = true)
725         {
726             $ret = array();
727         foreach($this->redirectVars as $var) {
728             if(!empty($_REQUEST['login_'.$var]) || $add_empty) {
729                 $ret["login_".$var] = isset($_REQUEST['login_'.$var])?$_REQUEST['login_'.$var]:'';
730             }
731         }
732             return $ret;
733         }
734
735         /**
736          * Get URL to redirect after the login
737          * @return string the URL to redirect to
738          */
739         public function getLoginRedirect()
740         {
741         $vars = array();
742         foreach($this->redirectVars as $var) {
743             if(!empty($_REQUEST['login_'.$var])) $vars[$var] = $_REQUEST['login_'.$var];
744         }
745         if(isset($_REQUEST['mobile'])) {
746             $vars['mobile'] = $_REQUEST['mobile'];
747         }
748
749         if(isset($_REQUEST['mobile']))
750         {
751                       $vars['mobile'] = $_REQUEST['mobile'];
752         }
753         if(empty($vars)) {
754             return "index.php?module=Home&action=index";
755         } else {
756             return "index.php?".http_build_query($vars);
757         }
758         }
759 }