Internal.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <?php
  2. /**
  3. * Request Client for Internal Execution
  4. *
  5. * @package KO7\Base
  6. *
  7. * @copyright (c) 2007-2016 Kohana Team
  8. * @copyright (c) since 2016 Koseven Team
  9. * @license https://koseven.dev/LICENSE
  10. *
  11. * @since 3.1.0
  12. */
  13. class KO7_Request_Client_Internal extends Request_Client {
  14. /**
  15. * Processes the request, executing the controller action that handles this
  16. * request, determined by the [Route].
  17. *
  18. * $request->execute();
  19. *
  20. * @param Request $request Request Object
  21. * @param Response $response Response Object
  22. *
  23. * @return Response
  24. */
  25. public function execute_request(Request $request, Response $response)
  26. {
  27. // Create the class prefix
  28. $prefix = 'Controller_';
  29. // Directory
  30. $directory = $request->directory();
  31. // Controller
  32. $controller = $request->controller();
  33. if ($directory)
  34. {
  35. // Add the directory name to the class prefix
  36. $prefix .= str_replace(['\\', '/'], '_', trim($directory, '/')) . '_';
  37. }
  38. if (KO7::$profiling)
  39. {
  40. // Set the benchmark name
  41. $benchmark = '"' . $request->uri() . '"';
  42. if ($request !== Request::$initial AND Request::$current)
  43. {
  44. // Add the parent request uri
  45. $benchmark .= ' « "' . Request::$current->uri() . '"'; // @codeCoverageIgnore
  46. }
  47. // Start benchmarking
  48. $benchmark = Profiler::start('Requests', $benchmark);
  49. }
  50. // Store the currently active request
  51. $previous = Request::$current;
  52. // Change the current request to this request
  53. Request::$current = $request;
  54. try
  55. {
  56. if ( ! class_exists($prefix . $controller))
  57. {
  58. throw HTTP_Exception::factory(404, 'The requested URL :uri was not found on this server.', [
  59. ':uri' => $request->uri()
  60. ])->request($request);
  61. }
  62. // Load the controller using reflection
  63. $class = new ReflectionClass($prefix . $controller);
  64. if ($class->isAbstract())
  65. {
  66. throw new KO7_Exception('Cannot create instances of abstract :controller', [
  67. ':controller' => $prefix . $controller
  68. ]);
  69. }
  70. // Create a new instance of the controller
  71. $controller = $class->newInstance($request, $response);
  72. // Run the controller's execute() method
  73. $response = $class->getMethod('execute')->invoke($controller);
  74. if ( ! $response instanceof Response)
  75. {
  76. // Controller failed to return a Response.
  77. throw new KO7_Exception('Controller failed to return a Response');
  78. }
  79. }
  80. catch (HTTP_Exception $e)
  81. {
  82. // Store the request context in the Exception
  83. if ($e->request() === NULL)
  84. {
  85. $e->request($request); // @codeCoverageIgnore
  86. }
  87. // Get the response via the Exception
  88. $response = $e->get_response();
  89. }
  90. catch (Exception $e)
  91. {
  92. // Generate an appropriate Response object
  93. $response = KO7_Exception::_handler($e);
  94. }
  95. // Restore the previous request
  96. Request::$current = $previous;
  97. if (isset($benchmark))
  98. {
  99. // Stop the benchmark
  100. Profiler::stop($benchmark);
  101. }
  102. // Return the response
  103. return $response;
  104. }
  105. }