WebflowApiClient.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. namespace App\Http;
  3. use Psr\Log\LoggerAwareInterface;
  4. use Symfony\Component\Cache\Adapter\FilesystemAdapter;
  5. use Symfony\Component\Cache\Adapter\TraceableAdapter;
  6. use Symfony\Component\HttpClient\HttpClient;
  7. use Symfony\Component\HttpClient\Response\MockResponse;
  8. use Symfony\Contracts\Cache\CacheInterface;
  9. use Symfony\Contracts\Cache\ItemInterface;
  10. use Symfony\Contracts\HttpClient\ResponseInterface;
  11. class WebflowApiClient implements LoggerAwareInterface {
  12. private $client;
  13. private $cache;
  14. private $url;
  15. private $options = [];
  16. public $lastResponse;
  17. public function __construct(CacheInterface $cache, string $token, string $api_url, string $version = '1.0.0') {
  18. $this->url = $api_url;
  19. $this->options = [
  20. 'auth_bearer' => $token,
  21. 'headers' => [
  22. 'accept-version' => $version,
  23. ],
  24. ];
  25. $this->client = HttpClient::createForBaseUri(
  26. sprintf('https://%s', $api_url),
  27. $this->options
  28. );
  29. $this->cache = $cache;
  30. }
  31. public function scopeFromBase(string $scope): string {
  32. return sprintf('https://%s/%s', $this->url, ltrim($scope, '/'));
  33. }
  34. private function scopeId(string $scope_string): string {
  35. return "webflow_api_" . sha1($scope_string);
  36. }
  37. public function post(string $scope, array $data): ResponseInterface {
  38. $data = array_filter($data, function ($in) {
  39. if ($in === false)
  40. return true;
  41. return !empty($in);
  42. });
  43. $resp = $this->client->request('POST', $this->scopeFromBase(
  44. $scope
  45. ), ['json' => [
  46. "fields" => $data
  47. ]]);
  48. $this->lastResponse = $resp->getHeaders();
  49. $this->logger->debug(__METHOD__, [
  50. $resp->getStatusCode(), $resp->toArray(), $data
  51. ]);
  52. return $resp;
  53. }
  54. public function get(string $scope, int $ttl = 1800): ResponseInterface {
  55. $this->logger->debug(__METHOD__, ['ttl' => $ttl, 'scope' => $scope]);
  56. $id = $this->scopeId($scope);
  57. if ($ttl <= 0) {
  58. $resp = $this->client->request('GET',
  59. $this->scopeFromBase($scope),
  60. );
  61. $this->lastResponse = $resp->getHeaders();
  62. if ($resp->getStatusCode() >= 300)
  63. return $resp;
  64. $this->cache->get($id, function(ItemInterface $item) use ($scope, $ttl, $resp) {
  65. $item->set([
  66. 'header' => $resp->getHeaders(),
  67. 'content' => $resp->getContent(),
  68. ]);
  69. $this->cache->save($item);
  70. });
  71. $this->cache->commit();
  72. return $resp;
  73. }
  74. $item = $this->cache->get($id, function (ItemInterface $item) use ($scope, $ttl) {
  75. $item->expiresAfter($ttl);
  76. $response = $this->client->request('GET',
  77. $this->scopeFromBase($scope),
  78. );
  79. $this->lastResponse = $response->getHeaders();
  80. if ($response->getStatusCode() >= 300)
  81. return ['header' => $response->getHeaders(), "content" => $response->getContent()];
  82. $item->set([
  83. 'header' => $response->getHeaders(),
  84. 'content' => $response->getContent(),
  85. ]);
  86. $this->cache->save($item);
  87. return $item->get();
  88. });
  89. $this->cache->commit();
  90. $this->logger->debug(__METHOD__, [$scope, array_keys($item)]);
  91. if (!$item)
  92. return $this->get($scope, -1);
  93. $this->lastResponse = $item['header'];
  94. return MockResponse::fromRequest('GET', $scope, $item['header'], new MockResponse($item['content']));
  95. }
  96. public function setLogger(\Psr\Log\LoggerInterface $logger)
  97. {
  98. $this->logger = $logger;
  99. }
  100. }
  101. ?>