1: <?php
2:
3: namespace SellerLabs\Snagshout;
4:
5: use Closure;
6: use DateTime;
7: use GuzzleHttp\Client as HttpClient;
8: use Http\Adapter\Guzzle6\Client as GuzzleAdapter;
9: use GuzzleHttp\Handler\CurlHandler;
10: use GuzzleHttp\HandlerStack;
11: use GuzzleHttp\Psr7\Uri;
12: use Http\Message\MessageFactory\GuzzleMessageFactory;
13: use Joli\Jane\Runtime\Encoder\RawEncoder;
14: use Psr\Http\Message\RequestInterface;
15: use SellerLabs\Snagshout\Resource\CampaignResource;
16: use SellerLabs\Snagshout\Resource\CategoryResource;
17: use SellerLabs\Snagshout\Resource\FrontResource;
18: use SellerLabs\Snagshout\Utils\NormalizerFactory;
19: use SellerLabs\Snagshout\Resource\DefaultResource;
20: use Symfony\Component\Serializer\Encoder\JsonDecode;
21: use Symfony\Component\Serializer\Encoder\JsonEncode;
22: use Symfony\Component\Serializer\Encoder\JsonEncoder;
23: use Symfony\Component\Serializer\Serializer;
24:
25: 26: 27: 28: 29: 30: 31:
32: class Client
33: {
34: 35: 36:
37: protected $publicId;
38:
39: 40: 41:
42: protected $secretKey;
43:
44: 45: 46:
47: protected $endpoint;
48:
49: 50: 51: 52: 53: 54:
55: public function __construct($publicId, $secretKey)
56: {
57: $this->publicId = $publicId;
58: $this->secretKey = $secretKey;
59:
60: $this->endpoint = new Uri('https://www.snagshout.com');
61:
62: $stack = new HandlerStack();
63:
64: $stack->setHandler(new CurlHandler());
65:
66: $stack->push($this->makeAuthHandler());
67:
68: $this->client = new HttpClient([
69: 'handler' => $stack,
70: ]);
71: }
72:
73: 74: 75:
76: public function setPublicId(string $publicId)
77: {
78: $this->publicId = $publicId;
79: }
80:
81: 82: 83:
84: public function setSecretKey(string $secretKey)
85: {
86: $this->secretKey = $secretKey;
87: }
88:
89: 90: 91:
92: public function setEndpoint(Uri $endpoint)
93: {
94: $this->endpoint = $endpoint;
95: }
96:
97: 98: 99: 100: 101: 102: 103:
104: protected function hash($content)
105: {
106: $timestamp = (new DateTime())->format('Y-m-d H');
107:
108: return hash_hmac(
109: 'sha512',
110: $content . $timestamp,
111: $this->secretKey
112: );
113: }
114:
115: 116: 117: 118: 119: 120:
121: protected function makeAuthHandler()
122: {
123: return function (callable $handler) {
124: return function (
125: RequestInterface $request,
126: array $options
127: ) use ($handler) {
128: $contentHash = $this->hash($request->getBody());
129:
130: $partialUri = $request->getUri();
131: $uri = $this->endpoint
132: ->withPath(
133: $this->endpoint->getPath()
134: . $partialUri->getPath()
135: )
136: ->withQuery($partialUri->getQuery())
137: ->withFragment($partialUri->getFragment());
138:
139: $request = $request
140: ->withUri($uri)
141: ->withHeader(
142: 'Authorization',
143: vsprintf('Hash %s', [$this->publicId])
144: )
145: ->withHeader('Content-Hash', $contentHash);
146:
147: return $handler($request, $options);
148: };
149: };
150: }
151:
152: 153: 154: 155: 156: 157: 158:
159: protected function buildResource($resourceClass)
160: {
161: return new $resourceClass(
162: new GuzzleAdapter($this->client),
163: new GuzzleMessageFactory(),
164: new Serializer(
165: NormalizerFactory::create(),
166: [
167: new JsonEncoder(
168: new JsonEncode(),
169: new JsonDecode()
170: ),
171: new RawEncoder()
172: ]
173: )
174: );
175: }
176:
177: 178: 179: 180: 181:
182: public function campaign()
183: {
184: return $this->buildResource(CampaignResource::class);
185: }
186:
187: 188: 189: 190: 191:
192: public function category()
193: {
194: return $this->buildResource(CategoryResource::class);
195: }
196:
197: 198: 199: 200: 201:
202: public function front()
203: {
204: return $this->buildResource(FrontResource::class);
205: }
206: }