Skip to content

Commit 5af4754

Browse files
committed
Base package skeleton
0 parents  commit 5af4754

33 files changed

Lines changed: 1628 additions & 0 deletions

.gitattributes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/tests export-ignore
2+
/.gitattributes export-ignore
3+
/.gitignore export-ignore
4+
/phpunit.xml export-ignore

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/.idea
2+
/vendor
3+
/composer.lock
4+
.DS_Store

README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<h1 align="center">SendCloud API client for PHP</h1>
2+
3+
<img src="https://i.imgur.com/kEZU7HH.png" />
4+
5+
## Installation
6+
7+
```
8+
$ composer require imbue/sendcloud-api-php:^0.1
9+
10+
{
11+
"require": {
12+
"imbue/sendcloud-api-php": "^0.1"
13+
}
14+
}
15+
```
16+
17+
## Getting started
18+
19+
Initialize the SendCloud API client
20+
21+
```php
22+
$sendCloud = new \Imbue\SendCloud\SendCloudApiClient();
23+
$sendCloud->setApiAuth('gb3iogpp8uf74p92holav67ij7jmpswe', '1m9mtv4ylnd8fy0xb61ury81pt6xp3fh');
24+
```
25+
26+
Creating a new parcel
27+
28+
```php
29+
$payment = $sendcloud->parcels->create([
30+
'name' => 'Julie Appleseed',
31+
'company_name' => 'SendCloud',
32+
'address' => 'Insulindelaan 115',
33+
'house_number' => 115,
34+
'city' => 'Eindhoven',
35+
'postal_code' => '5642CV',
36+
'telephone' => '+31612345678',
37+
'request_label' => true,
38+
'email' => 'julie@appleseed.com',
39+
'country' => 'NL',
40+
'shipment' => [
41+
'id' => 8,
42+
],
43+
'weight' => '10.000',
44+
'order_number' => '1234567890',
45+
'insured_value' => 2000,
46+
]);
47+
```

composer.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "imbue/sendcloud-api-php",
3+
"description": "SendCloud API client library for PHP. SendCloud is a European shipping software for e-commerce.",
4+
"keywords": [
5+
"sendcloud",
6+
"php",
7+
"shipping",
8+
"shipping software"
9+
],
10+
"license": "MIT",
11+
"homepage": "https://github.com/imbue/sendcloud-api-php",
12+
"authors": [
13+
{
14+
"name": "Liam Boer",
15+
"email": "liam.boer@outlook.com"
16+
}
17+
],
18+
"require": {
19+
"php": "^7.2",
20+
"guzzlehttp/guzzle": "^6.3"
21+
},
22+
"require-dev": {
23+
"phpunit/phpunit": "^5.7 || ^6.5 || ^7.1"
24+
},
25+
"config": {
26+
"sort-packages": true
27+
},
28+
"autoload": {
29+
"psr-4": {
30+
"Imbue\\SendCloud\\": "src/"
31+
}
32+
},
33+
"autoload-dev": {
34+
"psr-4": {
35+
"Tests\\": "tests"
36+
}
37+
}
38+
}

