diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a2e58f1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.idea/ +.git/ +runtime/ +vendor/ +.env +.DS_Store +*.lock +*.cache +.bashrc diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php new file mode 100644 index 0000000..8cf2010 --- /dev/null +++ b/.php-cs-fixer.php @@ -0,0 +1,80 @@ +setRiskyAllowed(true) + ->setRules([ + '@PSR2' => true, + '@Symfony' => true, + '@DoctrineAnnotation' => true, + '@PhpCsFixer' => true, + 'array_syntax' => [ + 'syntax' => 'short' + ], + 'list_syntax' => [ + 'syntax' => 'short' + ], + 'concat_space' => [ + 'spacing' => 'one' + ], + 'blank_line_before_statement' => [ + 'statements' => [ + 'declare', + ], + ], + 'general_phpdoc_annotation_remove' => [ + 'annotations' => [ + 'author' + ], + ], + 'ordered_imports' => [ + 'imports_order' => [ + 'class', 'function', 'const', + ], + 'sort_algorithm' => 'alpha', + ], + 'single_line_comment_style' => [ + 'comment_types' => [ + ], + ], + 'yoda_style' => [ + 'always_move_variable' => false, + 'equal' => false, + 'identical' => false, + ], + 'phpdoc_align' => [ + 'align' => 'left', + ], + 'multiline_whitespace_before_semicolons' => [ + 'strategy' => 'no_multi_line', + ], + 'constant_case' => [ + 'case' => 'lower', + ], + 'global_namespace_import' => [ + 'import_classes' => true, + 'import_constants' => true, + 'import_functions' => null, + ], + 'class_attributes_separation' => true, + 'combine_consecutive_unsets' => true, + 'declare_strict_types' => true, + 'linebreak_after_opening_tag' => true, + 'lowercase_static_reference' => true, + 'no_useless_else' => true, + 'no_unused_imports' => true, + 'not_operator_with_successor_space' => true, + 'not_operator_with_space' => false, + 'ordered_class_elements' => true, + 'php_unit_strict' => false, + 'phpdoc_separation' => false, + 'single_quote' => true, + 'standardize_not_equals' => true, + 'multiline_comment_opening_closing' => true, + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->exclude('runtime') + ->exclude('vendor') + ->in(__DIR__) + ) + ->setUsingCache(false); \ No newline at end of file diff --git a/README.md b/README.md index 5b364cb..5f48066 100644 --- a/README.md +++ b/README.md @@ -1 +1,31 @@ -# kwaixiaodian-sdk \ No newline at end of file +# kwaixiaodian-sdk + +let php developer easier to access kwaixiaodian api + +Install the latest version with + +```bash +$ composer require ydg/kwaixiaodian-sdk" +``` + +## Basic Usage + +```php + 'your app_key', + 'app_secret' => 'your app_secret', + 'sign_secret' => 'your sign_secret', + 'access_token' => 'your access_token', + 'http' => [ // set default options to http client + 'headers' => [ + 'Content-Type' => 'application/x-www-form-urlencoded', + 'Accept' => 'application/json;charset=UTF-8', + ], + ] +]); +$app->user->openUserInfoGet(); +``` diff --git a/bootstrap.php b/bootstrap.php new file mode 100644 index 0000000..6a16f77 --- /dev/null +++ b/bootstrap.php @@ -0,0 +1,20 @@ +addAdapter(Adapter\PutenvAdapter::class) + ->immutable() + ->make(); + + Dotenv::create($repository, [BASE_PATH])->load(); +} diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..471a583 --- /dev/null +++ b/composer.json @@ -0,0 +1,39 @@ +{ + "name": "ydg/kwaixiaodian-sdk", + "description": "Easier to create a sdk", + "license": "MIT", + "keywords": [ + "php", + "sdk", + "kwai", + "kwaixiaodian", + "kwaixiaodian-sdk" + ], + "require": { + "php": "^7.0|^8.0", + "ydg/foudation-sdk": "^1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.12", + "phpunit/phpunit": "^9.5", + "vlucas/phpdotenv": "^5.0" + }, + "autoload": { + "psr-4": { + "Ydg\\KwaixiaodianSdk\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "YdgTest\\KwaixiaodianSdk\\": "tests/" + } + }, + "config": { + "optimize-autoloader": true, + "sort-packages": true + }, + "scripts": { + "test": "phpunit", + "cs-fix": "php-cs-fixer fix ." + } +} \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..3be2630 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,21 @@ + + + + + ./src + + + + + ./tests + + + \ No newline at end of file diff --git a/src/Api/Distribution/Distribution.php b/src/Api/Distribution/Distribution.php new file mode 100644 index 0000000..f9a1b2b --- /dev/null +++ b/src/Api/Distribution/Distribution.php @@ -0,0 +1,36 @@ +get('open.distribution.cps.kwaimoney.order.detail', [ + 'oid' => implode(',', $oid), + ]); + } +} \ No newline at end of file diff --git a/src/Api/Distribution/ServiceProvider.php b/src/Api/Distribution/ServiceProvider.php new file mode 100644 index 0000000..b3e8ab6 --- /dev/null +++ b/src/Api/Distribution/ServiceProvider.php @@ -0,0 +1,24 @@ +toArray() : []); + }; + } +} \ No newline at end of file diff --git a/src/Api/User/ServiceProvider.php b/src/Api/User/ServiceProvider.php new file mode 100644 index 0000000..0684cac --- /dev/null +++ b/src/Api/User/ServiceProvider.php @@ -0,0 +1,24 @@ +toArray() : []); + }; + } +} \ No newline at end of file diff --git a/src/Api/User/User.php b/src/Api/User/User.php new file mode 100644 index 0000000..478ff91 --- /dev/null +++ b/src/Api/User/User.php @@ -0,0 +1,19 @@ +get('open.user.info.get'); + } +} \ No newline at end of file diff --git a/src/Kwaixiaodian.php b/src/Kwaixiaodian.php new file mode 100644 index 0000000..bca2766 --- /dev/null +++ b/src/Kwaixiaodian.php @@ -0,0 +1,19 @@ +baseUri = $baseUri; + } + + /** + * @return string + */ + public function getBaseUri(): string + { + return $this->baseUri; + } + + /** + * @throws GuzzleException + */ + public function get($method, $param = []): array + { + return $this->request($method, $param, 'GET'); + } + + /** + * @param string $method + * @param array $param + * @param string $request_method + * @return array + * @throws GuzzleException + */ + public function request(string $method, array $param, string $request_method): array + { + $config = $this->getConfig(); + + $params = [ + 'method' => $method, + 'appkey' => $config['app_key'], + 'access_token' => $config['access_token'], + 'version' => $config['version'], + 'signMethod' => $config['sign_method'], + 'timestamp' => Utils::getMsecTime(), + 'param' => Utils::arrayToJson($param), + ]; + + $params['sign'] = $this->makeSign($params, $config['sign_secret']); + + if ($request_method == 'POST') { + $response = $this->getHttpClient()->get($this->getUri($method), $params); + } else { + $response = $this->getHttpClient()->post($this->getUri($method), $params); + } + + return Utils::jsonResponseToArray($response); + } + + public function getConfig(): array + { + return array_merge(['version' => 1, 'sign_method' => 'MD5'], $this->toArray()); + } + + /** + * @param array $params + * @param string $signSecret + * @return string + */ + public function makeSign(array $params, string $signSecret): string + { + ksort($params); + $paramsStr = ''; + array_walk($params, function ($item, $key) use (&$paramsStr) { + if ('@' != substr((string)$item, 0, 1)) { + $paramsStr .= sprintf('%s%s%s%s', $key, '=', $item, '&'); + } + }); + return md5(sprintf('%s%s%s%s', $paramsStr, 'signSecret', '=', $signSecret)); + } + + /** + * @param string $method + * @return string + */ + public function getUri(string $method): string + { + return $this->getBaseUri() . str_replace('.', '/', $method); + } + + /** + * @throws GuzzleException + */ + public function post($method, $param): array + { + return $this->request($method, $param, 'POST'); + } + + /** + * @throws GuzzleException + */ + public function __call($name, $arguments) + { + // 根据方法名转化为method + $method = strtolower(preg_replace('/(?<=[a-z])([A-Z])/', '.$1', $name)); + + $methods = explode('.', $method); + $action = array_pop($methods); + + $requestMethod = in_array($action, ['list', 'detail']) ? 'GET' : 'POST'; + + return $this->request($method, $arguments[0] ?? [], $requestMethod); + } + + public function getHttpClientDefaultOptions(): array + { + return [ + 'headers' => [ + 'Content-Type' => 'application/x-www-form-urlencoded', + 'Accept' => 'application/json;charset=UTF-8', + ], + 'verify' => false + ]; + } +} \ No newline at end of file diff --git a/src/Oauth/Oauth.php b/src/Oauth/Oauth.php new file mode 100644 index 0000000..9102952 --- /dev/null +++ b/src/Oauth/Oauth.php @@ -0,0 +1,51 @@ +getConfig(); + $response = $this->getHttpClient()->request('GET', $this->getBaseUri() . 'oauth2/access_token', [ + 'query' => [ + 'app_id' => $config['app_key'], + 'app_secret' => $config['app_secret'], + 'grant_type' => $grant_type, + 'code' => $code, + ], + ]); + return Utils::jsonResponseToArray($response); + } + + /** + * @param $refresh_token + * @return array + * @throws GuzzleException + */ + public function refreshToken($refresh_token): array + { + $config = $this->getConfig(); + $response = $this->getHttpClient()->request('GET', $this->getBaseUri() . 'oauth2/refresh_token', [ + 'query' => [ + 'app_id' => $config['app_key'], + 'app_secret' => $config['app_secret'], + 'grant_type' => 'refresh_token', + 'refresh_token' => $refresh_token, + ], + ]); + return Utils::jsonResponseToArray($response); + } +} \ No newline at end of file diff --git a/src/Oauth/ServiceProvider.php b/src/Oauth/ServiceProvider.php new file mode 100644 index 0000000..9434567 --- /dev/null +++ b/src/Oauth/ServiceProvider.php @@ -0,0 +1,24 @@ +toArray() : []); + }; + } +} \ No newline at end of file diff --git a/src/Support/Utils.php b/src/Support/Utils.php new file mode 100644 index 0000000..4d31565 --- /dev/null +++ b/src/Support/Utils.php @@ -0,0 +1,26 @@ +getBody()->getContents(), true); + } +} \ No newline at end of file diff --git a/tests/AbstractTest.php b/tests/AbstractTest.php new file mode 100644 index 0000000..b605e62 --- /dev/null +++ b/tests/AbstractTest.php @@ -0,0 +1,26 @@ + 'your app_key', + 'app_secret' => 'your app_secret', + 'sign_secret' => 'your sign_secret', + 'access_token' => 'your access_token', + ]; + } + + public function isSuccessResponse($response) + { + $this->assertArrayHasKey('result', $response); + $this->assertEquals(1, $response['result']); + } +} \ No newline at end of file diff --git a/tests/Api/DistributionTest.php b/tests/Api/DistributionTest.php new file mode 100644 index 0000000..0dbb0d5 --- /dev/null +++ b/tests/Api/DistributionTest.php @@ -0,0 +1,58 @@ +getConfig()); + $response = $app->distribution->openDistributionCpsKwaimoneyPidList([ + 'page' => 1, + 'pageSize' => 10, + ]); + $this->isSuccessResponse($response); + } + + public function testOpenDistributionCpsKwaimoneySelectionItemList() + { + $app = new Kwaixiaodian($this->getConfig()); + $response = $app->distribution->openDistributionCpsKwaimoneySelectionItemList([ + 'pageIndex' => 1, + 'pageSize' => 10, + 'planType' => 1, + ]); + $this->isSuccessResponse($response); + } + + public function testOpenDistributionCpsKwaimoneyLinkCreate() + { + $app = new Kwaixiaodian($this->getConfig()); + + $pidListResult = $app->distribution->openDistributionCpsKwaimoneyPidList([ + 'page' => 1, + 'pageSize' => 1, + ]); + $pid = $pidListResult['data']['cpsPidData'][0]; + + $itemListResult = $app->distribution->openDistributionCpsKwaimoneySelectionItemList([ + 'pageIndex' => 1, + 'pageSize' => 1, + 'planType' => 1, + ]); + $item = $itemListResult['data']['itemList'][0]; + + $response = $app->distribution->openDistributionCpsKwaimoneyLinkCreate([ + 'linkType' => 101, + 'linkCarrierId' => $item['goodsId'], + 'comments' => 'sdk_test', + 'cpsPid' => $pid['cpsPid'], + ]); + $this->isSuccessResponse($response); + } +} \ No newline at end of file diff --git a/tests/Api/UserTest.php b/tests/Api/UserTest.php new file mode 100644 index 0000000..f1a05de --- /dev/null +++ b/tests/Api/UserTest.php @@ -0,0 +1,21 @@ +getConfig()); + $response = $app->user->openUserInfoGet(); + $this->isSuccessResponse($response); + } +} \ No newline at end of file