PageRenderTime 65ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/include/MVC/Controller/SugarController.php

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