PageRenderTime 57ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/library/controller.class.php

https://github.com/acurrieclark/clocktower
PHP | 372 lines | 274 code | 85 blank | 13 comment | 129 complexity | 2d2f884ef233b39b8e0aeda56fd16f74 MD5 | raw file
  1. <?php
  2. /**
  3. * baseController
  4. */
  5. class baseController
  6. {
  7. protected $reset_security_flag, $construct_completed;
  8. public $ajax_return, $controller_error, $method_error, $before_filters, $security_token_lifetime;
  9. function __construct() {
  10. if (db::getInstance()) {
  11. session::start();
  12. }
  13. $this->template = new template;
  14. $this->reset_security_flag = false;
  15. $this->construct_completed = true;
  16. // check for identifiable ajax request
  17. if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')
  18. {
  19. $this->set_request_type('ajax');
  20. }
  21. else $this->set_request_type('http');
  22. }
  23. function setup($properties) {
  24. global $flash;
  25. if (!($this->security_token_lifetime)) {
  26. $this->security_token_lifetime = SECURITY_TOKEN_LIFETIME;
  27. }
  28. foreach ($properties as $property => $value) {
  29. $this->$property = $value;
  30. }
  31. // if a file which does not exist has been requested respond with 404 header and no html
  32. if (preg_match('/\S*\.\S{1,}/',$this->url)) {
  33. logger::Not_Found();
  34. $this->file_not_found = true;
  35. }
  36. if ($this->controller_error || $this->method_error) {
  37. logger::Not_Found();
  38. }
  39. if (!$this->construct_completed) {
  40. logger::Warning("$this->controller controller __construct does not include parent::__construct() function");
  41. logger::write();
  42. }
  43. // autoload the user if we have a valid page and if we are using users
  44. if (!$this->file_not_found && !$this->controller_error && !$this->method_error && AUTOLOAD_USER) {
  45. user::autoload_user();
  46. }
  47. $flash = new flash(array('message' => retrieve_and_remove('message'),
  48. 'error' => retrieve_and_remove('error'),
  49. 'information' => retrieve_and_remove('information'),
  50. 'warning' => retrieve_and_remove('warning'),
  51. 'system_error' => retrieve_and_remove('system_error'),
  52. 'system_message' => retrieve_and_remove('system_message'),
  53. ));
  54. $this->setup_back();
  55. $this->verify_posted();
  56. if (empty($this->get)) $this->get = array();
  57. if (DEVELOPMENT_ENVIRONMENT == true) {
  58. if ($this->posted)
  59. logger::Posted(json_encode($this->posted));
  60. else if ($this->delete) {
  61. logger::Delete(json_encode($this->delete));
  62. }
  63. }
  64. }
  65. protected function set_request_type($type) {
  66. if ($type == 'ajax') {
  67. ob_start();
  68. $this->request_type = 'ajax';
  69. }
  70. if ($type == 'http') {
  71. $this->request_type = 'http';
  72. }
  73. }
  74. private function setup_back()
  75. {
  76. if (!isset($this->get['iframe']) && ($this->request_type != 'ajax')) {
  77. if (isset($_SESSION['back'])) {
  78. $this->back = $_SESSION['back'];
  79. $this->doubleback = $_SESSION['doubleback'];
  80. }
  81. else {
  82. $this->back = '';
  83. $this->doubleback = '';
  84. }
  85. if ($this->full_request == $this->back) {
  86. $this->back = $_SESSION['doubleback'];
  87. }
  88. }
  89. }
  90. function finalise_back() {
  91. if ($this->full_request != $this->back && !isset($this->get['iframe']) && ($this->request_type != 'ajax') && !($this->controller_error || ($this->method_error) || $this->file_not_found)) {
  92. $_SESSION['doubleback'] = $this->back;
  93. $_SESSION['back'] = $this->full_request;
  94. }
  95. // this attempts to resolve redirection after login, but is not quite right
  96. // basically, we want to remove the 'back after login' session variable but
  97. // only if we are clearly not going to use it.
  98. if (isset($_SESSION['back_after_login']) && isset($this->doubleback) && ($_SESSION['back_after_login'] != $this->doubleback && $_SESSION['back_after_login'] != $_SESSION['doubleback'] && $_SESSION['back_after_login'] != $_SESSION['back'])) {
  99. unset($_SESSION['back_after_login']);
  100. }
  101. }
  102. function activate_reset_security() {
  103. $this->reset_security_flag = true;
  104. }
  105. function cancel_reset_security() {
  106. $this->reset_security_flag = false;
  107. }
  108. function reset_security($force = false) {
  109. if (($this->reset_security_flag && ($_SERVER['REQUEST_METHOD'] == "POST" || $_SERVER['REQUEST_METHOD'] == "DELETE" || $_SERVER['REQUEST_METHOD'] == "PUT")) || $force) {
  110. logger::Security('Resetting Security');
  111. unset($this->security_token);
  112. unset($_SESSION['SecurityTokenTime']);
  113. unset($_SESSION['SecurityToken']);
  114. unset($_SESSION['SecurityTokenCount']);
  115. }
  116. }
  117. private function verify_posted() {
  118. if ($_SERVER['REQUEST_METHOD'] == "POST" || $_SERVER['REQUEST_METHOD'] == "DELETE" || $_SERVER['REQUEST_METHOD'] == "PUT") {
  119. $tokenAge = time() - $_SESSION['SecurityTokenTime'];
  120. $security_token = ($this->posted['security_token']) ? $this->posted['security_token'] : $this->get['security_token'];
  121. if ($_SERVER['REQUEST_METHOD'] == 'DELETE' && !$security_token) {
  122. $security_token = $this->delete['security_token'];
  123. }
  124. if (!$security_token || ($security_token != $_SESSION['SecurityToken']) && ($tokenAge <= $this->security_token_lifetime)) {
  125. unset($_SESSION['SecurityTokenTime']);
  126. unset($_SESSION['SecurityToken']);
  127. unset($_SESSION['SecurityTokenCount']);
  128. error('The form you have submitted contains an incorrect security token');
  129. logger::Error('Forgery Detected');
  130. redirect_to();
  131. }
  132. else if (!($tokenAge <= $this->security_token_lifetime)) {
  133. unset($_SESSION['SecurityTokenTime']);
  134. unset($_SESSION['SecurityToken']);
  135. unset($_SESSION['SecurityTokenCount']);
  136. error('The form you have submitted has expired. Please refresh or try again.');
  137. redirect_to('back');
  138. }
  139. else if ($_SESSION['SecurityTokenCount'] > 10) {
  140. unset($_SESSION['SecurityTokenTime']);
  141. unset($_SESSION['SecurityToken']);
  142. unset($_SESSION['SecurityTokenCount']);
  143. error('You have submitted the same form too many times. Please try starting again.');
  144. redirect_to('back');
  145. }
  146. else {
  147. $this->security_token = ($_SESSION['SecurityToken']);
  148. if ($this->request_type != 'ajax') $_SESSION['SecurityTokenCount']++;
  149. }
  150. }
  151. }
  152. function ajax_response($ajax) {
  153. $this->ajax_respond = $ajax;
  154. }
  155. function set_action_to_render($action) {
  156. $this->action_to_render = $action;
  157. }
  158. function html_email($template = 'email', $email_content_template = false) {
  159. include(ROOT . DS . 'library/vendor/CssToInlineStyles/CssToInlineStyles.php');
  160. ob_start();
  161. include(ROOT.DS.'application/views/mailers/'.$template.'.php');
  162. $html = ob_get_clean();
  163. ob_start();
  164. include(ROOT.DS.'public/css/email.css');
  165. $css = ob_get_clean();
  166. $inliner = new CssToInlineStyles($html, $css);
  167. $inliner->setEncoding('utf-8');
  168. return $inliner->convert();
  169. }
  170. function text_email($template, $email_content_template = false) {
  171. include(ROOT . DS . 'library/vendor/html2text.class.php');
  172. ob_start();
  173. include(ROOT.DS.'application/views/mailers/'.$template.'.php');
  174. $html = ob_get_clean();
  175. return html2text::convert($html);
  176. }
  177. function use_template($template) {
  178. if (file_exists(ROOT . DS . 'application' . DS . 'views'. DS .$this->controller.DS.$template.'_template.php'))
  179. $this->template_to_use = ROOT . DS . 'application' . DS . 'views'. DS .$this->controller.DS.$template.'_template.php';
  180. else if (file_exists(ROOT . DS . 'application' . DS . 'views'. DS .'application'.DS.$template.'_template.php'))
  181. $this->template_to_use = ROOT . DS . 'application' . DS . 'views'. DS .'application'.DS.$template.'_template.php';
  182. else {
  183. logger::Template('Designated template could not be found. Remember that "_template" is automatically added to the name. Using Default');
  184. $this->template_to_use = false;
  185. }
  186. logger::Template($this->template_to_use);
  187. }
  188. function render() {
  189. global $flash;
  190. $this->finalise_back();
  191. $this->reset_security();
  192. if ($this->request_type == 'ajax') {
  193. if ($this->controller_error || $this->method_error) {
  194. error('The requested asset does not exist');
  195. redirect_to();
  196. }
  197. else {
  198. if (!header_already_set())
  199. header('Content-type: application/json');
  200. logger::Sending("Ajax Response");
  201. logger::Sending("Headers: ". json_encode(headers_list()));
  202. $response_output = ob_get_clean();
  203. if (strlen($response_output) > 0) {
  204. logger::Sending($response_output);
  205. echo $response_output;
  206. }
  207. else {
  208. echo $flash->json_string();
  209. logger::Sending(stripslashes(json_encode($flash->json_string())));
  210. }
  211. }
  212. }
  213. else {
  214. add_stylesheet('system/bootstrap.min');
  215. add_stylesheet('main');
  216. add_javascript('system/jquery-1.11.0.min');
  217. add_javascript('system/modernizr-2.6.2-respond-1.1.0.min');
  218. add_javascript('main');
  219. add_javascript('system/bootstrap.min');
  220. try {
  221. // add default stylesheet and javascript if present
  222. if (file_exists(ROOT . DS . 'public' . DS . 'css'. DS .$this->controller. '.css'))
  223. add_stylesheet($this->controller);
  224. if (file_exists(ROOT . DS . 'public' . DS . 'js'. DS .$this->controller. '.js'))
  225. add_javascript($this->controller);
  226. if (!isset($this->action_to_render))
  227. $this->action_to_render = $this->action;
  228. $this->template->content_start("main");
  229. if ((DEVELOPMENT_ENVIRONMENT != true) && ($this->controller_error || ($this->method_error) || $this->file_not_found)) {
  230. require_once (ROOT . DS. 'public' . DS . '404.php');
  231. }
  232. else {
  233. if ($this->file_not_found) {
  234. header("HTTP/1.0 404 Not Found");
  235. render_exception("File Not Found", "The file <strong>'$this->url'</strong> does not exist.");
  236. }
  237. else if ($this->controller_error) {
  238. header("HTTP/1.0 404 Not Found");
  239. render_exception("Controller not found", "The controller <strong>'$this->controller'</strong> does not exist.");
  240. }
  241. else if ($this->method_error) {
  242. header("HTTP/1.0 404 Not Found");
  243. render_exception("Method not found", "The method <strong>'$this->action_to_render'</strong> does not exist for the controller <strong>'$this->controller'</strong>. Please check the controller file.");
  244. }
  245. else {
  246. // if the page is static, load it
  247. if ($this->static_page) require_once(ROOT."/application/static/$this->controller.php");
  248. // if we know the view to be rendered, load that
  249. else if (file_exists(ROOT . DS . 'application' . DS . 'views'. DS .$this->controller. DS . $this->action_to_render .'.php'))
  250. require_once(ROOT . DS . 'application' . DS . 'views'. DS .$this->controller. DS . $this->action_to_render .'.php');
  251. // otherwise throw an exception
  252. else render_exception("View for method '$this->action_to_render' could not be found.", "Please ensure the view file has been named correctly and is in the correct folder.");
  253. }
  254. }
  255. content_end();
  256. if (isset($this->template_to_use) && $this->template_to_use)
  257. require($this->template_to_use);
  258. else if (file_exists(ROOT . DS . 'application' . DS . 'views'. DS .$this->controller.DS.'template.php'))
  259. require( ROOT . DS . 'application' . DS . 'views'. DS .$this->controller.DS.'template.php');
  260. else if (file_exists(ROOT . DS . 'application' . DS . 'views'. DS . 'application'. DS . 'template.php'))
  261. require(ROOT . DS . 'application' . DS . 'views'. DS . 'application'. DS . 'template.php');
  262. else
  263. render_exception("There does not appear to be a valid template file", "Please create a template.php file in application/views/application for your controller or application.");
  264. if ($this->controller_error || $this->method_error || $this->file_not_found)
  265. $logger_string = '404.php';
  266. else {
  267. $action_string = ($this->action_to_render && $this->action_to_render != 'index') ? " - ".$this->action_to_render : '' ;
  268. $logger_string = $this->controller.$action_string;
  269. }
  270. if ($this->id != "") $logger_string .= " - ".$this->id;
  271. logger::Rendering($logger_string);
  272. }
  273. catch(Exception $e){
  274. error($e->getMessage());
  275. }
  276. }
  277. logger::write();
  278. }
  279. function render_partial ($name, $variables = array()) {
  280. if (file_exists(ROOT . DS . 'application' . DS . 'views'. DS .$this->controller.DS.'_'. $name.'.php'))
  281. include(ROOT . DS . 'application' . DS . 'views'. DS .$this->controller.DS.'_'. $name.'.php');
  282. else if (file_exists(ROOT . DS . 'application' . DS . 'views'. DS .'application'.DS.'_'. $name.'.php'))
  283. include(ROOT . DS . 'application' . DS . 'views'. DS .'application'.DS.'_'. $name.'.php');
  284. else render_exception("Partial Missing", "The partial \"$name\" you have requested does not appear to exist. Please check.");
  285. }
  286. }
  287. ?>