Client.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <?php
  2. namespace DNB;
  3. use HaydenPierce\ClassFinder\ClassFinder;
  4. use Symfony\Component\HttpClient\HttpClient;
  5. use Symfony\Contracts\HttpClient\HttpClientInterface;
  6. final class Client {
  7. private HttpClientInterface $client;
  8. private ClientConfig $clientConfig;
  9. private object $auth;
  10. public function __construct(ClientConfig $clientConfig) {
  11. $this->clientConfig = $clientConfig;
  12. $this->client = HttpClient::create(
  13. [
  14. 'headers' => [
  15. 'cache-control' => 'no-cache',
  16. ]
  17. ]
  18. );
  19. $this->auth = $this->authenticate();
  20. }
  21. private function getUrl(string $endpoint, string $path): string {
  22. return sprintf(
  23. 'https://%s.azurewebsites.net/%s', rtrim($endpoint, '/'), ltrim($path, '/')
  24. );
  25. }
  26. public function authenticate(): object {
  27. $request = $this->client->request(
  28. 'POST',
  29. $this->getUrl($this->clientConfig->get()->auth_endpoint, '/connect/token'), [
  30. 'body' => [
  31. 'grant_type' => 'client_credentials',
  32. 'client_id' => $this->clientConfig->get()->id,
  33. 'client_secret' => $this->clientConfig->get()->secret
  34. ]
  35. ]
  36. );
  37. $result = $request->toArray();
  38. return new class (
  39. $result['access_token'],
  40. $result['token_type']
  41. ) {
  42. private string $token;
  43. private string $type;
  44. public function __construct(
  45. string $token,
  46. string $type
  47. ) {
  48. $this->token = $token;
  49. $this->type = $type;
  50. }
  51. public function getHeader(): string {
  52. return sprintf("%s %s", $this->type, $this->token);
  53. }
  54. };
  55. }
  56. private function getAuthClient(): HttpClientInterface {
  57. return $this->client->withOptions([
  58. 'headers' => [
  59. 'Authorization' => $this->auth->getHeader(),
  60. ]
  61. ]);
  62. }
  63. private function findInNamespace(string $ns): ?string {
  64. $classes = array_filter(ClassFinder::getClassesInNamespace(
  65. dirname(str_replace('\\', DIRECTORY_SEPARATOR, self::class))
  66. ), function (string $class) {
  67. return class_implements($class, AbstractPostSerializable::class) && strpos($class, AbstractPostSerializable::class) !== 0;
  68. });
  69. $key = array_search(strtolower($ns), array_map(function (string $class): string {
  70. return $class::namespace();
  71. }, $classes));
  72. return $key ? $classes[$key] : null;
  73. }
  74. public function orderProspectus(
  75. Prospectus $prospectus
  76. ): bool {
  77. $ret = $this->getAuthClient()->request(
  78. "POST",
  79. $this->getUrl($this->clientConfig->get()->endpoint, '/api/v1/autoprospect/orderprospect'), [
  80. 'json' => $prospectus->toPostParams(),
  81. ]
  82. );
  83. try {
  84. $ret->getContent();
  85. return true;
  86. } catch (\Exception $e) {
  87. $content = json_decode($ret->getContent(false), true);
  88. if (json_last_error() == JSON_ERROR_NONE) {
  89. foreach ($content as $key => $value) {
  90. $scope = explode('.', $key);
  91. if (sizeof($scope) <= 1)
  92. continue;
  93. $ns = $this->findInNamespace($scope[0]);
  94. foreach (array_keys($ns::getPostParams()) as $param) {
  95. if (strpos(strtolower($param), strtolower($scope[1])) == strlen($ns::namespace())+1) {
  96. unset($content[$key]);
  97. $content[$param] = $value;
  98. }
  99. }
  100. }
  101. $content = json_encode($content);
  102. } else
  103. $content = $ret->getContent(false);
  104. throw new \InvalidArgumentException($content ? $content : $e->getMessage(), $e->getCode(), $e);
  105. }
  106. return false;
  107. }
  108. }