/** * @param action $action * @param array $arguments * @param null|bool $withoutBase * * @param bool $stopApp * * @throws Stop * @throws webApplicationException */ public function dispatch(action $action, array $arguments = [], $withoutBase = null, $stopApp = false) { static $apiTypes; profiler::addStack('app::dispatch'); MPCMF_LL_DEBUG && self::log()->addDebug(__METHOD__ . '(' . json_encode(func_get_args(), 320) . ')'); if ($apiTypes === null) { $apiTypes = [action::TYPE__API_FOR_ITEM => true, action::TYPE__API_GLOBAL => true]; } $slim = Slim::getInstance(); $aclManager = aclManager::getInstance(); $request = $slim->request(); $isApiRequest = isset($apiTypes[$action->getType()]); $isJson = $request->get(self::REQUEST__JSON, false) || $isApiRequest; $jsonPretty = $request->get(self::REQUEST__JSON_PRETTY, false); $jsonTemplate = $jsonPretty ? 'json.pretty.tpl' : 'json.tpl'; if ($isApiRequest) { $aclResponse = $aclManager->checkActionAccessByToken($action, $request->get('access_token')); if (!$aclResponse['status']) { $slim->render($jsonTemplate, ['data' => $aclResponse]); $slim->stop(); } } else { $aclManagerResponse = $aclManager->checkActionAccess($action); if (!$aclManagerResponse['status']) { $currentUrl = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/'; $forbiddenUrl = $this->getUrl('/authex/user/forbidden', ['redirectUrl' => base64_encode($currentUrl)]); $slim->redirect($forbiddenUrl); $slim->stop(); } } try { $result = call_user_func_array($action->getCallable(), $arguments); } catch (actionException $actionException) { throw new webApplicationException("Action exception: {$actionException->getMessage()}", $actionException->getCode(), $actionException); } if ($isApiRequest) { echo json_encode($result); $slim->stop(); } elseif ($isJson) { array_walk_recursive($result, function (&$item) { if ($item instanceof \Traversable) { $item = iterator_to_array($item); foreach ($item as &$itemValue) { if ($itemValue instanceof modelBase) { $itemValue = $itemValue->export(); } else { break; } } } elseif ($item instanceof modelBase) { $item = $item->export(); } }); $slim->render($jsonTemplate, ['data' => $result]); } else { try { $result['_entity'] = $action->getEntityActions()->getEntity(); $result['i18n'] = i18n::lang(); $result['_profiler'] = profiler::get(); $result['_acl'] = $aclManager; $result['_slim'] = $slim; $result['_route'] = $slim->router()->getCurrentRoute(); $result['_application'] = $this; } catch (entityException $entityException) { throw new webApplicationException("Web application route process exception: {$entityException->getMessage()}", $entityException->getCode(), $entityException); } catch (modulePartsHelperException $modulePartsHelperException) { throw new webApplicationException("Web application route process exception: {$modulePartsHelperException->getMessage()}", $modulePartsHelperException->getCode(), $modulePartsHelperException); } if ($withoutBase === null) { $withoutBase = (bool) $request->get(self::REQUEST__WITHOUT_BASE, false); } try { if (!$withoutBase && $action->useBase()) { $result['_template'] = $action->getTemplate(); $slim->render('index.tpl', $result); } else { $result['_template'] = ''; $slim->render($action->getTemplate(), $result); } } catch (Stop $stopException) { if (!$stopApp) { throw $stopException; } } } }