Primo Committ

This commit is contained in:
paoloar77
2024-05-07 12:17:25 +02:00
commit e73d0e5113
7204 changed files with 884387 additions and 0 deletions

21
vendor/automattic/woocommerce/LICENSE vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016, Automattic (https://automattic.com/)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

169
vendor/automattic/woocommerce/README.md vendored Normal file
View File

@@ -0,0 +1,169 @@
# WooCommerce API - PHP Client
A PHP wrapper for the WooCommerce REST API. Easily interact with the WooCommerce REST API securely using this library. If using a HTTPS connection this library uses BasicAuth, else it uses Oauth to provide a secure connection to WooCommerce.
[![CI status](https://github.com/woocommerce/wc-api-php/actions/workflows/ci.yml/badge.svg?branch=trunk)](https://github.com/woocommerce/wc-api-php/actions/workflows/ci.yml)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/woocommerce/wc-api-php/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/woocommerce/wc-api-php/?branch=master)
[![PHP version](https://badge.fury.io/ph/automattic%2Fwoocommerce.svg)](https://packagist.org/packages/automattic/woocommerce)
## Installation
```
composer require automattic/woocommerce
```
## Getting started
Generate API credentials (Consumer Key & Consumer Secret) following this instructions <http://docs.woocommerce.com/document/woocommerce-rest-api/>
.
Check out the WooCommerce API endpoints and data that can be manipulated in <https://woocommerce.github.io/woocommerce-rest-api-docs/>.
## Setup
Setup for the new WP REST API integration (WooCommerce 2.6 or later):
```php
require __DIR__ . '/vendor/autoload.php';
use Automattic\WooCommerce\Client;
$woocommerce = new Client(
'http://example.com',
'ck_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
'cs_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
[
'version' => 'wc/v3',
]
);
```
## Client class
```php
$woocommerce = new Client($url, $consumer_key, $consumer_secret, $options);
```
### Options
| Option | Type | Required | Description |
| ----------------- | -------- | -------- | ------------------------------------------ |
| `url` | `string` | yes | Your Store URL, example: http://woo.dev/ |
| `consumer_key` | `string` | yes | Your API consumer key |
| `consumer_secret` | `string` | yes | Your API consumer secret |
| `options` | `array` | no | Extra arguments (see client options table) |
#### Client options
| Option | Type | Required | Description |
| ------------------------ | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `version` | `string` | no | API version, default is `wc/v3` |
| `timeout` | `int` | no | Request timeout, default is `15` |
| `verify_ssl` | `bool` | no | Verify SSL when connect, use this option as `false` when need to test with self-signed certificates, default is `true` |
| `follow_redirects` | `bool` | no | Allow the API call to follow redirects |
| `query_string_auth` | `bool` | no | Force Basic Authentication as query string when `true` and using under HTTPS, default is `false` |
| `oauth_timestamp` | `string` | no | Custom oAuth timestamp, default is `time()` |
| `oauth_only` | `bool` | no | Only use oauth for requests, it will disable Basic Auth, default is `false` |
| `user_agent` | `string` | no | Custom user-agent, default is `WooCommerce API Client-PHP` |
| `wp_api_prefix` | `string` | no | Custom WP REST API URL prefix, used to support custom prefixes created with the `rest_url_prefix` filter |
| `wp_api` | `bool` | no | Set to `false` in order to use the legacy WooCommerce REST API (deprecated and not recommended) |
| `method_override_query` | `bool` | no | If true will mask all non-GET/POST methods by using POST method with added query parameter `?_method=METHOD` into URL |
| `method_override_header` | `bool` | no | If true will mask all non-GET/POST methods (PUT/DELETE/etc.) by using POST method with added `X-HTTP-Method-Override: METHOD` HTTP header into request |
## Client methods
### GET
```php
$woocommerce->get($endpoint, $parameters = []);
```
### POST
```php
$woocommerce->post($endpoint, $data);
```
### PUT
```php
$woocommerce->put($endpoint, $data);
```
### DELETE
```php
$woocommerce->delete($endpoint, $parameters = []);
```
### OPTIONS
```php
$woocommerce->options($endpoint);
```
#### Arguments
| Params | Type | Description |
| ------------ | -------- | ------------------------------------------------------------ |
| `endpoint` | `string` | WooCommerce API endpoint, example: `customers` or `order/12` |
| `data` | `array` | Only for POST and PUT, data that will be converted to JSON |
| `parameters` | `array` | Only for GET and DELETE, request query string |
#### Response
All methods will return arrays on success or throwing `HttpClientException` errors on failure.
```php
use Automattic\WooCommerce\HttpClient\HttpClientException;
try {
// Array of response results.
$results = $woocommerce->get('customers');
// Example: ['customers' => [[ 'id' => 8, 'created_at' => '2015-05-06T17:43:51Z', 'email' => ...
echo '<pre><code>' . print_r($results, true) . '</code><pre>'; // JSON output.
// Last request data.
$lastRequest = $woocommerce->http->getRequest();
echo '<pre><code>' . print_r($lastRequest->getUrl(), true) . '</code><pre>'; // Requested URL (string).
echo '<pre><code>' .
print_r($lastRequest->getMethod(), true) .
'</code><pre>'; // Request method (string).
echo '<pre><code>' .
print_r($lastRequest->getParameters(), true) .
'</code><pre>'; // Request parameters (array).
echo '<pre><code>' .
print_r($lastRequest->getHeaders(), true) .
'</code><pre>'; // Request headers (array).
echo '<pre><code>' . print_r($lastRequest->getBody(), true) . '</code><pre>'; // Request body (JSON).
// Last response data.
$lastResponse = $woocommerce->http->getResponse();
echo '<pre><code>' . print_r($lastResponse->getCode(), true) . '</code><pre>'; // Response code (int).
echo '<pre><code>' .
print_r($lastResponse->getHeaders(), true) .
'</code><pre>'; // Response headers (array).
echo '<pre><code>' . print_r($lastResponse->getBody(), true) . '</code><pre>'; // Response body (JSON).
} catch (HttpClientException $e) {
echo '<pre><code>' . print_r($e->getMessage(), true) . '</code><pre>'; // Error message.
echo '<pre><code>' . print_r($e->getRequest(), true) . '</code><pre>'; // Last request data.
echo '<pre><code>' . print_r($e->getResponse(), true) . '</code><pre>'; // Last response data.
}
```
## Release History
- 2022-03-18 - 3.1.0 - Added new options to support `_method` and `X-HTTP-Method-Override` from WP, supports 7+, dropped support to PHP 5.
- 2019-01-16 - 3.0.0 - Legacy API turned off by default, and improved JSON error handler.
- 2018-03-29 - 2.0.1 - Fixed fatal errors on `lookForErrors`.
- 2018-01-12 - 2.0.0 - Responses changes from arrays to `stdClass` objects. Added `follow_redirects` option.
- 2017-06-06 - 1.3.0 - Remove BOM before decoding and added support for multi-dimensional arrays for oAuth1.0a.
- 2017-03-15 - 1.2.0 - Added `user_agent` option.
- 2016-12-14 - 1.1.4 - Fixed WordPress 4.7 compatibility.
- 2016-10-26 - 1.1.3 - Allow set `oauth_timestamp` and improved how is handled the response headers.
- 2016-09-30 - 1.1.2 - Added `wp_api_prefix` option to allow custom WP REST API URL prefix.
- 2016-05-10 - 1.1.1 - Fixed oAuth and error handler for WP REST API.
- 2016-05-09 - 1.1.0 - Added support for WP REST API, added method `Automattic\WooCommerce\Client::options` and fixed multiple headers responses.
- 2016-01-25 - 1.0.2 - Fixed an error when getting data containing non-latin characters.
- 2016-01-21 - 1.0.1 - Sort all oAuth parameters before build request URLs.
- 2016-01-11 - 1.0.0 - Stable release.

View File

@@ -0,0 +1,38 @@
{
"name": "automattic/woocommerce",
"description": "A PHP wrapper for the WooCommerce REST API",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Claudio Sanches",
"email": "claudio.sanches@automattic.com"
}
],
"minimum-stability": "dev",
"keywords": [
"API",
"WooCommerce"
],
"require": {
"php": ">= 7.1.0",
"ext-curl": "*",
"ext-json": "*"
},
"require-dev": {
"phpunit/phpunit": "^8",
"squizlabs/php_codesniffer": "3.*",
"overtrue/phplint": "7.4.x-dev"
},
"autoload": {
"psr-4": {
"Automattic\\WooCommerce\\": ["src/WooCommerce"]
}
},
"autoload-dev": {
"psr-4": {
"Automattic\\WooCommerce\\LegacyTests\\": "tests/legacy-php/WooCommerce/Tests",
"Automattic\\WooCommerce\\Tests\\": "tests/php/WooCommerce/Tests"
}
}
}

View File

@@ -0,0 +1,109 @@
<?php
/**
* WooCommerce REST API Client
*
* @category Client
* @package Automattic/WooCommerce
*/
namespace Automattic\WooCommerce;
use Automattic\WooCommerce\HttpClient\HttpClient;
/**
* REST API Client class.
*
* @package Automattic/WooCommerce
*/
class Client
{
/**
* WooCommerce REST API Client version.
*/
public const VERSION = '3.1.0';
/**
* HttpClient instance.
*
* @var HttpClient
*/
public $http;
/**
* Initialize client.
*
* @param string $url Store URL.
* @param string $consumerKey Consumer key.
* @param string $consumerSecret Consumer secret.
* @param array $options Options (version, timeout, verify_ssl, oauth_only).
*/
public function __construct($url, $consumerKey, $consumerSecret, $options = [])
{
$this->http = new HttpClient($url, $consumerKey, $consumerSecret, $options);
}
/**
* POST method.
*
* @param string $endpoint API endpoint.
* @param array $data Request data.
*
* @return \stdClass
*/
public function post($endpoint, $data)
{
return $this->http->request($endpoint, 'POST', $data);
}
/**
* PUT method.
*
* @param string $endpoint API endpoint.
* @param array $data Request data.
*
* @return \stdClass
*/
public function put($endpoint, $data)
{
return $this->http->request($endpoint, 'PUT', $data);
}
/**
* GET method.
*
* @param string $endpoint API endpoint.
* @param array $parameters Request parameters.
*
* @return \stdClass
*/
public function get($endpoint, $parameters = [])
{
return $this->http->request($endpoint, 'GET', [], $parameters);
}
/**
* DELETE method.
*
* @param string $endpoint API endpoint.
* @param array $parameters Request parameters.
*
* @return \stdClass
*/
public function delete($endpoint, $parameters = [])
{
return $this->http->request($endpoint, 'DELETE', [], $parameters);
}
/**
* OPTIONS method.
*
* @param string $endpoint API endpoint.
*
* @return \stdClass
*/
public function options($endpoint)
{
return $this->http->request($endpoint, 'OPTIONS', [], []);
}
}

View File

@@ -0,0 +1,96 @@
<?php
/**
* WooCommerce Basic Authentication
*
* @category HttpClient
* @package Automattic/WooCommerce
*/
namespace Automattic\WooCommerce\HttpClient;
/**
* Basic Authentication class.
*
* @package Automattic/WooCommerce
*/
class BasicAuth
{
/**
* cURL handle.
*
* @var resource
*/
protected $ch;
/**
* Consumer key.
*
* @var string
*/
protected $consumerKey;
/**
* Consumer secret.
*
* @var string
*/
protected $consumerSecret;
/**
* Do query string auth.
*
* @var bool
*/
protected $doQueryString;
/**
* Request parameters.
*
* @var array
*/
protected $parameters;
/**
* Initialize Basic Authentication class.
*
* @param resource $ch cURL handle.
* @param string $consumerKey Consumer key.
* @param string $consumerSecret Consumer Secret.
* @param bool $doQueryString Do or not query string auth.
* @param array $parameters Request parameters.
*/
public function __construct($ch, $consumerKey, $consumerSecret, $doQueryString, $parameters = [])
{
$this->ch = $ch;
$this->consumerKey = $consumerKey;
$this->consumerSecret = $consumerSecret;
$this->doQueryString = $doQueryString;
$this->parameters = $parameters;
$this->processAuth();
}
/**
* Process auth.
*/
protected function processAuth()
{
if ($this->doQueryString) {
$this->parameters['consumer_key'] = $this->consumerKey;
$this->parameters['consumer_secret'] = $this->consumerSecret;
} else {
\curl_setopt($this->ch, CURLOPT_USERPWD, $this->consumerKey . ':' . $this->consumerSecret);
}
}
/**
* Get parameters.
*
* @return array
*/
public function getParameters()
{
return $this->parameters;
}
}

View File

@@ -0,0 +1,487 @@
<?php
/**
* WooCommerce REST API HTTP Client
*
* @category HttpClient
* @package Automattic/WooCommerce
*/
namespace Automattic\WooCommerce\HttpClient;
use Automattic\WooCommerce\Client;
use Automattic\WooCommerce\HttpClient\BasicAuth;
use Automattic\WooCommerce\HttpClient\HttpClientException;
use Automattic\WooCommerce\HttpClient\OAuth;
use Automattic\WooCommerce\HttpClient\Options;
use Automattic\WooCommerce\HttpClient\Request;
use Automattic\WooCommerce\HttpClient\Response;
/**
* REST API HTTP Client class.
*
* @package Automattic/WooCommerce
*/
class HttpClient
{
/**
* cURL handle.
*
* @var resource
*/
protected $ch;
/**
* Store API URL.
*
* @var string
*/
protected $url;
/**
* Consumer key.
*
* @var string
*/
protected $consumerKey;
/**
* Consumer secret.
*
* @var string
*/
protected $consumerSecret;
/**
* Client options.
*
* @var Options
*/
protected $options;
/**
* The custom cURL options to use in the requests.
*
* @var array
*/
private $customCurlOptions = [];
/**
* Request.
*
* @var Request
*/
private $request;
/**
* Response.
*
* @var Response
*/
private $response;
/**
* Response headers.
*
* @var string
*/
private $responseHeaders;
/**
* Initialize HTTP client.
*
* @param string $url Store URL.
* @param string $consumerKey Consumer key.
* @param string $consumerSecret Consumer Secret.
* @param array $options Client options.
*/
public function __construct($url, $consumerKey, $consumerSecret, $options)
{
if (!\function_exists('curl_version')) {
throw new HttpClientException('cURL is NOT installed on this server', -1, new Request(), new Response());
}
$this->options = new Options($options);
$this->url = $this->buildApiUrl($url);
$this->consumerKey = $consumerKey;
$this->consumerSecret = $consumerSecret;
}
/**
* Check if is under SSL.
*
* @return bool
*/
protected function isSsl()
{
return 'https://' === \substr($this->url, 0, 8);
}
/**
* Build API URL.
*
* @param string $url Store URL.
*
* @return string
*/
protected function buildApiUrl($url)
{
$api = $this->options->isWPAPI() ? $this->options->apiPrefix() : '/wc-api/';
return \rtrim($url, '/') . $api . $this->options->getVersion() . '/';
}
/**
* Build URL.
*
* @param string $url URL.
* @param array $parameters Query string parameters.
*
* @return string
*/
protected function buildUrlQuery($url, $parameters = [])
{
if (!empty($parameters)) {
if (false !== strpos($url, '?')) {
$url .= '&' . \http_build_query($parameters);
} else {
$url .= '?' . \http_build_query($parameters);
}
}
return $url;
}
/**
* Authenticate.
*
* @param string $url Request URL.
* @param string $method Request method.
* @param array $parameters Request parameters.
*
* @return array
*/
protected function authenticate($url, $method, $parameters = [])
{
// Setup authentication.
if (!$this->options->isOAuthOnly() && $this->isSsl()) {
$basicAuth = new BasicAuth(
$this->ch,
$this->consumerKey,
$this->consumerSecret,
$this->options->isQueryStringAuth(),
$parameters
);
$parameters = $basicAuth->getParameters();
} else {
$oAuth = new OAuth(
$url,
$this->consumerKey,
$this->consumerSecret,
$this->options->getVersion(),
$method,
$parameters,
$this->options->oauthTimestamp()
);
$parameters = $oAuth->getParameters();
}
return $parameters;
}
/**
* Setup method.
*
* @param string $method Request method.
*/
protected function setupMethod($method)
{
if ('POST' == $method) {
\curl_setopt($this->ch, CURLOPT_POST, true);
} elseif (\in_array($method, ['PUT', 'DELETE', 'OPTIONS'])) {
\curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $method);
}
}
/**
* Get request headers.
*
* @param bool $sendData If request send data or not.
*
* @return array
*/
protected function getRequestHeaders($sendData = false)
{
$headers = [
'Accept' => 'application/json',
'User-Agent' => $this->options->userAgent() . '/' . Client::VERSION,
];
if ($sendData) {
$headers['Content-Type'] = 'application/json;charset=utf-8';
}
return $headers;
}
/**
* Create request.
*
* @param string $endpoint Request endpoint.
* @param string $method Request method.
* @param array $data Request data.
* @param array $parameters Request parameters.
*
* @return Request
*/
protected function createRequest($endpoint, $method, $data = [], $parameters = [])
{
$body = '';
$url = $this->url . $endpoint;
$hasData = !empty($data);
$headers = $this->getRequestHeaders($hasData);
// HTTP method override feature which masks PUT and DELETE HTTP methods as POST method with added
// ?_method=PUT query parameter and/or X-HTTP-Method-Override HTTP header.
if (!in_array($method, ['GET', 'POST'])) {
$usePostMethod = false;
if ($this->options->isMethodOverrideQuery()) {
$parameters = array_merge(['_method' => $method], $parameters);
$usePostMethod = true;
}
if ($this->options->isMethodOverrideHeader()) {
$headers['X-HTTP-Method-Override'] = $method;
$usePostMethod = true;
}
if ($usePostMethod) {
$method = 'POST';
}
}
// Setup authentication.
$parameters = $this->authenticate($url, $method, $parameters);
// Setup method.
$this->setupMethod($method);
// Include post fields.
if ($hasData) {
$body = \json_encode($data);
\curl_setopt($this->ch, CURLOPT_POSTFIELDS, $body);
}
$this->request = new Request(
$this->buildUrlQuery($url, $parameters),
$method,
$parameters,
$headers,
$body
);
return $this->getRequest();
}
/**
* Get response headers.
*
* @return array
*/
protected function getResponseHeaders()
{
$headers = [];
$lines = \explode("\n", $this->responseHeaders);
$lines = \array_filter($lines, 'trim');
foreach ($lines as $index => $line) {
// Remove HTTP/xxx params.
if (strpos($line, ': ') === false) {
continue;
}
list($key, $value) = \explode(': ', $line);
$headers[$key] = isset($headers[$key]) ? $headers[$key] . ', ' . trim($value) : trim($value);
}
return $headers;
}
/**
* Create response.
*
* @return Response
*/
protected function createResponse()
{
// Set response headers.
$this->responseHeaders = '';
\curl_setopt($this->ch, CURLOPT_HEADERFUNCTION, function ($_, $headers) {
$this->responseHeaders .= $headers;
return \strlen($headers);
});
// Get response data.
$body = \curl_exec($this->ch);
$code = \curl_getinfo($this->ch, CURLINFO_HTTP_CODE);
$headers = $this->getResponseHeaders();
// Register response.
$this->response = new Response($code, $headers, $body);
return $this->getResponse();
}
/**
* Set default cURL settings.
*/
protected function setDefaultCurlSettings()
{
$verifySsl = $this->options->verifySsl();
$timeout = $this->options->getTimeout();
$followRedirects = $this->options->getFollowRedirects();
\curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, $verifySsl);
if (!$verifySsl) {
\curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, $verifySsl);
}
if ($followRedirects) {
\curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, true);
}
\curl_setopt($this->ch, CURLOPT_CONNECTTIMEOUT, $timeout);
\curl_setopt($this->ch, CURLOPT_TIMEOUT, $timeout);
\curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
\curl_setopt($this->ch, CURLOPT_HTTPHEADER, $this->request->getRawHeaders());
\curl_setopt($this->ch, CURLOPT_URL, $this->request->getUrl());
foreach ($this->customCurlOptions as $customCurlOptionKey => $customCurlOptionValue) {
\curl_setopt($this->ch, $customCurlOptionKey, $customCurlOptionValue);
}
}
/**
* Look for errors in the request.
*
* @param array $parsedResponse Parsed body response.
*/
protected function lookForErrors($parsedResponse)
{
// Any non-200/201/202 response code indicates an error.
if (!\in_array($this->response->getCode(), ['200', '201', '202'])) {
$errors = isset($parsedResponse->errors) ? $parsedResponse->errors : $parsedResponse;
$errorMessage = '';
$errorCode = '';
if (is_array($errors)) {
$errorMessage = $errors[0]->message;
$errorCode = $errors[0]->code;
} elseif (isset($errors->message, $errors->code)) {
$errorMessage = $errors->message;
$errorCode = $errors->code;
}
throw new HttpClientException(
\sprintf('Error: %s [%s]', $errorMessage, $errorCode),
$this->response->getCode(),
$this->request,
$this->response
);
}
}
/**
* Process response.
*
* @return \stdClass
*/
protected function processResponse()
{
$body = $this->response->getBody();
// Look for UTF-8 BOM and remove.
if (0 === strpos(bin2hex(substr($body, 0, 4)), 'efbbbf')) {
$body = substr($body, 3);
}
$parsedResponse = \json_decode($body);
// Test if return a valid JSON.
if (JSON_ERROR_NONE !== json_last_error()) {
$message = function_exists('json_last_error_msg') ? json_last_error_msg() : 'Invalid JSON returned';
throw new HttpClientException(
sprintf('JSON ERROR: %s', $message),
$this->response->getCode(),
$this->request,
$this->response
);
}
$this->lookForErrors($parsedResponse);
return $parsedResponse;
}
/**
* Make requests.
*
* @param string $endpoint Request endpoint.
* @param string $method Request method.
* @param array $data Request data.
* @param array $parameters Request parameters.
*
* @return \stdClass
*/
public function request($endpoint, $method, $data = [], $parameters = [])
{
// Initialize cURL.
$this->ch = \curl_init();
// Set request args.
$request = $this->createRequest($endpoint, $method, $data, $parameters);
// Default cURL settings.
$this->setDefaultCurlSettings();
// Get response.
$response = $this->createResponse();
// Check for cURL errors.
if (\curl_errno($this->ch)) {
throw new HttpClientException('cURL Error: ' . \curl_error($this->ch), 0, $request, $response);
}
\curl_close($this->ch);
return $this->processResponse();
}
/**
* Get request data.
*
* @return Request
*/
public function getRequest()
{
return $this->request;
}
/**
* Get response data.
*
* @return Response
*/
public function getResponse()
{
return $this->response;
}
/**
* Set custom cURL options to use in requests.
*
* @param array $curlOptions
*/
public function setCustomCurlOptions(array $curlOptions)
{
$this->customCurlOptions = $curlOptions;
}
}

