/** * This function executes the current request and outputs the response directly. */ public function execute() { ob_start(); $this->response = $this->getResponse(); try { $this->request = $this->getRequest(); $this->request_headers = $this->request->request_headers; if ($this->min_version > $this->request->version || $this->max_version < $this->request->version) { throw new SugarApiExceptionIncorrectVersion("Please change your url to reflect version between {$this->min_version} and {$this->max_version}"); } $authenticateUser = $this->authenticateUser(); $isLoggedIn = $authenticateUser['isLoggedIn']; $loginException = $authenticateUser['exception']; // Figure out the platform if ($isLoggedIn) { if (isset($_SESSION['platform'])) { $this->platform = $_SESSION['platform']; } } else { // Since we don't have a session we have to allow the user to specify their platform // However, since the results from the same URL will be different with // no variation in the oauth_token header we need to only take it as a GET request. if (!empty($_GET['platform'])) { $this->platform = basename($_GET['platform']); } } $this->request->setPlatform($this->platform); $GLOBALS['logic_hook']->call_custom_logic('', 'before_routing', array("api" => $this, "request" => $this->request)); $route = $this->findRoute($this->request); if ($route == false) { throw new SugarApiExceptionNoMethod('Could not find any route that accepted a path like: ' . $this->request->rawPath); } $this->request->setRoute($route); $GLOBALS['logic_hook']->call_custom_logic('', 'after_routing', array("api" => $this, "request" => $this->request)); // Get it back in case hook changed it $route = $this->request->getRoute(); if (empty($route['keepSession'])) { $this->releaseSession(); } // Get the request args early for use in current user api $argArray = $this->getRequestArgs($route); if (!$isLoggedIn && !empty($route['allowDownloadCookie'])) { $isLoggedIn = $this->authenticateUserForDownload(); } // Make sure the system is ready for them // This section of code is a portion of the code referred // to as Critical Control Software under the End User // License Agreement. Neither the Company nor the Users // may modify any portion of the Critical Control Software. $systemStatus = apiCheckSystemStatus(); if ($systemStatus !== true && $systemStatus['level'] != 'warning' && !($systemStatus['level'] == 'maintenance' && isset($this->user) && $this->user->isAdmin()) && empty($route['ignoreSystemStatusError'])) { // The system is unhappy and the route isn't flagged to let them through $e = new SugarApiExceptionMaintenance($systemStatus['message'], null, null, 0, $systemStatus['level']); $e->setExtraData("url", $systemStatus['url']); throw $e; } //END REQUIRED CODE DO NOT MODIFY if (!isset($route['noLoginRequired']) || $route['noLoginRequired'] == false) { if (!$isLoggedIn) { if (!$loginException) { $this->needLogin(); } else { throw $loginException; } } else { if (empty($route['ignoreMetaHash'])) { // Check metadata hash state and return an error to force a // resync so that the new metadata gets picked up if it is // out of date if (!$this->isMetadataCurrent()) { // Mismatch in hashes... Return error so the client will // resync its metadata and try again. throw new SugarApiExceptionInvalidHash(); } } } } if ($isLoggedIn) { // This is needed to load in the app_strings and the app_list_strings and the such $this->loadUserEnvironment(); } else { $this->loadGuestEnvironment(); } $headers = array(); foreach ($this->special_headers as $header) { if (isset($this->request_headers[$header])) { $headers[$header] = $this->request_headers[$header]; } } if (!empty($headers)) { $argArray['_headers'] = $headers; } $this->request->setArgs($argArray)->setRoute($route); $GLOBALS['logic_hook']->call_custom_logic('', 'before_api_call', array("api" => $this, "request" => $this->request)); // Get it back in case hook changed it $route = $this->request->getRoute(); $argArray = $this->request->getArgs(); // Trying to fetch correct module while API use search $module = $route['className']; if (isset($argArray['module'])) { $module = $argArray['module']; } elseif (isset($argArray['module_list'])) { $module = $argArray['module_list']; } SugarMetric_Manager::getInstance()->setTransactionName('rest_' . $module . '_' . $route['method']); $apiClass = $this->loadApiClass($route); $apiMethod = $route['method']; $this->handleErrorOutput('php_error_before_api'); $this->response->setContent($apiClass->{$apiMethod}($this, $argArray)); $this->respond($route, $argArray); if (empty($route['rawReply'])) { $this->handleErrorOutput('php_error_after_api'); } } catch (Exception $e) { $this->handleException($e); } // last chance for hooks to mess with the response $GLOBALS['logic_hook']->call_custom_logic('', "before_respond", $this->response); $this->response->send(); }