Controller.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. <?php
  2. /**
  3. * Controller file.
  4. *
  5. * Provides a class to handle all posible request.
  6. *
  7. * @author Iñigo Valentin <i@inigovalentin.com>
  8. * @license https://www.gnu.org/licenses/gpl-3.0.en.html GNU General Public License V3
  9. * @package IVV
  10. */
  11. require_once(__DIR__ . "/helper/DB_Helper.php");
  12. require_once(__DIR__ . "/helper/TEXT_Helper.php");
  13. require_once(__DIR__ . "/helper/NET_Helper.php");
  14. require_once(__DIR__ . "/helper/HTML_Helper.php");
  15. require_once(__DIR__ . "/util/Log.php");
  16. require_once(__DIR__ . "/util/Path.php");
  17. require_once(__DIR__ . "/util/URL.php");
  18. require_once(__DIR__ . "/Context.php");
  19. /**
  20. * Application controller.
  21. *
  22. * Handles every request, creating the required models and selecting the
  23. * view.
  24. *
  25. * @category Controller
  26. */
  27. class Controller extends Context{
  28. /**
  29. * @var string[] GET parameters received by the controller.
  30. */
  31. private $params = [];
  32. /**
  33. * @var Context Publicly available context.
  34. */
  35. private $context;
  36. /**
  37. * @var string URL command (first parameter, excluding optional language).
  38. */
  39. private $command = "";
  40. /**
  41. * @var int HTTP status.
  42. */
  43. private $status = 201;
  44. /**
  45. * @var string HTTP message.
  46. */
  47. private $message = "OK";
  48. /**
  49. * Retrieves the application context.
  50. *
  51. * @return Context The context.
  52. */
  53. public function get_context(){return $this->context;}
  54. /**
  55. * Controller constructor.
  56. *
  57. * Initializes a database connection and sets up the public context.
  58. */
  59. public function __construct(){
  60. $this->context = new Context();
  61. session_start();
  62. $configuration = parse_ini_file(__DIR__ . "/config/config.ini", true);
  63. $this->db = DB::start($configuration["database"]);
  64. $this->context->set_db($this->db);
  65. Log::debug("Controller created succesfully");
  66. }
  67. private function execute_action($action){
  68. require_once(PATH::ACTION . $action . ".php");
  69. action();
  70. return;
  71. }
  72. /**
  73. * Handles the request parameters.
  74. *
  75. * Receives the request params and gets itself ready. Authenticates the user (if needed)
  76. * and validates the URL.
  77. *
  78. * @param string[] $params GET parameters of the request.
  79. */
  80. public function prepare($params){
  81. // Parse parameters.
  82. foreach($params as $p){
  83. if (strlen($p) > 0){
  84. Log::debug("Controller parameter: $p");
  85. array_push($this->params, $p);
  86. }
  87. }
  88. // Check if the first parameter is a language code.
  89. if (sizeof($this->params) > 0 && $this->context->get_user()->is_valid_language($this->params[0])){
  90. $this->context->set_lang($this->params[0]);
  91. $this->params = array_slice($this->params, 1);
  92. }
  93. elseif(isSet($_COOKIE['lang']) && $this->context->get_user()->is_valid_language($_COOKIE['lang'])){
  94. $this->context->set_lang($_COOKIE['lang']);
  95. }
  96. else{
  97. $lang = "";
  98. // Set a default
  99. if (sizeof($this->context->get_user()->get_langs()) > 0)
  100. $lang = $this->context->get_user()->get_langs()[0]->get_code();
  101. // Get a list of avaiable languages from client browser.
  102. foreach (explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $accepted) {
  103. $code = substr($accepted, 0, 2);
  104. if ($this->context->get_user()->is_valid_language($code)){
  105. $lang = $code;
  106. break;
  107. }
  108. }
  109. if ($lang != "") $this->context->set_lang($lang);
  110. }
  111. // Obtain the command and process it
  112. if (sizeof($this->params) > 0) $this->command = strtoupper($this->params[0]);
  113. Log::debug("Controller command set: '" . $this->command . "'");
  114. }
  115. /**
  116. * Executes the required action.
  117. *
  118. * Must be called after {@see Controller::prepare()}.
  119. * @return void|number
  120. */
  121. public function action(){
  122. Log::debug("Executing action");
  123. // If there was an error in preparation, it's time to throw it.
  124. if ($this->status >= 400 && $this->status < 500){
  125. Log::debug("Executing action error code: " . $this->status);
  126. require_once(PATH::PAGE . "Error_Page.php");
  127. $page = new Error_Page($this->status, $this->message);
  128. require_once($page->get_view());
  129. http_response_code($this->status);
  130. return $this->status;
  131. }
  132. // Process the command
  133. $page = null;
  134. switch ($this->command){
  135. case "": // Main page
  136. require_once(PATH::PAGE . "Home_Page.php");
  137. $page = new Home_Page();
  138. break;
  139. case "PROJECT": // Projects
  140. case "PROJECTS": // Projects
  141. if (sizeof($this->params) > 1){
  142. require_once(PATH::PAGE . "Project_Page.php");
  143. $page = new Project_Page($this->params[1]);
  144. }
  145. else{
  146. require_once(PATH::PAGE . "Projects_Page.php");
  147. $page = new Projects_Page();
  148. }
  149. break;
  150. case "PROFILE": // Profile
  151. require_once(PATH::PAGE . "Profile_Page.php");
  152. $page = new Profile_Page();
  153. break;
  154. case "HELP": // Help static page
  155. require_once(PATH::PAGE . "Help_Page.php");
  156. $page = new Help_Page();
  157. break;
  158. case "SITEMAP.XML": // Sitemap file
  159. require_once(PATH::PAGE . "Sitemap_Page.php");
  160. $page = new Sitemap_Page();
  161. break;
  162. case "ROBOTS.TXT": // robots.txt file
  163. require_once(PATH::PAGE . "Robots_Page.php");
  164. $page = new Robots_Page();
  165. break;
  166. }
  167. // If page is not set, it's a not found.
  168. if ($page == null){
  169. require_once(PATH::PAGE . "Error_Page.php");
  170. $page = new Error_Page(404, "Page not found");
  171. }
  172. // Once the page is loaded, chack if it can be seen
  173. // TODO verify
  174. if ($page->get_code() >= 400 && $page->get_code() < 600){
  175. require_once(PATH::PAGE . "Error_Page.php");
  176. $page = new Error_Page($page->get_code(), $page->get_message());
  177. http_response_code($page->get_code());
  178. }
  179. // Load the view, or set an error code.
  180. Log::debug("Loading view: " . $page->get_view());
  181. require_once($page->get_view());
  182. http_response_code($page->get_code());
  183. }
  184. }
  185. ?>