View File

@@ -0,0 +1,71 @@
<?php
/**
* WooCommerce REST API HTTP Client Exception
*
* @category HttpClient
* @package Automattic/WooCommerce
*/
namespace Automattic\WooCommerce\HttpClient;
use Automattic\WooCommerce\HttpClient\Request;
use Automattic\WooCommerce\HttpClient\Response;
/**
* REST API HTTP Client Exception class.
*
* @package Automattic/WooCommerce
*/
class HttpClientException extends \Exception
{
/**
* Request.
*
* @var Request
*/
private $request;
/**
* Response.
*
* @var Response
*/
private $response;
/**
* Initialize exception.
*
* @param string $message Error message.
* @param int $code Error code.
* @param Request $request Request data.
* @param Response $response Response data.
*/
public function __construct($message, $code, Request $request, Response $response)
{
parent::__construct($message, $code);
$this->request = $request;
$this->response = $response;
}
/**
* Get request data.
*
* @return Request
*/
public function getRequest()
{
return $this->request;
}
/**
* Get response data.
*
* @return Response
*/
public function getResponse()
{
return $this->response;
}
}

View File

@@ -0,0 +1,268 @@
<?php
/**
* WooCommerce oAuth1.0
*
* @category HttpClient
* @package Automattic/WooCommerce
*/
namespace Automattic\WooCommerce\HttpClient;
/**
* oAuth1.0 class.
*
* @package Automattic/WooCommerce
*/
class OAuth
{
/**
* OAuth signature method algorithm.
*/
public const HASH_ALGORITHM = 'SHA256';
/**
* API endpoint URL.
*
* @var string
*/
protected $url;
/**
* Consumer key.
*
* @var string
*/
protected $consumerKey;
/**
* Consumer secret.
*
* @var string
*/
protected $consumerSecret;
/**
* API version.
*
* @var string
*/
protected $apiVersion;
/**
* Request method.
*
* @var string
*/
protected $method;
/**
* Request parameters.
*
* @var array
*/
protected $parameters;
/**
* Timestamp.
*
* @var string
*/
protected $timestamp;
/**
* Initialize oAuth class.
*
* @param string $url Store URL.
* @param string $consumerKey Consumer key.
* @param string $consumerSecret Consumer Secret.
* @param string $method Request method.
* @param string $apiVersion API version.
* @param array $parameters Request parameters.
* @param string $timestamp Timestamp.
*/
public function __construct(
$url,
$consumerKey,
$consumerSecret,
$apiVersion,
$method,
$parameters = [],
$timestamp = ''
) {
$this->url = $url;
$this->consumerKey = $consumerKey;
$this->consumerSecret = $consumerSecret;
$this->apiVersion = $apiVersion;
$this->method = $method;
$this->parameters = $parameters;
$this->timestamp = $timestamp;
}
/**
* Encode according to RFC 3986.
*
* @param string|array $value Value to be normalized.
*
* @return string
*/
protected function encode($value)
{
if (is_array($value)) {
return array_map([$this, 'encode'], $value);
} else {
return str_replace(['+', '%7E'], [' ', '~'], rawurlencode($value));
}
}
/**
* Normalize parameters.
*
* @param array $parameters Parameters to normalize.
*
* @return array
*/
protected function normalizeParameters($parameters)
{
$normalized = [];
foreach ($parameters as $key => $value) {
// Percent symbols (%) must be double-encoded.
$key = $this->encode($key);
$value = $this->encode($value);
$normalized[$key] = $value;
}
return $normalized;
}
/**
* Process filters.
*
* @param array $parameters Request parameters.
*
* @return array
*/
protected function processFilters($parameters)
{
if (isset($parameters['filter'])) {
$filters = $parameters['filter'];
unset($parameters['filter']);
foreach ($filters as $filter => $value) {
$parameters['filter[' . $filter . ']'] = $value;
}
}
return $parameters;
}
/**
* Get secret.
*
* @return string
*/
protected function getSecret()
{
$secret = $this->consumerSecret;
// Fix secret for v3 or later.
if (!\in_array($this->apiVersion, ['v1', 'v2'])) {
$secret .= '&';
}
return $secret;
}
/**
* Generate oAuth1.0 signature.
*
* @param array $parameters Request parameters including oauth.
*
* @return string
*/
protected function generateOauthSignature($parameters)
{
$baseRequestUri = \rawurlencode($this->url);
// Extract filters.
$parameters = $this->processFilters($parameters);
// Normalize parameter key/values and sort them.
$parameters = $this->normalizeParameters($parameters);
$parameters = $this->getSortedParameters($parameters);
// Set query string.
$queryString = \implode('%26', $this->joinWithEqualsSign($parameters)); // Join with ampersand.
$stringToSign = $this->method . '&' . $baseRequestUri . '&' . $queryString;
$secret = $this->getSecret();
return \base64_encode(\hash_hmac(self::HASH_ALGORITHM, $stringToSign, $secret, true));
}
/**
* Creates an array of urlencoded strings out of each array key/value pairs.
*
* @param array $params Array of parameters to convert.
* @param array $queryParams Array to extend.
* @param string $key Optional Array key to append
* @return string Array of urlencoded strings
*/
protected function joinWithEqualsSign($params, $queryParams = [], $key = '')
{
foreach ($params as $paramKey => $paramValue) {
if ($key) {
$paramKey = $key . '%5B' . $paramKey . '%5D'; // Handle multi-dimensional array.
}
if (is_array($paramValue)) {
$queryParams = $this->joinWithEqualsSign($paramValue, $queryParams, $paramKey);
} else {
$string = $paramKey . '=' . $paramValue; // Join with equals sign.
$queryParams[] = $this->encode($string);
}
}
return $queryParams;
}
/**
* Sort parameters.
*
* @param array $parameters Parameters to sort in byte-order.
*
* @return array
*/
protected function getSortedParameters($parameters)
{
\uksort($parameters, 'strcmp');
foreach ($parameters as $key => $value) {
if (\is_array($value)) {
\uksort($parameters[$key], 'strcmp');
}
}
return $parameters;
}
/**
* Get oAuth1.0 parameters.
*
* @return string
*/
public function getParameters()
{
$parameters = \array_merge($this->parameters, [
'oauth_consumer_key' => $this->consumerKey,
'oauth_timestamp' => $this->timestamp,
'oauth_nonce' => \sha1(\microtime()),
'oauth_signature_method' => 'HMAC-' . self::HASH_ALGORITHM,
]);
// The parameters above must be included in the signature generation.
$parameters['oauth_signature'] = $this->generateOauthSignature($parameters);
return $this->getSortedParameters($parameters);
}
}

