RequestActionTrait.php 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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. * Redistributions of files must retain the above copyright notice.
  8. *
  9. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  10. * @link https://cakephp.org CakePHP(tm) Project
  11. * @since 3.0.0
  12. * @license https://opensource.org/licenses/mit-license.php MIT License
  13. */
  14. namespace Cake\Routing;
  15. use Cake\Core\Configure;
  16. use Cake\Http\Response;
  17. use Cake\Http\ServerRequest;
  18. use Cake\Network\Session;
  19. use Cake\Routing\Filter\ControllerFactoryFilter;
  20. use Cake\Routing\Filter\RoutingFilter;
  21. /**
  22. * Provides the requestAction() method for doing sub-requests
  23. *
  24. * @deprecated 3.3.0 Use view cells instead.
  25. */
  26. trait RequestActionTrait
  27. {
  28. /**
  29. * Calls a controller's method from any location. Can be used to connect controllers together
  30. * or tie plugins into a main application. requestAction can be used to return rendered views
  31. * or fetch the return value from controller actions.
  32. *
  33. * Under the hood this method uses Router::reverse() to convert the $url parameter into a string
  34. * URL. You should use URL formats that are compatible with Router::reverse()
  35. *
  36. * ### Examples
  37. *
  38. * A basic example getting the return value of the controller action:
  39. *
  40. * ```
  41. * $variables = $this->requestAction('/articles/popular');
  42. * ```
  43. *
  44. * A basic example of request action to fetch a rendered page without the layout.
  45. *
  46. * ```
  47. * $viewHtml = $this->requestAction('/articles/popular', ['return']);
  48. * ```
  49. *
  50. * You can also pass the URL as an array:
  51. *
  52. * ```
  53. * $vars = $this->requestAction(['controller' => 'articles', 'action' => 'popular']);
  54. * ```
  55. *
  56. * ### Passing other request data
  57. *
  58. * You can pass POST, GET, COOKIE and other data into the request using the appropriate keys.
  59. * Cookies can be passed using the `cookies` key. Get parameters can be set with `query` and post
  60. * data can be sent using the `post` key.
  61. *
  62. * ```
  63. * $vars = $this->requestAction('/articles/popular', [
  64. * 'query' => ['page' => 1],
  65. * 'cookies' => ['remember_me' => 1],
  66. * ]);
  67. * ```
  68. *
  69. * ### Sending environment or header values
  70. *
  71. * By default actions dispatched with this method will use the global $_SERVER and $_ENV
  72. * values. If you want to override those values for a request action, you can specify the values:
  73. *
  74. * ```
  75. * $vars = $this->requestAction('/articles/popular', [
  76. * 'environment' => ['CONTENT_TYPE' => 'application/json']
  77. * ]);
  78. * ```
  79. *
  80. * ### Transmitting the session
  81. *
  82. * By default actions dispatched with this method will use the standard session object.
  83. * If you want a particular session instance to be used, you need to specify it.
  84. *
  85. * ```
  86. * $vars = $this->requestAction('/articles/popular', [
  87. * 'session' => new Session($someSessionConfig)
  88. * ]);
  89. * ```
  90. *
  91. * @param string|array $url String or array-based url. Unlike other url arrays in CakePHP, this
  92. * url will not automatically handle passed arguments in the $url parameter.
  93. * @param array $extra if array includes the key "return" it sets the autoRender to true. Can
  94. * also be used to submit GET/POST data, and passed arguments.
  95. * @return mixed Boolean true or false on success/failure, or contents
  96. * of rendered action if 'return' is set in $extra.
  97. * @deprecated 3.3.0 You should refactor your code to use View Cells instead of this method.
  98. */
  99. public function requestAction($url, array $extra = [])
  100. {
  101. deprecationWarning(
  102. 'RequestActionTrait::requestAction() is deprecated. ' .
  103. 'You should refactor to use View Cells or Components instead.'
  104. );
  105. if (empty($url)) {
  106. return false;
  107. }
  108. if (($index = array_search('return', $extra)) !== false) {
  109. $extra['return'] = 0;
  110. $extra['autoRender'] = 1;
  111. unset($extra[$index]);
  112. }
  113. $extra += ['autoRender' => 0, 'return' => 1, 'bare' => 1, 'requested' => 1];
  114. $baseUrl = Configure::read('App.fullBaseUrl');
  115. if (is_string($url) && strpos($url, $baseUrl) === 0) {
  116. $url = Router::normalize(str_replace($baseUrl, '', $url));
  117. }
  118. if (is_string($url)) {
  119. $params = [
  120. 'url' => $url
  121. ];
  122. } elseif (is_array($url)) {
  123. $defaultParams = ['plugin' => null, 'controller' => null, 'action' => null];
  124. $params = [
  125. 'params' => $url + $defaultParams,
  126. 'base' => false,
  127. 'url' => Router::reverse($url)
  128. ];
  129. if (empty($params['params']['pass'])) {
  130. $params['params']['pass'] = [];
  131. }
  132. }
  133. $current = Router::getRequest();
  134. if ($current) {
  135. $params['base'] = $current->base;
  136. $params['webroot'] = $current->webroot;
  137. }
  138. $params['post'] = $params['query'] = [];
  139. if (isset($extra['post'])) {
  140. $params['post'] = $extra['post'];
  141. }
  142. if (isset($extra['query'])) {
  143. $params['query'] = $extra['query'];
  144. }
  145. if (isset($extra['cookies'])) {
  146. $params['cookies'] = $extra['cookies'];
  147. }
  148. if (isset($extra['environment'])) {
  149. $params['environment'] = $extra['environment'] + $_SERVER + $_ENV;
  150. }
  151. unset($extra['environment'], $extra['post'], $extra['query']);
  152. $params['session'] = isset($extra['session']) ? $extra['session'] : new Session();
  153. $request = new ServerRequest($params);
  154. $request->addParams($extra);
  155. $dispatcher = DispatcherFactory::create();
  156. // If an application is using PSR7 middleware,
  157. // we need to 'fix' their missing dispatcher filters.
  158. $needed = [
  159. 'routing' => RoutingFilter::class,
  160. 'controller' => ControllerFactoryFilter::class
  161. ];
  162. foreach ($dispatcher->filters() as $filter) {
  163. if ($filter instanceof RoutingFilter) {
  164. unset($needed['routing']);
  165. }
  166. if ($filter instanceof ControllerFactoryFilter) {
  167. unset($needed['controller']);
  168. }
  169. }
  170. foreach ($needed as $class) {
  171. $dispatcher->addFilter(new $class);
  172. }
  173. $result = $dispatcher->dispatch($request, new Response());
  174. Router::popRequest();
  175. return $result;
  176. }
  177. }