PageRenderTime 29ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/controllers/node.php

https://github.com/laposa/onxshop
PHP | 395 lines | 169 code | 111 blank | 115 comment | 121 complexity | 530e329edfee4e8ccd22b6203285cf88 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * Copyright (c) 2005-2021 Laposa Limited (https://laposa.ie)
  4. * Licensed under the New BSD License. See the file LICENSE.txt for details.
  5. *
  6. */
  7. class Onyx_Controller_Node extends Onyx_Controller {
  8. /**
  9. * main action
  10. */
  11. public function mainAction() {
  12. if ($this->processNode()) return true;
  13. else return false;
  14. }
  15. /**
  16. * process node
  17. */
  18. public function processNode() {
  19. /**
  20. * check node id value
  21. */
  22. if (!is_numeric($this->GET['id'])) {
  23. msg("Node.processNode(): id is not numeric", 'error');
  24. return false;
  25. } else {
  26. $node_id = $this->GET['id'];
  27. }
  28. /**
  29. * initialize
  30. */
  31. require_once('models/common/common_node.php');
  32. $this->Node = new common_node();
  33. $node_data = $this->Node->nodeDetail($node_id);
  34. if (!is_array($node_data)) {
  35. msg("Node ID {$node_id} does not exists", 'error');
  36. return false;
  37. }
  38. $source = $node_data;
  39. $this->temp['node_group'] = $node_data['node_group'];
  40. /**
  41. * Initialise node configuration overwrites
  42. */
  43. $global_conf_node_overwrites = $this->initGlobalNodeConfigurationOverwrites($node_id );
  44. /**
  45. * merge
  46. */
  47. $GLOBALS['onyx_conf'] = $this->array_replace_recursive($GLOBALS['onyx_conf'], $global_conf_node_overwrites);
  48. /**
  49. * check if the page can be viewed
  50. */
  51. if ($node_data['node_group'] == 'page' && !$this->canViewPage($node_data)) {
  52. // send 404 HTTP code
  53. http_response_code(404);
  54. // don't allow to save this request to the cache
  55. $this->container->set('omit_cache', true);
  56. // display 404 page content
  57. $_Onyx_Request = new Onyx_Request('node~id=' . $this->Node->conf['id_map-404'].'~');
  58. $node_data['content'] = $_Onyx_Request->getContent();
  59. $this->tpl->assign('NODE', $node_data);
  60. $this->tpl->parse('content.wrapper');
  61. return true;
  62. }
  63. /**
  64. * force login
  65. */
  66. if ($node_data['require_login'] == 1 && $_SESSION['client']['customer']['id'] == 0) {
  67. onyxGoTo("page/" . $this->Node->conf['id_map-login'] . "?to=" . urlencode($_SERVER['REQUEST_URI']));//will exit immediatelly
  68. }
  69. /**
  70. * force SSL
  71. * this is no longer effective since Onyx 1.7 when we force SSL for all pages
  72. * when ONYX_CUSTOMER_USE_SSL is set to "true"
  73. * kept here for transitional period
  74. */
  75. if ($node_data['require_ssl'] == 1) {
  76. if (!($_SERVER['SSL_PROTOCOL'] || $_SERVER['HTTPS']) && ONYX_CUSTOMER_USE_SSL) {
  77. //don't exit in this case, just say "next time use SSL"
  78. header("Location: https://{$_SERVER['SERVER_NAME']}{$_SERVER['REQUEST_URI']}");
  79. }
  80. }
  81. /**
  82. * check if template file exists in ONYX_DIR or in ONYX_PROJECT_DIR
  83. */
  84. $template_path = "node/{$node_data['node_group']}/{$node_data['node_controller']}";
  85. $template_file_path = "templates/{$template_path}.html";
  86. if (file_exists(ONYX_DIR . $template_file_path) || file_exists(ONYX_PROJECT_DIR . $template_file_path)) {
  87. $template = $template_path;
  88. } else {
  89. msg("missing $template_file_path", 'error', 1);
  90. //fallback to default
  91. $template = "node/{$node_data['node_group']}/default";
  92. }
  93. /**
  94. * check if controller exits
  95. */
  96. $controller_path = $template_path; //try the same filename as for the template
  97. $controller_file_path = "controllers/{$controller_path}.php";
  98. if (file_exists(ONYX_DIR . $controller_file_path) || file_exists(ONYX_PROJECT_DIR . $controller_file_path)) {
  99. $controller = $controller_path;
  100. } else {
  101. //fallback to default
  102. $controller = "node/{$node_data['node_group']}/default";
  103. }
  104. /**
  105. * check if we need to use default_controller@specic_template
  106. */
  107. if ($template == $controller) $controller_request = $template;
  108. else $controller_request = "{$controller}@{$template}";
  109. /**
  110. * process controller referred from this node
  111. */
  112. msg("Node process: $controller", 'ok', 2);
  113. if (isset($GLOBALS['components'])) {
  114. $GLOBALS['components'][count($GLOBALS['components']) - 1]['node'] = $node_data['title'];
  115. }
  116. $_Onyx_Request = new Onyx_Request("$controller_request&id={$node_data['id']}&parent_id={$node_data['parent']}");
  117. $node_data['content'] = $_Onyx_Request->getContent();
  118. /**
  119. * add extra_css_class
  120. */
  121. $node_data['extra_css_class'] = '';
  122. /*
  123. if (trim($node_data['css_class']) != '') {
  124. $css_classes = explode(" ", $node_data['css_class']);
  125. foreach ($css_classes as $css_class_item) {
  126. $node_data['extra_css_class'] .= "node-$css_class_item ";
  127. }
  128. }
  129. */
  130. /**
  131. * check visibility and than display
  132. */
  133. if ($node_visibility = $this->checkVisibility($node_data)) {
  134. if ($this->_checkPermissionForExtraCSS($node_data)) {
  135. //TODO: add and icon with status
  136. // we cannot add this css_class to normal node.css_class, because of inheritance
  137. if ($node_data['display_permission'] == 1) $node_data['extra_css_class'] = $node_data['extra_css_class'] . ' show-at-normal-login';
  138. else if ($node_data['display_permission'] == 2) $node_data['extra_css_class'] = $node_data['extra_css_class'] . ' hide-at-normal-login';
  139. else if ($node_data['display_permission'] == 3) $node_data['extra_css_class'] = $node_data['extra_css_class'] . ' show-at-trade-login';
  140. else if ($node_data['display_permission'] == 4) $node_data['extra_css_class'] = $node_data['extra_css_class'] . ' hide-at-trade-login';
  141. if (is_array($node_data['display_permission_group_acl'])) $node_data['extra_css_class'] = $node_data['extra_css_class'] . ' acl-in-use';
  142. if ($node_data['publish'] == 0) $node_data['extra_css_class'] = $node_data['extra_css_class'] . ' not-public';
  143. if ($node_data['node_controller'] == 'adaptive') $node_data['extra_css_class'] = $node_data['extra_css_class'] . ' adaptive';
  144. }
  145. $this->tpl->assign("NODE", $node_data);
  146. }
  147. /**
  148. * front-end node edit and node move (sort) icons
  149. * node add are inserted in controller/node/default
  150. */
  151. // don't show edit icons when disable_fe_edit or shared parameter is 1 (i.e. passed from shared content)
  152. // and not authenticated for the backend
  153. $show_fe_edit = false;
  154. if (Onyx_Bo_Authentication::getInstance()->isAuthenticated()) $show_fe_edit = true;
  155. if ($this->GET['disable_fe_edit'] || $this->GET['shared']) $show_fe_edit = false;
  156. if ($show_fe_edit == true) {
  157. if ($node_data['node_group'] == 'variable' && $_SESSION['fe_edit_mode'] == 'edit') {
  158. $this->tpl->parse('content.wrapper.variable_edit');
  159. } else if ($node_data['node_group'] == 'content' && $_SESSION['fe_edit_mode'] == 'edit') {
  160. if ($node_data['node_controller'] == 'shared') {
  161. $this->tpl->assign("SOURCE", $source);
  162. $this->tpl->parse('content.wrapper.fe_edit.edit_source');
  163. }
  164. $this->tpl->parse('content.wrapper.fe_edit');
  165. } else if ($node_data['node_group'] == 'layout' && $_SESSION['fe_edit_mode'] == 'edit') {
  166. if ($node_data['node_controller'] == 'shared') {
  167. $this->tpl->parse('content.wrapper.fe_layout_property.edit_shared');
  168. }
  169. $this->tpl->parse('content.wrapper.fe_layout_property');
  170. //$this->tpl->parse('content.wrapper.layout_add');
  171. } else if ($node_data['node_group'] == 'page' && $_SESSION['fe_edit_mode'] == 'edit') {
  172. $this->tpl->parse('content.wrapper.fe_page_properties');
  173. }
  174. // show extra wrappers when in edit or sorting mode
  175. if ($_SESSION['fe_edit_mode'] == 'edit' || $_SESSION['fe_edit_mode'] == 'move') {
  176. // node_group variable doesn't have any wrapper
  177. if ($node_data['node_group'] !== 'variable') {
  178. /** check parent isn't page or layout */
  179. $this->tpl->parse('content.wrapper.backend_wrapper_before');
  180. $this->tpl->parse('content.wrapper.backend_wrapper_after');
  181. }
  182. }
  183. }
  184. if ($node_visibility) $this->tpl->parse('content.wrapper');
  185. return true;
  186. }
  187. /**
  188. * checkVisibility
  189. */
  190. public function checkVisibility($node_data) {
  191. $visibility = false;
  192. //force visibility for admin, only when in edit or preview mode
  193. if ($_SESSION['fe_edit_mode'] == 'edit' || $_SESSION['fe_edit_mode'] == 'move') $force_admin_visibility = true;
  194. else $force_admin_visibility = false;
  195. /**
  196. * CONDITIONAL DISPLAY OPTION BY display_permission
  197. */
  198. if ($this->Node->checkDisplayPermission($node_data, $force_admin_visibility)) {
  199. //don't display hidden node in preview mode
  200. if ($node_data['publish'] == 0 && Onyx_Bo_Authentication::getInstance()->isAuthenticated() && $_SESSION['fe_edit_mode'] == 'preview' ) $visibility1 = false;
  201. else $visibility1 = true;
  202. }
  203. /**
  204. * check permission from group_acl
  205. */
  206. if ($this->Node->checkDisplayPermissionGroupAcl($node_data, $force_admin_visibility)) {
  207. $visibility2 = true;
  208. } else {
  209. $visibility2 = false;
  210. }
  211. /**
  212. * visible only if preview token is provided and all permissions are correct
  213. */
  214. if ($this->checkForValidPreviewToken($node_data)) return true;
  215. else if ($visibility1 && $visibility2) return true;
  216. else return false;
  217. }
  218. /**
  219. * check if add CSS highlight
  220. */
  221. public function _checkPermissionForExtraCSS($node_data) {
  222. //add css class when when logged in and using edit or move mode
  223. if (Onyx_Bo_Authentication::getInstance()->isAuthenticated() && ($_SESSION['fe_edit_mode'] == 'edit' || $_SESSION['fe_edit_mode'] == 'move')) return true;
  224. else return false;
  225. }
  226. /**
  227. * Initialise configuration overwrites from database
  228. */
  229. function initGlobalNodeConfigurationOverwrites($node_id) {
  230. if (!is_numeric($node_id)) return false;
  231. $conf = array();
  232. require_once ('models/common/common_configuration.php');
  233. $Configuration = new common_configuration();
  234. $conf = $Configuration->getConfiguration($node_id);
  235. return $conf;
  236. }
  237. /**
  238. * canViewPage
  239. * check if page is published, but keep it available in edit mode
  240. * and allow to see when provided GET.preview_token
  241. */
  242. public function canViewPage($node_data) {
  243. if ($this->checkForValidPreviewToken($node_data)) {
  244. msg("This page is waiting for approval");
  245. return true;
  246. } else if (Onyx_Bo_Authentication::getInstance()->isAuthenticated()) {
  247. return true;
  248. } else if ($this->Node->isInBin($node_data['id'])) {
  249. return false;
  250. } else {
  251. return $node_data['publish'];
  252. }
  253. }
  254. /**
  255. * checkForValidPreviewToken
  256. */
  257. private function checkForValidPreviewToken($node_data) {
  258. // currently applies only to pages
  259. if ($node_data['node_group'] != 'page') return;
  260. if (array_key_exists('preview_token', $_GET)) {
  261. if ($this->Node->verifyPreviewToken($node_data, $_GET['preview_token'])) {
  262. return true;
  263. } else {
  264. msg("Invalid preview_token", 'error');
  265. return false;
  266. }
  267. } else {
  268. return false;
  269. }
  270. }
  271. /**
  272. * merge array with overwrites (for local configuration overwrites)
  273. * TEMP: native array_replace_recursive function available in PHP 5.3
  274. */
  275. function array_replace_recursive($Arr1, $Arr2) {
  276. foreach($Arr2 as $key => $Value) {
  277. if(array_key_exists($key, $Arr1) && is_array($Value)) $Arr1[$key] = $this->array_replace_recursive($Arr1[$key], $Arr2[$key]);
  278. else $Arr1[$key] = $Value;
  279. }
  280. return $Arr1;
  281. }
  282. }