PNG %k25u25%fgd5n!
PNG %k25u25%fgd5n!PK [Z\ͻ>nP P automattic/woocommerce/LICENSEnu Iw 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.
PK [Z\ܨ" " automattic/woocommerce/README.mdnu Iw # 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.
[](https://github.com/woocommerce/wc-api-php/actions/workflows/ci.yml)
[](https://scrutinizer-ci.com/g/woocommerce/wc-api-php/?branch=master)
[](https://packagist.org/packages/automattic/woocommerce)
## Installation
```
composer require automattic/woocommerce
```
## Getting started
Generate API credentials (Consumer Key & Consumer Secret) following this instructions
' . print_r($results, true) . ''; // JSON output. // Last request data. $lastRequest = $woocommerce->http->getRequest(); echo '' . print_r($lastRequest->getUrl(), true) . ''; // Requested URL (string). echo '' . print_r($lastRequest->getMethod(), true) . ''; // Request method (string). echo '' . print_r($lastRequest->getParameters(), true) . ''; // Request parameters (array). echo '' . print_r($lastRequest->getHeaders(), true) . ''; // Request headers (array). echo '' . print_r($lastRequest->getBody(), true) . ''; // Request body (JSON). // Last response data. $lastResponse = $woocommerce->http->getResponse(); echo '' . print_r($lastResponse->getCode(), true) . ''; // Response code (int). echo '' . print_r($lastResponse->getHeaders(), true) . ''; // Response headers (array). echo '' . print_r($lastResponse->getBody(), true) . ''; // Response body (JSON). } catch (HttpClientException $e) { echo '' . print_r($e->getMessage(), true) . ''; // Error message. echo '' . print_r($e->getRequest(), true) . ''; // Last request data. echo '' . print_r($e->getResponse(), true) . ''; // 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. PK [Z\[]S S $ automattic/woocommerce/composer.jsonnu Iw { "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" } } } PK [Z\Nt ? automattic/woocommerce/src/WooCommerce/HttpClient/BasicAuth.phpnu Iw 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; } } PK [Z\ aG G > automattic/woocommerce/src/WooCommerce/HttpClient/Response.phpnu Iw 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; } } PK [Z\y = automattic/woocommerce/src/WooCommerce/HttpClient/Options.phpnu Iw 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']; } } PK [Z\8> > = automattic/woocommerce/src/WooCommerce/HttpClient/Request.phpnu Iw 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; } } PK [Z\B#N1 1 I automattic/woocommerce/src/WooCommerce/HttpClient/HttpClientException.phpnu Iw 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; } } PK [Z\%-V2 V2 @ automattic/woocommerce/src/WooCommerce/HttpClient/HttpClient.phpnu Iw 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; } } PK [Z\O;y ; automattic/woocommerce/src/WooCommerce/HttpClient/OAuth.phpnu Iw 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); } } PK [Z\#UO O 1 automattic/woocommerce/src/WooCommerce/Client.phpnu Iw 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', [], []); } } PK [Z\/0VȲ autoload.phpnu Iw