Skip to content

Commit 3920628

Browse files
committed
add capability to offload images to optimole
1 parent dda54f4 commit 3920628

24 files changed

+1426
-7
lines changed

README.md

+37-3
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,29 @@ $ composer require codeinwp/optimole-sdk
1818

1919
## Usage
2020

21-
To begin, you need to create an account on [Optimole][1] and get your API key. You can then initialize the SDK with your
22-
API key using the `Optimole` facade:
21+
To begin, you need to create an account on [Optimole][1] and get your API key.
22+
23+
### Initializing the SDK
24+
25+
You can then initialize the SDK with your API key using the `Optimole` facade:
2326

2427
```php
2528
use Optimole\Sdk\Optimole;
2629

27-
Optimole::init('your-api-key');
30+
Optimole::init('your-api-key', $options);
2831
```
2932

33+
The second argument of the `init` method is optional. It allows you to pass options to the SDK that can be used to
34+
configure it. These options are:
35+
36+
* `base_domain`: The base domain to connect to Optimole's API. Default is `i.optimole.com`.
37+
* `cache_buster`: A string value that will be appended to the URL of the optimized assets to bust Optimole's cache.
38+
* `dashboard_api_url`: The URL of the dashboard API. Default is `https://dashboard.optimole.com/api`.
39+
* `upload_api_credentials`: An array with the credentials to use for the upload API. The array should contain the keys `userKey` and `secret`. The default is empty and the SDK will use the API key provided in the `init` method to fetch them from the dashboard API.
40+
* `upload_api_url`: The URL of the upload API. Default is `https://generateurls-prod.i.optimole.com/upload`.
41+
42+
### Optimizing Images and Assets
43+
3044
The `Optimole` facade is your starting point for creating optimized images or other assets. You can control the optimization
3145
properties using the fluent interface provided by the SDK. Here's an example of how to optimize an image by changing its
3246
quality and cropping it:
@@ -44,6 +58,26 @@ echo $image->getUrl();
4458
echo (string) $image;
4559
```
4660

61+
### Offloading Images to Optimole
62+
63+
The SDK also provides a way to offload images to Optimole. This is useful when you want to serve images from Optimole's
64+
content delivery network. Here's an example of how to offload an image:
65+
66+
```php
67+
use Optimole\Sdk\Optimole;
68+
69+
$imageId = Optimole::offload()->uploadImage('path/to/image.jpg', 'https://url/to/image.jpg');
70+
```
71+
72+
This will upload the image to Optimole and return the image ID. You can then use this image ID to interact with the
73+
image. For example, you can get the URL of the offloaded image:
74+
75+
```php
76+
use Optimole\Sdk\Optimole;
77+
78+
$imageUrl = Optimole::offload()->getImageUrl($imageId);
79+
```
80+
4781
## Contributing
4882

4983
Install dependencies using composer and run the test suite:

composer.json

+9-1
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,20 @@
1616
},
1717
"require": {
1818
"php": ">=7.4",
19+
"ext-json": "*",
1920
"symfony/polyfill-php80": "^1.29"
2021
},
2122
"require-dev": {
2223
"friendsofphp/php-cs-fixer": "^3.0",
24+
"guzzlehttp/guzzle": "^7.0",
25+
"php-mock/php-mock-phpunit": "^2.10",
26+
"php-stubs/wordpress-stubs": "^6.5",
2327
"phpstan/phpstan": "^1.0",
24-
"phpunit/phpunit": "^9.6"
28+
"phpunit/phpunit": "^9.6",
29+
"szepeviktor/phpstan-wordpress": "^1.3"
30+
},
31+
"suggest": {
32+
"guzzlehttp/guzzle": "Use the Guzzle HTTP client to make requests to the API"
2533
},
2634
"config": {
2735
"optimize-autoloader": true,

phpstan.neon

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
includes:
2+
- ./vendor/szepeviktor/phpstan-wordpress/extension.neon
13
parameters:
24
level: 5
35
paths:

phpunit.xml.dist

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit bootstrap="vendor/autoload.php"
2+
<phpunit bootstrap="tests/bootstrap.php"
33
backupGlobals="false"
44
backupStaticAttributes="false"
55
colors="true"
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of Optimole PHP SDK.
7+
*
8+
* (c) Optimole Team <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Optimole\Sdk\Exception;
15+
16+
class BadResponseException extends RuntimeException
17+
{
18+
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of Optimole PHP SDK.
7+
*
8+
* (c) Optimole Team <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Optimole\Sdk\Exception;
15+
16+
class DashboardApiException extends BadResponseException
17+
{
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of Optimole PHP SDK.
7+
*
8+
* (c) Optimole Team <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Optimole\Sdk\Exception;
15+
16+
class InvalidDashboardApiResponseException extends DashboardApiException
17+
{
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of Optimole PHP SDK.
7+
*
8+
* (c) Optimole Team <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Optimole\Sdk\Exception;
15+
16+
class InvalidUploadApiResponseException extends UploadApiException
17+
{
18+
}

src/Exception/UploadApiException.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of Optimole PHP SDK.
7+
*
8+
* (c) Optimole Team <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Optimole\Sdk\Exception;
15+
16+
class UploadApiException extends BadResponseException
17+
{
18+
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of Optimole PHP SDK.
7+
*
8+
* (c) Optimole Team <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Optimole\Sdk\Exception;
15+
16+
class UploadFailedException extends RuntimeException
17+
{
18+
}
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of Optimole PHP SDK.
7+
*
8+
* (c) Optimole Team <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Optimole\Sdk\Exception;
15+
16+
use Optimole\Sdk\ValueObject\OffloadUsage;
17+
18+
class UploadLimitException extends UploadApiException
19+
{
20+
/**
21+
* The offload service usage.
22+
*/
23+
private OffloadUsage $usage;
24+
25+
/**
26+
* Constructor.
27+
*/
28+
public function __construct(OffloadUsage $usage, string $message = '', int $code = 0, ?\Throwable $previous = null)
29+
{
30+
parent::__construct($message, $code, $previous);
31+
32+
$this->usage = $usage;
33+
}
34+
35+
/**
36+
* Get the offload service usage.
37+
*/
38+
public function getUsage(): OffloadUsage
39+
{
40+
return $this->usage;
41+
}
42+
}

src/Http/ClientInterface.php

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of Optimole PHP SDK.
7+
*
8+
* (c) Optimole Team <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Optimole\Sdk\Http;
15+
16+
interface ClientInterface
17+
{
18+
/**
19+
* Sends an HTTP request and returns the JSON decoded body.
20+
*/
21+
public function sendRequest(string $method, string $url, $body = null, array $headers = []): ?array;
22+
}

src/Http/GuzzleClient.php

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of Optimole PHP SDK.
7+
*
8+
* (c) Optimole Team <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Optimole\Sdk\Http;
15+
16+
use GuzzleHttp\ClientInterface as GuzzleClientInterface;
17+
use GuzzleHttp\Exception\BadResponseException as GuzzleBadResponseException;
18+
use GuzzleHttp\Exception\GuzzleException;
19+
use GuzzleHttp\Psr7\Request;
20+
use Optimole\Sdk\Exception\BadResponseException;
21+
use Optimole\Sdk\Exception\InvalidArgumentException;
22+
use Optimole\Sdk\Exception\RuntimeException;
23+
use Optimole\Sdk\Optimole;
24+
25+
class GuzzleClient implements ClientInterface
26+
{
27+
/**
28+
* The Guzzle HTTP client.
29+
*/
30+
private GuzzleClientInterface $client;
31+
32+
/**
33+
* Constructor.
34+
*/
35+
public function __construct(GuzzleClientInterface $client)
36+
{
37+
$this->client = $client;
38+
}
39+
40+
/**
41+
* {@inheritdoc}
42+
*/
43+
public function sendRequest(string $method, string $url, $body = null, array $headers = []): ?array
44+
{
45+
try {
46+
$response = $this->client->send($this->createRequest($method, $url, $body, $headers), ['verify' => false]);
47+
} catch (GuzzleBadResponseException $exception) {
48+
throw new BadResponseException($exception->getMessage(), $exception->getCode(), $exception);
49+
} catch (GuzzleException $exception) {
50+
throw new RuntimeException($exception->getMessage(), $exception->getCode(), $exception);
51+
}
52+
53+
$body = (string) $response->getBody();
54+
55+
if (empty($body)) {
56+
return null;
57+
}
58+
59+
$body = (array) json_decode($body, true);
60+
61+
if (JSON_ERROR_NONE !== json_last_error()) {
62+
throw new BadResponseException(sprintf('Unable to decode JSON response: %s', json_last_error_msg()));
63+
}
64+
65+
return $body;
66+
}
67+
68+
/**
69+
* Create a request object.
70+
*/
71+
private function createRequest(string $method, string $url, $body = null, array $headers = []): Request
72+
{
73+
if (is_array($body)) {
74+
$body = json_encode($body);
75+
}
76+
77+
if (null !== $body && !is_string($body)) {
78+
throw new InvalidArgumentException('"body" must be a string or an array');
79+
}
80+
81+
$headers = array_merge($headers, [
82+
'User-Agent' => sprintf('optimole-sdk-php/%s', Optimole::VERSION),
83+
]);
84+
$method = strtolower($method);
85+
86+
return new Request($method, $url, $headers, $body);
87+
}
88+
}

0 commit comments

Comments
 (0)