View File

@@ -0,0 +1,182 @@
<?php
/**
* WooCommerce REST API HTTP Client Options
*
* @category HttpClient
* @package Automattic/WooCommerce
*/
namespace Automattic\WooCommerce\HttpClient;
/**
* REST API HTTP Client Options class.
*
* @package Automattic/WooCommerce
*/
class Options
{
/**
* Default WooCommerce REST API version.
*
* @var string
*/
public const VERSION = 'wc/v3';
/**
* Default request timeout.
*/
public const TIMEOUT = 15;
/**
* Default WP API prefix.
* Including leading and trailing slashes.
*/
public const WP_API_PREFIX = '/wp-json/';
/**
* Default User Agent.
* No version number.
*/
public const USER_AGENT = 'WooCommerce API Client-PHP';
/**
* Options.
*
* @var array
*/
private $options;
/**
* Initialize HTTP client options.
*
* @param array $options Client options.
*/
public function __construct($options)
{
$this->options = $options;
}
/**
* Get API version.
*
* @return string
*/
public function getVersion()
{
return isset($this->options['version']) ? $this->options['version'] : self::VERSION;
}
/**
* Check if need to verify SSL.
*
* @return bool
*/
public function verifySsl()
{
return isset($this->options['verify_ssl']) ? (bool) $this->options['verify_ssl'] : true;
}
/**
* Only use OAuth.
*
* @return bool
*/
public function isOAuthOnly()
{
return isset($this->options['oauth_only']) ? (bool) $this->options['oauth_only'] : false;
}
/**
* Get timeout.
*
* @return int
*/
public function getTimeout()
{
return isset($this->options['timeout']) ? (int) $this->options['timeout'] : self::TIMEOUT;
}
/**
* Basic Authentication as query string.
* Some old servers are not able to use CURLOPT_USERPWD.
*
* @return bool
*/
public function isQueryStringAuth()
{
return isset($this->options['query_string_auth']) ? (bool) $this->options['query_string_auth'] : false;
}
/**
* Check if is WP REST API.
*
* @return bool
*/
public function isWPAPI()
{
return isset($this->options['wp_api']) ? (bool) $this->options['wp_api'] : true;
}
/**
* Custom API Prefix for WP API.
*
* @return string
*/
public function apiPrefix()
{
return isset($this->options['wp_api_prefix']) ? $this->options['wp_api_prefix'] : self::WP_API_PREFIX;
}
/**
* oAuth timestamp.
*
* @return string
*/
public function oauthTimestamp()
{
return isset($this->options['oauth_timestamp']) ? $this->options['oauth_timestamp'] : \time();
}
/**
* Custom user agent.
*
* @return string
*/
public function userAgent()
{
return isset($this->options['user_agent']) ? $this->options['user_agent'] : self::USER_AGENT;
}
/**
* Get follow redirects.
*
* @return bool
*/
public function getFollowRedirects()
{
return isset($this->options['follow_redirects']) ? (bool) $this->options['follow_redirects'] : false;
}
/**
* Check is it needed to mask all non-GET/POST methods (PUT/DELETE/etc.) by using POST method with added
* query parameter ?_method=METHOD into URL.
*
* @return bool
*/
public function isMethodOverrideQuery()
{
return isset($this->options['method_override_query']) && $this->options['method_override_query'];
}
/**
* Check is it needed to mask all non-GET/POST methods (PUT/DELETE/etc.) by using POST method with added
* "X-HTTP-Method-Override: METHOD" HTTP header into request.
*
* @return bool
*/
public function isMethodOverrideHeader()
{
return isset($this->options['method_override_header']) && $this->options['method_override_header'];
}
}

