api de gestion de ticket, basé sur php-crud-api. Le but est de décorrélé les outils de gestion des données, afin
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Api.php 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <?php
  2. namespace Tqdev\PhpCrudApi;
  3. use Psr\Http\Message\ResponseInterface;
  4. use Psr\Http\Message\ServerRequestInterface;
  5. use Psr\Http\Server\RequestHandlerInterface;
  6. use Tqdev\PhpCrudApi\Cache\CacheFactory;
  7. use Tqdev\PhpCrudApi\Column\DefinitionService;
  8. use Tqdev\PhpCrudApi\Column\ReflectionService;
  9. use Tqdev\PhpCrudApi\Controller\CacheController;
  10. use Tqdev\PhpCrudApi\Controller\ColumnController;
  11. use Tqdev\PhpCrudApi\Controller\GeoJsonController;
  12. use Tqdev\PhpCrudApi\Controller\JsonResponder;
  13. use Tqdev\PhpCrudApi\Controller\OpenApiController;
  14. use Tqdev\PhpCrudApi\Controller\RecordController;
  15. use Tqdev\PhpCrudApi\Database\GenericDB;
  16. use Tqdev\PhpCrudApi\GeoJson\GeoJsonService;
  17. use Tqdev\PhpCrudApi\Middleware\AuthorizationMiddleware;
  18. use Tqdev\PhpCrudApi\Middleware\BasicAuthMiddleware;
  19. use Tqdev\PhpCrudApi\Middleware\CorsMiddleware;
  20. use Tqdev\PhpCrudApi\Middleware\CustomizationMiddleware;
  21. use Tqdev\PhpCrudApi\Middleware\DbAuthMiddleware;
  22. use Tqdev\PhpCrudApi\Middleware\FirewallMiddleware;
  23. use Tqdev\PhpCrudApi\Middleware\IpAddressMiddleware;
  24. use Tqdev\PhpCrudApi\Middleware\JoinLimitsMiddleware;
  25. use Tqdev\PhpCrudApi\Middleware\JwtAuthMiddleware;
  26. use Tqdev\PhpCrudApi\Middleware\MultiTenancyMiddleware;
  27. use Tqdev\PhpCrudApi\Middleware\PageLimitsMiddleware;
  28. use Tqdev\PhpCrudApi\Middleware\ReconnectMiddleware;
  29. use Tqdev\PhpCrudApi\Middleware\Router\SimpleRouter;
  30. use Tqdev\PhpCrudApi\Middleware\SanitationMiddleware;
  31. use Tqdev\PhpCrudApi\Middleware\ValidationMiddleware;
  32. use Tqdev\PhpCrudApi\Middleware\XsrfMiddleware;
  33. use Tqdev\PhpCrudApi\OpenApi\OpenApiService;
  34. use Tqdev\PhpCrudApi\Record\ErrorCode;
  35. use Tqdev\PhpCrudApi\Record\RecordService;
  36. use Tqdev\PhpCrudApi\ResponseUtils;
  37. class Api implements RequestHandlerInterface
  38. {
  39. private $router;
  40. private $responder;
  41. private $debug;
  42. public function __construct(Config $config)
  43. {
  44. $db = new GenericDB(
  45. $config->getDriver(),
  46. $config->getAddress(),
  47. $config->getPort(),
  48. $config->getDatabase(),
  49. $config->getUsername(),
  50. $config->getPassword()
  51. );
  52. $prefix = sprintf('phpcrudapi-%s-', substr(md5(__FILE__), 0, 8));
  53. $cache = CacheFactory::create($config->getCacheType(), $prefix, $config->getCachePath());
  54. $reflection = new ReflectionService($db, $cache, $config->getCacheTime());
  55. $responder = new JsonResponder();
  56. $router = new SimpleRouter($config->getBasePath(), $responder, $cache, $config->getCacheTime(), $config->getDebug());
  57. foreach ($config->getMiddlewares() as $middleware => $properties) {
  58. switch ($middleware) {
  59. case 'cors':
  60. new CorsMiddleware($router, $responder, $properties);
  61. break;
  62. case 'firewall':
  63. new FirewallMiddleware($router, $responder, $properties);
  64. break;
  65. case 'basicAuth':
  66. new BasicAuthMiddleware($router, $responder, $properties);
  67. break;
  68. case 'jwtAuth':
  69. new JwtAuthMiddleware($router, $responder, $properties);
  70. break;
  71. case 'dbAuth':
  72. new DbAuthMiddleware($router, $responder, $properties, $reflection, $db);
  73. break;
  74. case 'reconnect':
  75. new ReconnectMiddleware($router, $responder, $properties, $reflection, $db);
  76. break;
  77. case 'validation':
  78. new ValidationMiddleware($router, $responder, $properties, $reflection);
  79. break;
  80. case 'ipAddress':
  81. new IpAddressMiddleware($router, $responder, $properties, $reflection);
  82. break;
  83. case 'sanitation':
  84. new SanitationMiddleware($router, $responder, $properties, $reflection);
  85. break;
  86. case 'multiTenancy':
  87. new MultiTenancyMiddleware($router, $responder, $properties, $reflection);
  88. break;
  89. case 'authorization':
  90. new AuthorizationMiddleware($router, $responder, $properties, $reflection);
  91. break;
  92. case 'xsrf':
  93. new XsrfMiddleware($router, $responder, $properties);
  94. break;
  95. case 'pageLimits':
  96. new PageLimitsMiddleware($router, $responder, $properties, $reflection);
  97. break;
  98. case 'joinLimits':
  99. new JoinLimitsMiddleware($router, $responder, $properties, $reflection);
  100. break;
  101. case 'customization':
  102. new CustomizationMiddleware($router, $responder, $properties, $reflection);
  103. break;
  104. }
  105. }
  106. foreach ($config->getControllers() as $controller) {
  107. switch ($controller) {
  108. case 'records':
  109. $records = new RecordService($db, $reflection);
  110. new RecordController($router, $responder, $records);
  111. break;
  112. case 'columns':
  113. $definition = new DefinitionService($db, $reflection);
  114. new ColumnController($router, $responder, $reflection, $definition);
  115. break;
  116. case 'cache':
  117. new CacheController($router, $responder, $cache);
  118. break;
  119. case 'openapi':
  120. $openApi = new OpenApiService($reflection, $config->getOpenApiBase());
  121. new OpenApiController($router, $responder, $openApi);
  122. break;
  123. case 'geojson':
  124. $records = new RecordService($db, $reflection);
  125. $geoJson = new GeoJsonService($reflection, $records);
  126. new GeoJsonController($router, $responder, $geoJson);
  127. break;
  128. }
  129. }
  130. $this->router = $router;
  131. $this->responder = $responder;
  132. $this->debug = $config->getDebug();
  133. }
  134. private function parseBody(string $body) /*: ?object*/
  135. {
  136. $first = substr($body, 0, 1);
  137. if ($first == '[' || $first == '{') {
  138. $object = json_decode($body);
  139. $causeCode = json_last_error();
  140. if ($causeCode !== JSON_ERROR_NONE) {
  141. $object = null;
  142. }
  143. } else {
  144. parse_str($body, $input);
  145. foreach ($input as $key => $value) {
  146. if (substr($key, -9) == '__is_null') {
  147. $input[substr($key, 0, -9)] = null;
  148. unset($input[$key]);
  149. }
  150. }
  151. $object = (object) $input;
  152. }
  153. return $object;
  154. }
  155. private function addParsedBody(ServerRequestInterface $request): ServerRequestInterface
  156. {
  157. $body = $request->getBody();
  158. if ($body->isReadable() && $body->isSeekable()) {
  159. $contents = $body->getContents();
  160. $body->rewind();
  161. if ($contents) {
  162. $parsedBody = $this->parseBody($contents);
  163. $request = $request->withParsedBody($parsedBody);
  164. }
  165. }
  166. return $request;
  167. }
  168. public function handle(ServerRequestInterface $request): ResponseInterface
  169. {
  170. $response = null;
  171. try {
  172. $response = $this->router->route($this->addParsedBody($request));
  173. } catch (\Throwable $e) {
  174. $response = $this->responder->error(ErrorCode::ERROR_NOT_FOUND, $e->getMessage());
  175. if ($this->debug) {
  176. $response = ResponseUtils::addExceptionHeaders($response, $e);
  177. }
  178. }
  179. return $response;
  180. }
  181. }