Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 67efd6c

Browse files
committedMay 22, 2024··
add capability to offload images to optimole
1 parent dda54f4 commit 67efd6c

23 files changed

+1361
-4
lines changed
 

‎composer.json

+8-1
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,19 @@
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-stubs/wordpress-stubs": "^6.5",
2326
"phpstan/phpstan": "^1.0",
24-
"phpunit/phpunit": "^9.6"
27+
"phpunit/phpunit": "^9.6",
28+
"szepeviktor/phpstan-wordpress": "^1.3"
29+
},
30+
"suggest": {
31+
"guzzlehttp/guzzle": "Use the Guzzle HTTP client to make requests to the API"
2532
},
2633
"config": {
2734
"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 <friends@optimole.com>
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 <friends@optimole.com>
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 <friends@optimole.com>
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 <friends@optimole.com>
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 <friends@optimole.com>
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 <friends@optimole.com>
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 <friends@optimole.com>
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 <friends@optimole.com>
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 <friends@optimole.com>
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+
}

‎src/Http/WordPressClient.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 <friends@optimole.com>
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 Optimole\Sdk\Exception\BadResponseException;
17+
use Optimole\Sdk\Exception\InvalidArgumentException;
18+
use Optimole\Sdk\Exception\RuntimeException;
19+
use Optimole\Sdk\Optimole;
20+
21+
class WordPressClient implements ClientInterface
22+
{
23+
/**
24+
* The WordPress HTTP client.
25+
*/
26+
private \WP_Http $client;
27+
28+
/**
29+
* Constructor.
30+
*/
31+
public function __construct(\WP_Http $client)
32+
{
33+
$this->client = $client;
34+
}
35+
36+
/**
37+
* {@inheritdoc}
38+
*/
39+
public function sendRequest(string $method, string $url, $body = null, array $headers = []): ?array
40+
{
41+
if (is_array($body)) {
42+
$body = json_encode($body);
43+
}
44+
45+
if (null !== $body && !is_string($body)) {
46+
throw new InvalidArgumentException('"body" must be a string or an array');
47+
}
48+
49+
$args = [
50+
'method' => $method,
51+
'headers' => array_merge($headers, [
52+
'User-Agent' => sprintf('optimole-sdk-php/%s', Optimole::VERSION),
53+
]),
54+
];
55+
56+
if (null !== $body) {
57+
$args['body'] = $body;
58+
}
59+
60+
$response = $this->client->request($url, $args);
61+
62+
if ($response instanceof \WP_Error) {
63+
throw new RuntimeException((string) $response->get_error_message(), (int) $response->get_error_code());
64+
} elseif (200 !== $this->getResponseStatusCode($response)) {
65+
throw new BadResponseException(sprintf('Response status code: %s', $this->getResponseStatusCode($response)));
66+
}
67+
68+
if (empty($response['body'])) {
69+
return null;
70+
}
71+
72+
$body = (array) json_decode($response['body'], true);
73+
74+
if (JSON_ERROR_NONE !== json_last_error()) {
75+
throw new BadResponseException(sprintf('Unable to decode JSON response: %s', json_last_error_msg()));
76+
}
77+
78+
return $body;
79+
}
80+
81+
/**
82+
* Get the status code from the given response.
83+
*/
84+
private function getResponseStatusCode(array $response): ?int
85+
{
86+
return $response['response']['code'] ?? null;
87+
}
88+
}

0 commit comments

Comments
 (0)
Please sign in to comment.