ControllerFactory.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 3.3.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Http;
  16. use Cake\Core\App;
  17. use Cake\Routing\Exception\MissingControllerException;
  18. use Cake\Utility\Inflector;
  19. use ReflectionClass;
  20. /**
  21. * Factory method for building controllers from request/response pairs.
  22. */
  23. class ControllerFactory
  24. {
  25. /**
  26. * Create a controller for a given request/response
  27. *
  28. * @param \Cake\Http\ServerRequest $request The request to build a controller for.
  29. * @param \Cake\Http\Response $response The response to use.
  30. * @return \Cake\Controller\Controller
  31. * @throws \ReflectionException
  32. */
  33. public function create(ServerRequest $request, Response $response)
  34. {
  35. $className = $this->getControllerClass($request);
  36. if (!$className) {
  37. $this->missingController($request);
  38. }
  39. $reflection = new ReflectionClass($className);
  40. if ($reflection->isAbstract() || $reflection->isInterface()) {
  41. $this->missingController($request);
  42. }
  43. /** @var \Cake\Controller\Controller $controller */
  44. $controller = $reflection->newInstance($request, $response);
  45. return $controller;
  46. }
  47. /**
  48. * Determine the controller class name based on current request and controller param
  49. *
  50. * @param \Cake\Http\ServerRequest $request The request to build a controller for.
  51. * @return string|null
  52. */
  53. public function getControllerClass(ServerRequest $request)
  54. {
  55. $pluginPath = $controller = null;
  56. $namespace = 'Controller';
  57. if ($request->getParam('controller')) {
  58. $controller = $request->getParam('controller');
  59. }
  60. if ($request->getParam('plugin')) {
  61. $pluginPath = $request->getParam('plugin') . '.';
  62. }
  63. if ($request->getParam('prefix')) {
  64. if (strpos($request->getParam('prefix'), '/') === false) {
  65. $namespace .= '/' . Inflector::camelize($request->getParam('prefix'));
  66. } else {
  67. $prefixes = array_map(
  68. 'Cake\Utility\Inflector::camelize',
  69. explode('/', $request->getParam('prefix'))
  70. );
  71. $namespace .= '/' . implode('/', $prefixes);
  72. }
  73. }
  74. $firstChar = substr($controller, 0, 1);
  75. // Disallow plugin short forms, / and \\ from
  76. // controller names as they allow direct references to
  77. // be created.
  78. if (strpos($controller, '\\') !== false ||
  79. strpos($controller, '/') !== false ||
  80. strpos($controller, '.') !== false ||
  81. $firstChar === strtolower($firstChar)
  82. ) {
  83. $this->missingController($request);
  84. }
  85. return App::className($pluginPath . $controller, $namespace, 'Controller') ?: null;
  86. }
  87. /**
  88. * Throws an exception when a controller is missing.
  89. *
  90. * @param \Cake\Http\ServerRequest $request The request.
  91. * @throws \Cake\Routing\Exception\MissingControllerException
  92. * @return void
  93. */
  94. protected function missingController($request)
  95. {
  96. throw new MissingControllerException([
  97. 'class' => $request->getParam('controller'),
  98. 'plugin' => $request->getParam('plugin'),
  99. 'prefix' => $request->getParam('prefix'),
  100. '_ext' => $request->getParam('_ext')
  101. ]);
  102. }
  103. }