Controller.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OCP\AppFramework;
  8. use OCP\AppFramework\Http\DataResponse;
  9. use OCP\AppFramework\Http\JSONResponse;
  10. use OCP\AppFramework\Http\Response;
  11. use OCP\IRequest;
  12. /**
  13. * Base class to inherit your controllers from
  14. * @since 6.0.0
  15. */
  16. abstract class Controller {
  17. /**
  18. * app name
  19. * @var string
  20. * @since 7.0.0
  21. */
  22. protected $appName;
  23. /**
  24. * current request
  25. * @var \OCP\IRequest
  26. * @since 6.0.0
  27. */
  28. protected $request;
  29. /**
  30. * @var array
  31. * @since 7.0.0
  32. */
  33. private $responders;
  34. /**
  35. * constructor of the controller
  36. * @param string $appName the name of the app
  37. * @param IRequest $request an instance of the request
  38. * @since 6.0.0 - parameter $appName was added in 7.0.0 - parameter $app was removed in 7.0.0
  39. */
  40. public function __construct($appName,
  41. IRequest $request) {
  42. $this->appName = $appName;
  43. $this->request = $request;
  44. // default responders
  45. $this->responders = [
  46. 'json' => function ($data) {
  47. if ($data instanceof DataResponse) {
  48. $response = new JSONResponse(
  49. $data->getData(),
  50. $data->getStatus()
  51. );
  52. $dataHeaders = $data->getHeaders();
  53. $headers = $response->getHeaders();
  54. // do not overwrite Content-Type if it already exists
  55. if (isset($dataHeaders['Content-Type'])) {
  56. unset($headers['Content-Type']);
  57. }
  58. $response->setHeaders(array_merge($dataHeaders, $headers));
  59. if ($data->getETag() !== null) {
  60. $response->setETag($data->getETag());
  61. }
  62. if ($data->getLastModified() !== null) {
  63. $response->setLastModified($data->getLastModified());
  64. }
  65. if ($data->isThrottled()) {
  66. $response->throttle($data->getThrottleMetadata());
  67. }
  68. return $response;
  69. }
  70. return new JSONResponse($data);
  71. }
  72. ];
  73. }
  74. /**
  75. * Parses an HTTP accept header and returns the supported responder type
  76. * @param string $acceptHeader
  77. * @param string $default
  78. * @return string the responder type
  79. * @since 7.0.0
  80. * @since 9.1.0 Added default parameter
  81. */
  82. public function getResponderByHTTPHeader($acceptHeader, $default = 'json') {
  83. $headers = explode(',', $acceptHeader);
  84. // return the first matching responder
  85. foreach ($headers as $header) {
  86. $header = strtolower(trim($header));
  87. $responder = str_replace('application/', '', $header);
  88. if (array_key_exists($responder, $this->responders)) {
  89. return $responder;
  90. }
  91. }
  92. // no matching header return default
  93. return $default;
  94. }
  95. /**
  96. * Registers a formatter for a type
  97. * @param string $format
  98. * @param \Closure $responder
  99. * @since 7.0.0
  100. */
  101. protected function registerResponder($format, \Closure $responder) {
  102. $this->responders[$format] = $responder;
  103. }
  104. /**
  105. * Serializes and formats a response
  106. * @param mixed $response the value that was returned from a controller and
  107. * is not a Response instance
  108. * @param string $format the format for which a formatter has been registered
  109. * @throws \DomainException if format does not match a registered formatter
  110. * @return Response
  111. * @since 7.0.0
  112. */
  113. public function buildResponse($response, $format = 'json') {
  114. if (array_key_exists($format, $this->responders)) {
  115. $responder = $this->responders[$format];
  116. return $responder($response);
  117. }
  118. throw new \DomainException('No responder registered for format ' .
  119. $format . '!');
  120. }
  121. }