Commit 3abf4283 authored by DESKTOP-J74Q997\abc's avatar DESKTOP-J74Q997\abc

新增shoplazza 工具包

parent 5d7f10d5
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/18
* Time: 8:13
*/
namespace Meibuyu\Micro\Shoplazza;
use Exception;
use Meibuyu\Micro\Shopify\lib\AbstractShopify;
use Meibuyu\Micro\Shopify\lib\Collect;
use Meibuyu\Micro\Shopify\lib\Collection;
use Meibuyu\Micro\Shopify\lib\CustomCollection;
use Meibuyu\Micro\Shopify\lib\Event;
use Meibuyu\Micro\Shopify\lib\Fulfillment;
use Meibuyu\Micro\Shopify\lib\FulfillmentOrder;
use Meibuyu\Micro\Shopify\lib\FulfillmentService;
use Meibuyu\Micro\Shopify\lib\GraphQL;
use Meibuyu\Micro\Shopify\lib\InventoryItem;
use Meibuyu\Micro\Shopify\lib\InventoryLevel;
use Meibuyu\Micro\Shopify\lib\Location;
use Meibuyu\Micro\Shopify\lib\Metafield;
use Meibuyu\Micro\Shopify\lib\Order;
use Meibuyu\Micro\Shopify\lib\Product;
use Meibuyu\Micro\Shopify\lib\ProductVariant;
use Meibuyu\Micro\Shopify\lib\SmartCollection;
use Meibuyu\Micro\Shopify\lib\Webhook;
/**
* Class ShoplazzaApp
* @package Meibuyu\Micro\Shoplazza
*
* @property-read Webhook $Webhook
* @property-read Collect $Collect
* @property-read Collection $Collection
* @property-read CustomCollection $CustomCollection
* @property-read SmartCollection $SmartCollection
* @property-read Metafield $Metafield
* @property-read Product $Product
* @property-read ProductVariant $ProductVariant
* @property-read InventoryItem $InventoryItem
* @property-read InventoryLevel $InventoryLevel
* @property-read Location $Location
* @property-read Order $Order
* @property-read Event $Event
* @property-read Fulfillment $Fulfillment
* @property-read FulfillmentService $FulfillmentService
* @property-read GraphQL $GraphQL
*
* @method Webhook Webhook(integer $id = null)
* @method Collection Collection(integer $id = null)
* @method CustomCollection CustomCollection(integer $id = null)
* @method SmartCollection SmartCollection(integer $id = null)
* @method Metafield Metafield(integer $id = null)
* @method Product Product(integer $id = null)
* @method ProductVariant ProductVariant(integer $id = null)
* @method InventoryItem InventoryItem(integer $id = null)
* @method InventoryLevel InventoryLevel(integer $id = null)
* @method Location Location(integer $id = null)
* @method Order Order(integer $id = null)
* @method Event Event(integer $id = null)
* @method Fulfillment Fulfillment(integer $id = null)
* @method FulfillmentOrder FulfillmentOrder()
* @method FulfillmentService FulfillmentService(integer $id = null)
* @method GraphQL GraphQL()
*
*/
class ShoplazzaApp
{
protected $resources = [
'Webhook',
'Collect',
'Collection',
'CustomCollection',
'SmartCollection',
'Metafield',
'Product',
'ProductVariant',
'InventoryItem',
'InventoryLevel',
'Location',
'Order',
'Event',
'Fulfillment',
'FulfillmentOrder',
'FulfillmentService',
'GraphQL',
];
protected $childResources = array(
'Fulfillment' => 'Order',
'FulfillmentEvent' => 'Fulfillment',
'FulfillmentOrder' => 'Order',
'OrderRisk' => 'Order',
'ProductImage' => 'Product',
'ProductVariant' => 'Product',
'DiscountCode' => 'PriceRule',
'Refund' => 'Order',
'Transaction' => 'Order',
);
public $config = [];
public $defaultApiVersion = '2022-01';
/**
* ShopifyApp constructor.
* @param array $config
*/
public function __construct($config)
{
$this->config = [
'api_version' => $this->defaultApiVersion
];
foreach ($config as $key => $value) {
$this->config[$key] = $value;
}
if (isset($config['shop_url'])) {
$this->setApiUrl();
}
}
/**
* 返回AbstractShopify实例
* @param string $className 实现的类名
* @return AbstractShopify
* @throws Exception
*/
public function __get($className)
{
return $this->$className();
}
/**
* 返回AbstractShopify实例
* @param string $className 实现的类名
* @param $arguments
* @return AbstractShopify
* @throws Exception
*/
public function __call($className, $arguments)
{
if (!in_array($className, $this->resources)) {
if (isset($this->childResources[$className])) {
$message = "$className 是属于 {$this->childResources[$className]} 的子集, 无法直接访问";
} else {
$message = "未知类 $className";
}
throw new Exception($message);
}
$resourceID = !empty($arguments) ? $arguments[0] : null;
$resourceClassName = __NAMESPACE__ . "\\lib\\$className";
return new $resourceClassName($this->config, $resourceID);
}
public function setApiUrl()
{
$shopUrl = $this->config['shop_url'];
$shopUrl = preg_replace('#^https?://|/$#', '', $shopUrl);
$apiVersion = $this->config['api_version'];
$this->config['api_url'] = "https://$shopUrl/openapi/$apiVersion/";
}
}
<?php
namespace Meibuyu\Micro\Shoplazza;
use Hyperf\Contract\ContainerInterface;
class ShoplazzaFactory
{
/**
* @var ContainerInterface
*/
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function create(array $config = []): ShoplazzaApp
{
if (method_exists($this->container, 'make')) {
// Create by DI for AOP.
return $this->container->make(ShoplazzaApp::class, ['config' => $config]);
}
return new ShoplazzaApp($config);
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/18
* Time: 8:18
*/
namespace Meibuyu\Micro\Shoplazza\lib;
use Exception;
use Meibuyu\Micro\Shoplazza\tools\CurlHttpRequestJson;
use Meibuyu\Micro\Shoplazza\tools\HttpRequestJson;
use Psr\Http\Message\ResponseInterface;
abstract class AbstractShopify
{
/**
* 资源id
* @var int
*/
public $id = null;
protected $httpHeaders = [];
protected $resourceUrl;
protected $resourceKey;
protected $pluralizeKey;
/**
* 无count方法
* @var boolean
*/
public $countEnabled = true;
// 子集资源
protected $childResource = [];
// 自定义请求方法
protected $customGetActions = [];
protected $customPostActions = [];
protected $customPutActions = [];
protected $customDeleteActions = [];
private $config;
/**
* @var HttpRequestJson|CurlHttpRequestJson
*/
private $httpRequestJson;
/**
* AbstractShopify constructor.
* @param $config
* @param null $id
* @param string $parentResourceUrl
* @throws Exception
*/
public function __construct($config, $id = null, $parentResourceUrl = null)
{
$this->config = $config;
$this->id = $id;
$this->pluralizeKey = $this->pluralizeKey ?: $this->resourceKey . 's';
$this->resourceUrl = ($parentResourceUrl ? "$parentResourceUrl/" : $config['api_url']) . $this->pluralizeKey . ($this->id ? "/{$this->id}" : '');
$this->httpRequestJson = make(CurlHttpRequestJson::class);
if (isset($config['access_token'])) {
$this->httpHeaders['access-token'] = $config['access_token'];
} elseif (!isset($config['access_token'])) {
throw new Exception("请设置access_token值");
}
}
/**
* 调用子集资源
* @param $childName
* @return mixed
*/
public function __get($childName)
{
return $this->$childName();
}
/**
* 调用自定义方法
* @param $name
* @param $arguments
* @return mixed
* @throws Exception
*/
public function __call($name, $arguments)
{
if (ctype_upper($name[0])) {
$childKey = array_search($name, $this->childResource);
if ($childKey === false) {
throw new Exception(" $name 不属于 {$this->getResourceName()}");
}
$childClassName = !is_numeric($childKey) ? $childKey : $name;
$childClass = __NAMESPACE__ . "\\" . $childClassName;
$resourceID = !empty($arguments) ? $arguments[0] : null;
return new $childClass($this->config, $resourceID, $this->resourceUrl);
} else {
$actionMaps = [
'post' => 'customPostActions',
'put' => 'customPutActions',
'get' => 'customGetActions',
'delete' => 'customDeleteActions',
];
//Get the array key for the action in the actions array
foreach ($actionMaps as $httpMethod => $actionArrayKey) {
$actionKey = array_search($name, $this->$actionArrayKey);
if ($actionKey !== false) break;
}
if ($actionKey === false) {
throw new Exception("No action named $name is defined for " . $this->getResourceName());
}
//If any associative key is given to the action, then it will be considered as the method name,
//otherwise the action name will be the method name
$customAction = !is_numeric($actionKey) ? $actionKey : $name;
//Get the first argument if provided with the method call
$methodArgument = !empty($arguments) ? $arguments[0] : [];
//Url parameters
$urlParams = [];
//Data body
$dataArray = [];
//Consider the argument as url parameters for get and delete request
//and data array for post and put request
if ($httpMethod == 'post' || $httpMethod == 'put') {
$dataArray = $methodArgument;
} else {
$urlParams = $methodArgument;
}
$url = $this->generateUrl($urlParams, null, $customAction);
if ($httpMethod == 'post' || $httpMethod == 'put') {
return $this->$httpMethod($dataArray, $url, false);
} else {
return $this->$httpMethod($dataArray, $url);
}
}
}
private function getResourceName()
{
return substr(get_called_class(), strrpos(get_called_class(), '\\') + 1);
}
public function generateUrl($urlParams = [], $id = null, $customAction = null)
{
$resourceUrl = $this->resourceUrl;
if ($id) {
if ($this->id) {
if ($id !== $this->id) {
$resourceUrl = str_replace($this->id, $id, $this->resourceUrl);
}
} else {
$resourceUrl = $this->resourceUrl . "/$id";
}
}
return $resourceUrl . ($customAction ? "/$customAction" : '') . (!empty($urlParams) ? '?' . http_build_query($urlParams) : '');
}
/**
* 获取数量
* @param array $urlParams
* @return mixed
* @throws Exception
*/
public function count($urlParams = [])
{
if (!$this->countEnabled) {
throw new Exception("当前类{$this->getResourceName()}不支持count()方法");
}
$url = $this->generateUrl($urlParams, null, 'count');
return $this->get([], $url, 'count');
}
/**
* @param array $urlParams
* @param null $url
* @param null $dataKey
* @return mixed
* @throws Exception
*/
public function get($urlParams = [], $url = null, $dataKey = null)
{
if (!$url) $url = $this->generateUrl($urlParams);
$response = $this->httpRequestJson->get($url, $this->httpHeaders);
if (!$dataKey) $dataKey = $this->id ? $this->resourceKey : $this->pluralizeKey;
return $this->processResponse($response, $dataKey);
}
/**
* 分页
* @param null $url
* @param array $urlParams
* @return mixed ['data' => [数据], 'next_link' => '下一页链接']
* @throws Exception
*/
public function page($url = null, $urlParams = [])
{
if (!$url) $url = $this->generateUrl($urlParams);
$response = $this->httpRequestJson->get($url, $this->httpHeaders);
return $this->processPageResponse($response, $this->pluralizeKey);
}
/**
* 根据id获取一条数据
* @param $id
* @param array $urlParams
* @return mixed
* @throws Exception
*/
public function show($id, $urlParams = [])
{
$url = $this->generateUrl($urlParams, $id);
$response = $this->httpRequestJson->get($url, $this->httpHeaders);
return $this->processResponse($response, $this->resourceKey);
}
/**
* @param $dataArray
* @param null $url
* @param bool $wrapData
* @return mixed
* @throws Exception
*/
public function post($dataArray, $url = null, $wrapData = true)
{
if (!$url) $url = $this->generateUrl();
if ($wrapData && !empty($dataArray)) $dataArray = $this->wrapData($dataArray);
$response = $this->httpRequestJson->post($url, $dataArray, $this->httpHeaders);
return $this->processResponse($response, $this->resourceKey);
}
/**
* @param int|string $id
* @param $dataArray
* @param null $url
* @param bool $wrapData
* @return mixed
* @throws Exception
*/
public function put($id, $dataArray, $url = null, $wrapData = true)
{
if (!$url) $url = $this->generateUrl([], $id);
if ($wrapData && !empty($dataArray)) $dataArray = $this->wrapData($dataArray);
$response = $this->httpRequestJson->put($url, $dataArray, $this->httpHeaders);
return $this->processResponse($response, $this->resourceKey);
}
/**
* @param int|string $id
* @param array $urlParams
* @param null $url
* @return mixed
* @throws Exception
*/
public function delete($id = null, $urlParams = [], $url = null)
{
if (!$url) $url = $this->generateUrl($urlParams, $id);
$response = $this->httpRequestJson->delete($url, $this->httpHeaders);
return $this->processResponse($response);
}
protected function wrapData($dataArray, $dataKey = null)
{
if (!$dataKey) $dataKey = $this->resourceKey;
return [$dataKey => $dataArray];
}
protected function castString($array)
{
if (!is_array($array)) return (string)$array;
$string = '';
$i = 0;
foreach ($array as $key => $val) {
$string .= ($i === $key ? '' : "$key - ") . $this->castString($val) . ', ';
$i++;
}
$string = rtrim($string, ', ');
return $string;
}
/**
* 处理响应
* @param array $response
* @param null $dataKey
* @return mixed
* @throws Exception
*/
public function processResponse($response, $dataKey = null)
{
[$code, , $content] = $response;
$content = json_decode($content, true);
if (isset($content['errors'])) {
throw new Exception($this->castString($content['errors']), $code);
}
if ($dataKey && isset($content[$dataKey])) {
return $content[$dataKey];
} else {
return $content;
}
}
/**
* 处理响应
* @param ResponseInterface $response
* @param null $dataKey
* @return mixed
* @throws Exception
*/
public function processPageResponse($response, $dataKey = null)
{
[$code, $headers, $content] = $response;
$content = json_decode($content, true);
$link = $this->getLink($headers);
if (isset($content['errors'])) {
throw new Exception($this->castString($content['errors']), $code);
}
if ($dataKey && isset($content[$dataKey])) {
$data = $content[$dataKey];
} else {
$data = $content;
}
return ['data' => $data, 'next_link' => $link];
}
public function getLink($header, $type = 'next')
{
if (!empty($header['x-shopify-api-version'][0]) && $header['x-shopify-api-version'][0] < '2019-07') {
return null;
}
if (!empty($header['link'][0])) {
$headerLinks = $header['link'][0];
if (stristr($headerLinks, '; rel="' . $type . '"') > -1) {
$headerLinks = explode(',', $headerLinks);
foreach ($headerLinks as $headerLink) {
if (stristr($headerLink, '; rel="' . $type . '"') === -1) {
continue;
}
$pattern = '#<(.*?)>; rel="' . $type . '"#m';
preg_match($pattern, $headerLink, $linkResponseHeaders);
if ($linkResponseHeaders) {
return $linkResponseHeaders[1];
}
}
}
}
return null;
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/24
* Time: 16:50
*/
namespace Meibuyu\Micro\Shoplazza\lib;
class Collect extends AbstractShopify
{
protected $resourceKey = 'collect';
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/24
* Time: 16:50
*/
namespace Meibuyu\Micro\Shoplazza\lib;
/**
* Class Collection
* @package Meibuyu\Micro\Shoplazza\lib
*
* @property-read Metafield $Metafield
*
* @method Metafield Metafield(integer $id = null)
*/
class Collection extends AbstractShopify
{
protected $resourceKey = 'collection';
protected $childResource = [
'Metafield',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/22
* Time: 16:14
*/
namespace Meibuyu\Micro\Shoplazza\lib;
/**
* Class CustomCollection
* @package Meibuyu\Micro\Shoplazza\lib
*
* @property-read Metafield $Metafield
*
* @method Metafield Metafield(integer $id = null)
*/
class CustomCollection extends AbstractShopify
{
protected $resourceKey = 'custom_collection';
protected $childResource = [
'Metafield',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shoplazza\lib;
/**
* Class Event
* @package App\Shoplazza\lib
*/
class Event extends AbstractShopify
{
protected $resourceKey = 'event';
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shoplazza\lib;
/**
* Class Fulfillment
* @package Meibuyu\Micro\Shoplazza\lib
*
* @property-read Event $Event
*
* @method Event Event(integer $id = null)
*
* @method array update_tracking($info) Update Tracking
* @method array complete() Complete a fulfillment
* @method array open() Open a pending fulfillment
* @method array cancel() Cancel a fulfillment
*/
class Fulfillment extends AbstractShopify
{
protected $resourceKey = 'fulfillment';
protected $childResource = [
'FulfillmentEvent' => 'Event',
];
protected $customPostActions = [
'update_tracking',
'complete',
'open',
'cancel',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shoplazza\lib;
/**
* Class FulfillmentEvent
* @package Meibuyu\Micro\Shoplazza\lib
*/
class FulfillmentEvent extends AbstractShopify
{
protected $resourceKey = 'event';
}
<?php
namespace Meibuyu\Micro\Shoplazza\lib;
/**
* Class FulfillmentOrder
* @package Meibuyu\Micro\Shoplazza\lib
*
* @property-read Event $Event
*
* @method array cancel() Cancel a fulfillment order
* @method array close() Marks a fulfillment order as incomplete
* @method array move() Moves a fulfillment order to a new location
*/
class FulfillmentOrder extends AbstractShopify
{
protected $resourceKey = 'fulfillment_order';
protected $customPostActions = [
'cancel',
'close',
'move',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shoplazza\lib;
/**
* Class FulfillmentService
* @package Meibuyu\Micro\Shoplazza\lib
*/
class FulfillmentService extends AbstractShopify
{
protected $resourceKey = 'fulfillment_service';
public $countEnabled = false;
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2021/01/08
* Time: 09:34:30
*/
namespace Meibuyu\Micro\Shoplazza\lib;
use Exception;
use Meibuyu\Micro\Shoplazza\tools\HttpRequestGraphQL;
/**
* Class GraphQL
* @package Meibuyu\Micro\Shoplazza\lib
*/
class GraphQL extends AbstractShopify
{
protected $resourceKey = 'graphql';
protected $pluralizeKey = 'graphql';
public function post($graphQL, $url = null, $wrapData = false, $variables = null)
{
if (!$url) $url = $this->generateUrl();
$response = HttpRequestGraphQL::post($url, $graphQL, $this->httpHeaders, $variables);
return $this->processResponse($response);
}
public function get($urlParams = array(), $url = null, $dataKey = null)
{
throw new Exception("GraphQL 只支持 POST 请求!");
}
public function put($id, $dataArray, $url = null, $wrapData = true)
{
throw new Exception("GraphQL 只支持 POST 请求!");
}
public function delete($id = null, $urlParams = [], $url = null)
{
throw new Exception("GraphQL 只支持 POST 请求!");
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/23
* Time: 8:58
*/
namespace Meibuyu\Micro\Shoplazza\lib;
class InventoryItem extends AbstractShopify
{
protected $resourceKey = 'inventory_item';
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/23
* Time: 8:58
*/
namespace Meibuyu\Micro\Shoplazza\lib;
/**
* Class InventoryLevel
* @package Meibuyu\Micro\Shoplazza\lib
*
* @method array adjust($data) Adjust inventory level.
* @method array connect($data) Connect an inventory item to a location.
* @method array set($data) Sets an inventory level for a single inventory item within a location.
*/
class InventoryLevel extends AbstractShopify
{
protected $resourceKey = 'inventory_level';
protected $customPostActions = [
'adjust',
'connect',
'set',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/23
* Time: 8:58
*/
namespace Meibuyu\Micro\Shoplazza\lib;
/**
* Class Location
* @package Meibuyu\Micro\Shoplazza\lib
*/
class Location extends AbstractShopify
{
protected $resourceKey = 'location';
protected $childResource = [
'InventoryLevel',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/26
* Time: 15:50
*/
namespace Meibuyu\Micro\Shoplazza\lib;
class Metafield extends AbstractShopify
{
protected $resourceKey = 'metafield';
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shoplazza\lib;
/**
* Class Order
* @package Meibuyu\Micro\Shoplazza\lib
*
* @property-read Fulfillment $Fulfillment
* @property-read Event $Event
*
* @method Fulfillment Fulfillment(integer $id = null)
* @method FulfillmentOrder FulfillmentOrder()
* @method Event Event(integer $id = null)
*
* @method array close() Close an Order
* @method array open() Re-open a closed Order
* @method array cancel(array $data) Cancel an Order
*/
class Order extends AbstractShopify
{
protected $resourceKey = 'order';
protected $childResource = [
'Fulfillment',
'FulfillmentOrder',
'Event',
];
protected $customPostActions = [
'close',
'open',
'cancel',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shoplazza\lib;
/**
* Class Product
* @package Meibuyu\Micro\Shoplazza\lib
*
* @property-read ProductImage $Image
* @property-read ProductVariant $Variant
* @property-read Metafield $Metafield
*
* @method ProductImage Image(integer $id = null)
* @method ProductVariant Variant(integer $id = null)
* @method Metafield Metafield(integer $id = null)
*/
class Product extends AbstractShopify
{
protected $resourceKey = 'product';
protected $childResource = [
'ProductImage' => 'Image',
'ProductVariant' => 'Variant',
'Metafield',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shoplazza\lib;
class ProductImage extends AbstractShopify
{
protected $resourceKey = 'image';
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/9/2
* Time: 16:50
*/
namespace Meibuyu\Micro\Shoplazza\lib;
/**
* Class ProductVariant
* @package Meibuyu\Micro\Shoplazza\lib
*
* @property-read Metafield $Metafield
*
* @method Metafield Metafield(integer $id = null)
*/
class ProductVariant extends AbstractShopify
{
protected $resourceKey = 'variant';
protected $childResource = [
'Metafield',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/24
* Time: 16:50
*/
namespace Meibuyu\Micro\Shoplazza\lib;
/**\
* Class SmartCollection
* @package Meibuyu\Micro\Shoplazza\lib
*
* @property-read Metafield $Metafield
*
* @method Metafield Metafield(integer $id = null)
*/
class SmartCollection extends AbstractShopify
{
protected $resourceKey = 'smart_collection';
protected $childResource = [
'Metafield',
];
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/18
* Time: 8:13
*/
namespace Meibuyu\Micro\Shoplazza\lib;
class Webhook extends AbstractShopify
{
protected $resourceKey = 'webhook';
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/19
* Time: 9:06
*/
namespace Meibuyu\Micro\Shoplazza\tools;
use Exception;
/**
* Curl的json格式请求
* Class HttpRequestJson
* @package Meibuyu\Micro\Tools
*/
class CurlHttpRequestJson
{
protected function prepareRequest($headers, $data = [])
{
$data = json_encode($data);
if (!empty($data)) {
$headers['Content-type'] = 'application/json';
$headers['Content-Length'] = strlen($data);
}
return [$headers, $data];
}
/**
* @param $url
* @param array $headers
* @return array
* @throws Exception
* @author zero
*/
public function get($url, $headers = [])
{
return CurlRequest::get($url, $headers);
}
/**
* post请求
* @param $url
* @param $data
* @param array $headers
* @return array
* @throws Exception
* @author zero
*/
public function post($url, $data, $headers = [])
{
[$headers, $data] = self::prepareRequest($headers, $data);
return CurlRequest::post($url, $data, $headers);
}
/**
* put请求
* @param $url
* @param $data
* @param array $headers
* @return array
* @throws Exception
* @author zero
*/
public function put($url, $data, $headers = [])
{
[$headers, $data] = self::prepareRequest($headers, $data);
return CurlRequest::put($url, $data, $headers);
}
/**
* delete请求
* @param $url
* @param array $headers
* @return array
* @throws Exception
* @author zero
*/
public function delete($url, $headers = [])
{
return CurlRequest::delete($url, $headers);
}
}
<?php
namespace Meibuyu\Micro\Shoplazza\tools;
use Exception;
class CurlRequest
{
protected static function init($url, $httpHeaders = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 100); // 设置超时限制防止死循环
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'PHPClassic/PHPShopify');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // 检查证书中是否设置域名
$headers = [];
foreach ($httpHeaders as $key => $value) {
$headers[] = "$key: $value";
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
return $ch;
}
/**
* @param $url
* @param array $httpHeaders
* @return array
* @throws Exception
* @author zero
*/
public static function get($url, $httpHeaders = [])
{
$ch = self::init($url, $httpHeaders);
return self::processRequest($ch);
}
/**
* @param $url
* @param $data
* @param array $httpHeaders
* @return array
* @throws Exception
* @author zero
*/
public static function post($url, $data, $httpHeaders = [])
{
$ch = self::init($url, $httpHeaders);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
return self::processRequest($ch);
}
/**
* @param $url
* @param $data
* @param array $httpHeaders
* @return array
* @throws Exception
* @author zero
*/
public static function put($url, $data, $httpHeaders = [])
{
$ch = self::init($url, $httpHeaders);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
return self::processRequest($ch);
}
/**
* @param $url
* @param array $httpHeaders
* @return array
* @throws Exception
* @author zero
*/
public static function delete($url, $httpHeaders = [])
{
$ch = self::init($url, $httpHeaders);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
return self::processRequest($ch);
}
/**
* @param $ch
* @return array
* @throws Exception
* @author zero
*/
protected static function processRequest($ch)
{
$output = curl_exec($ch);
$response = new CurlResponse($output);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
// if ($httpCode == 429) {
// $limitHeader = explode('/', $response->getHeader('X-Shopify-Shop-Api-Call-Limit')[0], 2);
// if (isset($limitHeader[1]) && $limitHeader[0] < $limitHeader[1]) {
// throw new Exception($response->getBody());
// }
// }
if (curl_errno($ch)) {
throw new Exception(curl_errno($ch) . ' : ' . curl_error($ch));
}
curl_close($ch);
return [$httpCode, $response->getHeaders(), $response->getBody()];
}
}
<?php
namespace Meibuyu\Micro\Shoplazza\tools;
class CurlResponse
{
/** @var array */
private $headers = [];
/** @var string */
private $body;
public function __construct($response)
{
$this->parse($response);
}
/**
* @param string $response
*/
private function parse($response)
{
$response = explode("\r\n\r\n", $response);
if (count($response) > 1) {
// We want the last two parts
$response = array_slice($response, -2, 2);
list($headers, $body) = $response;
foreach (explode("\r\n", $headers) as $header) {
$pair = explode(': ', $header, 2);
if (isset($pair[1])) {
$headerKey = strtolower($pair[0]);
$this->headers[$headerKey][] = $pair[1];
}
}
} else {
$body = $response[0];
}
$this->body = $body;
}
/**
* @return array
*/
public function getHeaders()
{
return $this->headers;
}
/**
* @param string $key
*
* @return string
*/
public function getHeader($key)
{
return isset($this->headers[$key]) ? $this->headers[$key] : null;
}
/**
* @return string
*/
public function getBody()
{
return $this->body;
}
public function __toString()
{
$body = $this->getBody();
$body = $body ?: '';
return $body;
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Time: 2021/1/14 9:16
*/
namespace Meibuyu\Micro\Shoplazza\tools;
class GraphQL
{
public static function parseDeliveryProfileId($gid)
{
if ($gid && stripos($gid, 'gid://shopify/DeliveryProfile/') !== false) {
$gid = str_replace('gid://shopify/DeliveryProfile/', '', $gid);
}
return (int)$gid;
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Time: 2021/1/11 10:10
*/
namespace Meibuyu\Micro\Shoplazza\tools;
use Exception;
class HttpRequestGraphQL
{
/**
* @param array $headers
* @param array $data
* @param null $variables
* @return array
* @throws Exception
* @author zero
*/
protected static function prepareRequest($headers = [], $data = [], $variables = null)
{
if (is_string($data)) {
$postDataGraphQL = $data;
} else {
throw new Exception("Only GraphQL string is allowed!");
}
if (is_array($variables)) {
$postDataGraphQL = json_encode(['query' => $data, 'variables' => $variables]);
$headers['Content-type'] = 'application/json';
} else {
$headers['Content-type'] = 'application/graphql';
}
return [$headers, $postDataGraphQL];
}
/**
* @param $url
* @param $data
* @param array $headers
* @param null $variables
* @return array
* @throws Exception
* @author zero
*/
public static function post($url, $data, $headers = [], $variables = null)
{
[$headers, $postDataGraphQL] = self::prepareRequest($headers, $data, $variables);
return CurlRequest::post($url, $postDataGraphQL, $headers);
}
}
<?php
/**
* Created by PhpStorm.
* User: Zero
* Date: 2020/8/19
* Time: 9:06
*/
namespace Meibuyu\Micro\Shoplazza\tools;
use GuzzleHttp\HandlerStack;
use Hyperf\Guzzle\ClientFactory;
use Hyperf\Guzzle\HandlerStackFactory;
use Psr\Http\Message\ResponseInterface;
/**
* json格式请求
* Class HttpRequestJson
* @package Meibuyu\Micro\Tools
*/
class HttpRequestJson
{
/**
* @var ClientFactory
*/
private $clientFactory;
/**
* @var HandlerStack
*/
private $stack;
public function __construct(ClientFactory $clientFactory)
{
$this->clientFactory = $clientFactory;
$factory = new HandlerStackFactory();
$this->stack = $factory->create();
}
/**
* get请求
* @param $url
* @param array $httpHeaders
* @return ResponseInterface
*/
public function get($url, $httpHeaders = [])
{
$client = $this->clientFactory->create(['timeout' => 60, 'handler' => $this->stack,]);
$res = $client->get($url, ['headers' => $httpHeaders]);
return $this->processResponse($res);
}
/**
* post请求
* @param $url
* @param $data
* @param array $httpHeaders
* @return ResponseInterface
*/
public function post($url, $data, $httpHeaders = [])
{
$client = $this->clientFactory->create(['timeout' => 60, 'handler' => $this->stack,]);
$res = $client->post($url, ['headers' => $httpHeaders, 'json' => $data]);
return $this->processResponse($res);
}
/**
* put请求
* @param $url
* @param $data
* @param array $httpHeaders
* @return ResponseInterface
*/
public function put($url, $data, $httpHeaders = [])
{
$client = $this->clientFactory->create(['timeout' => 60, 'handler' => $this->stack,]);
$res = $client->put($url, ['headers' => $httpHeaders, 'json' => $data]);
return $this->processResponse($res);
}
/**
* delete请求
* @param $url
* @param array $httpHeaders
* @return ResponseInterface
*/
public function delete($url, $httpHeaders = [])
{
$client = $this->clientFactory->create(['timeout' => 60, 'handler' => $this->stack,]);
$res = $client->delete($url, ['headers' => $httpHeaders]);
return $this->processResponse($res);
}
/**
* 处理响应
* @param ResponseInterface $response
* @return mixed
*/
public function processResponse($response)
{
$code = $response->getStatusCode();
$headers = $response->getHeaders();
$content = $response->getBody()->getContents();
return [$code, $headers, $content];
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment