PageRenderTime 42ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/core/model/modx/modmanagerresponse.class.php

https://gitlab.com/haque.mdmanzurul/nga-loyaltymatters
PHP | 310 lines | 215 code | 24 blank | 71 comment | 47 complexity | 3455016cc41e03ad76a5960d6455e548 MD5 | raw file
  1. <?php
  2. /**
  3. * modManagerResponse
  4. *
  5. * @package modx
  6. */
  7. require_once MODX_CORE_PATH . 'model/modx/modresponse.class.php';
  8. /**
  9. * Encapsulates an HTTP response from the MODX manager.
  10. *
  11. * {@inheritdoc}
  12. *
  13. * @package modx
  14. */
  15. class modManagerResponse extends modResponse {
  16. /** @var array A cached array of the current modAction object */
  17. public $action = array();
  18. public $namespace = 'core';
  19. public $namespaces = array();
  20. protected function _loadNamespaces() {
  21. $loaded = false;
  22. $cache = $this->modx->call('modNamespace','loadCache',array(&$this->modx));
  23. if ($cache) {
  24. $this->namespaces = $cache;
  25. $loaded = true;
  26. }
  27. return $loaded;
  28. }
  29. /**
  30. * @param array $options
  31. * @return mixed|string
  32. */
  33. public function outputContent(array $options = array()) {
  34. $route = $this->modx->request->action;
  35. $this->namespace = $this->modx->request->namespace;
  36. if (empty($route)) {
  37. $route = $this->namespace == 'core' ? 'welcome' : 'index';
  38. }
  39. $this->modx->lexicon->load('dashboard','topmenu','file','action');
  40. $this->_loadNamespaces();
  41. if (!array_key_exists($this->namespace,$this->namespaces)) {
  42. $this->namespace = 'core';
  43. $this->action = array();
  44. } else {
  45. $namespace = $this->namespaces[$this->namespace];
  46. $this->action['namespace'] = $this->namespace;
  47. $this->action['namespace_name'] = $namespace['name'];
  48. $this->action['namespace_path'] = $namespace['path'];
  49. $this->action['namespace_assets_path'] = $namespace['assets_path'];
  50. $this->action['lang_topics'] = '';
  51. $this->action['controller'] = $route;
  52. }
  53. $isDeprecated = false;
  54. /* handle 2.2< controllers */
  55. if (intval($route) > 0) {
  56. $this->modx->request->loadActionMap();
  57. $this->action = !empty($this->modx->actionMap[$route]) ? $this->modx->actionMap[$route] : array();
  58. $this->namespace = !empty($this->action['namespace']) ? $this->action['namespace'] : 'core';
  59. $isDeprecated = true;
  60. }
  61. $isLoggedIn = $this->validateAuthentication();
  62. if ($isLoggedIn && !$this->checkForMenuPermissions($route)) {
  63. $this->body = $this->modx->error->failure($this->modx->lexicon('access_denied'));
  64. } else {
  65. $this->modx->loadClass('modManagerController','',false,true);
  66. $className = $this->loadControllerClass(!$isDeprecated);
  67. $this->instantiateController($className,$isDeprecated ? 'getInstanceDeprecated' : 'getInstance');
  68. $this->body = $this->modx->controller->render();
  69. }
  70. if (empty($this->body)) {
  71. $this->body = $this->modx->error->failure($this->modx->lexicon('action_err_ns'));
  72. }
  73. return $this->send();
  74. }
  75. /**
  76. * Ensure the user has access to the manager
  77. * @return bool|string
  78. */
  79. public function validateAuthentication() {
  80. $isLoggedIn = $this->modx->user->isAuthenticated('mgr');
  81. if (!$isLoggedIn) {
  82. $alternateLogin = $this->modx->getOption('manager_login_url_alternate',null,'');
  83. if (!empty($alternateLogin)) {
  84. $this->modx->sendRedirect($alternateLogin);
  85. return '';
  86. }
  87. $this->namespace = 'core';
  88. $this->action['namespace'] = 'core';
  89. $this->action['namespace_name'] = 'core';
  90. $this->action['namespace_path'] = $this->modx->getOption('manager_path',null,MODX_MANAGER_PATH);
  91. $this->action['namespace_assets_path'] = $this->modx->getOption('assets_path',null,MODX_ASSETS_PATH);
  92. $this->action['lang_topics'] = 'login';
  93. $this->action['controller'] = 'security/login';
  94. } else if (!$this->modx->hasPermission('frames')) {
  95. $this->namespace = 'core';
  96. $this->action['namespace'] = 'core';
  97. $this->action['namespace_name'] = 'core';
  98. $this->action['namespace_path'] = $this->modx->getOption('manager_path',null,MODX_MANAGER_PATH);
  99. $this->action['namespace_assets_path'] = $this->modx->getOption('assets_path',null,MODX_ASSETS_PATH);
  100. $this->action['lang_topics'] = 'login';
  101. $this->action['controller'] = 'security/logout';
  102. }
  103. return $isLoggedIn;
  104. }
  105. /**
  106. * Send the response to the client
  107. */
  108. public function send() {
  109. if (is_array($this->body)) {
  110. $this->modx->smarty->assign('_e', $this->body);
  111. if (!file_exists($this->modx->smarty->template_dir.'error.tpl')) {
  112. $templatePath = $this->modx->getOption('manager_path') . 'templates/default/';
  113. $this->modx->smarty->setTemplatePath($templatePath);
  114. }
  115. echo $this->modx->smarty->fetch('error.tpl');
  116. } else {
  117. echo $this->body;
  118. }
  119. @session_write_close();
  120. exit();
  121. }
  122. /**
  123. * Include the correct controller class for the action
  124. *
  125. * @param bool $prefixNamespace Whether or not to prefix the Namespace name to the class. Default for 2.3+
  126. * controllers, set to false for 2.2< deprecated controllers.
  127. * @return string
  128. */
  129. public function loadControllerClass($prefixNamespace = true) {
  130. $theme = $this->modx->getOption('manager_theme',null,'default');
  131. $paths = $this->getNamespacePath($theme);
  132. $f = $this->action['controller'];
  133. $className = $this->getControllerClassName();
  134. if (!class_exists($className) && $this->namespace != 'core' && $prefixNamespace) {
  135. $className = ucfirst($this->namespace).$className;
  136. }
  137. if (!class_exists($className)) {
  138. $classFile = strtolower($f).'.class.php';
  139. $classPath = null;
  140. foreach ($paths as $controllersPath) {
  141. if (!file_exists($controllersPath.$classFile)) {
  142. if (file_exists($controllersPath.strtolower($f).'/index.class.php')) {
  143. $classPath = $controllersPath.strtolower($f).'/index.class.php';
  144. }
  145. } else {
  146. $classPath = $controllersPath.$classFile;
  147. break;
  148. }
  149. }
  150. /* handle Revo <2.2 controllers */
  151. if (empty($classPath)) {
  152. $className = 'modManagerControllerDeprecated';
  153. $classPath = MODX_CORE_PATH.'model/modx/modmanagercontrollerdeprecated.class.php';
  154. }
  155. if (!file_exists($classPath)) {
  156. if (file_exists(strtolower($f).'/index.class.php')) {
  157. $classPath = strtolower($f).'/index.class.php';
  158. } else { /* handle Revo <2.2 controllers */
  159. $className = 'modManagerControllerDeprecated';
  160. $classPath = MODX_CORE_PATH.'model/modx/modmanagercontrollerdeprecated.class.php';
  161. }
  162. }
  163. ob_start();
  164. require_once $classPath;
  165. ob_end_clean();
  166. }
  167. return $className;
  168. }
  169. public function instantiateController($className,$getInstanceMethod = 'getInstance') {
  170. try {
  171. $c = new $className($this->modx,$this->action);
  172. if (!($c instanceof modExtraManagerController) && $getInstanceMethod == 'getInstanceDeprecated') {
  173. $getInstanceMethod = 'getInstance';
  174. }
  175. /* this line allows controller derivatives to decide what instance they want to return (say, for derivative class_key types) */
  176. $this->modx->controller = call_user_func_array(array($c,$getInstanceMethod),array($this->modx,$className,$this->action));
  177. $this->modx->controller->setProperties($c instanceof SecurityLoginManagerController ? $_POST : array_merge($_GET,$_POST));
  178. $this->modx->controller->initialize();
  179. } catch (Exception $e) {
  180. die($e->getMessage());
  181. }
  182. return $this->modx->controller;
  183. }
  184. /**
  185. * If this action has a menu item, ensure user has access to menu
  186. * @param string $action
  187. * @return bool
  188. */
  189. public function checkForMenuPermissions($action) {
  190. $canAccess = true;
  191. /** @var modMenu $menu */
  192. $menu = $this->modx->getObject('modMenu',array(
  193. 'action' => $action,
  194. ));
  195. if ($menu) {
  196. $permissions = $menu->get('permissions');
  197. if (!empty($permissions)) {
  198. $permissions = explode(',',$permissions);
  199. foreach ($permissions as $permission) {
  200. if (!$this->modx->hasPermission($permission)) {
  201. $canAccess = false;
  202. }
  203. }
  204. }
  205. }
  206. return $canAccess;
  207. }
  208. /**
  209. * Gets the controller class name from the active modAction object
  210. *
  211. * @return string
  212. */
  213. public function getControllerClassName() {
  214. $className = $this->action['controller'].(!empty($this->action['class_postfix']) ? $this->action['class_postfix'] : 'ManagerController');
  215. $className = explode('/',$className);
  216. $o = array();
  217. foreach ($className as $k) {
  218. $o[] = ucfirst(str_replace(array('.','_','-'),'',$k));
  219. }
  220. return implode('',$o);
  221. }
  222. /**
  223. * Get the appropriate path to the controllers directory for the active Namespace.
  224. *
  225. * @param string $theme
  226. * @return array An array of paths to the Namespace's controllers directory.
  227. */
  228. public function getNamespacePath($theme = 'default') {
  229. $namespace = array_key_exists($this->namespace,$this->namespaces) ? $this->namespaces[$this->namespace] : $this->namespaces['core'];
  230. /* find context path */
  231. if (isset($namespace['name']) && $namespace['name'] != 'core') {
  232. $paths[] = $namespace['path'].'controllers/'.trim($theme,'/').'/';
  233. if ($theme != 'default') {
  234. $paths[] = $namespace['path'].'controllers/default/';
  235. }
  236. $paths[] = $namespace['path'].'controllers/';
  237. /* deprecated old usage */
  238. $paths[] = $namespace['path'].trim($theme,'/');
  239. if ($theme != 'default') {
  240. $paths[] = $namespace['path'].'default/';
  241. }
  242. $paths[] = $namespace['path'];
  243. } else {
  244. $paths[] = $namespace['path'].'controllers/'.trim($theme,'/').'/';
  245. if ($theme != 'default') {
  246. $paths[] = $namespace['path'].'controllers/default/';
  247. }
  248. $paths[] = $namespace['path'].'controllers/';
  249. }
  250. return $paths;
  251. }
  252. /**
  253. * Adds a lexicon topic to this page's language topics to load. Will load
  254. * the topic as well.
  255. *
  256. * @param string $topic The topic to load, in standard namespace:topic format
  257. * @return boolean True if successful
  258. */
  259. public function addLangTopic($topic) {
  260. $this->modx->lexicon->load($topic);
  261. $topics = $this->getLangTopics();
  262. $topics[] = $topic;
  263. return $this->setLangTopics($topics);
  264. }
  265. /**
  266. * Adds a lexicon topic to this page's language topics to load
  267. *
  268. * @return boolean True if successful
  269. */
  270. public function getLangTopics() {
  271. $topics = $this->modx->smarty->get_template_vars('_lang_topics');
  272. return explode(',',$topics);
  273. }
  274. /**
  275. * Sets the language topics for this page
  276. *
  277. * @param array $topics The array of topics to set
  278. * @return boolean True if successful
  279. */
  280. public function setLangTopics(array $topics = array()) {
  281. if (!is_array($topics) || empty($topics)) return false;
  282. $topics = array_unique($topics);
  283. $topics = implode(',',$topics);
  284. return $this->modx->smarty->assign('_lang_topics',$topics);
  285. }
  286. }