]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/MVC/Controller/SugarController.php
Release 6.3.0
[Github/sugarcrm.git] / include / MVC / Controller / SugarController.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 require_once('include/MVC/View/SugarView.php');
38
39
40 class SugarController{
41         /**
42          * remap actions in here
43          * e.g. make all detail views go to edit views
44          * $action_remap = array('detailview'=>'editview');
45          */
46         protected $action_remap = array('index'=>'listview');
47         /**
48          * The name of the current module.
49          */
50         public $module = 'Home';
51         /**
52          * The name of the target module.
53          */
54         public $target_module = null;
55         /**
56          * The name of the current action.
57          */
58         public $action = 'index';
59         /**
60          * The id of the current record.
61          */
62         public $record = '';
63         /**
64          * The name of the return module.
65          */
66         public $return_module = null;
67         /**
68          * The name of the return action.
69          */
70         public $return_action = null;
71         /**
72          * The id of the return record.
73          */
74         public $return_id = null;
75         /**
76          * If the action was remapped it will be set to do_action and then we will just
77          * use do_action for the actual action to perform.
78          */
79         protected $do_action = 'index';
80         /**
81          * If a bean is present that set it.
82          */
83         public $bean = null;
84         /**
85          * url to redirect to
86          */
87         public $redirect_url = '';
88         /**
89          * any subcontroller can modify this to change the view
90          */
91         public $view = 'classic';
92         /**
93          * this array will hold the mappings between a key and an object for use within the view.
94          */
95         public $view_object_map = array();
96
97         /**
98          * This array holds the methods that handleAction() will invoke, in sequence.
99          */
100         protected $tasks = array(
101                                            'pre_action',
102                                            'do_action',
103                                            'post_action'
104                                            );
105         /**
106          * List of options to run through within the process() method.
107          * This list is meant to easily allow additions for new functionality as well as
108          * the ability to add a controller's own handling.
109          */
110         public $process_tasks = array(
111                                                 'blockFileAccess',
112                                                 'handleEntryPoint',
113                                                 'callLegacyCode',
114                                                 'remapAction',
115                                                 'handle_action',
116                                                 'handleActionMaps',
117                                         );
118         /**
119          * Whether or not the action has been handled by $process_tasks
120          *
121          * @var bool
122          */
123         protected $_processed = false;
124         /**
125          * Map an action directly to a file
126          */
127         /**
128          * Map an action directly to a file. This will be loaded from action_file_map.php
129          */
130         protected $action_file_map = array();
131         /**
132          * Map an action directly to a view
133          */
134         /**
135          * Map an action directly to a view. This will be loaded from action_view_map.php
136          */
137         protected $action_view_map = array();
138
139         /**
140          * This can be set from the application to tell us whether we have authorization to
141          * process the action. If this is set we will default to the noaccess view.
142          */
143         public $hasAccess = true;
144
145         /**
146          * Map case sensitive filenames to action.  This is used for linux/unix systems
147          * where filenames are case sensitive
148          */
149         public static $action_case_file = array(
150                                                                                 'editview'=>'EditView',
151                                                                                 'detailview'=>'DetailView',
152                                                                                 'listview'=>'ListView'
153                                                                           );
154
155         /**
156          * Constructor. This ie meant tot load up the module, action, record as well
157          * as the mapping arrays.
158          */
159         function SugarController(){
160         }
161
162         /**
163          * Called from SugarApplication and is meant to perform the setup operations
164          * on the controller.
165          *
166          */
167         public function setup($module = ''){
168                 if(empty($module) && !empty($_REQUEST['module']))
169                         $module = $_REQUEST['module'];
170                 //set the module
171                 if(!empty($module))
172                         $this->setModule($module);
173
174                 if(!empty($_REQUEST['target_module']) && $_REQUEST['target_module'] != 'undefined') {
175                         $this->target_module = $_REQUEST['target_module'];
176                 }
177                 //set properties on the controller from the $_REQUEST
178                 $this->loadPropertiesFromRequest();
179                 //load the mapping files
180                 $this->loadMappings();
181         }
182         /**
183          * Set the module on the Controller
184          *
185          * @param object $module
186          */
187         public function setModule($module){
188                 $this->module = $module;
189         }
190
191         /**
192          * Set properties on the Controller from the $_REQUEST
193          *
194          */
195         private function loadPropertiesFromRequest(){
196                 if(!empty($_REQUEST['action']))
197                         $this->action = $_REQUEST['action'];
198                 if(!empty($_REQUEST['record']))
199                         $this->record = $_REQUEST['record'];
200                 if(!empty($_REQUEST['view']))
201                         $this->view = $_REQUEST['view'];
202                 if(!empty($_REQUEST['return_module']))
203                         $this->return_module = $_REQUEST['return_module'];
204                 if(!empty($_REQUEST['return_action']))
205                         $this->return_action = $_REQUEST['return_action'];
206                 if(!empty($_REQUEST['return_id']))
207                         $this->return_id = $_REQUEST['return_id'];
208         }
209
210         /**
211          * Load map files for use within the Controller
212          *
213          */
214         private function loadMappings(){
215                 $this->loadMapping('action_view_map');
216                 $this->loadMapping('action_file_map');
217                 $this->loadMapping('action_remap', true);
218         }
219
220         /**
221          * Given a record id load the bean. This bean is accessible from any sub controllers.
222          */
223         public function loadBean()
224         {
225                 if(!empty($GLOBALS['beanList'][$this->module])){
226                         $class = $GLOBALS['beanList'][$this->module];
227                         if(!empty($GLOBALS['beanFiles'][$class])){
228                                 require_once($GLOBALS['beanFiles'][$class]);
229                                 $this->bean = new $class();
230                                 if(!empty($this->record)){
231                                         $this->bean->retrieve($this->record);
232                                         if($this->bean)
233                                                 $GLOBALS['FOCUS'] = $this->bean;
234                                 }
235                         }
236                 }
237         }
238
239         /**
240          * Generic load method to load mapping arrays.
241          */
242         private function loadMapping($var, $merge = false){
243                 $$var = sugar_cache_retrieve("CONTROLLER_". $var . "_".$this->module);
244                 if(!$$var){
245                         if($merge && !empty($this->$var)){
246                                 $$var = $this->$var;
247                         }else{
248                                 $$var = array();
249                         }
250                         if(file_exists('include/MVC/Controller/'. $var . '.php')){
251                                 require('include/MVC/Controller/'. $var . '.php');
252                         }
253                         if(file_exists('modules/'.$this->module.'/'. $var . '.php')){
254                                 require('modules/'.$this->module.'/'. $var . '.php');
255                         }
256                         if(file_exists('custom/modules/'.$this->module.'/'. $var . '.php')){
257                                 require('custom/modules/'.$this->module.'/'. $var . '.php');
258                         }
259                         if(file_exists('custom/include/MVC/Controller/'. $var . '.php')){
260                                 require('custom/include/MVC/Controller/'. $var . '.php');
261                         }
262
263             // entry_point_registry -> EntryPointRegistry
264
265                         $varname = str_replace(" ","",ucwords(str_replace("_"," ", $var)));
266             if(file_exists("custom/application/Ext/$varname/$var.ext.php")){
267                                 require("custom/application/Ext/$varname/$var.ext.php");
268                 }
269                         if(file_exists("custom/modules/{$this->module}/Ext/$varname/$var.ext.php")){
270                                 require("custom/modules/{$this->module}/Ext/$varname/$var.ext.php");
271                         }
272
273                         sugar_cache_put("CONTROLLER_". $var . "_".$this->module, $$var);
274                 }
275                 $this->$var = $$var;
276         }
277
278         /**
279          * This method is called from SugarApplication->execute and it will bootstrap the entire controller process
280          */
281         final public function execute(){
282                 $this->process();
283                 if(!empty($this->view)){
284                         $this->processView();
285                 }elseif(!empty($this->redirect_url)){
286                         $this->redirect();
287                 }
288         }
289
290         /**
291          * Display the appropriate view.
292          */
293         private function processView(){
294                 $view = ViewFactory::loadView($this->view, $this->module, $this->bean, $this->view_object_map, $this->target_module);
295                 $GLOBALS['current_view'] = $view;
296                 if(!empty($this->bean) && !$this->bean->ACLAccess($view->type) && $view->type != 'list'){
297                         ACLController::displayNoAccess(true);
298                         sugar_cleanup(true);
299                 }
300                 if(isset($this->errors)){
301                   $view->errors = $this->errors;
302                 }
303                 $view->process();
304         }
305
306         /**
307          * Meant to be overridden by a subclass and allows for specific functionality to be
308          * injected prior to the process() method being called.
309          */
310         public function preProcess()
311         {}
312
313         /**
314          * if we have a function to support the action use it otherwise use the default action
315          *
316          * 1) check for file
317          * 2) check for action
318          */
319         public function process(){
320                 $GLOBALS['action'] = $this->action;
321                 $GLOBALS['module'] = $this->module;
322
323                 //check to ensure we have access to the module.
324                 if($this->hasAccess){
325                         $this->do_action = $this->action;
326
327                         $file = self::getActionFilename($this->do_action);
328
329                         $this->loadBean();
330
331                         $processed = false;
332                         foreach($this->process_tasks as $process){
333                                 $this->$process();
334                                 if($this->_processed)
335                                         break;
336                         }
337
338                         $this->redirect();
339                 }else{
340                         $this->no_access();
341                 }
342         }
343
344         /**
345          * This method is called from the process method. I could also be called within an action_* method.
346          * It allows a developer to override any one of these methods contained within,
347          * or if the developer so chooses they can override the entire action_* method.
348          *
349          * @return true if any one of the pre_, do_, or post_ methods have been defined,
350          * false otherwise.  This is important b/c if none of these methods exists, then we will run the
351          * action_default() method.
352          */
353         protected function handle_action(){
354                 $processed = false;
355                 foreach($this->tasks as $task){
356                         $processed = ($this->$task() || $processed);
357                 }
358                 $this->_processed = $processed;
359         }
360
361         /**
362          * Perform an action prior to the specified action.
363          * This can be overridde in a sub-class
364          */
365         private function pre_action(){
366                 $function = 'pre_' . $this->action;
367                 if($this->hasFunction($function)){
368                         $GLOBALS['log']->debug('Performing pre_action');
369                         $this->$function();
370                         return true;
371                 }
372                 return false;
373         }
374
375         /**
376          * Perform the specified action.
377          * This can be overridde in a sub-class
378          */
379         private function do_action(){
380                 $function =  'action_'. strtolower($this->do_action);
381                 if($this->hasFunction($function)){
382                         $GLOBALS['log']->debug('Performing action: '.$function.' MODULE: '.$this->module);
383                         $this->$function();
384                         return true;
385                 }
386                 return false;
387         }
388
389         /**
390          * Perform an action after to the specified action has occurred.
391          * This can be overridde in a sub-class
392          */
393         private function post_action(){
394                 $function = 'post_' . $this->action;
395                 if($this->hasFunction($function)){
396                         $GLOBALS['log']->debug('Performing post_action');
397                         $this->$function();
398                         return true;
399                 }
400                 return false;
401         }
402
403         /**
404          * If there is no action found then display an error to the user.
405          */
406         protected function no_action(){
407                 sugar_die($GLOBALS['app_strings']['LBL_NO_ACTION']);
408         }
409
410         /**
411          * The default action handler for instances where we do not have access to process.
412          */
413         protected function no_access(){
414                 $this->view = 'noaccess';
415         }
416
417         ///////////////////////////////////////////////
418         /////// HELPER FUNCTIONS
419         ///////////////////////////////////////////////
420
421         /**
422          * Determine if a given function exists on the objects
423          * @param function - the function to check
424          * @return true if the method exists on the object, false otherwise
425          */
426         protected function hasFunction($function){
427                 return method_exists($this, $function);
428         }
429
430
431         /**
432          * Set the url to which we will want to redirect
433          *
434          * @param string url - the url to which we will want to redirect
435          */
436         protected function set_redirect($url){
437                 $this->redirect_url = $url;
438         }
439
440         /**
441          * Perform redirection based on the redirect_url
442          *
443          */
444         protected function redirect(){
445
446                 if(!empty($this->redirect_url))
447                         SugarApplication::redirect($this->redirect_url);
448         }
449
450         ////////////////////////////////////////////////////////
451         ////// DEFAULT ACTIONS
452         ///////////////////////////////////////////////////////
453
454         /*
455          * Save a bean
456          */
457
458         /**
459          * Do some processing before saving the bean to the database.
460          */
461         public function pre_save(){
462                 if(!empty($_POST['assigned_user_id']) && $_POST['assigned_user_id'] != $this->bean->assigned_user_id && $_POST['assigned_user_id'] != $GLOBALS['current_user']->id && empty($GLOBALS['sugar_config']['exclude_notifications'][$this->bean->module_dir])){
463                         $this->bean->notify_on_save = true;
464                 }
465                 $GLOBALS['log']->debug("SugarController:: performing pre_save.");
466         require_once('include/SugarFields/SugarFieldHandler.php');
467         $sfh = new SugarFieldHandler();
468                 foreach($this->bean->field_defs as $field => $properties) {
469                         $type = !empty($properties['custom_type']) ? $properties['custom_type'] : $properties['type'];
470                     $sf = $sfh->getSugarField(ucfirst($type), true);
471                         if(isset($_POST[$field])) {
472                                 if(is_array($_POST[$field]) && !empty($properties['isMultiSelect'])) {
473                                         if(empty($_POST[$field][0])) {
474                                                 unset($_POST[$field][0]);
475                                         }
476                                         $_POST[$field] = encodeMultienumValue($_POST[$field]);
477                                 }
478                                 $this->bean->$field = $_POST[$field];
479                         } else if(!empty($properties['isMultiSelect']) && !isset($_POST[$field]) && isset($_POST[$field . '_multiselect'])) {
480                                 $this->bean->$field = '';
481                         }
482             if($sf != null){
483                 $sf->save($this->bean, $_POST, $field, $properties);
484             }
485                 }
486
487                 foreach($this->bean->relationship_fields as $field=>$link){
488                         if(!empty($_POST[$field])){
489                                 $this->bean->$field = $_POST[$field];
490                         }
491                 }
492                 if(!$this->bean->ACLAccess('save')){
493                         ACLController::displayNoAccess(true);
494                         sugar_cleanup(true);
495                 }
496                 $this->bean->unformat_all_fields();
497         }
498
499         /**
500          * Perform the actual save
501          */
502         public function action_save(){
503                 $this->bean->save(!empty($this->bean->notify_on_save));
504         }
505
506         /**
507          * Specify what happens after the save has occurred.
508          */
509         protected function post_save(){
510                 $module = (!empty($this->return_module) ? $this->return_module : $this->module);
511                 $action = (!empty($this->return_action) ? $this->return_action : 'DetailView');
512                 $id = (!empty($this->return_id) ? $this->return_id : $this->bean->id);
513
514                 $url = "index.php?module=".$module."&action=".$action."&record=".$id;
515                 $this->set_redirect($url);
516         }
517
518         /*
519          * Delete a bean
520          */
521
522         /**
523          * Perform the actual deletion.
524          */
525         protected function action_delete(){
526                 //do any pre delete processing
527                 //if there is some custom logic for deletion.
528                 if(!empty($_REQUEST['record'])){
529                         if(!$this->bean->ACLAccess('Delete')){
530                                 ACLController::displayNoAccess(true);
531                                 sugar_cleanup(true);
532                         }
533                         $this->bean->mark_deleted($_REQUEST['record']);
534                 }else{
535                         sugar_die("A record number must be specified to delete");
536                 }
537         }
538
539         /**
540          * Specify what happens after the deletion has occurred.
541          */
542         protected function post_delete(){
543                 $return_module = isset($_REQUEST['return_module']) ?
544                         $_REQUEST['return_module'] :
545                         $GLOBALS['sugar_config']['default_module'];
546                 $return_action = isset($_REQUEST['return_action']) ?
547                         $_REQUEST['return_action'] :
548                         $GLOBALS['sugar_config']['default_action'];
549                 $return_id = isset($_REQUEST['return_id']) ?
550                         $_REQUEST['return_id'] :
551                         '';
552                 $url = "index.php?module=".$return_module."&action=".$return_action."&record=".$return_id;
553                 
554                 //eggsurplus Bug 23816: maintain VCR after an edit/save. If it is a duplicate then don't worry about it. The offset is now worthless.
555                 if(isset($_REQUEST['offset']) && empty($_REQUEST['duplicateSave'])) {
556                     $url .= "&offset=".$_REQUEST['offset'];
557                 }
558                 
559                 $this->set_redirect($url);
560         }
561         /**
562          * Perform the actual massupdate.
563          */
564         protected function action_massupdate(){
565                 if(!empty($_REQUEST['massupdate']) && $_REQUEST['massupdate'] == 'true' && (!empty($_REQUEST['uid']) || !empty($_REQUEST['entire']))){
566                         if(!empty($_REQUEST['Delete']) && $_REQUEST['Delete']=='true' && !$this->bean->ACLAccess('delete')
567                 || (empty($_REQUEST['Delete']) || $_REQUEST['Delete']!='true') && !$this->bean->ACLAccess('save')){
568                                 ACLController::displayNoAccess(true);
569                                 sugar_cleanup(true);
570                         }
571
572             set_time_limit(0);//I'm wondering if we will set it never goes timeout here.
573             // until we have more efficient way of handling MU, we have to disable the limit
574             $GLOBALS['db']->setQueryLimit(0);
575             require_once("include/MassUpdate.php");
576             require_once('modules/MySettings/StoreQuery.php');
577             $seed = loadBean($_REQUEST['module']);
578             $mass = new MassUpdate();
579             $mass->setSugarBean($seed);
580             if(isset($_REQUEST['entire']) && empty($_POST['mass'])) {
581                 $mass->generateSearchWhere($_REQUEST['module'], $_REQUEST['current_query_by_page']);
582             }
583             $mass->handleMassUpdate();
584             $storeQuery = new StoreQuery();//restore the current search. to solve bug 24722 for multi tabs massupdate.
585             $temp_req = array('current_query_by_page' => $_REQUEST['current_query_by_page'], 'return_module' => $_REQUEST['return_module'], 'return_action' => $_REQUEST['return_action']);
586             if($_REQUEST['return_module'] == 'Emails') {
587                 if(!empty($_REQUEST['type']) && !empty($_REQUEST['ie_assigned_user_id'])) {
588                     $this->req_for_email = array('type' => $_REQUEST['type'], 'ie_assigned_user_id' => $_REQUEST['ie_assigned_user_id']); //specificly for My Achieves
589                 }
590             }
591             $_REQUEST = array();
592             $_REQUEST = unserialize(base64_decode($temp_req['current_query_by_page']));
593             unset($_REQUEST[$seed->module_dir.'2_'.strtoupper($seed->object_name).'_offset']);//after massupdate, the page should redirect to no offset page
594             $storeQuery->saveFromRequest($_REQUEST['module']);
595             $_REQUEST = array('return_module' => $temp_req['return_module'], 'return_action' => $temp_req['return_action']);//for post_massupdate, to go back to original page.
596                 }else{
597                         sugar_die("You must massupdate at least one record");
598                 }
599         }
600         /**
601          * Specify what happens after the massupdate has occurred.
602          */
603         protected function post_massupdate(){
604                 $return_module = isset($_REQUEST['return_module']) ?
605                         $_REQUEST['return_module'] :
606                         $GLOBALS['sugar_config']['default_module'];
607                 $return_action = isset($_REQUEST['return_action']) ?
608                         $_REQUEST['return_action'] :
609                         $GLOBALS['sugar_config']['default_action'];
610                 $url = "index.php?module=".$return_module."&action=".$return_action;
611                 if($return_module == 'Emails'){//specificly for My Achieves
612                         if(!empty($this->req_for_email['type']) && !empty($this->req_for_email['ie_assigned_user_id'])) {
613                                 $url = $url . "&type=".$this->req_for_email['type']."&assigned_user_id=".$this->req_for_email['ie_assigned_user_id'];
614                         }
615                 }
616                 $this->set_redirect($url);
617         }
618         /**
619          * Perform the listview action
620          */
621         protected function action_listview(){
622                 $this->view_object_map['bean'] = $this->bean;
623                 $this->view = 'list';
624         }
625
626 /*
627
628         //THIS IS HANDLED IN ACTION_REMAP WHERE INDEX IS SET TO LISTVIEW
629         function action_index(){
630         }
631 */
632
633         /**
634          * Action to handle when using a file as was done in previous versions of Sugar.
635          */
636         protected function action_default(){
637                 $this->view = 'classic';
638         }
639
640         /**
641          * this method id used within a Dashlet when performing an ajax call
642          */
643         protected function action_callmethoddashlet(){
644                 if(!empty($_REQUEST['id'])) {
645                     $id = $_REQUEST['id'];
646                     $requestedMethod = $_REQUEST['method'];
647                     $dashletDefs = $GLOBALS['current_user']->getPreference('dashlets', 'Home'); // load user's dashlets config
648                     if(!empty($dashletDefs[$id])) {
649                         require_once($dashletDefs[$id]['fileLocation']);
650
651                         $dashlet = new $dashletDefs[$id]['className']($id, (isset($dashletDefs[$id]['options']) ? $dashletDefs[$id]['options'] : array()));
652
653                         if(method_exists($dashlet, $requestedMethod) || method_exists($dashlet, '__call')) {
654                             echo $dashlet->$requestedMethod();
655                         }
656                         else {
657                             echo 'no method';
658                         }
659                     }
660                 }
661         }
662
663         /**
664          * this method is used within a Dashlet when the options configuration is posted
665          */
666         protected function action_configuredashlet(){
667                 global $current_user, $mod_strings;
668
669                 if(!empty($_REQUEST['id'])) {
670                     $id = $_REQUEST['id'];
671                     $dashletDefs = $current_user->getPreference('dashlets', $_REQUEST['module']); // load user's dashlets config
672                     require_once($dashletDefs[$id]['fileLocation']);
673
674                     $dashlet = new $dashletDefs[$id]['className']($id, (isset($dashletDefs[$id]['options']) ? $dashletDefs[$id]['options'] : array()));
675                     if(!empty($_REQUEST['configure']) && $_REQUEST['configure']) { // save settings
676                         $dashletDefs[$id]['options'] = $dashlet->saveOptions($_REQUEST);
677                         $current_user->setPreference('dashlets', $dashletDefs, 0, $_REQUEST['module']);
678                     }
679                     else { // display options
680                         $json = getJSONobj();
681                         return 'result = ' . $json->encode((array('header' => $dashlet->title . ' : ' . $mod_strings['LBL_OPTIONS'],
682                                                                  'body'  => $dashlet->displayOptions())));
683
684                     }
685                 }
686                 else {
687                     return '0';
688                 }
689         }
690
691         /**
692          * getActionFilename
693          */
694         public static function getActionFilename($action) {
695            if(isset(self::$action_case_file[$action])) {
696                   return self::$action_case_file[$action];
697            }
698            return $action;
699         }
700
701         /********************************************************************/
702         //                              PROCESS TASKS
703         /********************************************************************/
704
705         /**
706          * Given the module and action, determine whether the super/admin has prevented access
707          * to this url. In addition if any links specified for this module, load the links into
708          * GLOBALS
709          *
710          * @return true if we want to stop processing, false if processing should continue
711          */
712         private function blockFileAccess(){
713                 //check if the we have enabled file_access_control and if so then check the mappings on the request;
714                 if(!empty($GLOBALS['sugar_config']['admin_access_control']) && $GLOBALS['sugar_config']['admin_access_control']){
715                         $this->loadMapping('file_access_control_map');
716                         //since we have this turned on, check the mapping file
717                         $module = strtolower($this->module);
718                         $action = strtolower($this->do_action);
719                         if(!empty($this->file_access_control_map['modules'][$module]['links'])){
720                                 $GLOBALS['admin_access_control_links'] = $this->file_access_control_map['modules'][$module]['links'];
721                         }
722
723                         if(!empty($this->file_access_control_map['modules'][$module]['actions']) && (in_array($action, $this->file_access_control_map['modules'][$module]['actions']) || !empty($this->file_access_control_map['modules'][$module]['actions'][$action]))){
724                                 //check params
725                                 if(!empty($this->file_access_control_map['modules'][$module]['actions'][$action]['params'])){
726                                         $block = true;
727                                         $params = $this->file_access_control_map['modules'][$module]['actions'][$action]['params'];
728                                         foreach($params as $param => $paramVals){
729                                                 if(!empty($_REQUEST[$param])){
730                                                         if(!in_array($_REQUEST[$param], $paramVals)){
731                                                                 $block = false;
732                                                                 break;
733                                                         }
734                                                 }
735                                         }
736                                         if($block){
737                                                 $this->_processed = true;
738                                                 $this->no_access();
739                                         }
740                                 }else{
741                                         $this->_processed = true;
742                                         $this->no_access();
743                                 }
744                         }
745                 }else
746                         $this->_processed = false;
747         }
748
749         /**
750          * This code is part of the entry points reworking. We have consolidated all
751          * entry points to go through index.php. Now in order to bring up an entry point
752          * it will follow the format:
753          * 'index.php?entryPoint=download'
754          * the download entry point is mapped in the following file: entry_point_registry.php
755          *
756          */
757         private function handleEntryPoint(){
758                 if(!empty($_REQUEST['entryPoint'])){
759                         $this->loadMapping('entry_point_registry');
760                         $entryPoint = $_REQUEST['entryPoint'];
761
762                         if(!empty($this->entry_point_registry[$entryPoint])){
763                                 require_once($this->entry_point_registry[$entryPoint]['file']);
764                                 $this->_processed = true;
765                                 $this->view = '';
766                         }
767                 }
768         }
769
770     /**
771      * Checks to see if the requested entry point requires auth
772      *
773      * @param  $entrypoint string name of the entrypoint
774      * @return bool true if auth is required, false if not
775      */
776     public function checkEntryPointRequiresAuth($entryPoint)
777     {
778         $this->loadMapping('entry_point_registry');
779
780         if ( isset($this->entry_point_registry[$entryPoint]['auth'])
781                 && !$this->entry_point_registry[$entryPoint]['auth'] )
782             return false;
783         return true;
784     }
785
786         /**
787          * Meant to handle old views e.g. DetailView.php.
788          *
789          */
790         protected function callLegacyCode()
791         {
792                 $file = self::getActionFilename($this->do_action);
793                 if ( isset($this->action_view_map[strtolower($this->do_action)]) ) {
794                 $action = $this->action_view_map[strtolower($this->do_action)];
795             }
796             else {
797                 $action = $this->do_action;
798             }
799             // index actions actually maps to the view.list.php view
800             if ( $action == 'index' ) {
801                 $action = 'list';
802             }
803
804                 if ((file_exists('modules/' . $this->module . '/'. $file . '.php')
805                 && !file_exists('modules/' . $this->module . '/views/view.'. $action . '.php'))
806             || (file_exists('custom/modules/' . $this->module . '/'. $file . '.php')
807                 && !file_exists('custom/modules/' . $this->module . '/views/view.'. $action . '.php'))
808             ) {
809                         // A 'classic' module, using the old pre-MVC display files
810                         // We should now discard the bean we just obtained for tracking as the pre-MVC module will instantiate its own
811                         unset($GLOBALS['FOCUS']);
812                         $GLOBALS['log']->debug('Module:' . $this->module . ' using file: '. $file);
813                         $this->action_default();
814                         $this->_processed = true;
815                 }
816         }
817
818         /**
819          * If the action has been remapped to a different action as defined in
820          * action_file_map.php or action_view_map.php load those maps here.
821          *
822          */
823         private function handleActionMaps(){
824                 if(!empty($this->action_file_map[strtolower($this->do_action)])){
825                         $this->view = '';
826                         $GLOBALS['log']->debug('Using Action File Map:' . $this->action_file_map[strtolower($this->do_action)]);
827                         require_once($this->action_file_map[strtolower($this->do_action)]);
828                         $this->_processed = true;
829                 }elseif(!empty($this->action_view_map[strtolower($this->do_action)])){
830                         $GLOBALS['log']->debug('Using Action View Map:' . $this->action_view_map[strtolower($this->do_action)]);
831                         $this->view = $this->action_view_map[strtolower($this->do_action)];
832                         $this->_processed = true;
833                 }else
834                         $this->no_action();
835         }
836
837         /**
838          * Actually remap the action if required.
839          *
840          */
841         protected function remapAction(){
842                 if(!empty($this->action_remap[$this->do_action])){
843                         $this->action = $this->action_remap[$this->do_action];
844                         $this->do_action = $this->action;
845                 }
846         }
847
848 }
849 ?>