View File

@@ -0,0 +1,187 @@
<?php
/**
* WooCommerce REST API HTTP Client Request
*
* @category HttpClient
* @package Automattic/WooCommerce
*/
namespace Automattic\WooCommerce\HttpClient;
/**
* REST API HTTP Client Request class.
*
* @package Automattic/WooCommerce
*/
class Request
{
/**
* Request url.
*
* @var string
*/
private $url;
/**
* Request method.
*
* @var string
*/
private $method;
/**
* Request paramenters.
*
* @var array
*/
private $parameters;
/**
* Request headers.
*
* @var array
*/
private $headers;
/**
* Request body.
*
* @var string
*/
private $body;
/**
* Initialize request.
*
* @param string $url Request url.
* @param string $method Request method.
* @param array $parameters Request paramenters.
* @param array $headers Request headers.
* @param string $body Request body.
*/
public function __construct($url = '', $method = 'POST', $parameters = [], $headers = [], $body = '')
{
$this->url = $url;
$this->method = $method;
$this->parameters = $parameters;
$this->headers = $headers;
$this->body = $body;
}
/**
* Set url.
*
* @param string $url Request url.
*/
public function setUrl($url)
{
$this->url = $url;
}
/**
* Set method.
*
* @param string $method Request method.
*/
public function setMethod($method)
{
$this->method = $method;
}
/**
* Set parameters.
*
* @param array $parameters Request paramenters.
*/
public function setParameters($parameters)
{
$this->parameters = $parameters;
}
/**
* Set headers.
*
* @param array $headers Request headers.
*/
public function setHeaders($headers)
{
$this->headers = $headers;
}
/**
* Set body.
*
* @param string $body Request body.
*/
public function setBody($body)
{
$this->body = $body;
}
/**
* Get url.
*
* @return string
*/
public function getUrl()
{
return $this->url;
}
/**
* Get method.
*
* @return string
*/
public function getMethod()
{
return $this->method;
}
/**
* Get parameters.
*
* @return array
*/
public function getParameters()
{
return $this->parameters;
}
/**
* Get headers.
*
* @return array
*/
public function getHeaders()
{
return $this->headers;
}
/**
* Get raw headers.
*
* @return array
*/
public function getRawHeaders()
{
$headers = [];
foreach ($this->headers as $key => $value) {
$headers[] = $key . ': ' . $value;
}
return $headers;
}
/**
* Get body.
*
* @return string
*/
public function getBody()
{
return $this->body;
}
}