src/Endpoints/AbstractEndpoint.php

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
<?php
2+
3+
namespace Imbue\SendCloud\Endpoints;
4+
5+
use Imbue\SendCloud\Exceptions\ApiException;
6+
use Imbue\SendCloud\Resources\AbstractResource;
7+
use Imbue\SendCloud\Resources\Collections\AbstractCollection;
8+
use Imbue\SendCloud\Resources\ResourceFactory;
9+
use Imbue\SendCloud\SendCloudApiClient;
10+
use InvalidArgumentException;
11+
12+
abstract class AbstractEndpoint
13+
{
14+
protected const REST_READ = SendCloudApiClient::HTTP_GET;
15+
protected const REST_LIST = SendCloudApiClient::HTTP_GET;
16+
protected const REST_CREATE = SendCloudApiClient::HTTP_POST;
17+
protected const REST_UPDATE = SendCloudApiClient::HTTP_PATCH;
18+
protected const REST_DELETE = SendCloudApiClient::HTTP_DELETE;
19+
20+
/** @var SendCloudApiClient */
21+
protected $client;
22+
/** @var string */
23+
protected $resourcePath;
24+
/** @var string */
25+
protected $parentId;
26+
27+
/**
28+
* AbstractEndpoint constructor.
29+
* @param SendCloudApiClient $client
30+
*/
31+
public function __construct(SendCloudApiClient $client)
32+
{
33+
$this->client = $client;
34+
}
35+
36+
/**
37+
* @param array $filters
38+
* @return string
39+
*/
40+
protected function buildQueryString(array $filters)
41+
{
42+
if (empty($filters)) {
43+
return '';
44+
}
45+
46+
foreach ($filters as $key => $value) {
47+
if ($value === true) {
48+
$filters[$key] = 'true';
49+
}
50+
if ($value === false) {
51+
$filters[$key] = 'false';
52+
}
53+
}
54+
55+
return '?' . http_build_query($filters, '', '&');
56+
}
57+
58+
/**
59+
* @param array $body
60+
* @return AbstractResource
61+
* @throws ApiException
62+
*/
63+
protected function restCreate(array $body)
64+
{
65+
$result = $this->client->performHttpCall(
66+
self::REST_CREATE,
67+
$this->getResourcePath(),
68+
$this->parseRequestBody($body)
69+
);
70+
71+
return ResourceFactory::createFromApiResult($result, $this->getResourceObject());
72+
}
73+
74+
/**
75+
* @param $id
76+
* @param array $filters
77+
* @return AbstractResource
78+
* @throws ApiException
79+
*/
80+
protected function restRead($id, array $filters)
81+
{
82+
if (empty($id)) {
83+
throw new ApiException('Invalid resource id.');
84+
}
85+
86+
$id = urlencode($id);
87+
88+
$result = $this->client->performHttpCall(
89+
self::REST_READ,
90+
"{$this->getResourcePath()}/{$id}" . $this->buildQueryString($filters)
91+
);
92+
93+
return ResourceFactory::createFromApiResult($result, $this->getResourceObject());
94+
}
95+
96+
/**
97+
* @param $id
98+
* @param array $body
99+
* @return AbstractResource|null
100+
* @throws ApiException
101+
*/
102+
protected function restDelete($id, array $body = [])
103+
{
104+
if (empty($id)) {
105+
throw new ApiException('Invalid resource id.');
106+
}
107+
108+
$id = urlencode($id);
109+
110+
$result = $this->client->performHttpCall(
111+
self::REST_DELETE,
112+
"{$this->getResourcePath()}/{$id}",
113+
$this->parseRequestBody($body)
114+
);
115+
116+
if ($result === null) {
117+
return null;
118+
}
119+
120+
return ResourceFactory::createFromApiResult($result, $this->getResourceObject());
121+
}
122+
123+
/**
124+
* @param array $filters
125+
* @return array|AbstractCollection
126+
* @throws ApiException
127+
*/
128+
protected function restList(array $filters = [])
129+
{
130+
$apiPath = $this->getResourcePath();
131+
132+
if (count($filters)) {
133+
$apiPath .= $this->buildQueryString($filters);
134+
}
135+
136+
$result = $this->client->performHttpCall(self::REST_LIST, $apiPath);
137+
138+
$collection = null;
139+
140+
if (is_object($result)) {
141+
$previous = null;
142+
$next = null;
143+
144+
if (isset($result->previous)) {
145+
$previous = $result->previous;
146+
}
147+
148+
if (isset($result->next)) {
149+
$next = $result->next;
150+
}
151+
152+
/** @var AbstractCollection $collection */
153+
$collection = $this->getResourceCollectionObject(
154+
$previous,
155+
$next
156+
);
157+
158+
foreach ($result->{$collection->getCollectionResourceName()} as $dataResult) {
159+
$collection[] = ResourceFactory::createFromApiResult($dataResult, $this->getResourceObject());
160+
}
161+
} else {
162+
foreach ($result as $dataResult) {
163+
$collection[] = ResourceFactory::createFromApiResult($dataResult, $this->getResourceObject());
164+
}
165+
}
166+
167+
return $collection;
168+
}
169+
170+
/**
171+
* @return mixed
172+
*/
173+
abstract protected function getResourceObject();
174+
175+
/**
176+
* @param string $resourcePath
177+
*/
178+
public function setResourcePath($resourcePath)
179+
{
180+
$this->resourcePath = strtolower($resourcePath);
181+
}
182+
183+
/**
184+
* @return string
185+
* @throws ApiException
186+
*/
187+
public function getResourcePath()
188+
{
189+
if (strpos($this->resourcePath, '/{}/') !== false) {
190+
list($parentResource, $childResource) = explode('/{}/', $this->resourcePath, 2);
191+
if (empty($this->parentId)) {
192+
throw new ApiException("Subresource '{$this->resourcePath}' used without parent '$parentResource' ID.");
193+
}
194+
return "$parentResource/{$this->parentId}/$childResource";
195+
}
196+
return $this->resourcePath;
197+
}
198+
199+
/**
200+
* @param array $body
201+
* @return null|string
202+
* @throws ApiException
203+
*/
204+
protected function parseRequestBody(array $body)
205+
{
206+
if (empty($body)) {
207+
return null;
208+
}
209+
try {
210+
$encoded = json_encode($body);
211+
} catch (InvalidArgumentException $e) {
212+
throw new ApiException("Error encoding parameters into JSON: '" . $e->getMessage() . "'");
213+
}
214+
215+
return $encoded;
216+
}
217+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Imbue\SendCloud\Endpoints;
4+
5+
use Imbue\SendCloud\Exceptions\ApiException;
6+
use Imbue\SendCloud\Resources\Collections\AbstractCollection;
7+
use Imbue\SendCloud\Resources\Integration;
8+
9+
class IntegrationEndpoint extends AbstractEndpoint
10+
{
11+
/** @var string */
12+
protected $resourcePath = 'integrations';
13+
14+
/**
15+
* @return Integration
16+
*/
17+
protected function getResourceObject(): Integration
18+
{
19+
return new Integration($this->client);
20+
}
21+
22+
/**
23+
* @return array|AbstractCollection
24+
* @throws ApiException
25+
*/
26+
public function list()
27+
{
28+
return $this->restList();
29+
}
30+
}

0 commit comments

Comments
 (0)