Skip to content

Commit

Permalink
add capability to offload images to optimole
Browse files Browse the repository at this point in the history
  • Loading branch information
carlalexander committed May 23, 2024
1 parent dda54f4 commit 3920628
Show file tree
Hide file tree
Showing 24 changed files with 1,426 additions and 7 deletions.
40 changes: 37 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,29 @@ $ composer require codeinwp/optimole-sdk

## Usage

To begin, you need to create an account on [Optimole][1] and get your API key. You can then initialize the SDK with your
API key using the `Optimole` facade:
To begin, you need to create an account on [Optimole][1] and get your API key.

### Initializing the SDK

You can then initialize the SDK with your API key using the `Optimole` facade:

```php
use Optimole\Sdk\Optimole;

Optimole::init('your-api-key');
Optimole::init('your-api-key', $options);
```

The second argument of the `init` method is optional. It allows you to pass options to the SDK that can be used to
configure it. These options are:

* `base_domain`: The base domain to connect to Optimole's API. Default is `i.optimole.com`.
* `cache_buster`: A string value that will be appended to the URL of the optimized assets to bust Optimole's cache.
* `dashboard_api_url`: The URL of the dashboard API. Default is `https://dashboard.optimole.com/api`.
* `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.
* `upload_api_url`: The URL of the upload API. Default is `https://generateurls-prod.i.optimole.com/upload`.

### Optimizing Images and Assets

The `Optimole` facade is your starting point for creating optimized images or other assets. You can control the optimization
properties using the fluent interface provided by the SDK. Here's an example of how to optimize an image by changing its
quality and cropping it:
Expand All @@ -44,6 +58,26 @@ echo $image->getUrl();
echo (string) $image;
```

### Offloading Images to Optimole

The SDK also provides a way to offload images to Optimole. This is useful when you want to serve images from Optimole's
content delivery network. Here's an example of how to offload an image:

```php
use Optimole\Sdk\Optimole;

$imageId = Optimole::offload()->uploadImage('path/to/image.jpg', 'https://url/to/image.jpg');
```

This will upload the image to Optimole and return the image ID. You can then use this image ID to interact with the
image. For example, you can get the URL of the offloaded image:

```php
use Optimole\Sdk\Optimole;