View File

@@ -0,0 +1,127 @@
<?php
/**
* WooCommerce REST API HTTP Client Response
*
* @category HttpClient
* @package Automattic/WooCommerce
*/
namespace Automattic\WooCommerce\HttpClient;
/**
* REST API HTTP Client Response class.
*
* @package Automattic/WooCommerce
*/
class Response
{
/**
* Response code.
*
* @var int
*/
private $code;
/**
* Response headers.
*
* @var array
*/
private $headers;
/**
* Response body.
*
* @var string
*/
private $body;
/**
* Initialize response.
*
* @param int $code Response code.
* @param array $headers Response headers.
* @param string $body Response body.
*/
public function __construct($code = 0, $headers = [], $body = '')
{
$this->code = $code;
$this->headers = $headers;
$this->body = $body;
}
/**
* To string.
*
* @return string
*/
public function __toString()
{
return \json_encode([
'code' => $this->code,
'headers' => $this->headers,
'body' => $this->body,
]);
}
/**
* Set code.
*
* @param int $code Response code.
*/
public function setCode($code)
{
$this->code = (int) $code;
}
/**
* Set headers.
*
* @param array $headers Response headers.
*/
public function setHeaders($headers)
{
$this->headers = $headers;
}
/**
* Set body.
*
* @param string $body Response body.
*/
public function setBody($body)
{
$this->body = $body;
}
/**
* Get code.
*
* @return int
*/
public function getCode()
{
return $this->code;
}
/**
* Get headers.
*
* @return array $headers Response headers.
*/
public function getHeaders()
{
return $this->headers;
}
/**
* Get body.
*
* @return string $body Response body.
*/
public function getBody()
{
return $this->body;
}
}