Overview

Namespaces

  • SellerLabs
    • Snagshout
      • Model
      • Normalizer
      • Resource
      • Utils

Classes

  • SellerLabs\Snagshout\Client
  • SellerLabs\Snagshout\Model\AmazonData
  • SellerLabs\Snagshout\Model\Attribute
  • SellerLabs\Snagshout\Model\BookmarkMetadata
  • SellerLabs\Snagshout\Model\Campaign
  • SellerLabs\Snagshout\Model\Category
  • SellerLabs\Snagshout\Model\Image
  • SellerLabs\Snagshout\Model\ImageMetadata
  • SellerLabs\Snagshout\Model\Links
  • SellerLabs\Snagshout\Model\Product
  • SellerLabs\Snagshout\Model\PromoCode
  • SellerLabs\Snagshout\Model\Promotion
  • SellerLabs\Snagshout\Model\Shipping
  • SellerLabs\Snagshout\Model\V1GetCampaignsResponse
  • SellerLabs\Snagshout\Model\V1GetCategoriesResponse
  • SellerLabs\Snagshout\Model\V1GetStatus
  • SellerLabs\Snagshout\Model\V1GetStatusResponse
  • SellerLabs\Snagshout\Normalizer\AmazonDataNormalizer
  • SellerLabs\Snagshout\Normalizer\AttributeNormalizer
  • SellerLabs\Snagshout\Normalizer\BookmarkMetadataNormalizer
  • SellerLabs\Snagshout\Normalizer\CampaignNormalizer
  • SellerLabs\Snagshout\Normalizer\CategoryNormalizer
  • SellerLabs\Snagshout\Normalizer\ImageMetadataNormalizer
  • SellerLabs\Snagshout\Normalizer\ImageNormalizer
  • SellerLabs\Snagshout\Normalizer\LinksNormalizer
  • SellerLabs\Snagshout\Normalizer\NormalizerFactory
  • SellerLabs\Snagshout\Normalizer\ProductNormalizer
  • SellerLabs\Snagshout\Normalizer\PromoCodeNormalizer
  • SellerLabs\Snagshout\Normalizer\PromotionNormalizer
  • SellerLabs\Snagshout\Normalizer\ShippingNormalizer
  • SellerLabs\Snagshout\Normalizer\V1GetCampaignsResponseNormalizer
  • SellerLabs\Snagshout\Normalizer\V1GetCategoriesResponseNormalizer
  • SellerLabs\Snagshout\Normalizer\V1GetStatusNormalizer
  • SellerLabs\Snagshout\Normalizer\V1GetStatusResponseNormalizer
  • SellerLabs\Snagshout\Resource\CampaignResource
  • SellerLabs\Snagshout\Resource\CategoryResource
  • SellerLabs\Snagshout\Resource\FrontResource
  • SellerLabs\Snagshout\SyndicationClient
  • SellerLabs\Snagshout\Utils\NormalizerFactory
  • SellerLabs\Snagshout\Utils\NullNormalizer
  • Overview
  • Namespace
  • Class
  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:  * Class Client
 27:  *
 28:  * @package SellerLabs\Snagshout
 29:  *
 30:  * @author Eduardo Trujillo <ed@sellerlabs.com>
 31:  */
 32: class Client
 33: {
 34:     /**
 35:      * @var string
 36:      */
 37:     protected $publicId;
 38: 
 39:     /**
 40:      * @var string
 41:      */
 42:     protected $secretKey;
 43: 
 44:     /**
 45:      * @var Uri
 46:      */
 47:     protected $endpoint;
 48: 
 49:     /**
 50:      * SyndicationClient constructor.
 51:      *
 52:      * @param string $publicId
 53:      * @param string $secretKey
 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:      * @param string $publicId
 75:      */
 76:     public function setPublicId(string $publicId)
 77:     {
 78:         $this->publicId = $publicId;
 79:     }
 80: 
 81:     /**
 82:      * @param string $secretKey
 83:      */
 84:     public function setSecretKey(string $secretKey)
 85:     {
 86:         $this->secretKey = $secretKey;
 87:     }
 88: 
 89:     /**
 90:      * @param Uri $endpoint
 91:      */
 92:     public function setEndpoint(Uri $endpoint)
 93:     {
 94:         $this->endpoint = $endpoint;
 95:     }
 96: 
 97:     /**
 98:      * Computes the hash of a string using the secret key.
 99:      *
100:      * @param string $content
101:      *
102:      * @return string
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:      * A Guzzle middleware that automatically adds the required Authorization
117:      * and Content-Hash headers required by the Snagshout API.
118:      *
119:      * @return Closure
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:      * A wrapper for constructing instances of resource classes.
154:      *
155:      * @param string $resourceClass
156:      *
157:      * @return Resource
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:      * Builds an instance of the Campaign resource.
179:      *
180:      * @return CampaignResource
181:      */
182:     public function campaign()
183:     {
184:         return $this->buildResource(CampaignResource::class);
185:     }
186: 
187:     /**
188:      * Builds an instance of the Campaign resource.
189:      *
190:      * @return CategoryResource
191:      */
192:     public function category()
193:     {
194:         return $this->buildResource(CategoryResource::class);
195:     }
196: 
197:     /**
198:      * Builds an instance of the Front resource.
199:      *
200:      * @return FrontResource
201:      */
202:     public function front()
203:     {
204:         return $this->buildResource(FrontResource::class);
205:     }
206: }
API documentation generated by ApiGen