$imageUrl = Optimole::offload()->getImageUrl($imageId);
```

## Contributing

Install dependencies using composer and run the test suite:
Expand Down
10 changes: 9 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,20 @@
},
"require": {
"php": ">=7.4",
"ext-json": "*",
"symfony/polyfill-php80": "^1.29"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.0",
"guzzlehttp/guzzle": "^7.0",
"php-mock/php-mock-phpunit": "^2.10",
"php-stubs/wordpress-stubs": "^6.5",
"phpstan/phpstan": "^1.0",
"phpunit/phpunit": "^9.6"
"phpunit/phpunit": "^9.6",
"szepeviktor/phpstan-wordpress": "^1.3"
},
"suggest": {
"guzzlehttp/guzzle": "Use the Guzzle HTTP client to make requests to the API"
},
"config": {
"optimize-autoloader": true,
Expand Down
2 changes: 2 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
includes:
- ./vendor/szepeviktor/phpstan-wordpress/extension.neon
parameters:
level: 5
paths:
Expand Down
2 changes: 1 addition & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="vendor/autoload.php"
<phpunit bootstrap="tests/bootstrap.php"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
Expand Down
18 changes: 18 additions & 0 deletions src/Exception/BadResponseException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

/*
* This file is part of Optimole PHP SDK.
*
* (c) Optimole Team <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Optimole\Sdk\Exception;

class BadResponseException extends RuntimeException
{
}
18 changes: 18 additions & 0 deletions src/Exception/DashboardApiException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

/*
* This file is part of Optimole PHP SDK.
*
* (c) Optimole Team <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Optimole\Sdk\Exception;

class DashboardApiException extends BadResponseException
{
}
18 changes: 18 additions & 0 deletions src/Exception/InvalidDashboardApiResponseException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

/*
* This file is part of Optimole PHP SDK.
*
* (c) Optimole Team <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Optimole\Sdk\Exception;

class InvalidDashboardApiResponseException extends DashboardApiException
{
}
18 changes: 18 additions & 0 deletions src/Exception/InvalidUploadApiResponseException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

/*
* This file is part of Optimole PHP SDK.
*
* (c) Optimole Team <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Optimole\Sdk\Exception;

class InvalidUploadApiResponseException extends UploadApiException
{
}
18 changes: 18 additions & 0 deletions src/Exception/UploadApiException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

/*
* This file is part of Optimole PHP SDK.
*
* (c) Optimole Team <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Optimole\Sdk\Exception;

class UploadApiException extends BadResponseException
{
}
18 changes: 18 additions & 0 deletions src/Exception/UploadFailedException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

/*
* This file is part of Optimole PHP SDK.
*
* (c) Optimole Team <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Optimole\Sdk\Exception;

class UploadFailedException extends RuntimeException
{
}
42 changes: 42 additions & 0 deletions src/Exception/UploadLimitException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

/*
* This file is part of Optimole PHP SDK.
*
* (c) Optimole Team <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Optimole\Sdk\Exception;

use Optimole\Sdk\ValueObject\OffloadUsage;

class UploadLimitException extends UploadApiException
{
/**
* The offload service usage.
*/
private OffloadUsage $usage;

/**
* Constructor.
*/
public function __construct(OffloadUsage $usage, string $message = '', int $code = 0, ?\Throwable $previous = null)
{
parent::__construct($message, $code, $previous);

$this->usage = $usage;
}

/**
* Get the offload service usage.
*/
public function getUsage(): OffloadUsage
{
return $this->usage;
}
}
22 changes: 22 additions & 0 deletions src/Http/ClientInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

/*
* This file is part of Optimole PHP SDK.
*
* (c) Optimole Team <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Optimole\Sdk\Http;

interface ClientInterface
{
/**
* Sends an HTTP request and returns the JSON decoded body.
*/
public function sendRequest(string $method, string $url, $body = null, array $headers = []): ?array;
}
88 changes: 88 additions & 0 deletions src/Http/GuzzleClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

declare(strict_types=1);

/*
* This file is part of Optimole PHP SDK.
*
* (c) Optimole Team <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Optimole\Sdk\Http;

use GuzzleHttp\ClientInterface as GuzzleClientInterface;
use GuzzleHttp\Exception\BadResponseException as GuzzleBadResponseException;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Psr7\Request;
use Optimole\Sdk\Exception\BadResponseException;
use Optimole\Sdk\Exception\InvalidArgumentException;
use Optimole\Sdk\Exception\RuntimeException;
use Optimole\Sdk\Optimole;

class GuzzleClient implements ClientInterface
{
/**
* The Guzzle HTTP client.
*/
private GuzzleClientInterface $client;

/**
* Constructor.
*/
public function __construct(GuzzleClientInterface $client)
{
$this->client = $client;
}

/**
* {@inheritdoc}
*/
public function sendRequest(string $method, string $url, $body = null, array $headers = []): ?array
{
try {
$response = $this->client->send($this->createRequest($method, $url, $body, $headers), ['verify' => false]);
} catch (GuzzleBadResponseException $exception) {
throw new BadResponseException($exception->getMessage(), $exception->getCode(), $exception);
} catch (GuzzleException $exception) {
throw new RuntimeException($exception->getMessage(), $exception->getCode(), $exception);
}

$body = (string) $response->getBody();

if (empty($body)) {
return null;
}

$body = (array) json_decode($body, true);

if (JSON_ERROR_NONE !== json_last_error()) {
throw new BadResponseException(sprintf('Unable to decode JSON response: %s', json_last_error_msg()));
}

return $body;
}

/**
* Create a request object.
*/
private function createRequest(string $method, string $url, $body = null, array $headers = []): Request
{
if (is_array($body)) {
$body = json_encode($body);
}

if (null !== $body && !is_string($body)) {
throw new InvalidArgumentException('"body" must be a string or an array');
}

$headers = array_merge($headers, [
'User-Agent' => sprintf('optimole-sdk-php/%s', Optimole::VERSION),
]);
$method = strtolower($method);

return new Request($method, $url, $headers, $body);
}
}
Loading

0 comments on commit 3920628

Please sign in to comment.